summaryrefslogtreecommitdiff
path: root/fitz/base_context.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-01-18 15:49:09 +0000
committerRobin Watts <robin.watts@artifex.com>2012-01-19 12:40:24 +0000
commit40f4ed22806b88ba0e26c458915d4695f1f7c201 (patch)
treebacdebee1932d294f8233a8fb14cb86383e5f107 /fitz/base_context.c
parent2c836b57d5295b47655988cf8deaffda731e1c3c (diff)
downloadmupdf-40f4ed22806b88ba0e26c458915d4695f1f7c201.tar.xz
Multi-threading support for MuPDF
When we moved over to a context based system, we laid the foundation for a thread-safe mupdf. This commit should complete that process. Firstly, fz_clone_context is properly implemented so that it makes a new context, but shares certain sections (currently just the allocator, and the store). Secondly, we add locking (to parts of the code that have previously just had placeholder LOCK/UNLOCK comments). Functions to lock and unlock a mutex are added to the allocator structure; omit these (as is the case today) and no multithreading is (safely) possible. The context will refuse to clone if these are not provided. Finally we flesh out the LOCK/UNLOCK comments to be real calls of the functions - unfortunately this requires us to plumb fz_context into the fz_keep_storable function (and all the fz_keep_xxx functions that call it). This is the largest section of the patch. No changes expected to any test files.
Diffstat (limited to 'fitz/base_context.c')
-rw-r--r--fitz/base_context.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/fitz/base_context.c b/fitz/base_context.c
index 8991a565..68dba187 100644
--- a/fitz/base_context.c
+++ b/fitz/base_context.c
@@ -36,14 +36,14 @@ fz_free_context(fz_context *ctx)
ctx->alloc->free(ctx->alloc->user, ctx);
}
-fz_context *
-fz_new_context(fz_alloc_context *alloc, unsigned int max_store)
+/* Allocate new context structure, and initialise allocator, and sections
+ * that aren't shared between contexts.
+ */
+static fz_context *
+new_context_phase1(fz_alloc_context *alloc)
{
fz_context *ctx;
- if (!alloc)
- alloc = &fz_alloc_default;
-
ctx = alloc->malloc(alloc->user, sizeof(fz_context));
if (!ctx)
return NULL;
@@ -69,7 +69,6 @@ fz_new_context(fz_alloc_context *alloc, unsigned int max_store)
{
fz_new_font_context(ctx);
fz_new_aa_context(ctx);
- fz_new_store_context(ctx, max_store);
}
fz_catch(ctx)
{
@@ -79,14 +78,46 @@ fz_new_context(fz_alloc_context *alloc, unsigned int max_store)
return ctx;
cleanup:
- fprintf(stderr, "cannot create context\n");
+ fprintf(stderr, "cannot create context (phase 1)\n");
fz_free_context(ctx);
return NULL;
}
fz_context *
+fz_new_context(fz_alloc_context *alloc, unsigned int max_store)
+{
+ fz_context *ctx;
+
+ if (!alloc)
+ alloc = &fz_alloc_default;
+
+ ctx = new_context_phase1(alloc);
+
+ /* Now initialise sections that are shared */
+ fz_try(ctx)
+ {
+ fz_new_store_context(ctx, max_store);
+ }
+ fz_catch(ctx)
+ {
+ fprintf(stderr, "cannot create context (phase 2)\n");
+ fz_free_context(ctx);
+ return NULL;
+ }
+ return ctx;
+}
+
+fz_context *
fz_clone_context(fz_context *ctx)
{
- /* FIXME: Should be sharing store */
- return fz_new_context(ctx->alloc, 256<<20);
+ fz_context *new_ctx;
+
+ /* We cannot safely clone the context without having locking/
+ * unlocking functions. */
+ if (ctx == NULL || ctx->alloc == NULL || ctx->alloc->lock == NULL || ctx->alloc->unlock == NULL)
+ return NULL;
+
+ new_ctx = new_context_phase1(ctx->alloc);
+ new_ctx->store = fz_store_keep(ctx);
+ return ctx;
}