/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2005 Wim Taymans <wim@fluendo.com>
 *
 * gsttask.c: Streaming tasks
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gsttask
 * @title: GstTask
 * @short_description: Abstraction of GStreamer streaming threads.
 * @see_also: #GstElement, #GstPad
 *
 * #GstTask is used by #GstElement and #GstPad to provide the data passing
 * threads in a #GstPipeline.
 *
 * A #GstPad will typically start a #GstTask to push or pull data to/from the
 * peer pads. Most source elements start a #GstTask to push data. In some cases
 * a demuxer element can start a #GstTask to pull data from a peer element. This
 * is typically done when the demuxer can perform random access on the upstream
 * peer element for improved performance.
 *
 * Although convenience functions exist on #GstPad to start/pause/stop tasks, it
 * might sometimes be needed to create a #GstTask manually if it is not related to
 * a #GstPad.
 *
 * Before the #GstTask can be run, it needs a #GRecMutex that can be set with
 * gst_task_set_lock().
 *
 * The task can be started, paused and stopped with gst_task_start(), gst_task_pause()
 * and gst_task_stop() respectively or with the gst_task_set_state() function.
 *
 * A #GstTask will repeatedly call the #GstTaskFunction with the user data
 * that was provided when creating the task with gst_task_new(). While calling
 * the function it will acquire the provided lock. The provided lock is released
 * when the task pauses or stops.
 *
 * Stopping a task with gst_task_stop() will not immediately make sure the task is
 * not running anymore. Use gst_task_join() to make sure the task is completely
 * stopped and the thread is stopped.
 *
 * After creating a #GstTask, use gst_object_unref() to free its resources. This can
 * only be done when the task is not running anymore.
 *
 * Task functions can send a #GstMessage to send out-of-band data to the
 * application. The application can receive messages from the #GstBus in its
 * mainloop.
 *
 * For debugging purposes, the task will configure its object name as the thread
 * name on Linux. Please note that the object name should be configured before the
 * task is started; changing the object name after the task has been started, has
 * no effect on the thread name.
 */

#include "gst_private.h"

#include "gstinfo.h"
#include "gsttask.h"
#include "glib-compat-private.h"

#include <stdio.h>

#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif

#ifdef HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID
#include <pthread.h>
#endif

GST_DEBUG_CATEGORY_STATIC (task_debug);
#define GST_CAT_DEFAULT (task_debug)

#define SET_TASK_STATE(t,s) (g_atomic_int_set (&GST_TASK_STATE(t), (s)))
#define GET_TASK_STATE(t)   ((GstTaskState) g_atomic_int_get (&GST_TASK_STATE(t)))

#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 */
  GstTaskThreadFunc enter_func;
  gpointer enter_user_data;
  GDestroyNotify enter_notify;

  GstTaskThreadFunc leave_func;
  gpointer leave_user_data;
  GDestroyNotify leave_notify;

  /* configured pool */
  GstTaskPool *pool;

  /* remember the pool and id that is currently running. */
  gpointer id;
  GstTaskPool *pool_id;
};

#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

struct _THREADNAME_INFO
{
  DWORD dwType;                 // must be 0x1000
  LPCSTR szName;                // pointer to name (in user addr space)
  DWORD dwThreadID;             // thread ID (-1=caller thread)
  DWORD dwFlags;                // reserved for future use, must be zero
};
typedef struct _THREADNAME_INFO THREADNAME_INFO;

void
SetThreadName (DWORD dwThreadID, LPCSTR szThreadName)
{
  THREADNAME_INFO info;
  info.dwType = 0x1000;
  info.szName = szThreadName;
  info.dwThreadID = dwThreadID;
  info.dwFlags = 0;

  __try {
    RaiseException (0x406D1388, 0, sizeof (info) / sizeof (DWORD),
        (const ULONG_PTR *) &info);
  }
  __except (EXCEPTION_CONTINUE_EXECUTION) {
  }
}
#endif

static void gst_task_finalize (GObject * object);

static void gst_task_func (GstTask * task);

static GMutex pool_lock;

#define _do_init \
{ \
  GST_DEBUG_CATEGORY_INIT (task_debug, "task", 0, "Processing tasks"); \
}

