diff options
Diffstat (limited to 'docs/design/part-miniobject.txt')
-rw-r--r-- | docs/design/part-miniobject.txt | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/docs/design/part-miniobject.txt b/docs/design/part-miniobject.txt new file mode 100644 index 0000000..8c04780 --- /dev/null +++ b/docs/design/part-miniobject.txt @@ -0,0 +1,209 @@ +GstMiniObject +------------- + +This document describes the design of the miniobject base class. + +The miniobject abstract base class is used to construct lightweight refcounted +and boxed types that are frequently created and destroyed. + +Requirements +~~~~~~~~~~~~ + + - Be lightweight + - Refcounted + - I must be possible to control access to the object, ie. when the object is + readable and writable. + - Subclasses must be able to use their own allocator for the memory. + + +Usage +~~~~~ + +Users of the GstMiniObject infrastructure will need to define a structure that +includes the GstMiniObject structure as the first field. + + struct { + GstMiniObject mini_object; + + /* my fields */ + ... + } MyObject + +The subclass should then implement a constructor method where it allocates the +memory for its structure and initializes the miniobject structure with +gst_mini_object_init(). Copy and Free functions are provided to the +gst_mini_object_init() function. + + MyObject * + my_object_new() + { + MyObject *res = g_slice_new (MyObject); + + gst_mini_object_init (GST_MINI_OBJECT_CAST (res), 0, + MY_TYPE_OBJECT, + (GstMiniObjectCopyFunction) _my_object_copy, + (GstMiniObjectDisposeFunction) NULL, + (GstMiniObjectFreeFunction) _my_object_free); + + /* other init */ + ..... + + return res; + } + +The Free function is responsible for freeing the allocated memory for +the structure. + + static void + _my_object_free (MyObject *obj) + { + /* other cleanup */ + ... + + g_slice_free (MyObject, obj); + } + + +Lifecycle +~~~~~~~~~ + +GstMiniObject is refcounted. When a GstMiniObject is first created, +it has a refcount of 1. + +Each variable holding a reference to a GstMiniObject is responsible for +updating the refcount. This includes incrementing the refcount with +gst_mini_object_ref() when a reference is kept to a miniobject or +gst_mini_object_unref() when a reference is released. + +When the refcount reaches 0, and thus no objects hold a reference to the +miniobject anymore, we can free the miniobject. + +When freeing the miniobject, first the GstMiniObjectDisposeFunction is called. +This function is allowed to revive the object again by incrementing the +refcount, in which case it should return FALSE from the dispose function. The +dispose function is used by GstBuffer to revive the buffer back into the +GstBufferPool when needed. + +When the dispose function returns TRUE, the GstMiniObjectFreeFunction will be +called and the miniobject will be freed. + + +Copy +~~~~ + +A miniobject can be copied with gst_mini_object_copy(). This function will +call the custom copy function that was provided when registering the new +GstMiniObject subclass. + +The copy function should try to preserve as much info from the original object +as possible. + +The new copy should be writable. + + +Access management +~~~~~~~~~~~~~~~~~ + +GstMiniObject can be shared between multiple threads. It is important that when +a thread writes to a GstMiniObject that the other threads don't not see the +changes. + +To avoid exposing changes from one thread to another thread, the miniobjects +are managed in a Copy-On-Write way. A copy is only made when it is known that +the object is shared between multiple objects or threads. + +There are 2 methods implemented for controlling access to the miniobject. + + - A first method relies on the refcount of the object to control writability. + Objects using this method have the LOCKABLE flag unset. + + - A second method relies on a separate counter for controlling + the access to the object. Objects using this method have the LOCKABLE flag + set. + + You can check if an object is writable with gst_mini_object_is_writable() and + you can make any miniobject writable with gst_mini_object_make_writable(). + This will create a writable copy when the object was not writable. + + + non-LOCKABLE GstMiniObjects + --------------------------- + + These GstMiniObjects have the LOCKABLE flag unset. They use the refcount value + to control writability of the object. + + When the refcount of the miniobject is > 1, the objects it referenced by at + least 2 objects and is thus considered unwritable. A copy must be made before a + modification to the object can be done. + + Using the refcount to control writability is problematic for many language + bindings that can keep additional references to the objects. This method is + mainly for historical reasons until all users of the miniobjects are + converted to use the LOCAKBLE flag. + + + LOCKABLE GstMiniObjects + ----------------------- + + These GstMiniObjects have the LOCKABLE flag set. They use a separate counter + for controlling writability and access to the object. + + It consists of 2 components: + + * exclusive counter + + Each object that wants to keep a reference to a GstMiniObject and doesn't want to + see the changes from other owners of the same GstMiniObject needs to lock the + GstMiniObject in EXCLUSIVE mode, which will increase the exclusive counter. + + The exclusive counter counts the amount of objects that share this + GstMiniObject. The counter is initially 0, meaning that the object is not shared with + any object. + + When a reference to a GstMiniObject release, both the ref count and the + exclusive counter will be decreased with gst_mini_object_unref() and + gst_mini_object_unlock () respectively. + + * locking + + All read and write access must be performed between a gst_mini_object_lock() and + gst_mini_object_unlock() pair with the requested access method. + + A gst_mini_object_lock() can fail when a WRITE lock is requested and the exclusive + counter is > 1. Indeed a GstMiniObject object with an exclusive counter > 1 is + locked EXCLUSIVELY by at least 2 objects and is therefore not writable. + + Once the GstMiniObject is locked with a certain access mode, it can be recursively + locked with the same or narrower access mode. For example, first locking the + GstMiniObject in READWRITE mode allows you to recusively lock the + GstMiniObject in + READWRITE, READ and WRITE mode. Memory locked in READ mode cannot be locked + recursively in WRITE or READWRITE mode. + + Note that multiple threads can READ lock the GstMiniObject concurrently but cannot + lock the object in WRITE mode because the exclusive counter must be > 1. + + All calls to gst_mini_object_lock() need to be paired with one + gst_mini_object_unlock() call with the same access mode. When the last refcount + of the object is removed, there should be no more outstanding locks. + + Note that a shared counter of both 0 and 1 leaves the GstMiniObject writable. The + reason is to make it easy to create and pass ownership of the GstMiniObject to + another object while keeping it writable. When the GstMiniObject is + created with a shared count of 0, it is writable. When the GstMiniObject is then + added to another object, the shared count is incremented to 1 and the + GstMiniObject remains writable. The 0 share counter has a similar purpose as the floating + reference in GObject. + + +Weak references +~~~~~~~~~~~~~~~ + +GstMiniObject has support for weak references. A callback will be called when +the object is freed for all registered weak references. + + +QData +~~~~~ + +Extra data can be associated with a GstMiniObject by using the QData API. |