GstTask: allow setting callbacks
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 11 May 2009 21:19:53 +0000 (23:19 +0200)
committerWim Taymans <wim@metal.(none)>
Mon, 11 May 2009 21:19:53 +0000 (23:19 +0200)
Allow setting thread callbacks that will allow us to control the threads used by
the task.

docs/gst/gstreamer-sections.txt
gst/gsttask.c
gst/gsttask.h

index afad541..b261c47 100644 (file)
@@ -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
 
 <SUBSECTION Standard>
 GstTaskClass
+GstTaskPrivate
 GST_TASK
 GST_IS_TASK
 GST_TYPE_TASK
index 1807658..1dc536c 100644 (file)
 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:
index 65a9bf8..a160441 100644 (file)
@@ -47,6 +47,7 @@ typedef void         (*GstTaskFunction)          (void *data);
 
 typedef struct _GstTask GstTask;
 typedef struct _GstTaskClass GstTaskClass;
+typedef struct _GstTaskPrivate GstTaskPrivate;
 
 /**
  * GstTaskState:
@@ -108,6 +109,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
  * @cond: used to pause/resume 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);