G_DEFINE_TYPE_WITH_CODE (GstTask, gst_task, GST_TYPE_OBJECT, _do_init);

static void
init_klass_pool (GstTaskClass * klass)
{
  g_mutex_lock (&pool_lock);
  if (klass->pool) {
    gst_task_pool_cleanup (klass->pool);
    gst_object_unref (klass->pool);
  }
  klass->pool = gst_task_pool_new ();
  /* Classes are never destroyed so this ref will never be dropped */
  GST_OBJECT_FLAG_SET (klass->pool, GST_OBJECT_FLAG_MAY_BE_LEAKED);
  gst_task_pool_prepare (klass->pool, NULL);
  g_mutex_unlock (&pool_lock);
}

static void
gst_task_class_init (GstTaskClass * klass)
{
  GObjectClass *gobject_class;

  gobject_class = (GObjectClass *) klass;

  g_type_class_add_private (klass, sizeof (GstTaskPrivate));

  gobject_class->finalize = gst_task_finalize;

  init_klass_pool (klass);
}

static void
gst_task_init (GstTask * task)
{
  GstTaskClass *klass;

  klass = GST_TASK_GET_CLASS (task);

  task->priv = GST_TASK_GET_PRIVATE (task);
  task->running = FALSE;
  task->thread = NULL;
  task->lock = NULL;
  g_cond_init (&task->cond);
  SET_TASK_STATE (task, GST_TASK_STOPPED);

  /* use the default klass pool for this task, users can
   * override this later */
  g_mutex_lock (&pool_lock);
  task->priv->pool = gst_object_ref (klass->pool);
  g_mutex_unlock (&pool_lock);
}

static void
gst_task_finalize (GObject * object)
{
  GstTask *task = GST_TASK (object);
  GstTaskPrivate *priv = task->priv;

  GST_DEBUG ("task %p finalize", task);

  if (priv->enter_notify)
    priv->enter_notify (priv->enter_user_data);

  if (priv->leave_notify)
    priv->leave_notify (priv->leave_user_data);

  if (task->notify)
    task->notify (task->user_data);

  gst_object_unref (priv->pool);

  /* task thread cannot be running here since it holds a ref
   * to the task so that the finalize could not have happened */
  g_cond_clear (&task->cond);

  G_OBJECT_CLASS (gst_task_parent_class)->finalize (object);
}

/* should be called with the object LOCK */
static void
gst_task_configure_name (GstTask * task)
{
#if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_NAME)
  const gchar *name;
  gchar thread_name[17] = { 0, };

  GST_OBJECT_LOCK (task);
  name = GST_OBJECT_NAME (task);

  /* set the thread name to something easily identifiable */
  if (!snprintf (thread_name, 17, "%s", GST_STR_NULL (name))) {
    GST_DEBUG_OBJECT (task, "Could not create thread name for '%s'", name);
  } else {
    GST_DEBUG_OBJECT (task, "Setting thread name to '%s'", thread_name);
    if (prctl (PR_SET_NAME, (unsigned long int) thread_name, 0, 0, 0))
      GST_DEBUG_OBJECT (task, "Failed to set thread name");
  }
  GST_OBJECT_UNLOCK (task);
#elif defined(HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID)
  const gchar *name;

  GST_OBJECT_LOCK (task);
  name = GST_OBJECT_NAME (task);

  /* set the thread name to something easily identifiable */
  GST_DEBUG_OBJECT (task, "Setting thread name to '%s'", name);
  if (pthread_setname_np (name))
    GST_DEBUG_OBJECT (task, "Failed to set thread name");

  GST_OBJECT_UNLOCK (task);
#elif defined (_MSC_VER)
  const gchar *name;
  name = GST_OBJECT_NAME (task);

  /* set the thread name to something easily identifiable */
  GST_DEBUG_OBJECT (task, "Setting thread name to '%s'", name);
  SetThreadName (-1, name);
#endif
}

