You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Stanley Gambarin <st...@cs.bu.edu> on 1997/07/22 17:23:06 UTC
documentation stuff
This is a first draft of many. Please comment on the stuff
below, so that i may improve it. Is that documentation for the server
to be provided only as HTML files ??? (below was done with perl's pod
stuff). Personally, i find it extremely painful to only have html files
to work with (some of us don't have browsers). Also, if someone with
95/NT box has some free time, how about html->rtf->hlp (windows help
files) for all current documentation for 1.3?
Stanley.
NAME
apdoc_m - Apache's memory allocation routines
DESCRIPTION
Unless your modules are extremely trivial in implementation, a
dynamic memory allocation will be required. While Apache does
not prevent you from using system provided routines, such as
malloc(3C) and free(3C), it does offer an alternative which
leaves all memory management to the server and abstains the
module developer from fiddling with system components in a
portable way.
Apache provides a pool-based memory system, by which a memory is
allocated from a pool of memory, but is never freed. The memory
actually gets freed when the pool is destroyed by the server.
This approach allows for the faster allocation and deallocation
routines, where the server does not need to perform complex heap
management operations for each call to malloc(3C) and free(3C),
which would be otherwise done by the operating system.
Pool-based memory system is also extensively used by the
server's file and network i/o subsystems. Each server component,
such as file descriptor, can register a cleanup function that is
automatically invoked when the pool is destroyed. This allows
for a simple and clean maintainance of system resources.
NOTES
Pools are hierarchical in nature, therefore a destruction of the
pool would lead to the destruction of all subpools that are
created from the given pool. The care should be taken to avoid
such situations, where per-connection memory pool should not be
used to store and pass information across multiple requests
and/or connections. Any module that deals with memory allocation
routines should include alloc.h.
On the same note, make sure not to use the file descriptors that
were allocated from a pool after a pool is destroyed. As pool is
destroyed, a file descriptor will be closed and its usage
afterwards would lead to an undefined behavior.
Apache's server memory subsystem is designed to be signal and
thread safe. Thus no specific actions are required from the
module developers to maintain memory consistency and conherence.
API
pool *make_sub_pool (pool *pp)
Create and return a subpool of the pp. A chunk of memory is
allocated from a freelist, which contains a list of unused
memory blocks. If no such allocation can be made, malloc(3C)
system call is used. Additional memory is allocated by the
memory subsystem in the similar manner. A NULL is returned
if an error has occurred during memory allocation. If pp is
NULL, returned pool structure does not have a parent pool
and thus will persist until server termination or explicit
call to destroy_pool(). Such usage is highly discouraged as
it may lead to memory leaks by the server.
Example: pool *p = make_sub_pool (NULL);
void destroy_pool (pool *p)
Destroys pool p by freeing any memory that was associated
with it. Newly available memory chunks are placed onto the
freelist to be used later on by other subpools. Any cleanup
functions that were registered with p are invoked by the
server. After the call to this function, pointer p should
not be used, as its behavior will be undefined.
Example: destroy_sub_pool (p); p = NULL;
void clear_pool (pool *p)
This function is very similar to destroy_pool(), except the
memory that is associateed with pool p is not itself freed
and thus can be reused later on.
Example: clear_pool (p);
void cleanup_for_exec (void)
This function should NOT be used be used by module
developers, unless a module is performing an exec() function
call. The function is responsible for freeing any resources
associated with a current process and running cleanups on
the allocated pools.
Example: cleanup_for_exec(); exec(...)
void *palloc (pool *p, int nbytes)
Allocate the memory of nbytes bytes from the pool p and
return a pointer to it. This function or pcalloc() should be
called instead of malloc(3C) system call. Server does not
provide memory overflow checks, which must be done by the
module developers.
Example: p = make_sub_pool (NULL); ptr = palloc (p, 128);
void *pcalloc (pool *p, int nbytes)
This function is very similar to the palloc() function,
except that the returned memory has been zeroed out by the
server. This is the most commonly used function for memory
allocation and should be used with caution to avoid memory
overflow when dealing with pointer arithmetic.
Example: p = make_sub_pool (NULL); ptr = pcalloc (p, 128);
char *pstrdup (pool *p, const char *s)
Create and return new string, which is a copy of the string
s. The memory for the new string is allocated from pool p
using palloc() function. String pointed to by s should not
contain multibyte characters, as the results of executing
this function would provide for undefined behavior.
Example: p = make_sub_pool (NULL); s = pstrdup (p, "Geeks R
Us");
char *pstrndup (pool *p, const char *s, int n)
Create and return new string containing first n bytes
(excluding terminating NULL) of string s. The memory is
allocated from a pool p using palloc() function. String
pointed to by s should not contain multibyte characters as
that would lead to an indefined behavior.
Example: p = make_sub_pool (NULL); s = pstrndup (p, "Apache
is Cool", 6);
char *pstrcat (pool *p, ...)
Create and return a string which is a concatenation of all
the string specified as arguments. The memory is allocated
from pool p using palloc() function. Any additional argument
to this function should be a pointer to a character (char
*). If no arguments are specified, this function returns
NULL.
Example: p = make_sub_pool (NULL); ptr = pstrcat (p, "Hello
", "world ");
array_header *make_array (pool *p, int nelts, int elt_size)
Create an array of nelts elements, where each element is of
the size specified by elt_size. The memory for the array
elements is allocated from pool p using palloc() function.
Apache web server provides a dynamic array management
facility which abstains module developer from worrying of
array overflow and makes using arrays very easy.
Example: array_header *a = make_array (p, 20, sizeof (char
*));
void *push_array (array_header *a)
Return a pointer to the next available slot in the array a.
If there are no free slots in the given array, a new array
of bigger size is allocated from the same pool as a and then
copied over.
Example: array_header *a = make_array (p, 1, sizeof (char
*)); ptr = push_array (a);
void array_cat (array_header *dst, const array_header *src)
Concatenate arrays dst and src into dst. If there is not
enough space allocated for both arrays, additional space is
allocated from the same pool as dst array and the new values
are copied over. Array specified by src is unchanged by this
operation. The size of each element in dst and src arrays
should be the same, otherwise undefined behavior will occur.
Example: array_header *a = make_array (p, 1, sizeof (int));
array_header *b = make_array (p, 5, sizeof (int));
/* this will force overflow */
array_cat (a, b);
array_header *append_arrays (pool *p, const array_header *first, const array_header *second)
This function is very similar to array_cat() function except
that no modification is done to either first or second
array. Additional memory is allocated from the pool p as
necessary.
Example: array_header *a = make_array (p, 1, sizeof (int));
array_header *b = make_array (p, 5, sizeof (int));
array_header *c = append_array (p, a, b);
array_header *copy_array (pool *p, const array_header *src)
Create and return a copy of array specified by src. Any
required memory is allocated from the pool p. Array pointed
to by src is not modified by the execution of this function.
Example: array_header *a = make_array (p, 1, sizeof (int));
array_header *b = copy_array (p, a);
table *make_table (pool *p, int nelts)
Create and return a new table structure containing nelts
elements. The memory is allocated from the pool p. The table
structure is a structure containing key=>value pairs.
Current version of the Apache uses array_header data
structure to maintain the needed information, however, no
assumptions should be made about internal table
implementation.
Example: table *t = make_table (p, 5);
table *copy_table (pool *p, const table *t)
See copy_array().
void clear_table (table *)
Clears the table contents by setting the number of elements
in the table to 0. Successive use of the table would
override current contents of the table.
Example: table *t = make_table (p, 5); clear_table (t);
char *table_get (const table *t, const char *s)
Return the contents of the value field which corresponds to
the key field specified by the string s. Table t is searched
for the appropriate entry. If the entry is not found in the
table t, a NULL value is returned. The comparison of the key
fields against string s is case-insensitive.
Example: value = table_get (t, "Content-type");
void table_set (table *t, const char *name, const char *val)
Set the key specified by the name to the value specified by
val in the table t. Any previous value of the key field
specified by name is overriden by the new value. All string
comparisons are case-insensitive. Character pointers pointed
to by name and val should not be NULL values.
Example: table_set (t, "Content-type", "text/html");
/* overrider the previous value - even case-insensitive */
table_set (t, "Content-TYPE", "text/plain");
void table_merge (table *t, const char *name, const char *more_val)
This function is similar to table_set(), except that if the
key field specified by the name is already present, a
more_val is concatenated with the existing value field,
using comma as separator.
Example: table_set (t, "Vary", "accept-encoding");
/* this will result in Vary=accept-encoding, negotiate */
table_merge (t, "Vary", "negotiate");
void table_unset (table *t, const char *key)
Opposite of table_set(). This function is used to clear the
value of the specified key and remove the key from the table
t. Any further reference to the key in the same table would
result in NULL value. If key is not found in the table t, no
modifications are made.
Example: table_unset (t, "Content-Encoding");
void table_add (table *t, const char *name, const char *val)
Adds the key=value pair to the table t specified by the name
and val parameters. This function does not make any checks
for the previously existing key with the same name in the
table t and may result in the duplicate entries. Use
table_set() function to assure unique entries.
Example: table_add (t, "Content-Length", "800");
void table_do (int (*comp)(void *r, const char *name, const char *val), void *rec, const table *t, ...)
This function would invoke function specified by the comp
for each key=value pair in the table t. If no additional
parameters are specified, this function iterates over all
headers or until function specified by the comp would return
0. Otherwise, only headers where key field matches extra
parameter(s) will be passed to function comp. If the value
field specifies multiple comma-separated entries, only a
single function call will be issued by table_do and it is
the job of the comp() function to separate these values.
Example: int comp (void *r, char *key, char *val) { printf
("%s=%s\n", key, val); return (1); } table_do (comp, NULL,
t);
table *overlay_tables (pool *p, const table *overlay, const table *base)
See array_append().
array_header *table_elts (table *t)
Return pointer to the internal data structure containing the
contents of the table t. This function is provided to allow
for easy abstraction of the table data structure in the near
future.
void register_cleanup (pool *p, void *data, (void *)plain_cleanup (void *), void (*child_cleanup)(void *))
This function is seldomly used by the module developers as
it provides a generic interface for registering pool-based
resource cleanup functions. Pool p will be associated with
the registered cleanup, which will be automatically invoked
when pool is destroyed (either via clear_pool(p) or
destroy_pool(p)). A pointer to data variable indicates the
data to be passed to the cleanup functions. Function pointed
to by plain_cleanup is invoked during the destruction of the
pool, while function pointed to by the child_cleanup is
invoked on the subpools of the pool p. Ideally, both
plain_cleanup and child_cleanup would point to the same
function, as child_cleanup is rarely used by the server and
caution should be exercised in using it. Note that
destroy_pool() and clear_pool() functions would invoke
plain_cleanup function on the subpool, invoking
child_cleanup later on would lead to an undefined behavior.
Example: void *generic_cleanup (void *data) { free(data); }
register_cleanup (p, stuff, generic_cleanup,
generic_cleanup);
void kill_cleanup (pool *p, void *data, void (*plain_cleanup)(void *))
Delete previously registered cleanup function from this
pool's list of cleanup routines. If no registered cleanup
function can be found, this function has no effect on passed
parameters.
Example: kill_cleanup (p, NULL, generic_cleanup);
void run_cleanup (pool *p, void *data, void (*cleanup)(void *))
Explicitly run the cleanup function for the pool p. A check
is made to allow for only single run of the cleanup
function. After the execution of run_cleanup() function, a
function specified by the cleanup function pointer is no
longer registered as a cleanup for pool p.
Example: run_cleanup (p, NULL, generic_cleanup);
void block_alarms (void);
This function is used to assure that no signals are being
recieved while server processing is done. The signal
delivery is disabled until the call to unblock_alarms() is
made.
Example: block_alarms ();
void unblock_alarms (void)
This function is a complementary to block_alarms() function
and is used to enable signal delivery to the server process.
Example: unblock_alarms ();
FILE *pfopen (pool *p, const char *name, const char *fmode)
Open a file specified by the name parameter using fmode for
file mode. A cleanup function is automatically registered
with a pool p, which allows for closure of the file at the
moment of pool destruction.
Example: FILE *fp = pfopen (p, "index.html", "r");
FILE * pfdopen (pool *, int fd, const char *fmode)
Complement of the fdopen() system call with an addition of
the automatic registration of the cleanup function to close
used file descriptor during pool destruction.
Example: int fd = pfdopen (p, 1, "r");
int popenf (pool *p, const char *name, int flg, int mode)
Complement of the open() system call with an addition of the
automatic registration of the cleanup function to close used
file descriptor during pool destruction.
Example: int fd = popenf (p, "index.html", O_RDWR, 0644);
int pfclose (pool *p, FILE *fp)
Closes the file pointer pointed to by fp and kill the
cleanup that was associated with it. Same pool structure
should be specified as the one provided in pfopen() function
call, otherwise an undefined behavior may result. Mixing
calls to fopen() and pfclose() is ok, even though it is not
recommended.
Example: FILE *fp = pfopen (p, "index.html", "r"); pfclose
(p, fp);
int pclosef (pool *p, int fd)
Same as pfclose() but used in conjunction with popenf()
function.
Example: pclosef (p, 1);
DIR *popendir (pool *p, const char *name)
Complement of the opendir() system call with an addition of
the automatic registration of the cleanup function to close
used file descriptor during pool destruction.
Example: DIR *d = popendir (p, "/");
void pclosedir (pool *p, DIR *d)
Same as pfclose() but used in conjunction with popendir()
function.
Example: pclosedir (d);
long bytes_in_pool(pool *p)
Return the number of used bytes in the pool p.
Example: l = bytes_in_pool (p);
long bytes_in_free_blocks(void)
Return the number of bytes in the list containing "free"
memory blocks to be used by other pools.
Example: l = bytes_in_free_blocks();
regex_t * pregcomp (pool *p, const char *pattern, int cflags)
This function provides an Apache's interface to the regular
expression engine which is bundled with the web server. A
pool p is used to allocate any additional memory that maybe
required. Pattern is the pattern to search for when the
regexec() function is executed. A cleanup function is
registered with the pool p to allow management of the
regular expressions as any other system resource.
Example: regext_t *r = pregcomp (p, "^Mozilla",
REG_EXTENDED);
void pregfree (pool *p, regex_t *reg)
Delete any memory that was associated with a given regular
expression. Also kill any cleanups that may have been
registered with the pool p for a regular expression reg.
Example: pregfree (p, r);
int spawn_child_err (pool *p, int (*func)(void *), void *data, enum kill_conditions kill_how, FILE **pipe_in, FILE **pipe_out, FILE **pipe_err)
This function maybe used by the module that need to execute
and communicate with an outside process. The required
parameters include: pool p which is used for memory
allocation, a pointer to the function that should be
executed to provide needed functionality, a pointer to the
data that should be passed to the aforementioned function,
conditionds under which a new process should be terminated
and three pointers for process's input, output and error
streams.
Example: int worker (void *data) { printf ("%s", data); }
spawn_child_err (p, worker, (void *)"Hello World",
kill_after_timeout, NULL, &fp, NULL);
Re: documentation stuff
Posted by Stanley Gambarin <st...@cs.bu.edu>.
On Wed, 23 Jul 1997, Dean Gaudet wrote:
> What do we feel about using POD format to integrate this sort of thing
> with the code directly? (POD and C get along together, don't they?)
>
Thanks for reading the stuff... it must have been painful :)
My opinion on the using POD inside the code is a no-no. This would
contribute to code bloat in a huge way, as documentation that i write
usually surpasses the size of documented code. A possible solution is to
provide a comment header before each function which contains http link to
the corresponding .html file and html file can contain a link to the
corresponding source file, where the function is defined.
> > pool *make_sub_pool (pool *pp)
> > Create and return a subpool of the pp.
>
> This is pretty much all you should say for make_sub_pool. Although you
> should note that even though it is a "sub pool", memory allocation within
> it are in distinct chunks of memory. So there's no/little fragmentation
> potential.
Not fully agreed. (a) the documentation should provide all error
conditions that may be generated by the function call (returning NULL?)
(b) "Current" implementation uses distinct chunks of memory... the idea is
to provide a documentation, such as if Mr. Bob Jones would like to
implement his own pool alternative, all he has to do is to conform to the
provided API.
> > void register_cleanup (pool *p, void *data, (void *)plain_cleanup (void *), void (*child_cleanup)(void *))
> > pool, while function pointed to by the child_cleanup is
> > invoked on the subpools of the pool p.
>
> Not correct. The child_cleanup is used after a fork() to clean up
> resources in the child. Specifically consider a FILE *. A FILE * should
> be fclose()d exactly once, otherwise it may have part of its buffer
> flushed twice, leading to corrupt output. So notice that the
> child_cleanup for a FILE * just does a close(fileno(f))... which doesn't
> flush the buffer.
This is exactly what is needed in the documentation. I just read
the code and tried to see where it is used.
> > Example: run_cleanup (p, NULL, generic_cleanup);
>
> Interesting that we don't have a child equiv for this one.
Actually, the code calls run_cleanup() for both plain_cleanup and
child_clean parameters for generic_cleanup.
> > regex()
> > This function provides an Apache's interface to the regular
> > expression engine which is bundled with the web server. A
> > pool p is used to allocate any additional memory that maybe
> > required.
>
> Actually no pool is created ... it just registers cleanups for the compiled
> regex_t in the pool p.
I did not say created..i said used, as pool p is used to allocate
the memory for the matching expression (using pcalloc()).
I am currently in the process of the revamping the documentation
system (playfully named A(pache) D(ocumentation) P(roject)) which is going
to take some time to implement. In the meantime, would appreciate any
suggestions that people may have on the design. Should have some
preliminary version available hopefully by september (but i target this
for 2.0,so i guess i am in no hurry :() Current document directory
structure (not complete by any means) include something of the following:
+ search
+ intro
+ welcome to apache
+ how to use this documentation
+ what is apache
+ history of the apache server
+ apache group
+ notes on versioning (i.e this documentation is for 2.0 release)
+ apache user
+ intro
+ obtaining apache
+ compiling apache
+ starting/restarting/killing server
+ configuration
+ enabling multiple logs
+ enabling virtual hosts
+ directives
+ core
+ modules
+ a bunch of other stuff
+ apache server support
+ reporting problems
+ ciswu
+ mailing list
+ external support organization
+ apache developer
+ coding style
+ module developer
+ intro
+ targeted audience
+ why do we need extra modules
+ API exposed to module developer
+ memory
+ file/network i/o
+ logging/debugging
+ request hooks
+ implementing module in C
+ functions
+ registering module
+ implementing module in Perl
+ functions
+ registering module
+ testing your module
+ submitting a module
+ core/distributed
+ module registry
+ core developer
+ intro
+ targeted audience
+ submitting changes
+ OS limitations
+ fds / slack
+ accept(), etc.
+ design of the subsystems (detailed design of subsystems)
+ memory
+ file/network i/o
+ protocol implementation
+ request processing
+ trace/debugging/logging facility
+ porting
+ adding new ported system
+ compile time options
+ performance
+ optimizing code
+ future
+ requested features
+ planned enhancements
+ timeline
If i missed anything, please say so. To start with, .html format
will be used, which will then be transformed to .hlp (for win32 users) and
simple text for some os us at more disadvantaged positions.
Stanley.
Re: documentation stuff
Posted by Dean Gaudet <dg...@arctic.org>.
What do we feel about using POD format to integrate this sort of thing
with the code directly? (POD and C get along together, don't they?)
On Tue, 22 Jul 1997, Stanley Gambarin wrote:
> This is a first draft of many. Please comment on the stuff
> below, so that i may improve it. Is that documentation for the server
> to be provided only as HTML files ??? (below was done with perl's pod
> stuff). Personally, i find it extremely painful to only have html files
> to work with (some of us don't have browsers). Also, if someone with
> 95/NT box has some free time, how about html->rtf->hlp (windows help
> files) for all current documentation for 1.3?
I use lynx on local files a lot rather than start up a webserver/browser.
> DESCRIPTION
> Unless your modules are extremely trivial in implementation, a
> dynamic memory allocation will be required. While Apache does
> not prevent you from using system provided routines, such as
> malloc(3C) and free(3C), it does offer an alternative which
> leaves all memory management to the server and abstains the
> module developer from fiddling with system components in a
> portable way.
The main reason for the pools is resource cleanup, specifically after a
longjmp back to the child_main main loop; but more generally to free the
programmer from having to actively clean things up.
> NOTES
> Pools are hierarchical in nature, therefore a destruction of the
> pool would lead to the destruction of all subpools that are
> created from the given pool. The care should be taken to avoid
> such situations, where per-connection memory pool should not be
> used to store and pass information across multiple requests
> and/or connections. Any module that deals with memory allocation
> routines should include alloc.h.
per conn can be used for things across requests within the same
connection. But such state is anathema to HTTP, and so this isn't used by
anything in the core. I've had occasion to use it in a 3rd party
module...
> Apache's server memory subsystem is designed to be signal and
> thread safe. Thus no specific actions are required from the
> module developers to maintain memory consistency and conherence.
block_alarms()/unblock_alarms() are required around certain operations.
> API
> pool *make_sub_pool (pool *pp)
> Create and return a subpool of the pp.
This is pretty much all you should say for make_sub_pool. Although you
should note that even though it is a "sub pool", memory allocation within
it are in distinct chunks of memory. So there's no/little fragmentation
potential.
> A chunk of memory is
> allocated from a freelist, which contains a list of unused
> memory blocks. If no such allocation can be made, malloc(3C)
> system call is used. Additional memory is allocated by the
> memory subsystem in the similar manner. A NULL is returned
> if an error has occurred during memory allocation. If pp is
> NULL, returned pool structure does not have a parent pool
> and thus will persist until server termination or explicit
> call to destroy_pool(). Such usage is highly discouraged as
> it may lead to memory leaks by the server.
This belongs more with palloc().
> void clear_pool (pool *p)
> This function is very similar to destroy_pool(), except the
> memory that is associateed with pool p is not itself freed
> and thus can be reused later on.
A bit confusing. After a clear_pool(p), p has no resources allocated. It
has been returned to its blank state right after the make_sub_pool which
created it. What you mean is that the pointer p is still a valid pool,
but saying "the memory that is associated with pool p ..." might be
confused to mean "the memory *allocated* in pool p".
> void cleanup_for_exec (void)
> This function should NOT be used be used by module
> developers, unless a module is performing an exec() function
> call. The function is responsible for freeing any resources
> associated with a current process and running cleanups on
> the allocated pools.
Specifically, it runs all the child_cleanups for registered cleanups.
> void *palloc (pool *p, int nbytes)
> Allocate the memory of nbytes bytes from the pool p and
> return a pointer to it. This function or pcalloc() should be
> called instead of malloc(3C) system call. Server does not
> provide memory overflow checks, which must be done by the
> module developers.
Somewhere it would be useful to have a discussion of how to do large
memory allocations. In particular, *don't* do them ;) But if you have
to, then it is a good idea to create a sub pool for them specifically and
free that sub pool as soon as possible. Typically allocations are in the
request pool which has a possible lifetime of the entire request.
[I didn't read the table/array stuff closely.]
> void register_cleanup (pool *p, void *data, (void *)plain_cleanup (void *), void (*child_cleanup)(void *))
> pool, while function pointed to by the child_cleanup is
> invoked on the subpools of the pool p.
Not correct. The child_cleanup is used after a fork() to clean up
resources in the child. Specifically consider a FILE *. A FILE * should
be fclose()d exactly once, otherwise it may have part of its buffer
flushed twice, leading to corrupt output. So notice that the
child_cleanup for a FILE * just does a close(fileno(f))... which doesn't
flush the buffer.
> void run_cleanup (pool *p, void *data, void (*cleanup)(void *))
> Explicitly run the cleanup function for the pool p. A check
> is made to allow for only single run of the cleanup
> function. After the execution of run_cleanup() function, a
> function specified by the cleanup function pointer is no
> longer registered as a cleanup for pool p.
>
> Example: run_cleanup (p, NULL, generic_cleanup);
Interesting that we don't have a child equiv for this one.
> void block_alarms (void);
> void unblock_alarms (void)
Somewhere in the code is a description of when these are needed.
Essentially they're needed around events which you do not want to longjmp
out of. In particular, if a module is implementing its own cleanup it
would have to block alarms while it allocated the resource and registered
the cleanup. Then after registration it could unblock alarms.
kill_cleanups also has to be protected. Because if a longjmp occurs
while it's doing its job, corruption will occur.
> regex_t * pregcomp (pool *p, const char *pattern, int cflags)
> This function provides an Apache's interface to the regular
> expression engine which is bundled with the web server. A
> pool p is used to allocate any additional memory that maybe
> required.
Actually no pool is created ... it just registers cleanups for the compiled
regex_t in the pool p.
Dean
Re: documentation stuff
Posted by Alexei Kosut <ak...@organic.com>.
On Thu, 24 Jul 1997, Stanley Gambarin wrote:
> httpd.h exposes a lot of server insides, which should never be
> known to the modules. The ideal solution is to provide a single header
> file
> for all modules to use (but not httpd.h). That file would contain all
> the prototypes for exposed API.
Bzzzzt. Sorry, wrong. Thank you for playing. Do a grep httpd.h mod_*.c
sometime. Then tell me which "server insides" httpd.h exposes. I don't
see any.
-- Alexei Kosut <ak...@organic.com>
Re: documentation stuff
Posted by Stanley Gambarin <st...@cs.bu.edu>.
On Wed, 23 Jul 1997, Alexei Kosut wrote:
> Would it really hurt anything to have the http_*.h files at least just
> included by httpd.h?
>
httpd.h exposes a lot of server insides, which should never be
known to the modules. The ideal solution is to provide a single header
file
for all modules to use (but not httpd.h). That file would contain all
the prototypes for exposed API.
Just a thought.
Stanley.
Re: documentation stuff
Posted by Alexei Kosut <ak...@nueva.pvt.k12.ca.us>.
On Tue, 22 Jul 1997, Stanley Gambarin wrote:
[...]
> and/or connections. Any module that deals with memory allocation
> routines should include alloc.h.
Haven't read the rest of this yet, but I had to point out one thing:
Nothing should ever include alloc.h. Except httpd.h. Modules should
include httpd.h, which includes alloc.h, conf.h, and some other
things. Apache does not have protection against including a header
file multiple times, so if a module included alloc.h, it would result
in errors galore.
On that note... I recently noticed (for the first time, apparently, in
nearly two years), that when writing a module, one has to include a
lot of header files. Is it really neccessary for the module to have to
specify that it wants (as mod_cgi.c does) httpd.h, http_config.h,
http_request.h, http_core.h, http_protocol.h, http_main.h, http_log.h
and util_script.h?
Would it really hurt anything to have the http_*.h files at least just
included by httpd.h?
--
________________________________________________________________________
Alexei Kosut <ak...@nueva.pvt.k12.ca.us> The Apache HTTP Server
URL: http://www.nueva.pvt.k12.ca.us/~akosut/ http://www.apache.org/