diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-04-09 13:02:59 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-04-09 13:02:59 +0100 |
commit | 3c1654b2db5866394476de4fc0dff80e055bc376 (patch) | |
tree | 18b0b5496da0a34bb8e290315413f59b01aa64c1 | |
parent | 3f89d1b6d1d28018f8706faefbbac040e4188e1a (diff) | |
download | mupdf-3c1654b2db5866394476de4fc0dff80e055bc376.tar.xz |
Bug 692979: Fix race condition in thread debugging.
Bas Weelinck points out a potential problem with multiple threads
starting up at the same time, running into a race condition in
the thread debugging code. He suggests using an extra lock to
avoid this, and indeed, it would be a simple way.
I am reluctant to introduce an extra lock purely for this case
though, so I've instead reused the ALLOC lock. This has the advantage
of us not having to take the lock except in the 'first call with a
new context' case.
-rw-r--r-- | fitz/base_memory.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/fitz/base_memory.c b/fitz/base_memory.c index 32c7ff84..a30d75db 100644 --- a/fitz/base_memory.c +++ b/fitz/base_memory.c @@ -264,8 +264,23 @@ static int find_context(fz_context *ctx) return i; if (fz_lock_debug_contexts[i] == NULL) { - fz_lock_debug_contexts[i] = ctx; - return i; + int gottit; + /* We've not locked on this context before, so use + * this one for this new context. We might have other + * threads trying here too though so, so claim it + * atomically. No one has locked on this context + * before, so we are safe to take the ALLOC lock. */ + ctx->locks->lock(ctx->locks->user, FZ_LOCK_ALLOC); + /* If it's still free, then claim it as ours, + * otherwise we'll keep hunting. */ + if (fz_lock_debug_contexts[i] == NULL) + { + gottit = 1; + fz_lock_debug_contexts[i] = ctx; + } + ctx->locks->unlock(ctx->locks->user, FZ_LOCK_ALLOC); + if (gottit) + return i; } } return -1; |