[fitz-dev] On the fitz global context
tor andersson
tor at ghostscript.com
Sat Dec 20 08:16:12 PST 2003
The global context is used for three tasks:
1) storing error message and class
2) custom memory allocator
3) global name context for dynamic objects
To accomplish this it is passed around everywhere it is needed.
Being consistent, it is passed as the first argument to all
public functions exported by fitz, whether it is needed or not.
Keeping track of where it is needed or not is too much brainwork,
and any change that requires the use of any of the three tasks
might invalidate the function signatures in the api, which is bad.
The following functions are the only ones that actually use the context:
1) fz_throw, fz_thrownil, fz_croak, fz_strerror
2) fz_malloc, fz_realloc, fz_free
3) fz_intern
However, I don't like it much, and move to eliminate the global context
as passed around everywhere and make it global (or thread local storage)
with functions like OpenGL to change the current context.
It's ugly and awkward to write code that passes around a ctx all
over the place. Also, it has to have some cost passing it around
on the stack/in the registers all the time.
I don't like having 'runtimes' in C code. This is much too much like one.
It makes all fitz code depend too heavily on this global context. It should
be possible to rip out code (say, the filters) and not have it depend.
In clients, you need to have a fitz context and pass it around to all
fitz functions, contaminating further. Then, do clients get to use the
context for their own malloc/error reporting needs?
Oh, and there's one or two icky chicken-egg-cases when creating contexts.
Could someone please remind me again why we thought having an explicit
context was a good idea?
== New API proposal ==
I'm not convinced of the value of having an error code separate from the
message, or vice versa. I would prefer suggest one method (code only,
with more error code types, or message only) with a preference for
message-only.
Pointer-valued functions return nil if error.
Void-valued functions return -1 if error, 0 otherwise.
Int-valued functions return -1 if error, >= 0 otherwise.
Functions that have no return value call fz_abort on errors (rare).
If we have codes, this is the current set of error classes:
enum
{
FZ_ERROR, /* general catch-all */
FZ_EASSERT,
FZ_ENOMEM,
FZ_EIO,
FZ_ERANGE,
FZ_ETYPE,
FZ_ELIMIT,
FZ_ESYSCALL
};
struct fz_errctx_s
{
void (*abort)(int, char*);
int class;
char message[256];
};
void fz_seterrorcontext(fz_errctx *ec);
fz_errctx *fz_currenterrorcontext();
int fz_raise(int class, char *fmt, ...); /* returns -1 for convenience */
void fz_assert(int expr);
void fz_abort();
int fz_errorclass();
char *fz_errorstring();
void fz_setmemorycontext(fz_memctx *mc);
fz_memctx *fz_currentmemorycontext();
void *fz_malloc(int size);
void *fz_realloc(void *p, int size);
void fz_free(void *p);
void fz_setnamecontext(fz_namectx *nc);
fz_namectx *fz_currentnamecontext();
int fz_intern(char *s);
More information about the fitz-dev
mailing list