You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Bill Stoddard <st...@raleigh.ibm.com> on 1999/10/01 14:58:28 UTC

APR locks

The APR lock API is trying to hide too many details of the underlying code
for my taste. The current lock create call looks like this:

ap_create_lock(ap_context_t *, ap_locktype_e, ap_lockscope_e, char *,
ap_lock_t **)
where
ap_locktype_w is APR_MUTEX, APR_READWRITE
ap_lockscope_e is APR_CROSS_PROCESS, APR_INTRAPROCESS, APR_LOCKALL
char * is a lock name
ap_lock_t is the lock structure

The definition of ap_lock_t on Unix depend on the serialization #define
(PTHREAD, FCNTL, FLOCK, etc). ap_lock_t must contain the undelying lock
typedefs, e.g., on Win32, a mutex (cross process) and a critical section
(intra process). This structure also requires a runtime check each lock
operation to determine the lock scope. Too many details hidden which can
lead to subtle bugs. I'm thinking a seperate APIs for inter-process locking
and intra-process locking is preferable. The underlying implementation would
be simpler and it will be obvious looking at the code what kind of lock is
being used. Thoughts?

BTW,  ap_create_mutex(), et. al are #defined to (0) in apr_lib.h,  so
apr_pools are not being serialized.

Bill Stoddard




Re: APR locks

Posted by Bill Stoddard <st...@raleigh.ibm.com>.
> Well that's not right!  It's a legacy of the Unix pools not needing
> any multiplexing.  So, the current APR lock API isn't clever enough -
> i.e. apr_lockscope_e is missing APR_LOCK_NONE.
Sounds like a good addition.

>
> apr_lock.h belongs in apr_lib.h not apr_portable right?
>
> Aside: the 1.3 window's pool mutex are unnecessarily expensive using
> inter-process locking, but given the pattern of usage that's probably
> isn't a big deal.
It isn't too hard to change the pool locks to CriticalSections(). I've done
it in fact and could tell little difference in performance. That could be
because of the usage pattern or because the performance difference is
insignificant compared to the other performance problems in the Win32 port
(stat(), open() and read() consume a monster portion of the CPU cycles on
Win32. BTW, the native Win32 calls are significantly faster. I expect Apache
2.0 for Windows to be at least 50% faster serving static files than V1.3.
More if I can get accept socket reuse working. But I digress...)
>
> The dispatch to flavor of lock can be engineered N ways:
>  a. PROPOSED?:  do it in source at callers.
>  b. AS in 1.3:  do it at compile time, in the headers.
>  c. APR design: do it at runtime.
>  d. The every popular: assorted section of the above.
>
> I like b more than a, because the current primary user is already
> coded to have treat the mutex as an abstraction.  I like c more
> that b, but only slightly because I have heroic fantasies of
> pools and i/o pipelines that work in all three ways: user-serialized,
> intra-process, inter-process.
Option b does not lend itself to using CriticalSections and mutexs on
Windows in the same executable using the APR APIs. We either need seperate
API or do it like it's being done in APR now (runtime selectable, which as I
get into it, seems okay).

I brought this up because of the importance of avoiding unnecessary
complexity.  To remain successful, open source projects must be vigilant to
keep the barriers to entry (by new contributors) as low as possible (hence
the use of a common toolset like autoconf style build environments, gcc,
cvs, etc.).  Hiding too many details, I think, is not always the best way to
achieve simplicity (at least to open source develoeprs who tend to want to
understand all those details and not be passive users :-)

Bill


Re: APR locks

Posted by Ryan Bloom <rb...@raleigh.ibm.com>.
> Well that's not right!  It's a legacy of the Unix pools not needing
> any multiplexing.  So, the current APR lock API isn't clever enough -
> i.e. apr_lockscope_e is missing APR_LOCK_NONE.

Easy enough to put it in.  :)

> 
> apr_lock.h belongs in apr_lib.h not apr_portable right?

It definately NEEDS to be in apr_portable, but it also needs to be in
apr_lib.  It's an oversight.  :)

