From 9a6e87b6b6b46883825f700b9a7d6b1e862abbf1 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sat, 25 May 2002 20:58:08 +0000 Subject: [PATCH] added design doc for threadsafe properties Original commit message from CVS: added design doc for threadsafe properties --- docs/random/wingo/threadsafe-properties | 76 +++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 docs/random/wingo/threadsafe-properties diff --git a/docs/random/wingo/threadsafe-properties b/docs/random/wingo/threadsafe-properties new file mode 100644 index 0000000..7e9306f --- /dev/null +++ b/docs/random/wingo/threadsafe-properties @@ -0,0 +1,76 @@ +-*- 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. -- 2.7.4