diff options
author | Robin Watts <robin.watts@artifex.com> | 2015-04-08 11:19:50 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2015-04-08 11:19:50 +0100 |
commit | 7c3520a0849a51ec6e1c754c5a295dc981eea339 (patch) | |
tree | aa1f732352ea53e2893fc0112dd3778d604ef9bb /docs | |
parent | 30252bb78a1a91e4913d2a785cdf83c0837c6e95 (diff) | |
download | mupdf-7c3520a0849a51ec6e1c754c5a295dc981eea339.tar.xz |
Update documentation with fz_context changes.
Diffstat (limited to 'docs')
-rw-r--r-- | docs/overview.txt | 108 |
1 files changed, 21 insertions, 87 deletions
diff --git a/docs/overview.txt b/docs/overview.txt index 0fd7b90a..2bb6b843 100644 --- a/docs/overview.txt +++ b/docs/overview.txt @@ -19,7 +19,7 @@ using MuPDF should use the error handling strategies described below. Common function arguments ========================= -Many functions in MuPDFs interface take a context argument. +Most functions in MuPDFs interface take a context argument. A context contains global state used by MuPDF inside functions when parsing or rendering pages of the document. It contains for example: @@ -32,11 +32,6 @@ parsing or rendering pages of the document. It contains for example: a set of locks and (un-)locking functions (for multi-threading) -Other functions in MuPDF's interface take arguments such as document, -stream and device which contain state for each type of object. Those -arguments each have a reference to a context and therefore act as -proxies for a context. - Without the set of locks and accompanying functions the context and its proxies may only be used in a single-threaded application. @@ -212,22 +207,25 @@ multi-threaded operations run smoothly: same time as you create the thread. For more details see "Cloning the context" below. -2) "The document is bound to the context with which it is created." +2) "No simultaneous calls to MuPDF in different threads are + allowed to use the same document." + + Only one thread can be accessing a document at a time, but + once display lists are created from that document, multiple + threads at a time can operate on them. - All subsequent accesses to the document implicitly use the same - context; this means that only 1 thread can ever be accessing - the document at once. This does not mean that the document can - only ever be used from one thread, though in many cases this - is the simplest structure overall. See "Bound contexts" below. + The document can be used from several different threads as + long as there are safeguards in place to prevent the usages + being simultaneous. -3) "Any device is bound to the context with which it is created." +3) "No simultaneous calls to MuPDF in different threads are + allowed to use the same device." - All subsequent uses of a device implicitly use the context with - which it was created; this means that if a device is used with - a document, it should be created with the same context as that - document was. This does not mean that the device can only ever - be used from one thread, though in many cases this is the - simplest structure overall. See "Bound contexts" below. + Calling a device simultaneously from different threads will + cause it to get confused and may crash. Calling a device from + several different threads is perfectly acceptable as long as + there are safeguards in place to prevent the calls being + simultaneous. So, how does a multi-threaded example differ from a non-multithreaded one? @@ -252,11 +250,11 @@ glyph cache etc) with the original context, but will have their own exception stacks. To open a document, call fz_open_document as usual, passing a context -and a filename; this context is bound to the document. All future -calls to access the document will use this context internally. +and a filename. It is important to realise that only one thread at a +time can be accessing the documents itself. -Only one thread at a time can therefore perform operations such as -fetching a page, or rendering that page to a display list. Once a +This means that only one thread at a time can perform operations such +as fetching a page, or rendering that page to a display list. Once a display list has been obtained however, it can be rendered from any other thread (or even from several threads simultaneously, giving banded rendering). @@ -290,67 +288,3 @@ stack. A commonly used general scheme is therefore to create a 'base' context at program start up, and to clone this repeatedly to get new contexts that can be used on new threads. - -Bound contexts -============== - -Certain objects, bind themselves to the context with which they are -created. For instance, when a document (or device) is created it -remembers the context which it was initially passed. The advantage -of this is that any subsequent calls to the document do not need a -context to be passed (and internally, we only need to pass a document -pointer around rather than both a document and a context pointer). - -The downside to this is that care must be taken to only use the -document pointer with the same context. For example consider the -following pseudo code: - - // Create the base context - base_ctx = fz_new_context(...); - - // Open the document. doc remembers ctx. - doc = fz_open_document(ctx, ...); - - // Create a new context, possibly to use in another thread - ctx2 = fz_clone_context(ctx); - - // Get a page using that new context - fz_try(ctx2) - { - page = fz_load_page(doc, page_number); - } - fz_catch(ctx2) - { - // handle the error - ... - } - -On the face of it, this seems fine, until you consider what happens -internally to fz_load_page. The internals of fz_load_page will use -error handling too, and so will fz_throw in some circumstances (and -will probably do fz_try/fz_catch for themselves). In order to do so, -they will retrieve the ctx that doc was created with - in the above -example this will be base_ctx. - -This means that in the case of an error being thrown from within -fz_load_page we'll end up with something like the following: - - fz_try(ctx2) - { - ... - // inside fz_load_page, an error occurs - fz_throw(base_ctx, ... }; - ... - - } - fz_catch(ctx2) - { - // Handle the error - } - -The error will be thrown using the exception stack from base_ctx, but -the caller has set up the code to catch the error using the exception -stack from ctx2. Code that gets this wrong may well appear to work -perfectly well for long periods, and then only fail with files that -raise errors in particular places. This will cause the program to -terminate abnormally (or crash), and can be very hard to debug. |