mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Added a chapter about locking to PLUGINS.html
This commit is contained in:
parent
a4cde807bc
commit
d756628297
@ -2538,6 +2538,7 @@ Markus Ehrnsperger <markus.ehrnsperger@googlemail.com>
|
||||
for reporting a bug in error handling when loading a plugin
|
||||
for reporting a possible crash in cIndexFile::GetClosestIFrame()
|
||||
for reporting a missing 'const' in cTimers::GetTimerForEvent()
|
||||
for suggesting to add a chapter about locking to PLUGINS.html
|
||||
|
||||
Werner Färber <w.faerber@gmx.de>
|
||||
for reporting a bug in handling the cPluginManager::Active() result when pressing
|
||||
|
1
HISTORY
1
HISTORY
@ -9800,3 +9800,4 @@ Video Disk Recorder Revision History
|
||||
- Fixed a possible deadlock in case two SVDRP clients send each other POLL commands
|
||||
at the same time.
|
||||
- Added a missing 'const' to cTimers::GetTimerForEvent() (reported by Markus Ehrnsperger).
|
||||
- Added a chapter about locking to PLUGINS.html (suggested by Markus Ehrnsperger).
|
||||
|
53
PLUGINS.html
53
PLUGINS.html
@ -83,6 +83,7 @@ structures and allows it to hook itself into specific areas to perform special a
|
||||
<li><a href="#Internationalization">Internationalization</a>
|
||||
<li><a href="#Custom services">Custom services</a>
|
||||
<li><a href="#SVDRP commands">SVDRP commands</a>
|
||||
<li><a href="#Locking">Locking</a>
|
||||
<li><a href="#Loading plugins into VDR">Loading plugins into VDR</a>
|
||||
<li><a href="#Building the distribution package">Building the distribution package</a>
|
||||
</ul>
|
||||
@ -1185,9 +1186,59 @@ when presenting them to the caller, and the continuation character ('<tt>-</tt>'
|
||||
will be set for all but the last one.
|
||||
<p>
|
||||
<b>The SVDRP functions are called from the separate "SVDRP server handler" thread.
|
||||
Therefore the plugin needs to take care of proper locking if it accesses any
|
||||
Therefore the plugin needs to take care of proper <a href="#Locking">locking</a> if it accesses any
|
||||
global data.</b>
|
||||
|
||||
<hr><h2><a name="Locking">Locking</a></h2>
|
||||
|
||||
<div class="blurb">U can't touch this</div><p>
|
||||
|
||||
When accessing global data structures, proper locking is absolutely necessary.
|
||||
<p>
|
||||
There are several macros that allow for easy locking and unlocking. They all
|
||||
follow the naming convention <tt>LOCK_*_READ|WRITE</tt>, where <tt>'*'</tt> is the name
|
||||
of the global data structure, which can be one of <tt>TIMERS</tt>, <tt>CHANNELS</tt>,
|
||||
<tt>RECORDINGS</tt> or <tt>SCHEDULES</tt>. To implicitly avoid deadlocks in case you
|
||||
need to lock more than one structure, always make sure you use these macros in
|
||||
this sequence!
|
||||
<p>
|
||||
Using one of these macros sets a lock on the structure, creates a local pointer to the
|
||||
respective structure and makes sure the lock is released at the end of the current
|
||||
block:
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
if (some condition) {
|
||||
LOCK_TIMERS_READ; // creates local const cTimers *Timers
|
||||
for (const cTimer *Timer = Timers->First(); Timer; Timer = Timers->Next(Timer)) {
|
||||
// do something with Timer
|
||||
}
|
||||
}
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
Note the naming convention: TIMERS -> Timers etc.
|
||||
<p>
|
||||
The <tt>LOCK_*_READ</tt> macros create pointers that are '<tt>const</tt>', while
|
||||
the <tt>LOCK_*_WRITE</tt> macros allow modifications to the data structures.
|
||||
Both wait indefinitely to obtain the lock. However, if <tt>LOCK_*_WRITE</tt> is
|
||||
used twice in the same block, the second call will not obtain a lock and
|
||||
immediately return <tt>NULL</tt>, which may lead to a crash. In such cases a
|
||||
warning and backtrace is logged.
|
||||
<p>
|
||||
You may keep pointers to objects in such lists, even after releasing
|
||||
the lock. However, you may only access such objects if you are
|
||||
holding a proper lock again. If an object has been deleted from the list
|
||||
while you did not hold a lock (for instance by an other thread), the
|
||||
object will still be there, but no longer within this list (it is then
|
||||
stored in the ListGarbageCollector for a few seconds). That way even if you
|
||||
access the object after it has been deleted, you won't cause a segfault.
|
||||
You can call the Contains() function to check whether an object you are
|
||||
holding a pointer to is still in the list. Note that the garbage collector
|
||||
is purged when the usual housekeeping is done.
|
||||
<p>
|
||||
See tools.h, class <tt>cListBase</tt> for more documentation and information on how
|
||||
to use locking with timeouts, and thread.h, classes <tt>cStateLock</tt> and
|
||||
<tt>cStateKey</tt> on how to easily react to changes in such lists.
|
||||
|
||||
<hr><h2><a name="Loading plugins into VDR">Loading plugins into VDR</a></h2>
|
||||
|
||||
<div class="blurb">Saddling up!</div><p>
|
||||
|
Loading…
Reference in New Issue
Block a user