diff options
author | Robin Watts <robin.watts@artifex.com> | 2017-11-08 19:45:14 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2017-11-09 12:41:52 +0000 |
commit | 258f03a0a55c1aa802e1be47e463d8abc5096196 (patch) | |
tree | 7596f3081254276b29d929aa87b233a04d02ce51 /source/fitz/fitz-imp.h | |
parent | 9f32fdff17f9d6cb114c4f70d1e4b8364e8b5d11 (diff) | |
download | mupdf-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 'source/fitz/fitz-imp.h')
-rw-r--r-- | source/fitz/fitz-imp.h | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/source/fitz/fitz-imp.h b/source/fitz/fitz-imp.h index 23908a8d..41c905e4 100644 --- a/source/fitz/fitz-imp.h +++ b/source/fitz/fitz-imp.h @@ -91,4 +91,152 @@ void fz_new_output_context(fz_context *ctx); void fz_drop_output_context(fz_context *ctx); fz_output_context *fz_keep_output_context(fz_context *ctx); +#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 |