:right-sidebar: True Cond =================================================================== .. currentmodule:: gi.repository.GLib .. class:: Cond(*args, **kwargs) :no-contents-entry: :Constructors: :: Cond() Methods ------- .. rst-class:: interim-class .. class:: Cond :no-index: .. method:: broadcast() -> None If threads are waiting for ``cond``, all of them are unblocked. If no threads are waiting for ``cond``, this function has no effect. It is good practice to lock the same mutex as the waiting threads while calling this function, though not required. .. method:: clear() -> None Frees the resources allocated to a :obj:`~gi.repository.GLib.Cond` with :func:`~gi.repository.GLib.Cond.init`. This function should not be used with a :obj:`~gi.repository.GLib.Cond` that has been statically allocated. Calling :func:`~gi.repository.GLib.Cond.clear` for a :obj:`~gi.repository.GLib.Cond` on which threads are blocking leads to undefined behaviour. .. versionadded:: 2.32 .. method:: init() -> None Initialises a :obj:`~gi.repository.GLib.Cond` so that it can be used. This function is useful to initialise a :obj:`~gi.repository.GLib.Cond` that has been allocated as part of a larger structure. It is not necessary to initialise a :obj:`~gi.repository.GLib.Cond` that has been statically allocated. To undo the effect of :func:`~gi.repository.GLib.Cond.init` when a :obj:`~gi.repository.GLib.Cond` is no longer needed, use :func:`~gi.repository.GLib.Cond.clear`. Calling :func:`~gi.repository.GLib.Cond.init` on an already-initialised :obj:`~gi.repository.GLib.Cond` leads to undefined behaviour. .. versionadded:: 2.32 .. method:: signal() -> None If threads are waiting for ``cond``, at least one of them is unblocked. If no threads are waiting for ``cond``, this function has no effect. It is good practice to hold the same lock as the waiting thread while calling this function, though not required. .. method:: wait(mutex: ~gi.repository.GLib.Mutex) -> None Atomically releases ``mutex`` and waits until ``cond`` is signalled. When this function returns, ``mutex`` is locked again and owned by the calling thread. When using condition variables, it is possible that a spurious wakeup may occur (ie: :func:`~gi.repository.GLib.Cond.wait` returns even though :func:`~gi.repository.GLib.Cond.signal` was not called). It's also possible that a stolen wakeup may occur. This is when :func:`~gi.repository.GLib.Cond.signal` is called, but another thread acquires ``mutex`` before this thread and modifies the state of the program in such a way that when :func:`~gi.repository.GLib.Cond.wait` is able to return, the expected condition is no longer met. For this reason, :func:`~gi.repository.GLib.Cond.wait` must always be used in a loop. See the documentation for :obj:`~gi.repository.GLib.Cond` for a complete example. :param mutex: a :obj:`~gi.repository.GLib.Mutex` that is currently locked .. method:: wait_until(mutex: ~gi.repository.GLib.Mutex, end_time: int) -> bool Waits until either ``cond`` is signalled or ``end_time`` has passed. As with :func:`~gi.repository.GLib.Cond.wait` it is possible that a spurious or stolen wakeup could occur. For that reason, waiting on a condition variable should always be in a loop, based on an explicitly-checked predicate. :const:`True` is returned if the condition variable was signalled (or in the case of a spurious wakeup). :const:`False` is returned if ``end_time`` has passed. The following code shows how to correctly perform a timed wait on a condition variable (extending the example presented in the documentation for :obj:`~gi.repository.GLib.Cond`): .. code-block:: C :dedent: gpointer pop_data_timed (void) { gint64 end_time; gpointer data; g_mutex_lock (&data_mutex); end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND; while (!current_data) if (!g_cond_wait_until (&data_cond, &data_mutex, end_time)) { // timeout has passed. g_mutex_unlock (&data_mutex); return NULL; } // there is data for us data = current_data; current_data = NULL; g_mutex_unlock (&data_mutex); return data; } Notice that the end time is calculated once, before entering the loop and reused. This is the motivation behind the use of absolute time on this API -- if a relative time of 5 seconds were passed directly to the call and a spurious wakeup occurred, the program would have to start over waiting again (which would lead to a total wait time of more than 5 seconds). .. versionadded:: 2.32 :param mutex: a :obj:`~gi.repository.GLib.Mutex` that is currently locked :param end_time: the monotonic time to wait until Fields ------ .. rst-class:: interim-class .. class:: Cond :no-index: .. attribute:: i .. attribute:: p