summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-04-09 13:02:59 +0100
committerRobin Watts <robin.watts@artifex.com>2012-04-09 13:02:59 +0100
commit3c1654b2db5866394476de4fc0dff80e055bc376 (patch)
tree18b0b5496da0a34bb8e290315413f59b01aa64c1 /fitz
parent3f89d1b6d1d28018f8706faefbbac040e4188e1a (diff)
downloadmupdf-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.
Diffstat (limited to 'fitz')
-rw-r--r--fitz/base_memory.c19
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;