httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexei Kosut <ako...@leland.Stanford.EDU>
Subject Re: another naming question
Date Wed, 24 Dec 1997 11:40:57 GMT
On Wed, 24 Dec 1997, Dean Gaudet wrote:

[technical discussion snipped]

> Right, shared libraries are slower than static libraries.  Try linking a
> libc intensive program -static vs. not -static and time the two, you'll
> see the difference.  Shared libraries are just way more convenient and
> people generally accept the expense.

Okay... I'll take your word for it that calling functions directly is
faster. But as I pointed out, and you've also noted, shared libraries and
C++ and half a dozen other commonplace computer things (it's 3:06am,
that's the best word I can think of right now) do it - so I can't see it
being slow enough to make a real-world difference on a site that serves
less than half a trillion pages a day (hyperbole).

> > > Why do you think we need that?
> > 
> > Sometimes I wonder if anyone actually *read* those page-long emails I
> > kept writing last summer about my ideas for the Apache 2.0 API. I spent
> > hundereds of words on this topic. Certainly no-one responded. Silence
> > equals consent. Especially five months of it...
> silence != consent.  I'm not even sure what emails you're referring to.

Hmm. I can't seem to find the one right now that talks about this topic...
*sigh* Maybe I never wrote it. That would explain why no one responded,
eh? :)

> Besides, this is the Apache group you're referring to.  We never agree
> on anything, and we especially never agree on code which results from
> an accepted proposal.  It's only when there's code in front of our face
> that we have to vote on that we get anywhere.

Yeah, I know. I was just complaining.

> > Basically, I don't want the modules to have to use any symbols from the
> > core.  This makes modules much much easier to have as shared libraries -
> > especially on Windows, where we can get rid of the DLL import libraries,
> > and merge ApacheCore.dll back into Apache.exe. It also makes binary
> > compatibility of modules between versions of Apache:
> You can't have binary compatibility unless we let the API freeze.  We've
> never done that in the past, we've always changed things in subtle ways.
> I doubt that we'll be happy with a frozen API.

No, we don't have to let the API freeze. The nice thing about C data
structures is that, as long as you have control over how they get
allocated, you can add stuff on to the end, and things still work. We've
done this several times with the module type, on the source end, but it
works on the binary side too.

And an API consistent through upgrades has merits. One thing I'm
considering is the lack of commercial support for Apache modules. If I was
a company that, two years ago, downloaded IIS 1.0, read the (pretty
decent) ISAPI spec, wrote an ISAPI extension, which I sold in binary-only
form, that extension, without touching a thing, would still work with IIS
4.0. Now, Microsoft has added a lot to the spec since then, but it's still
binary compatible with the old files. This means that a company can create
a product, without needing to distribute source or anything else that
would violate their proprietary nature, and be relatively secure that
their customers can use this product for a while to come. This scenario
just wouldn't work for Apache. Admittedly, for other reasons as well (the
lack of clear documentation and the ability to easily load that module
into the server, for example), but the lack of binary compatibility
between versions has got to have something to do with it.

And in nearly two years, since Apache 0.8.0, I can only think of two
API functions that have been removed or substantially modified
(get_client_block() and set_last_modified()) such that an Apache 0.8
module would no longer compile on 1.3. 99% of our API changes are
additions. But a binary module compiled under 0.8 won't link into 1.3.
Well, it won't run anyway. And I'm saying that if we pay attention, this
doesn't have to be the case.

> > If the functions are
> > linked ordinally or by address, changing/adding/deleting functions will
> > change those numbers, and things will be screwed up.
> If a module is compiled with:
>     struct foo {
> 	int (*func1)(...);
> 	int (*func2)(...);
> 	...
>     };
> and later we change to:
>     struct foo {
> 	int (*func2)(...);
> 	int (*func3)(...);
> 	...
>     };
> then the module is broken.  The ordinals are still there, they're just
> hidden behind syntactic sugar.

But we have control over it. And, as I said earlier, if we make a
conscious effort to avoid deleting or moving things around in the
structures, a module compiled for 2.0b4 might still work with Apache 2.6.

> I haven't even mentioned yet the expense of having 20 function pointers
> in struct foo {} *for every instance of struct foo*, talk about blowing
> your RAM caches.  To deal with that you start behaving like C++ ... you
> end up with:

Point, I guess. One way to deal with this is to do what ISAPI does, and
only have four functions. But I don't want to do that.

> Huh?  So we're making the C ugly and slow just so that C++ programmers
> can have "pretty" syntax?

This was just another benefit of doing it that way - I'm not saying that
that in any way is the reason I'm advocating it. It is a silly reason.

> > I'm obviously not the only one who feels this way: A whole lot of APIs
> > I've seen lying around work in this manner: ISAPI and JNI are two I've
> > used recently.
> Yes, it's a very academic approach.  I applaud academia.  But I don't
> agree with everything it has to say.  practice != theory.

Funny, I can't remember the last time I saw anything from Microsoft or Sun
even theoretically good :)

Seriously, though... It still seems to me like there's not a good way to
acheive the compatibility issues that I want without doing it this way. To
be honest, if someone could show me that most major OSes load shared
libraries symbolically (i.e., using strings, as opposed to ordinally or by
address), then I'll concede the point. But last time I asked, the vauge
consensus seemed to be that Windows, at least, loads DLL symbols
ordinally. And when VC++ compiles a DLL, it orders the symbols

(although I suppose we could use a .def file to force an order onto the
symbols. Yuck.)

> Anyhow, the big thing I remember from the discussions earlier this summer
> was that we'd remove all the function pointers from the module structure
> leaving only an init() function.  The init() function would have to call
> register_phase(PHASE_NAME, phase_handler) for each of the phases the
> module wanted to handle.  This has explicit ordinals, structures with
> function pointers have implicit ordinals.  You can't lose the ordinals
> unless we started using strings for all the phase names or something
> (and if we did that we might as well just implement in java, we'd be
> about as slow).

Well, first off, I don't think that using strings for this particular
application would be bad. It's an API that Apache uses to get data from
the module at startup (when, IIRC speed isn't *that* important). It can
translate the strings it receives into more optimized forms, for later
access. But that's not the point. I still agree with this for functions in
the module called by the core. It's the other direction we're talking
about right now.

> I'm willing to take indirect control transfer in certain places in
> the API.  But I really don't understand the need to replace rputs()
> with r->rputs().  That is where I'm not following you.

-- Alexei Kosut <> <>
   Stanford University, Class of 2001 * Apache <> *

View raw message