> The dispatch to flavor of lock can be engineered N ways:
>  a. PROPOSED?:  do it in source at callers.
>  b. AS in 1.3:  do it at compile time, in the headers.
>  c. APR design: do it at runtime.
>  d. The every popular: assorted section of the above.
> 
> I like b more than a, because the current primary user is already
> coded to have treat the mutex as an abstraction.  I like c more
> that b, but only slightly because I have heroic fantasies of
> pools and i/o pipelines that work in all three ways: user-serialized,
> intra-process, inter-process.  But then it is always dangerous
> to encourage such enthusiasms.

I agree.  I think if we are going to divide the locks in any way at all,
it needs to be on type oif lock not scope of lock.  A lock is a lock is a
lock, whether that lock is cross process or cross thread shouldn't matter,
it is doing the same thing.  Protecting a section of code.  To break the
locks based on what they are affecting doesn't make any sense to me.  It
make more sense to break them on how they are protecting it.  But, that is
a discussion for another day.  :)

Ryan


_______________________________________________________________________
Ryan Bloom		rbb@raleigh.ibm.com
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.	


Re: APR locks

Posted by Ben Hyde <bh...@pobox.com>.
Pools are the primary customer of locks right now.  So they, at least,
should get what they need to "play nice".

> BTW,  ap_create_mutex(), et. al are #defined to (0) in apr_lib.h,  so
> apr_pools are not being serialized.

Well that's not right!  It's a legacy of the Unix pools not needing
any multiplexing.  So, the current APR lock API isn't clever enough -
i.e. apr_lockscope_e is missing APR_LOCK_NONE.

apr_lock.h belongs in apr_lib.h not apr_portable right?

Aside: the 1.3 window's pool mutex are unnecessarily expensive using
inter-process locking, but given the pattern of usage that's probably
isn't a big deal.

The dispatch to flavor of lock can be engineered N ways:
 a. PROPOSED?:  do it in source at callers.
 b. AS in 1.3:  do it at compile time, in the headers.
 c. APR design: do it at runtime.
 d. The every popular: assorted section of the above.

I like b more than a, because the current primary user is already
coded to have treat the mutex as an abstraction.  I like c more
that b, but only slightly because I have heroic fantasies of
pools and i/o pipelines that work in all three ways: user-serialized,
intra-process, inter-process.  But then it is always dangerous
to encourage such enthusiasms.

 - ben

Re: APR locks

Posted by Manoj Kasichainula <ma...@io.com>.
On Fri, Oct 01, 1999 at 08:58:28AM -0400, Bill Stoddard wrote:
> The definition of ap_lock_t on Unix depend on the serialization #define
> (PTHREAD, FCNTL, FLOCK, etc). ap_lock_t must contain the undelying lock
> typedefs, e.g., on Win32, a mutex (cross process) and a critical section
> (intra process). This structure also requires a runtime check each lock
> operation to determine the lock scope. Too many details hidden which can
> lead to subtle bugs. I'm thinking a seperate APIs for inter-process locking
> and intra-process locking is preferable. The underlying implementation would
> be simpler and it will be obvious looking at the code what kind of lock is
> being used.

Part of the reason Ryan did it this way is that at various times I
wanted the ability to specify:

- cross-process+thread locking required
- cross-process locking, thread locking optional(*)
- cross-proces locking, all threads allowed in
- thread locking, cross-process optional(*)

and so on. So, we came up with the current system as a way to support
these various schemes while trying to be as efficient as possible. If
I wanted the first lock scope above, I'd rather have APR use one
cross-process pthread lock if it's available, rather than having two
locks just because I was forced to by the API.

But, if splitting up the lock API will make up for sometimes adding
extra mutex calls, then I like the idea. Right now, the threaded Unix
MPMs are only using the (*) locks above anyway, so splitting up the
API can only speed things up.

-- 
Manoj Kasichainula - manojk at io dot com - http://www.io.com/~manojk/
"Yes, I'm Linus, and I'm your God" -- Linus Torvalds, Linux Expo '98

Re: APR locks

Posted by Dean Gaudet <dg...@arctic.org>.
On Fri, 1 Oct 1999, Bill Stoddard wrote:

> I'm thinking a seperate APIs for inter-process locking
> and intra-process locking is preferable.

oh that would definately be a better way to go.  intra-process locking
should be extremely light, and preferably inline... but at any rate it
shouldn't be stuck with extra conditionals in its path.

Dean