static void
gst_task_func (GstTask * task)
{
  GRecMutex *lock;
  GThread *tself;
  GstTaskPrivate *priv;

  priv = task->priv;

  tself = g_thread_self ();

  GST_DEBUG ("Entering task %p, thread %p", task, tself);

  /* we have to grab the lock to get the mutex. We also
   * mark our state running so that nobody can mess with
   * the mutex. */
  GST_OBJECT_LOCK (task);
  if (GET_TASK_STATE (task) == GST_TASK_STOPPED)
    goto exit;
  lock = GST_TASK_GET_LOCK (task);
  if (G_UNLIKELY (lock == NULL))
    goto no_lock;
  task->thread = tself;
  GST_OBJECT_UNLOCK (task);

  /* fire the enter_func callback when we need to */
  if (priv->enter_func)
    priv->enter_func (task, tself, priv->enter_user_data);

  /* locking order is TASK_LOCK, LOCK */
  g_rec_mutex_lock (lock);
  /* configure the thread name now */
  gst_task_configure_name (task);

  while (G_LIKELY (GET_TASK_STATE (task) != GST_TASK_STOPPED)) {
    GST_OBJECT_LOCK (task);
    while (G_UNLIKELY (GST_TASK_STATE (task) == GST_TASK_PAUSED)) {
      g_rec_mutex_unlock (lock);

      GST_TASK_SIGNAL (task);
      GST_INFO_OBJECT (task, "Task going to paused");
      GST_TASK_WAIT (task);
      GST_INFO_OBJECT (task, "Task resume from paused");
      GST_OBJECT_UNLOCK (task);
      /* locking order.. */
      g_rec_mutex_lock (lock);
      GST_OBJECT_LOCK (task);
    }

    if (G_UNLIKELY (GET_TASK_STATE (task) == GST_TASK_STOPPED)) {
      GST_OBJECT_UNLOCK (task);
      break;
    } else {
      GST_OBJECT_UNLOCK (task);
    }

    task->func (task->user_data);
  }

  g_rec_mutex_unlock (lock);

  GST_OBJECT_LOCK (task);
  task->thread = NULL;

exit:
  if (priv->leave_func) {
    /* fire the leave_func callback when we need to. We need to do this before
     * we signal the task and with the task lock released. */
    GST_OBJECT_UNLOCK (task);
    priv->leave_func (task, tself, priv->leave_user_data);
    GST_OBJECT_LOCK (task);
  }
  /* now we allow messing with the lock again by setting the running flag to
   * %FALSE. Together with the SIGNAL this is the sign for the _join() to
   * complete.
   * Note that we still have not dropped the final ref on the task. We could
   * check here if there is a pending join() going on and drop the last ref
   * before releasing the lock as we can be sure that a ref is held by the
   * caller of the join(). */
  task->running = FALSE;
  GST_TASK_SIGNAL (task);
  GST_OBJECT_UNLOCK (task);

  GST_DEBUG ("Exit task %p, thread %p", task, g_thread_self ());

  gst_object_unref (task);
  return;

no_lock:
  {
    g_warning ("starting task without a lock");
    goto exit;
  }
}

/**
 * gst_task_cleanup_all:
 *
 * Wait for all tasks to be stopped. This is mainly used internally
 * to ensure proper cleanup of internal data structures in test suites.
 *
 * MT safe.
 */
void
gst_task_cleanup_all (void)
{
  GstTaskClass *klass;

  if ((klass = g_type_class_peek (GST_TYPE_TASK))) {
    init_klass_pool (klass);
  }

  /* GstElement owns a GThreadPool */
  _priv_gst_element_cleanup ();
}

/**
 * gst_task_new:
 * @func: The #GstTaskFunction to use
 * @user_data: User data to pass to @func
 * @notify: the function to call when @user_data is no longer needed.
 *
 * Create a new Task that will repeatedly call the provided @func
 * with @user_data as a parameter. Typically the task will run in
 * a new thread.
 *
 * 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 #GRecMutex must be configured using the
 * gst_task_set_lock() function. This lock will always be acquired while
 * @func is called.
 *
 * Returns: (transfer full): A new #GstTask.
 *
 * MT safe.
 */
