| -*- Mode: text -*- | |
| Sometimes it's difficult to use GStreamer in real applications where the GUI and | |
| the GStreamer pipeline are in different threads. You have to somehow make sure | |
| that the object is not modifying its properties while you get and set them. This | |
| document is a brief outline of a potential fix to this issue. | |
| * When is it safe to get or set properties? | |
| Well, it is only safe to do so when other threads are not accessing an object. | |
| So, from the main thread, it is only safe to query or modify properties on an | |
| object when it is not in the RUNNING state, because when it is RUNNING its | |
| properties are potentially changing in the thread of execution. | |
| The only place that it is safe to get or set properties while in the RUNNING | |
| state is from within the thread of execution. Thus, something within the | |
| iteration loop of the thread must check to see if there are pending property | |
| changes or queries. There are two places this could be done, from within | |
| gstthread itself and from within the scheduler. Doing it from gstthread sounds | |
| like a good idea because it keeps more code out of the scheduler, but is also | |
| bad in a way because it requires a gstthread-specific api to proxy prop_set and | |
| prop_get. Setting it in the scheduler sounds good because of its finer | |
| granularity, but might be bad because it would clutter the scheduler a bit more. | |
| I propose to go with the scheduler-based solution based on system response time | |
| and out of potentials for integration with gst_clock_wait. | |
| * Implementation | |
| We do want to preserve some measure of generality, however. Considering that | |
| more threadsafety issues could pop up in the future, it would be nice to have | |
| one function to call from the scheduler, in the interests of code | |
| simplification. This function will be present in some elements and not in | |
| others, and will be modified at run time, so we will make it a function pointer | |
| within the GstElement struct. | |
| struct _GstElement { | |
| ... | |
| void (*pre_run_func) (GstElement *); | |
| void (*post_run_func) (GstElement *); | |
| } | |
| Only the managing bin of an element is allowed to set that function, because | |
| presumably that bin would know something about how to schedule the element. | |
| Then, in the scheduler, before we call chain functions and before we switch into | |
| loop functions: | |
| if (element->pre_run_func) | |
| element->pre_run_func (element); | |
| Then, to get or set properties, we use the new functions gst_element_get or | |
| gst_element_set. _set would add the property name and a gvalue onto a queue | |
| (probably a GAsyncQueue). Then the pre_run_func would go ahead and set the | |
| properties. _get is a little more tricky; _set doesn't hardly block at all, | |
| although it's not instantaneous. With _get though, you really don't know what | |
| the properties are until you query them. The best thing would be to connect to | |
| the ::notify signal, which executes within the thread of interest. However, say | |
| you really want to use _get. Hmm. I think that it would have to block. On what? | |
| Well, probably on an element's mutex. So it seems we might need a | |
| post_run_func too, to unlock the mutex. We can use the GstObject lock for this. | |
| But we need a little more. How do we know whether or not just calling | |
| g_object_get/set is ok? I'm thinking this whole prop set/get proxy thing should | |
| not be abstracted away, that it should be contained in gstelement.c. There are | |
| more kinds of bins that need threadsafety than just gstthread (I'm thinking | |
| about jack here). So, we can add on a GAsyncQueue *prop_set_queue; to the | |
| GstElement struct, and only initialize it in certain managing bins. Then, we can | |
| set a flag on gstelement, GST_ELEMENT_USE_THREADSAFE_PROPERTIES. If this flag is | |
| set (by the managing bin), do all this complicated mess; otherwise use the | |
| gobject native functionality. | |
| So, this is the plan. We'll see how the implementation goes. This should make MT | |
| gst programming much easier. | |
| wingo. | |
| 25 May 2002. |