httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ryan Bloom <>
Subject Thread safe functions in APR.
Date Wed, 06 Oct 1999 07:07:21 GMT

There has been some talk lately about how to make sure APR is thread-safe.
I have devised a method, and implemented it for the time functions.  I was
hoping to implement it in all of APR tonight, but the macro took longer to
get right than I expected, and I have just realized that I am pushing my
body too much after a recent illness.  So, here is the currently approved
method to make functions thread-safe in APR.  This has not been thoroughly
tested, and it may not work, but it is the best I have so far.  :->
Please make comments about this if you do not believe it will work.

I have defined two macros:

SAFETY_LOCK(fname, context, str)     -- lock the next few lines of code.
SAFETY_UNLOCK(fname)   -- unlock the previous lines of code.

fname is the name of the function you are trying to lock access to.
context is the context to use when doing this.
str is a string which represents the file to use if a file is required 
    for locking.  I am trying to get rid of this parameter, but not

These must be used together at ALL times.  (examples is a little while)

In the APR file you are fixing (eg time.c) define a static ap_lock_t * for
each function you want to protect.  The name should be lock_funcname.
Don't forget to initialize this to NULL.

For example, if I want to protect gmtime, the definition would be:

static ap_lock_t *lock_gmtime = NULL;

If later in the file you have the line:

gmtime(&currtime, &newtime);

replace this with:

SAFETY_LOCK(gmtime, context, "gmtimefile")   /* I garauntee you have
                          access to some context for doing this.  */
GMTIME_R(&currtime, &newtime);

Don't worry about creating the lock, SAFETY_LOCK will do that for you if
it is required.

Finally, you will need to edit the autoconf files.  In search
for AC_CHECK_FUNCS(gmtime_r localtime_r).  Add the new function to this
list, or create a new AC_CHECK_FUNCS line for the new functions.  Assuming
gmtime_r wasn't already there I would add:


Finally, in acconfig.h you need to define GMTIME_R.  Search for
LOCALTIME_R (I am trying to keep all of these definitions together in case
they all need to be modified).  Define the macro as follow:

#define GMTIME_R(x, y) gmtime_r(x, y)
#define GMTIME_R(x, y) memcpy(y, gmtime(x), sizeof(y))

Of course, memcpy may not be the correct function to use, but that portion
should be easy to figure out.

Now, you will have to run:

At this point, you should test the resulting code to make sure it works.

I have done it this way for a multitude of reasons.  1)  I think the
macros make the code easy to read with adding a lot of complexity for
people who have to debug this code.

2)  We need a lock per function.  The early suggestions for how to fix
this, involved a new lock attached to the APR type.  This won't do the
job.  I don't want to keep the same entity from using the same function
twice at the same time.  I want to keep all entities from using a given
function at the same time.  It is potentially possible, that there will be
two functions in different APR files that want to use the same function.
In this case, my scheme will not work without some modifications.  I do
not know of such a case currently, so I am ignoring it.  If that case
comes up, we just need to move where we define our lock.

I hope this message makes sense.  If not, I'm sorry, let me know and I
will clarify things tomorrow.  :)

I will spend more time tomorrow fixing the rest of APR.  The job is easy
now that the SAFETY_LOCK and SAFETY_UNLOCK functions are available.


Ryan Bloom
4205 S Miami Blvd	
RTP, NC 27709		It's a beautiful sight to see good dancers 
			doing simple steps.  It's a painful sight to
			see beginners doing complicated patterns.	

View raw message