docs: update synchronization docs
[platform/upstream/gstreamer.git] / docs / design / part-MT-refcounting.txt
1 Conventions for thread a safe API
2 ---------------------------------
3
4 The GStreamer API is designed to be thread safe. This means that API functions
5 can be called from multiple threads at the same time. GStreamer internally uses
6 threads to perform the data passing and various asynchronous services such as
7 the clock can also use threads.
8
9 This design decision has implications for the usage of the API and the objects
10 which this document explains.
11
12 MT safety techniques
13 ~~~~~~~~~~~~~~~~~~~~
14
15 Several design patterns are used to guarantee object consistency in GStreamer.
16 This is an overview of the methods used in various GStreamer subsystems.
17
18 Refcounting:
19
20   All shared objects have a refcount associated with them. Each reference
21   obtained to the object should increase the refcount and each reference lost
22   should decrease the refcount.
23
24   The refcounting is used to make sure that when another thread destroys the
25   object, the ones which still hold a reference to the object do not read from
26   invalid memory when accessing the object.
27
28   Refcounting is also used to ensure that mutable data structures are only
29   modified when they are owned by the calling code.
30
31   It is a requirement that when two threads have a handle on an object, the
32   refcount must be more than one. This means that when one thread passes an
33   object to another thread it must increase the refcount. This requirement makes
34   sure that one thread cannot suddenly dispose the object making the other
35   thread crash when it tries to access the pointer to invalid memory.
36
37 Shared data structures and writability:
38
39   All objects have a refcount associated with them. Each reference obtained to
40   the object should increase the refcount and each reference lost should
41   decrease the refcount.
42
43   Each thread having a refcount to the object can safely read from the object.
44   but modifications made to the object should be preceeded with a
45   _get_writable() function call. This function will check the refcount of the
46   object and if the object is referenced by more than one instance, a copy is
47   made of the object that is then by definition only referenced from the calling
48   thread. This new copy is then modifiable without being visible to other
49   refcount holders.
50
51   This technique is used for information objects that, once created, never
52   change their values. The lifetime of these objects is generally short, the
53   objects are usually simple and cheap to copy/create.
54
55   The advantage of this method is that no reader/writers locks are needed. all
56   threads can concurrently read but writes happen locally on a new copy. In most
57   cases _get_writable() can avoid a real copy because the calling method is the
58   only one holding a reference, which makes read/write very cheap.
59
60   The drawback is that sometimes 1 needless copy can be done. This would happen
61   when N threads call _get_writable() at the same time, all seeing that N
62   references are held on the object. In this case 1 copy too many will be done.
63   This is not a problem in any practical situation because the copy operation is
64   fast.
65  
66 Mutable substructures:
67
68   Special techniques are necessary to ensure the consistency of compound shared
69   objects. As mentioned above, shared objects need to have a reference count of
70   1 if they are to be modified. Implicit in this assumption is that all parts of
71   the shared object belong only to the object. For example, a GstStructure in
72   one GstCaps object should not belong to any other GstCaps object. This
73   condition suggests a parent-child relationship: structures can only be added
74   to parent object if they do not already have a parent object.
75
76   In addition, these substructures must not be modified while more than one code
77   segment has a reference on the parent object. For example, if the user creates
78   a GstStructure, adds it to a GstCaps, and the GstCaps is then referenced by
79   other code segments, the GstStructure should then become immutable, so that
80   changes to that data structure do not affect other parts of the code. This
81   means that the child is only mutable when the parent's reference count is 1,
82   as well as when the child structure has no parent.
83
84   The general solution to this problem is to include a field in child structures
85   pointing to the parent's atomic reference count. When set to NULL, this
86   indicates that the child has no parent. Otherwise, procedures that modify the
87   child structure must check if the parent's refcount is 1, and otherwise must
88   cause an error to be signaled.
89
90   Note that this is an internal implementation detail; application or plugin
91   code that calls _get_writable() on an object is guaranteed to receive an
92   object of refcount 1, which must then be writable. The only trick is that a
93   pointer to a child structure of an object is only valid while the calling code
94   has a reference on the parent object, because the parent is the owner of the
95   child.
96
97 Object locking:
98
99   For objects that contain state information and generally have a longer
100   lifetime, object locking is used to update the information contained in the
101   object.
102
103   All readers and writers acquire the lock before accessing the object. Only one
104   thread is allowed access the protected structures at a time.
105
106   Object locking is used for all objects extending from GstObject such as
107   GstElement, GstPad.
108
109   Object locking can be done with recursive locks or regular mutexes. Object
110   locks in GStreamer are implemented with mutexes which cause deadlocks when
111   locked recursively from the same thread. This is done because regular mutexes
112   are cheaper.
113
114 Atomic operations
115
116   Atomic operations are operations that are performed as one consistent
117   operation even when executed by multiple threads. They do however not use the
118   conventional aproach of using mutexes to protect the critical section but rely
119   on CPU features and instructions.
120
121   The advantages are mostly speed related since there are no heavyweight locks
122   involved. Most of these instructions also do not cause a context switch in case
123   of concurrent access but use a retry mechanism or spinlocking.
124
125   Disadvantages are that each of these instructions usually cause a cache flush
126   on multi-CPU machines when two processors perform concurrent access.
127
128   Atomic operations are generally used for refcounting and for the allocation of
129   small fixed size objects in a memchunk. They can also be used to implement a
130   lockfree list or stack.
131
132 Compare and swap
133
134   As part of the atomic operations, compare-and-swap (CAS) can be used to access
135   or update a single property or pointer in an object without having to take a
136   lock.
137
138   This technique is currently not used in GStreamer but might be added in the
139   future in performance critical places.
140  
141
142 Objects
143 ~~~~~~~
144
145 * Locking involved:
146
147     - atomic operations for refcounting
148     - object locking
149
150   All objects should have a lock associated with them. This lock is used to keep
151   internal consistency when multiple threads call API function on the object.
152
153   For objects that extend the GStreamer base object class this lock can be
154   obtained with the macros GST_OBJECT_LOCK() and GST_OBJECT_UNLOCK(). For other object that do
155   not extend from the base GstObject class these macros can be different.
156
157 * refcounting
158
159   All new objects created have the FLOATING flag set. This means that the object
160   is not owned or managed yet by anybody other than the one holding a reference
161   to the object. The object in this state has a reference count of 1.
162
163   Various object methods can take ownership of another object, this means that
164   after calling a method on object A with an object B as an argument, the object
165   B is made sole property of object A. This means that after the method call you
166   are not allowed to access the object anymore unless you keep an extra
167   reference to the object. An example of such a method is the _bin_add() method.
168   As soon as this function is called in a Bin, the element passed as an argument
169   is owned by the bin and you are not allowed to access it anymore without
170   taking a _ref() before adding it to the bin. The reason being that after the
171   _bin_add() call disposing the bin also destroys the element.
172
173   Taking ownership of an object happens through the process of "sinking" the
174   object. the _sink() method on an object will decrease the refcount of the
175   object if the FLOATING flag is set. The act of taking ownership of an object
176   is then performed as a _ref() followed by a _sink() call on the object.
177
178   The float/sink process is very useful when initializing elements that will
179   then be placed under control of a parent. The floating ref keeps the object
180   alive until it is parented, and once the object is parented you can forget
181   about it.
182
183   also see part-relations.txt
184   
185 * parent-child relations
186
187   One can create parent-child relationships with the _object_set_parent()
188   method. This method refs and sinks the object and assigns its parent property
189   to that of the managing parent.
190
191   The child is said to have a weak link to the parent since the refcount of the
192   parent is not increased in this process. This means that if the parent is
193   disposed it has to unset itself as the parent of the object before disposing
194   itself, else the child object holds a parent pointer to invalid memory.
195   
196   The responsibilities for an object that sinks other objects are summarised as:
197
198    - taking ownership of the object
199      - call _object_set_parent() to set itself as the object parent, this call
200        will _ref() and _sink() the object.
201      - keep reference to object in a datastructure such as a list or array.
202
203    - on dispose
204      - call _object_unparent() to reset the parent property and unref the
205        object.
206      - remove the object from the list.
207
208   also see part-relations.txt
209
210 * Properties
211   
212   Most objects also expose state information with public properties in the
213   object. Two types of properties might exist: accessible with or without
214   holding the object lock. All properties should only be accessed with their
215   corresponding macros. The public object properties are marked in the .h files
216   with /*< public >*/. The public properties that require a lock to be held are
217   marked with /*< public >*/ /* with <lock_type> */, where <lock_type> can be
218   "LOCK" or "STATE_LOCK" or any other lock to mark the type(s) of lock to be 
219   held.
220
221   Example:
222
223     in GstPad there is a public property "direction". It can be found in the
224     section marked as public and requiring the LOCK to be held. There exists
225     also a macro to access the property.
226
227       struct _GstRealPad {
228         ...
229         /*< public >*/ /* with LOCK */
230         ...
231         GstPadDirection                direction;
232         ...
233       };
234
235       #define GST_RPAD_DIRECTION(pad)      (GST_REAL_PAD_CAST(pad)->direction)
236   
237     Accessing the property is therefore allowed with the following code example:
238
239       GST_OBJECT_LOCK (pad);
240       direction = GST_RPAD_DIRECTION (pad);
241       GST_OBJECT_UNLOCK (pad);
242
243 * Property lifetime
244
245   All properties requiring a lock can change after releasing the associated
246   lock. This means that as long as you hold the lock, the state of the
247   object regarding the locked properties is consistent with the information
248   obtained. As soon as the lock is released, any values acquired from the
249   properties might not be valid anymore and can as best be described as a
250   snapshot of the state when the lock was held.
251
252   This means that all properties that require access beyond the scope of the
253   critial section should be copied or refcounted before releasing the lock.
254
255   Most object provide a _get_<property>() method to get a copy or refcounted
256   instance of the property value. The caller should not wory about any locks
257   but should unref/free the object after usage.
258
259   Example:
260
261     the following example correctly gets the peer pad of an element. It is
262     required to increase the refcount of the peer pad because as soon as the
263     lock is released, the peer could be unreffed and disposed, making the
264     pointer obtained in the critical section point to invalid memory.
265
266       GST_OBJECT_LOCK (pad);
267       peer = GST_RPAD_PEER (pad);
268       if (peer)
269         gst_object_ref (GST_OBJECT (peer));
270       GST_OBJECT_UNLOCK (pad);
271       ... use peer ...
272
273       if (peer)
274         gst_object_unref (GST_OBJECT (peer));
275
276     Note that after releasing the lock the peer might not actually be the peer
277     anymore of the pad. If you need to be sure it is, you need to extend the
278     critical section to include the operations on the peer.
279
280     The following code is equivalent to the above but with using the functions
281     to access object properties.
282
283       peer = gst_pad_get_peer (pad);
284       if (peer) {
285         ... use peer ...
286
287         gst_object_unref (GST_OBJECT (peer));
288       }
289
290   Example:
291
292     Accessing the name of an object makes a copy of the name. The caller of the
293     function should g_free() the name after usage.
294
295       GST_OBJECT_LOCK (object)
296       name = g_strdup (GST_OBJECT_NAME (object));
297       GST_OBJECT_UNLOCK (object)
298       ... use name ...
299
300       g_free (name);
301
302     or:
303
304       name = gst_object_get_name (object);
305
306       ... use name ...
307
308       g_free (name);
309     
310
311 * Accessor methods
312
313   For aplications it is encouraged to use the public methods of the object. Most
314   useful operations can be performed with the methods so it is seldom required
315   to access the public fields manually.
316
317   All accessor methods that return an object should increase the refcount of the
318   returned object. The caller should _unref() the object after usage. Each
319   method should state this refcounting policy in the documentation.
320
321 * Accessing lists
322
323   If the object property is a list, concurrent list iteration is needed to get
324   the contents of the list. GStreamer uses the cookie mechanism to mark the last
325   update of a list. The list and the cookie are protected by the same lock. Each
326   update to a list requires the following actions:
327
328    - acquire lock
329    - update list
330    - update cookie
331    - release lock
332
333   Updating the cookie is usually done by incrementing its value by one. Since
334   cookies use guint32 its wraparound is for all practical reasons is not a
335   problem.
336
337   Iterating a list can safely be done by surrounding the list iteration with a
338   lock/unlock of the lock.
339
340   In some cases it is not a good idea to hold the lock for a long time while
341   iterating the list. The state change code for a bin in GStreamer, for example,
342   has to iterate over each element and perform a blocking call on each of them
343   potentially causing infinite bin locking. In this case the cookie can be used 
344   to iterate a list.
345
346   Example:
347
348      The following algorithm iterates a list and reverses the updates in the
349      case a concurrent update was done to the list while iterating. The idea is
350      that whenever we reacquire the lock, we check for updates to the cookie to
351      decide if we are still iterating the right list.
352
353      GST_OBJECT_LOCK (lock);
354      /* grab list and cookie */
355      cookie = object->list_cookie;
356      list = object-list;
357      while (list) {
358        GstObject *item = GST_OBJECT (list->data);
359        /* need to ref the item before releasing the lock */
360        gst_object_ref (item);
361        GST_OBJECT_UNLOCK (lock);
362
363        ... use/change item here...
364
365        /* release item here */
366        gst_object_unref (item);
367   
368        GST_OBJECT_LOCK (lock);
369        if (cookie != object->list_cookie) {
370          /* handle rollback caused by concurrent modification 
371           * of the list here */
372
373          ...rollback changes to items...
374
375          /* grab new cookie and list */
376          cookie = object->list_cookie;
377          list = object->list;
378        }
379        else {
380          list = g_list_next (list);
381        }
382      }
383      GST_OBJECT_UNLOCK (lock);
384
385 * GstIterator
386
387   GstIterator provides an easier way of retrieving elements in a concurrent
388   list. The following code example is equivalent to the previous example.
389   
390   Example:
391     
392     it = _get_iterator(object);
393     while (!done) {
394       switch (gst_iterator_next (it, &item)) {
395         case GST_ITERATOR_OK:
396
397           ... use/change item here...
398
399           /* release item here */
400           gst_object_unref (item);
401           break;
402         case GST_ITERATOR_RESYNC:
403           /* handle rollback caused by concurrent modification 
404            * of the list here */
405
406           ...rollback changes to items...
407
408           /* resync iterator to start again */
409           gst_iterator_resync (it);
410           break;
411         case GST_ITERATOR_DONE:
412           done = TRUE;
413           break;
414       }
415     }
416     gst_iterator_free (it);
417