summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2015-04-08 11:19:50 +0100
committerRobin Watts <robin.watts@artifex.com>2015-04-08 11:19:50 +0100
commit7c3520a0849a51ec6e1c754c5a295dc981eea339 (patch)
treeaa1f732352ea53e2893fc0112dd3778d604ef9bb /docs
parent30252bb78a1a91e4913d2a785cdf83c0837c6e95 (diff)
downloadmupdf-7c3520a0849a51ec6e1c754c5a295dc981eea339.tar.xz
Update documentation with fz_context changes.
Diffstat (limited to 'docs')
-rw-r--r--docs/overview.txt108
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.