GstTask *
gst_task_new (GstTaskFunction func, gpointer user_data, GDestroyNotify notify)
{
  GstTask *task;

  g_return_val_if_fail (func != NULL, NULL);

  task = g_object_new (GST_TYPE_TASK, NULL);
  task->func = func;
  task->user_data = user_data;
  task->notify = notify;

  GST_DEBUG ("Created task %p", task);

  /* clear floating flag */
  gst_object_ref_sink (task);

  return task;
}

/**
 * gst_task_set_lock:
 * @task: The #GstTask to use
 * @mutex: The #GRecMutex to use
 *
 * Set the mutex used by the task. The mutex will be acquired before
 * calling the #GstTaskFunction.
 *
 * This function has to be called before calling gst_task_pause() or
 * gst_task_start().
 *
 * MT safe.
 */
void
gst_task_set_lock (GstTask * task, GRecMutex * mutex)
{
  g_return_if_fail (GST_IS_TASK (task));

  GST_OBJECT_LOCK (task);
  if (G_UNLIKELY (task->running))
    goto is_running;
  GST_INFO ("setting stream lock %p on task %p", mutex, task);
  GST_TASK_GET_LOCK (task) = mutex;
  GST_OBJECT_UNLOCK (task);

  return;

  /* ERRORS */
is_running:
  {
    GST_OBJECT_UNLOCK (task);
    g_warning ("cannot call set_lock on a running task");
  }
}

/**
 * gst_task_get_pool:
 * @task: a #GstTask
 *
 * Get the #GstTaskPool that this task will use for its streaming
 * threads.
 *
 * MT safe.
 *
 * Returns: (transfer full): the #GstTaskPool used by @task. gst_object_unref()
 * after usage.
 */
GstTaskPool *
gst_task_get_pool (GstTask * task)
{
  GstTaskPool *result;
  GstTaskPrivate *priv;

  g_return_val_if_fail (GST_IS_TASK (task), NULL);

  priv = task->priv;

  GST_OBJECT_LOCK (task);
  result = gst_object_ref (priv->pool);
  GST_OBJECT_UNLOCK (task);

  return result;
}

/**
 * gst_task_set_pool:
 * @task: a #GstTask
 * @pool: (transfer none): a #GstTaskPool
 *
 * Set @pool as the new GstTaskPool for @task. Any new streaming threads that
 * will be created by @task will now use @pool.
 *
 * MT safe.
 */
void
gst_task_set_pool (GstTask * task, GstTaskPool * pool)
{
  GstTaskPool *old;
  GstTaskPrivate *priv;

  g_return_if_fail (GST_IS_TASK (task));
  g_return_if_fail (GST_IS_TASK_POOL (pool));

  priv = task->priv;

  GST_OBJECT_LOCK (task);
  if (priv->pool != pool) {
    old = priv->pool;
    priv->pool = gst_object_ref (pool);
  } else
    old = NULL;
  GST_OBJECT_UNLOCK (task);

  if (old)
    gst_object_unref (old);
}

/**
 * gst_task_set_enter_callback:
 * @task: The #GstTask to use
 * @enter_func: (in): a #GstTaskThreadFunc
 * @user_data: user data passed to @enter_func
 * @notify: called when @user_data is no longer referenced
 *
 * Call @enter_func when the task function of @task is entered. @user_data will
 * be passed to @enter_func and @notify will be called when @user_data is no
 * longer referenced.
 */
void
gst_task_set_enter_callback (GstTask * task, GstTaskThreadFunc enter_func,
    gpointer user_data, GDestroyNotify notify)
{
  GDestroyNotify old_notify;

  g_return_if_fail (task != NULL);
  g_return_if_fail (GST_IS_TASK (task));

  GST_OBJECT_LOCK (task);
  if ((old_notify = task->priv->enter_notify)) {
    gpointer old_data = task->priv->enter_user_data;

    task->priv->enter_user_data = NULL;
    task->priv->enter_notify = NULL;
    GST_OBJECT_UNLOCK (task);

    old_notify (old_data);

    GST_OBJECT_LOCK (task);
  }
  task->priv->enter_func = enter_func;
  task->priv->enter_user_data = user_data;
  task->priv->enter_notify = notify;
  GST_OBJECT_UNLOCK (task);
}

