# HG changeset patch # User Tero Marttila # Date 1262271187 -7200 # Node ID f0d1011e88745dcdd7e4b9b1a14e022fac9cea8b # Parent ebcc49de97d0fe78466de85bf8c308d30307731f cleanup mutex when cancel'd in pthread_cond_wait diff -r ebcc49de97d0 -r f0d1011e8874 src/lib/ctx.c --- a/src/lib/ctx.c Thu Dec 31 16:40:13 2009 +0200 +++ b/src/lib/ctx.c Thu Dec 31 16:53:07 2009 +0200 @@ -6,6 +6,13 @@ #include #include // for perror +static void pt_mutex_unlock (void *arg) +{ + pthread_mutex_t *mutex = arg; + + assert(!pthread_mutex_unlock(mutex)); +} + /** * Enqueue the given piece of work * @@ -31,7 +38,8 @@ */ static void pt_work_dequeue (struct pt_ctx *ctx, struct pt_work **work_ptr) { - // acquire + // acquire, cancel-safe + pthread_cleanup_push(pt_mutex_unlock, &ctx->work_mutex); assert(!pthread_mutex_lock(&ctx->work_mutex)); // idle? @@ -40,6 +48,7 @@ // wait for work while (TAILQ_EMPTY(&ctx->work)) + // we can expect to get pthread_cancel'd here assert(!pthread_cond_wait(&ctx->work_cond, &ctx->work_mutex)); // pop work @@ -47,7 +56,7 @@ TAILQ_REMOVE(&ctx->work, *work_ptr, ctx_work); // release - assert(!pthread_mutex_unlock(&ctx->work_mutex)); + pthread_cleanup_pop(true); } /**