httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <>
Subject Re: work in progress: mpm-3.tar.gz (fwd)
Date Fri, 18 Jun 1999 18:25:32 GMT
On Fri, 18 Jun 1999, Zeev Suraski wrote:

> Correct me if I'm wrong, but you can't obtain the conn_rec from anywhere
> in the code by calling a simple get_conn_rec_ptr()..?

Everywhere which apache calls your module, it passes a request_rec, or a
conn_rec, or some other token by which you can figure out your context... 
beyond that, it's really up to you I think.  If you need a simple
get_conn_rec_ptr() routine, you can implement one rather easily, using
whatever portable, non-portable, etc. method you need. 

Yes, you won't be the only one needing this... but my point is more along
these lines:  it's not a difficult problem to solve, and I've got way more
difficult problems to solve at the moment. 

> I guess it'll be
> possible to implement such a function (if you keep some mapping between
> thread id's and their current corresponding conn_rec's, even though I'm
> not sure if you need it for other purposes or whether it would be just
> pure added overhead).
> Without such a function, you still have to pass the conn_rec pointer
> around everywhere, to any function that may possibly need access to a
> global per-thread variable, which is exactly what TLS comes to solve...

Yeah we're saying the same thing -- I'm saying I'm not worrying about it
because it's solveable.  TLS is really just a void * that magically
changes on context switches. 

> Well, I guess it all depends on what kind of stages we're talking about.
> If the model is remotely similar to Apache 1.x, then we're not in too much

The model is apache 1.x with a few extra config-time hooks at the moment. 

> Well then, I wasn't missing that, it's just not enough for our purposes :)

I still think it's enough, so maybe I'm not explaining myself well enough? 

> One question I raised is whether I can get to that resource from anywhere
> in the code even though it wasn't passed on to me through the stack. 

Yeah -- as I said above, the interface between you and apache are all
those methods in the module structure... and every one includes a
context... if you need that context everywhere in your code and don't pass
it around as a parameter to every one of your functions (as we do within
apache), then you'll need to set up some TLS -- but reset it on every
entry point to your module. 

> Also, it requires the TLS code to be Apache specific, instead of just
> platform specific.  As I said in my previous post, under Win32, for
> instance, the same PHP DLL is used for the CGI (which is just a 16KB big
> .exe) and the IIS module (which is a 90KB DLL).  Both use the very same
> language DLL.  This is more important that one may think, since the fact
> that all interfaces work with the same DLL allows you to link other DLLs
> against this DLL, and have these other DLLs work with any Win32 interface
> of PHP.  For example, if we want to distribute a MySQL extension DLL for
> PHP, we won't have to distribute one MySQL extension for CGI, one for IIS,
> another for Apache and another for NSAPI - but just one extension DLL,
> that's linked against the PHP DLL, that every interface uses.

Surely your DLL has a special entry point for each apache method you hook,
right?  Make that entry point set up your TLS. 

> Which brings me to another consideration - while I haven't read the full
> ISAPI spec anywhere (if it even exists) - I think you can rely on all of
> the request stages in ISAPI happening within the same thread (Microsoft
> certainly uses it in their examples as far as I recall).  If you won't be
> able to rely on it in Apache 2.0, it'll pretty much mean that ISAPI will
> not be supported..?

That's just too unfortunate then.  i.e. I don't care.  I'm not going to
stop the progress of apache just for some stupidity in ISAPI.

If ISAPI requires that, then the WINNT MPM will have to guarantee it. 
It's easy to guarantee it by not implementing any of the async stuff.  Too
bad for WINNT users, they're going to be stuck a generation behind in
technology (as if that should bother them, they're using NT after all). 

> I'm not exactly sure how we could implement Apache local storage
> equivalent, unless we have access to the conn_rec from anywhere in the
> code, regardless of function arguments.

I know I'm repeating myself a bunch... you have it at all the boundaries
between apache and your code.  That's enough. 

> If you want TLS support within
> Apache you can probably use the TLS code from PHP 4.0 (platform
> independant and more powerful than the TLS in Win32), you'd just implement
> the function that returns the thread id as a function that returns the
> conn_rec pointer or identifier somehow.

Ryan or someone working on APR might be interested in this. 

> Two 'still's remain here though.  It still means that the module would
> have to use Apache-specific TLS, which is less than optimal from a point
> of view of a module writer that wants the same code to be used on multiple
> servers (that would be me in our case:). 

Nope it wouldn't require apache-specific TLS... 

> And my general hunch about it is still negative, in the sense that I think
> we'd bump into many problems, especially in modules that use 3rd party
> libraries that are also thread safe (for example, say you initialize the
> MySQL client library in one phase, and then use it in another - there's a
> good chance there's thread-specific initialization in that library, and it
> won't happen in such a case;  In MySQL's case, I don't think we have a
> problem, but I'm almost sure there'd be others in which we would).  And
> there's also ISAPI.
> How feasible would it be to be able to mark a module as one that wants
> all of its request steps to be performed within the same thread? 

To be honest, at the moment I really only care about this requirement
between the handler phase, and the subsuquent logging phase. 

But I still say that such libraries are broken.  When you "initialize the
mysql client library" it passes you back a pointer, right?  A pointer
which you then pass to all other mysql library functions, right?  If their
code doesn't hang all the info they need off that pointer, then their code
is broken.  Sorry, but that's just how it is.  Why pass back a pointer if
it's not all the info they need?

That'd be like saying FILE *f = fopen("foo", "r"); can only be used within
the thread that the fopen occurs.  Which seems pretty silly to me... 

However, I can relax the requirement a small amount:  It's only MPMs which
support async behaviour which have this requirement.  On all unix
platforms there will be the prefork MPM which won't be async; and it's a
small exercise to build a pthread MPM which won't have async support. 
Async is an extra feature for the MPM, not a requirement.  So we can cater
to such brokenness on all unix platforms simply by choosing a less than
optimal MPM.

But for the majority of users, I want async MPM support. 


View raw message