/**
 * gst_task_set_leave_callback:
 * @task: The #GstTask to use
 * @leave_func: (in): a #GstTaskThreadFunc
 * @user_data: user data passed to @leave_func
 * @notify: called when @user_data is no longer referenced
 *
 * Call @leave_func when the task function of @task is left. @user_data will
 * be passed to @leave_func and @notify will be called when @user_data is no
 * longer referenced.
 */
void
gst_task_set_leave_callback (GstTask * task, GstTaskThreadFunc leave_func,
    gpointer user_data, GDestroyNotify notify)
{
  GDestroyNotify old_notify;

  g_return_if_fail (task != NULL);
  g_return_if_fail (GST_IS_TASK (task));

  GST_OBJECT_LOCK (task);
  if ((old_notify = task->priv->leave_notify)) {
    gpointer old_data = task->priv->leave_user_data;

    task->priv->leave_user_data = NULL;
    task->priv->leave_notify = NULL;
    GST_OBJECT_UNLOCK (task);

    old_notify (old_data);

    GST_OBJECT_LOCK (task);
  }
  task->priv->leave_func = leave_func;
  task->priv->leave_user_data = user_data;
  task->priv->leave_notify = notify;
  GST_OBJECT_UNLOCK (task);
}

/**
 * gst_task_get_state:
 * @task: The #GstTask to query
 *
 * Get the current state of the task.
 *
 * Returns: The #GstTaskState of the task
 *
 * MT safe.
 */
GstTaskState
gst_task_get_state (GstTask * task)
{
  GstTaskState result;

  g_return_val_if_fail (GST_IS_TASK (task), GST_TASK_STOPPED);

  result = GET_TASK_STATE (task);

  return result;
}

/* make sure the task is running and start a thread if it's not.
 * This function must be called with the task LOCK. */
static gboolean
start_task (GstTask * task)
{
  gboolean res = TRUE;
  GError *error = NULL;
  GstTaskPrivate *priv;

  priv = task->priv;

  /* new task, We ref before so that it remains alive while
   * the thread is running. */
  gst_object_ref (task);
  /* mark task as running so that a join will wait until we schedule
   * and exit the task function. */
  task->running = TRUE;

  /* push on the thread pool, we remember the original pool because the user
   * could change it later on and then we join to the wrong pool. */
  priv->pool_id = gst_object_ref (priv->pool);
  priv->id =
      gst_task_pool_push (priv->pool_id, (GstTaskPoolFunction) gst_task_func,
      task, &error);

  if (error != NULL) {
    g_warning ("failed to create thread: %s", error->message);
    g_error_free (error);
    res = FALSE;
  }
  return res;
}


/**
 * gst_task_set_state:
 * @task: a #GstTask
 * @state: the new task state
 *
 * Sets the state of @task to @state.
 *
 * The @task must have a lock associated with it using
 * gst_task_set_lock() when going to GST_TASK_STARTED or GST_TASK_PAUSED or
 * this function will return %FALSE.
 *
 * MT safe.
 *
 * Returns: %TRUE if the state could be changed.
 */
gboolean
gst_task_set_state (GstTask * task, GstTaskState state)
{
  GstTaskState old;
  gboolean res = TRUE;

  g_return_val_if_fail (GST_IS_TASK (task), FALSE);

  GST_DEBUG_OBJECT (task, "Changing task %p to state %d", task, state);

  GST_OBJECT_LOCK (task);
  if (state != GST_TASK_STOPPED)
    if (G_UNLIKELY (GST_TASK_GET_LOCK (task) == NULL))
      goto no_lock;

  /* if the state changed, do our thing */
  old = GET_TASK_STATE (task);
  if (old != state) {
    SET_TASK_STATE (task, state);
    switch (old) {
      case GST_TASK_STOPPED:
        /* If the task already has a thread scheduled we don't have to do
         * anything. */
        if (G_UNLIKELY (!task->running))
          res = start_task (task);
        break;
      case GST_TASK_PAUSED:
        /* when we are paused, signal to go to the new state */
        GST_TASK_SIGNAL (task);
        break;
      case GST_TASK_STARTED:
        /* if we were started, we'll go to the new state after the next
         * iteration. */
        break;
    }
  }
  GST_OBJECT_UNLOCK (task);

  return res;

  /* ERRORS */
no_lock:
  {
    GST_WARNING_OBJECT (task, "state %d set on task without a lock", state);
    GST_OBJECT_UNLOCK (task);
    g_warning ("task without a lock can't be set to state %d", state);
    return FALSE;
  }
}

