/* this is a timeout that runs in the main thread */ static gboolean on_timeout_completion_check(void *data) { TestFixture *fixture = data; fixture->completion_check_timeout_ran = TRUE; if (fixture->completion_should_be_blocked) { if (fixture->tasks_completed_count != 0) { g_error("The task was completed even though we had it blocked count=%d", fixture->tasks_completed_count); } /* Now unblock, so we quit the main loop */ hrt_task_unblock_completion(fixture->tasks[0].task); } else { /* In this case we should have quit the main loop without * running the timeout, so this should never be reached. */ if (fixture->tasks_completed_count != 1) { g_error("The task was not completed even though we didn't block it count=%d", fixture->tasks_completed_count); } } return FALSE; }
/* IN OUR TASK THREAD */ static void notify_if_done(HioOutputStream *stream) { HRT_ASSERT_IN_TASK_THREAD(stream->task); if (g_atomic_int_get(&stream->done_notified) == 0 && hio_output_stream_is_done(stream)) { g_atomic_int_inc(&stream->done_notified); /* allow task to complete, assuming it has no other watchers. * * Another side effect: this should mean the task can complete * even if no watcher was ever added, which happens if the * stream is closed with no bytes ever written. */ hrt_task_unblock_completion(stream->task); g_mutex_lock(stream->done_notify_lock); if (stream->done_notify_func != NULL) { HioOutputStreamDoneNotify func = stream->done_notify_func; void *data = stream->done_notify_data; GDestroyNotify dnotify = stream->done_notify_dnotify; stream->done_notify_func = NULL; stream->done_notify_data = NULL; stream->done_notify_dnotify = NULL; g_mutex_unlock(stream->done_notify_lock); g_object_ref(stream); (* func) (stream, data); if (dnotify != NULL) { (* dnotify) (data); } g_object_unref(stream); } else { g_mutex_unlock(stream->done_notify_lock); } } }