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/