g_return_val_if_fail (comp != NULL, OMX_ErrorUndefined);
- gst_omx_rec_mutex_lock (&comp->state_lock);
+ gst_omx_rec_mutex_lock_for_recursion (&comp->state_lock);
old_state = comp->state;
GST_DEBUG_OBJECT (comp->parent, "Setting state from %d to %d", old_state,
state);
/* No need to check if anything has changed here */
done:
- gst_omx_rec_mutex_unlock (&comp->state_lock);
+ gst_omx_rec_mutex_unlock_for_recursion (&comp->state_lock);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (comp->parent,
GST_DEBUG_OBJECT (comp->parent, "Releasing buffer %p (%p) to port %u",
buf, buf->omx_buf->pBuffer, port->index);
- gst_omx_rec_mutex_lock (&port->port_lock);
+ gst_omx_rec_mutex_lock_for_recursion (&port->port_lock);
if (port->port_def.eDir == OMX_DirInput) {
/* Reset all flags, some implementations don't
buf, port->index, gst_omx_error_to_string (err), err);
done:
- gst_omx_rec_mutex_unlock (&port->port_lock);
+ gst_omx_rec_mutex_unlock_for_recursion (&port->port_lock);
return err;
}
GST_DEBUG_OBJECT (comp->parent, "Setting port %d to %sflushing",
port->index, (flush ? "" : "not "));
- gst_omx_rec_mutex_lock (&port->port_lock);
+ gst_omx_rec_mutex_lock_for_recursion (&port->port_lock);
if (! !flush == ! !port->flushing) {
GST_DEBUG_OBJECT (comp->parent, "Port %u was %sflushing already",
port->index, (flush ? "" : "not "));
done:
GST_DEBUG_OBJECT (comp->parent, "Set port %u to %sflushing: %s (0x%08x)",
port->index, (flush ? "" : "not "), gst_omx_error_to_string (err), err);
- gst_omx_rec_mutex_unlock (&port->port_lock);
+ gst_omx_rec_mutex_unlock_for_recursion (&port->port_lock);
return err;
g_return_val_if_fail (port != NULL, OMX_ErrorUndefined);
- gst_omx_rec_mutex_lock (&port->port_lock);
+ gst_omx_rec_mutex_lock_for_recursion (&port->port_lock);
err = gst_omx_port_allocate_buffers_unlocked (port);
- gst_omx_rec_mutex_unlock (&port->port_lock);
+ gst_omx_rec_mutex_unlock_for_recursion (&port->port_lock);
return err;
}
g_return_val_if_fail (port != NULL, OMX_ErrorUndefined);
- gst_omx_rec_mutex_lock (&port->port_lock);
+ gst_omx_rec_mutex_lock_for_recursion (&port->port_lock);
err = gst_omx_port_deallocate_buffers_unlocked (port);
- gst_omx_rec_mutex_unlock (&port->port_lock);
+ gst_omx_rec_mutex_unlock_for_recursion (&port->port_lock);
return err;
}
g_return_val_if_fail (port != NULL, OMX_ErrorUndefined);
- gst_omx_rec_mutex_lock (&port->port_lock);
+ gst_omx_rec_mutex_lock_for_recursion (&port->port_lock);
err = gst_omx_port_set_enabled_unlocked (port, enabled);
- gst_omx_rec_mutex_unlock (&port->port_lock);
+ gst_omx_rec_mutex_unlock_for_recursion (&port->port_lock);
return err;
}
GST_DEBUG_OBJECT (comp->parent, "Reconfiguring port %u", port->index);
- gst_omx_rec_mutex_lock (&port->port_lock);
+ gst_omx_rec_mutex_lock_for_recursion (&port->port_lock);
if (!port->settings_changed)
goto done;
GST_DEBUG_OBJECT (comp->parent, "Reconfigured port %u: %s (0x%08x)",
port->index, gst_omx_error_to_string (err), err);
- gst_omx_rec_mutex_unlock (&port->port_lock);
+ gst_omx_rec_mutex_unlock_for_recursion (&port->port_lock);
+
return err;
}
g_mutex_unlock (&mutex->lock);
}
+void
+gst_omx_rec_mutex_lock_for_recursion (GstOMXRecMutex * mutex)
+{
+ gboolean exchanged;
+
+ g_mutex_lock (&mutex->lock);
+ exchanged =
+ g_atomic_int_compare_and_exchange (&mutex->recursion_pending, FALSE,
+ TRUE);
+ g_assert (exchanged);
+}
+
+void
+gst_omx_rec_mutex_unlock_for_recursion (GstOMXRecMutex * mutex)
+{
+ gboolean exchanged;
+
+ exchanged =
+ g_atomic_int_compare_and_exchange (&mutex->recursion_pending, TRUE,
+ FALSE);
+ g_assert (exchanged);
+ g_cond_broadcast (&mutex->recursion_wait_cond);
+ g_mutex_unlock (&mutex->lock);
+}
+
/* must be called with mutex->lock taken */
void
gst_omx_rec_mutex_begin_recursion (GstOMXRecMutex * mutex)
g_atomic_int_compare_and_exchange (&mutex->recursion_allowed, FALSE,
TRUE);
g_assert (exchanged);
+ exchanged =
+ g_atomic_int_compare_and_exchange (&mutex->recursion_pending, TRUE,
+ FALSE);
+ g_assert (exchanged);
+ g_cond_broadcast (&mutex->recursion_wait_cond);
g_mutex_unlock (&mutex->recursion_lock);
}
g_atomic_int_compare_and_exchange (&mutex->recursion_allowed, TRUE,
FALSE);
g_assert (exchanged);
+ exchanged =
+ g_atomic_int_compare_and_exchange (&mutex->recursion_pending, FALSE,
+ TRUE);
+ g_assert (exchanged);
g_mutex_unlock (&mutex->recursion_lock);
}
{
g_mutex_lock (&mutex->recursion_lock);
if (!g_atomic_int_get (&mutex->recursion_allowed)) {
- /* no recursion allowed, lock the proper mutex */
- g_mutex_unlock (&mutex->recursion_lock);
- g_mutex_lock (&mutex->lock);
+ /* If recursion is pending wait until it happened */
+ while (g_atomic_int_get (&mutex->recursion_pending))
+ g_cond_wait (&mutex->recursion_wait_cond, &mutex->recursion_lock);
+
+ if (!g_atomic_int_get (&mutex->recursion_allowed)) {
+ /* no recursion allowed, lock the proper mutex */
+ g_mutex_lock (&mutex->lock);
+ g_mutex_unlock (&mutex->recursion_lock);
+ }
}
}