diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index afad541db3..b261c47afe 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -2173,18 +2173,24 @@ GST_TASK_SIGNAL GST_TASK_STATE GST_TASK_WAIT -gst_task_cleanup_all gst_task_create +gst_task_set_lock + +GstTaskThreadCallbacks +gst_task_set_thread_callbacks + gst_task_get_state gst_task_set_state -gst_task_join gst_task_pause -gst_task_set_lock gst_task_start gst_task_stop +gst_task_join + +gst_task_cleanup_all GstTaskClass +GstTaskPrivate GST_TASK GST_IS_TASK GST_TYPE_TASK diff --git a/gst/gsttask.c b/gst/gsttask.c index 1807658221..1dc536c032 100644 --- a/gst/gsttask.c +++ b/gst/gsttask.c @@ -67,6 +67,17 @@ GST_DEBUG_CATEGORY_STATIC (task_debug); #define GST_CAT_DEFAULT (task_debug) +#define GST_TASK_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_TASK, GstTaskPrivate)) + +struct _GstTaskPrivate +{ + /* callbacks for managing the thread of this task */ + GstTaskThreadCallbacks thr_callbacks; + gpointer thr_user_data; + GDestroyNotify thr_notify; +}; + static void gst_task_class_init (GstTaskClass * klass); static void gst_task_init (GstTask * task); static void gst_task_finalize (GObject * object); @@ -102,6 +113,7 @@ gst_task_class_init (GstTaskClass * klass) static void gst_task_init (GstTask * task) { + task->priv = GST_TASK_GET_PRIVATE (task); task->running = FALSE; task->abidata.ABI.thread = NULL; task->lock = NULL; @@ -246,6 +258,13 @@ gst_task_cleanup_all (void) * The function cannot be changed after the task has been created. You * must create a new #GstTask to change the function. * + * This function will not yet create and start a thread. Use gst_task_start() or + * gst_task_pause() to create and start the GThread. + * + * Before the task can be used, a #GStaticRecMutex must be configured using the + * gst_task_set_lock() function. This lock will always be acquired while + * @func is called. + * * Returns: A new #GstTask. * * MT safe. @@ -296,6 +315,55 @@ is_running: } } +/** + * gst_task_thread_callbacks: + * @task: The #GstTask to use + * @callbacks: a #GstTaskThreadCallbacks pointer + * @user_data: user data passed to the callbacks + * @notify: called when @user_data is no longer referenced + * + * Set callbacks which will be executed when a new thread is needed, the thread + * function is entered and left and when the thread is joined. + * + * By default a thread for @task will be created from a default thread pool. + * Elements can use custom GThreads for the task by installing callbacks. + * + * Since: 0.10.24 + * + * MT safe. + */ +void +gst_task_set_thread_callbacks (GstTask * task, + GstTaskThreadCallbacks * callbacks, gpointer user_data, + GDestroyNotify notify) +{ + GDestroyNotify old_notify; + + g_return_if_fail (task != NULL); + g_return_if_fail (GST_IS_TASK (task)); + g_return_if_fail (callbacks != NULL); + + GST_OBJECT_LOCK (task); + old_notify = task->priv->thr_notify; + + if (old_notify) { + gpointer old_data; + + old_data = task->priv->thr_user_data; + + task->priv->thr_user_data = NULL; + task->priv->thr_notify = NULL; + GST_OBJECT_UNLOCK (task); + + old_notify (old_data); + + GST_OBJECT_LOCK (task); + } + task->priv->thr_callbacks = *callbacks; + task->priv->thr_user_data = user_data; + task->priv->thr_notify = notify; + GST_OBJECT_UNLOCK (task); +} /** * gst_task_get_state: diff --git a/gst/gsttask.h b/gst/gsttask.h index 65a9bf8438..a160441a12 100644 --- a/gst/gsttask.h +++ b/gst/gsttask.h @@ -47,6 +47,7 @@ typedef void (*GstTaskFunction) (void *data); typedef struct _GstTask GstTask; typedef struct _GstTaskClass GstTaskClass; +typedef struct _GstTaskPrivate GstTaskPrivate; /** * GstTaskState: @@ -107,6 +108,28 @@ typedef enum { */ #define GST_TASK_GET_LOCK(task) (GST_TASK_CAST(task)->lock) +/** + * GstTaskCallbacks: + * @create_thread: Create a thread that calls @func with @task as the argument + * @enter_thread: a thread is entered + * @leave_thread: a thread is exiting + * @join_thread: a thread is joined + * + * Custom GstTask thread callback functions that can be installed. + * + * Since: 0.10.24 + */ +typedef struct { + /* creating threads */ + GThread * (*create_thread) (GstTask *task, GThreadFunc func, gpointer user_data); + /* manage the lifetime of the thread */ + void (*enter_thread) (GstTask *task, GThread *thread, gpointer user_data); + void (*leave_thread) (GstTask *task, GThread *thread, gpointer user_data); + void (*join_thread) (GstTask *task, GThread *thread, gpointer user_data); + /*< private >*/ + gpointer _gst_reserved[GST_PADDING]; +} GstTaskThreadCallbacks; + /** * GstTask: * @state: the state of the task @@ -138,10 +161,10 @@ struct _GstTask { /* thread this task is currently running in */ GThread *thread; } ABI; - /* adding + 0 to mark ABI change to be undone later */ - gpointer _gst_reserved[GST_PADDING + 0]; + gpointer _gst_reserved[GST_PADDING - 1]; } abidata; + GstTaskPrivate *priv; }; struct _GstTaskClass { @@ -161,6 +184,11 @@ GType gst_task_get_type (void); GstTask* gst_task_create (GstTaskFunction func, gpointer data); void gst_task_set_lock (GstTask *task, GStaticRecMutex *mutex); +void gst_task_set_thread_callbacks (GstTask *task, + GstTaskThreadCallbacks *callbacks, + gpointer user_data, + GDestroyNotify notify); + GstTaskState gst_task_get_state (GstTask *task); gboolean gst_task_set_state (GstTask *task, GstTaskState state);