diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-01-18 15:49:09 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-01-19 12:40:24 +0000 |
commit | 40f4ed22806b88ba0e26c458915d4695f1f7c201 (patch) | |
tree | bacdebee1932d294f8233a8fb14cb86383e5f107 /fitz/base_context.c | |
parent | 2c836b57d5295b47655988cf8deaffda731e1c3c (diff) | |
download | mupdf-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.c | 49 |
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; } |