/**
 * gst_task_start:
 * @task: The #GstTask to start
 *
 * Starts @task. The @task must have a lock associated with it using
 * gst_task_set_lock() or this function will return %FALSE.
 *
 * Returns: %TRUE if the task could be started.
 *
 * MT safe.
 */
gboolean
gst_task_start (GstTask * task)
{
  return gst_task_set_state (task, GST_TASK_STARTED);
}

/**
 * gst_task_stop:
 * @task: The #GstTask to stop
 *
 * Stops @task. This method merely schedules the task to stop and
 * will not wait for the task to have completely stopped. Use
 * gst_task_join() to stop and wait for completion.
 *
 * Returns: %TRUE if the task could be stopped.
 *
 * MT safe.
 */
gboolean
gst_task_stop (GstTask * task)
{
  return gst_task_set_state (task, GST_TASK_STOPPED);
}

/**
 * gst_task_pause:
 * @task: The #GstTask to pause
 *
 * Pauses @task. This method can also be called on a task in the
 * stopped state, in which case a thread will be started and will remain
 * in the paused state. This function does not wait for the task to complete
 * the paused state.
 *
 * Returns: %TRUE if the task could be paused.
 *
 * MT safe.
 */
gboolean
gst_task_pause (GstTask * task)
{
  return gst_task_set_state (task, GST_TASK_PAUSED);
}

/**
 * gst_task_join:
 * @task: The #GstTask to join
 *
 * Joins @task. After this call, it is safe to unref the task
 * and clean up the lock set with gst_task_set_lock().
 *
 * The task will automatically be stopped with this call.
 *
 * This function cannot be called from within a task function as this
 * would cause a deadlock. The function will detect this and print a
 * g_warning.
 *
 * Returns: %TRUE if the task could be joined.
 *
 * MT safe.
 */
gboolean
gst_task_join (GstTask * task)
{
  GThread *tself;
  GstTaskPrivate *priv;
  gpointer id;
  GstTaskPool *pool = NULL;

  g_return_val_if_fail (GST_IS_TASK (task), FALSE);

  priv = task->priv;

  tself = g_thread_self ();

  GST_DEBUG_OBJECT (task, "Joining task %p, thread %p", task, tself);

  /* we don't use a real thread join here because we are using
   * thread pools */
  GST_OBJECT_LOCK (task);
  if (G_UNLIKELY (tself == task->thread))
    goto joining_self;
  SET_TASK_STATE (task, GST_TASK_STOPPED);
  /* signal the state change for when it was blocked in PAUSED. */
  GST_TASK_SIGNAL (task);
  /* we set the running flag when pushing the task on the thread pool.
   * This means that the task function might not be called when we try
   * to join it here. */
  while (G_LIKELY (task->running))
    GST_TASK_WAIT (task);
  /* clean the thread */
  task->thread = NULL;
  /* get the id and pool to join */
  pool = priv->pool_id;
  id = priv->id;
  priv->pool_id = NULL;
  priv->id = NULL;
  GST_OBJECT_UNLOCK (task);

  if (pool) {
    if (id)
      gst_task_pool_join (pool, id);
    gst_object_unref (pool);
  }

  GST_DEBUG_OBJECT (task, "Joined task %p", task);

  return TRUE;

  /* ERRORS */
joining_self:
  {
    GST_WARNING_OBJECT (task, "trying to join task from its thread");
    GST_OBJECT_UNLOCK (task);
    g_warning ("\nTrying to join task %p from its thread would deadlock.\n"
        "You cannot change the state of an element from its streaming\n"
        "thread. Use g_idle_add() or post a GstMessage on the bus to\n"
        "schedule the state change from the main thread.\n", task);
    return FALSE;
  }
}
