Implementation

These keep and drop calls for simple objects are generally implemented by using one of a set of standard functions. There are a range of these, depending on the expected size of the reference counts, and all handle the locking required to ensure thread safety:


\begin{lstlisting}
void *fz_keep_imp(fz_context *ctx, void *p, int *refs);
void ...
...s);
int fz_drop_imp16(fz_context *ctx, void *p, int16_t *refs);
\end{lstlisting}

As an example, a fz_path structure is defined as:


\begin{lstlisting}
typedef struct {
int8_t refs;
} fz_path;
\end{lstlisting}

and thus appropriate keep and drop functions can be defined simply:


\begin{lstlisting}
fz_path *fz_keep_path(fz_context *ctx, fz_path *path)
{
retu...
...;
/* code to free the contents of the path structure */
...
}
\end{lstlisting}

More complex variations of these functions are available to cope with `storable' objects, and still more complex versions to cope with `key storable' objects - these are explained in the following sections.

However they are implemented, these objects all look basically the same to most users - they can simply be `kept' and `dropped' as required.