async->data = NULL;
async->result = -1;
async->notifiers = NULL;
+ async->notifier_count = 0;
async->store_private = NULL;
return async;
return;
}
- while (async->status != ASYNC_COMPLETE) {
+ while (async->status != ASYNC_COMPLETE
+ || g_atomic_int_get(&async->notifier_count) > 0) {
g_cond_wait(async->completion_cond, async->lock);
}
GFunc func, gpointer user_data)
{
struct BlueSkyNotifierList *nl = g_new(struct BlueSkyNotifierList, 1);
+ g_mutex_lock(async->lock);
nl->next = async->notifiers;
nl->func = func;
nl->async = async; bluesky_store_async_ref(async);
nl->user_data = user_data;
+ g_atomic_int_inc(&async->notifier_count);
if (async->status == ASYNC_COMPLETE) {
g_thread_pool_push(notifier_thread_pool, nl, NULL);
} else {
async->notifiers = nl;
}
+ g_mutex_unlock(async->lock);
}
/* Mark an asynchronous operation as complete. This should only be called by
struct BlueSkyNotifierList *notifier = (struct BlueSkyNotifierList *)n;
notifier->func(notifier->async, notifier->user_data);
+ if (g_atomic_int_dec_and_test(¬ifier->async->notifier_count)) {
+ g_cond_broadcast(notifier->async->completion_cond);
+ }
bluesky_store_async_unref(notifier->async);
g_free(notifier);
}