summaryrefslogtreecommitdiff
path: root/include/mupdf/fitz/context.h
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-11-08 19:45:14 +0000
committerRobin Watts <robin.watts@artifex.com>2017-11-09 12:41:52 +0000
commit258f03a0a55c1aa802e1be47e463d8abc5096196 (patch)
tree7596f3081254276b29d929aa87b233a04d02ce51 /include/mupdf/fitz/context.h
parent9f32fdff17f9d6cb114c4f70d1e4b8364e8b5d11 (diff)
downloadmupdf-258f03a0a55c1aa802e1be47e463d8abc5096196.tar.xz
Bug 698353: Avoid having our API depend on DEBUG/NDEBUG.
Currently, our API uses static inlines for fz_lock and fz_unlock, the definitions for which depend on whether we build NDEBUG or not. This isn't ideal as it causes problems when people link a release binary with a debug lib (or vice versa). We really want to continue to use static inlines for the locking functions as used from MuPDF, as we hit them hard in the keep/drop functions. We therefore remove fz_lock/fz_unlock from the public API entirely. Accordingly, we move the fz_lock/fz_unlock static inlines into fitz-imp.h (an internal header), together with the fz_keep_.../fz_drop_... functions. We then have public fz_lock/fz_unlock functions for any external callers to use that are free of compilications. At the same time, to avoid another indirection, we change from holding the locking functions as a pointer to a struct to a struct itself.
Diffstat (limited to 'include/mupdf/fitz/context.h')
-rw-r--r--include/mupdf/fitz/context.h220
1 files changed, 36 insertions, 184 deletions
diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h
index 129fb686..5a88433f 100644
--- a/include/mupdf/fitz/context.h
+++ b/include/mupdf/fitz/context.h
@@ -108,11 +108,46 @@ enum
*/
void fz_flush_warnings(fz_context *ctx);
+/*
+ Locking functions
+
+ MuPDF is kept deliberately free of any knowledge of particular
+ threading systems. As such, in order for safe multi-threaded
+ operation, we rely on callbacks to client provided functions.
+
+ A client is expected to provide FZ_LOCK_MAX number of mutexes,
+ and a function to lock/unlock each of them. These may be
+ recursive mutexes, but do not have to be.
+
+ If a client does not intend to use multiple threads, then it
+ may pass NULL instead of a lock structure.
+
+ In order to avoid deadlocks, we have one simple rule
+ internally as to how we use locks: We can never take lock n
+ when we already hold any lock i, where 0 <= i <= n. In order
+ to verify this, we have some debugging code, that can be
+ enabled by defining FITZ_DEBUG_LOCKING.
+*/
+
+struct fz_locks_context_s
+{
+ void *user;
+ void (*lock)(void *user, int lock);
+ void (*unlock)(void *user, int lock);
+};
+
+enum {
+ FZ_LOCK_ALLOC = 0,
+ FZ_LOCK_FREETYPE,
+ FZ_LOCK_GLYPHCACHE,
+ FZ_LOCK_MAX
+};
+
struct fz_context_s
{
void *user;
const fz_alloc_context *alloc;
- const fz_locks_context *locks;
+ fz_locks_context locks;
fz_id_context *id;
fz_error_context *error;
fz_warn_context *warn;
@@ -354,41 +389,6 @@ int fz_use_document_css(fz_context *ctx);
void fz_set_use_document_css(fz_context *ctx, int use);
/*
- Locking functions
-
- MuPDF is kept deliberately free of any knowledge of particular
- threading systems. As such, in order for safe multi-threaded
- operation, we rely on callbacks to client provided functions.
-
- A client is expected to provide FZ_LOCK_MAX number of mutexes,
- and a function to lock/unlock each of them. These may be
- recursive mutexes, but do not have to be.
-
- If a client does not intend to use multiple threads, then it
- may pass NULL instead of a lock structure.
-
- In order to avoid deadlocks, we have one simple rule
- internally as to how we use locks: We can never take lock n
- when we already hold any lock i, where 0 <= i <= n. In order
- to verify this, we have some debugging code, that can be
- enabled by defining FITZ_DEBUG_LOCKING.
-*/
-
-struct fz_locks_context_s
-{
- void *user;
- void (*lock)(void *user, int lock);
- void (*unlock)(void *user, int lock);
-};
-
-enum {
- FZ_LOCK_ALLOC = 0,
- FZ_LOCK_FREETYPE,
- FZ_LOCK_GLYPHCACHE,
- FZ_LOCK_MAX
-};
-
-/*
Memory Allocation and Scavenging:
All calls to MuPDF's allocator functions pass through to the
@@ -563,152 +563,4 @@ extern fz_alloc_context fz_alloc_default;
/* Default locks */
extern fz_locks_context fz_locks_default;
-#if defined(MEMENTO) || !defined(NDEBUG)
-#define FITZ_DEBUG_LOCKING
-#endif
-
-#ifdef FITZ_DEBUG_LOCKING
-
-void fz_assert_lock_held(fz_context *ctx, int lock);
-void fz_assert_lock_not_held(fz_context *ctx, int lock);
-void fz_lock_debug_lock(fz_context *ctx, int lock);
-void fz_lock_debug_unlock(fz_context *ctx, int lock);
-
-#else
-
-#define fz_assert_lock_held(A,B) do { } while (0)
-#define fz_assert_lock_not_held(A,B) do { } while (0)
-#define fz_lock_debug_lock(A,B) do { } while (0)
-#define fz_lock_debug_unlock(A,B) do { } while (0)
-
-#endif /* !FITZ_DEBUG_LOCKING */
-
-static inline void
-fz_lock(fz_context *ctx, int lock)
-{
- fz_lock_debug_lock(ctx, lock);
- ctx->locks->lock(ctx->locks->user, lock);
-}
-
-static inline void
-fz_unlock(fz_context *ctx, int lock)
-{
- fz_lock_debug_unlock(ctx, lock);
- ctx->locks->unlock(ctx->locks->user, lock);
-}
-
-static inline void *
-fz_keep_imp(fz_context *ctx, void *p, int *refs)
-{
- if (p)
- {
- (void)Memento_checkIntPointerOrNull(refs);
- fz_lock(ctx, FZ_LOCK_ALLOC);
- if (*refs > 0)
- {
- (void)Memento_takeRef(p);
- ++*refs;
- }
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- }
- return p;
-}
-
-static inline void *
-fz_keep_imp8(fz_context *ctx, void *p, int8_t *refs)
-{
- if (p)
- {
- (void)Memento_checkBytePointerOrNull(refs);
- fz_lock(ctx, FZ_LOCK_ALLOC);
- if (*refs > 0)
- {
- (void)Memento_takeRef(p);
- ++*refs;
- }
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- }
- return p;
-}
-
-static inline void *
-fz_keep_imp16(fz_context *ctx, void *p, int16_t *refs)
-{
- if (p)
- {
- (void)Memento_checkShortPointerOrNull(refs);
- fz_lock(ctx, FZ_LOCK_ALLOC);
- if (*refs > 0)
- {
- (void)Memento_takeRef(p);
- ++*refs;
- }
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- }
- return p;
-}
-
-static inline int
-fz_drop_imp(fz_context *ctx, void *p, int *refs)
-{
- if (p)
- {
- int drop;
- (void)Memento_checkIntPointerOrNull(refs);
- fz_lock(ctx, FZ_LOCK_ALLOC);
- if (*refs > 0)
- {
- (void)Memento_dropIntRef(p);
- drop = --*refs == 0;
- }
- else
- drop = 0;
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- return drop;
- }
- return 0;
-}
-
-static inline int
-fz_drop_imp8(fz_context *ctx, void *p, int8_t *refs)
-{
- if (p)
- {
- int drop;
- (void)Memento_checkBytePointerOrNull(refs);
- fz_lock(ctx, FZ_LOCK_ALLOC);
- if (*refs > 0)
- {
- (void)Memento_dropByteRef(p);
- drop = --*refs == 0;
- }
- else
- drop = 0;
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- return drop;
- }
- return 0;
-}
-
-static inline int
-fz_drop_imp16(fz_context *ctx, void *p, int16_t *refs)
-{
- if (p)
- {
- int drop;
- (void)Memento_checkShortPointerOrNull(refs);
- fz_lock(ctx, FZ_LOCK_ALLOC);
- if (*refs > 0)
- {
- (void)Memento_dropShortRef(p);
- drop = --*refs == 0;
- }
- else
- drop = 0;
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- return drop;
- }
- return 0;
-}
-
#endif