Main Page | Modules | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages | Examples

apr_thread_proc.h

Go to the documentation of this file.
00001 /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
00002  * applicable.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef APR_THREAD_PROC_H
00018 #define APR_THREAD_PROC_H
00019 
00020 /**
00021  * @file apr_thread_proc.h
00022  * @brief APR Thread and Process Library
00023  */
00024 
00025 #include "apr.h"
00026 #include "apr_file_io.h"
00027 #include "apr_pools.h"
00028 #include "apr_errno.h"
00029 
00030 #if APR_HAVE_STRUCT_RLIMIT
00031 #include <sys/time.h>
00032 #include <sys/resource.h>
00033 #endif
00034 
00035 #ifdef __cplusplus
00036 extern "C" {
00037 #endif /* __cplusplus */
00038 
00039 /**
00040  * @defgroup apr_thread_proc Threads and Process Functions
00041  * @ingroup APR 
00042  * @{
00043  */
00044 
00045 typedef enum {
00046     APR_SHELLCMD,       /**< use the shell to invoke the program */
00047     APR_PROGRAM,        /**< invoke the program directly, no copied env */
00048     APR_PROGRAM_ENV,    /**< invoke the program, replicating our environment */
00049     APR_PROGRAM_PATH,   /**< find program on PATH, use our environment */
00050     APR_SHELLCMD_ENV    /**< use the shell to invoke the program,
00051                           *   replicating our environment
00052                           */
00053 } apr_cmdtype_e;
00054 
00055 typedef enum {
00056     APR_WAIT,           /**< wait for the specified process to finish */
00057     APR_NOWAIT          /**< do not wait -- just see if it has finished */
00058 } apr_wait_how_e;
00059 
00060 /* I am specifically calling out the values so that the macros below make
00061  * more sense.  Yes, I know I don't need to, but I am hoping this makes what
00062  * I am doing more clear.  If you want to add more reasons to exit, continue
00063  * to use bitmasks.
00064  */
00065 typedef enum {
00066     APR_PROC_EXIT = 1,          /**< process exited normally */
00067     APR_PROC_SIGNAL = 2,        /**< process exited due to a signal */
00068     APR_PROC_SIGNAL_CORE = 4    /**< process exited and dumped a core file */
00069 } apr_exit_why_e;
00070 
00071 /** did we exit the process */
00072 #define APR_PROC_CHECK_EXIT(x)        (x & APR_PROC_EXIT)
00073 /** did we get a signal */
00074 #define APR_PROC_CHECK_SIGNALED(x)    (x & APR_PROC_SIGNAL)
00075 /** did we get core */
00076 #define APR_PROC_CHECK_CORE_DUMP(x)   (x & APR_PROC_SIGNAL_CORE)
00077 
00078 /** @see apr_procattr_io_set */
00079 #define APR_NO_PIPE          0
00080 
00081 /** @see apr_procattr_io_set */
00082 #define APR_FULL_BLOCK       1
00083 /** @see apr_procattr_io_set */
00084 #define APR_FULL_NONBLOCK    2
00085 /** @see apr_procattr_io_set */
00086 #define APR_PARENT_BLOCK     3
00087 /** @see apr_procattr_io_set */
00088 #define APR_CHILD_BLOCK      4
00089 
00090 /** @see apr_procattr_limit_set */
00091 #define APR_LIMIT_CPU        0
00092 /** @see apr_procattr_limit_set */
00093 #define APR_LIMIT_MEM        1
00094 /** @see apr_procattr_limit_set */
00095 #define APR_LIMIT_NPROC      2
00096 /** @see apr_procattr_limit_set */
00097 #define APR_LIMIT_NOFILE     3
00098 
00099 /**
00100  * @defgroup APR_OC Other Child Flags
00101  * @{
00102  */
00103 #define APR_OC_REASON_DEATH         0     /**< child has died, caller must call
00104                                            * unregister still */
00105 #define APR_OC_REASON_UNWRITABLE    1     /**< write_fd is unwritable */
00106 #define APR_OC_REASON_RESTART       2     /**< a restart is occuring, perform
00107                                            * any necessary cleanup (including
00108                                            * sending a special signal to child)
00109                                            */
00110 #define APR_OC_REASON_UNREGISTER    3     /**< unregister has been called, do
00111                                            * whatever is necessary (including
00112                                            * kill the child) */
00113 #define APR_OC_REASON_LOST          4     /**< somehow the child exited without
00114                                            * us knowing ... buggy os? */
00115 #define APR_OC_REASON_RUNNING       5     /**< a health check is occuring, 
00116                                            * for most maintainence functions
00117                                            * this is a no-op.
00118                                            */
00119 /** @} */
00120 
00121 /** The APR process type */
00122 typedef struct apr_proc_t {
00123     /** The process ID */
00124     pid_t pid;
00125     /** Parent's side of pipe to child's stdin */
00126     apr_file_t *in;
00127     /** Parent's side of pipe to child's stdout */
00128     apr_file_t *out;
00129     /** Parent's side of pipe to child's stdouterr */
00130     apr_file_t *err;
00131 #if APR_HAS_PROC_INVOKED || defined(DOXYGEN)
00132     /** Diagnositics/debugging string of the command invoked for 
00133      *  this process [only present if APR_HAS_PROC_INVOKED is true]
00134      * @remark Only enabled on Win32 by default.
00135      * @bug This should either always or never be present in release
00136      * builds - since it breaks binary compatibility.  We may enable
00137      * it always in APR 1.0 yet leave it undefined in most cases.
00138      */
00139     char *invoked;
00140 #endif
00141 #if defined(WIN32) || defined(DOXYGEN)
00142     /** (Win32 only) Creator's handle granting access to the process
00143      * @remark This handle is closed and reset to NULL in every case
00144      * corresponding to a waitpid() on Unix which returns the exit status.
00145      * Therefore Win32 correspond's to Unix's zombie reaping characteristics
00146      * and avoids potential handle leaks.
00147      */
00148     HANDLE hproc;
00149 #endif
00150 } apr_proc_t;
00151 
00152 /**
00153  * The prototype for APR child errfn functions.  (See the description
00154  * of apr_procattr_child_errfn_set() for more information.)
00155  * It is passed the following parameters:
00156  * @param pool Pool associated with the apr_proc_t.  If your child
00157  *             error function needs user data, associate it with this
00158  *             pool.
00159  * @param err APR error code describing the error
00160  * @param description Text description of type of processing which failed
00161  */
00162 typedef void (apr_child_errfn_t)(apr_pool_t *proc, apr_status_t err,
00163                                  const char *description);
00164 
00165 /** Opaque Thread structure. */
00166 typedef struct apr_thread_t           apr_thread_t;
00167 
00168 /** Opaque Thread attributes structure. */
00169 typedef struct apr_threadattr_t       apr_threadattr_t;
00170 
00171 /** Opaque Process attributes structure. */
00172 typedef struct apr_procattr_t         apr_procattr_t;
00173 
00174 /** Opaque control variable for one-time atomic variables.  */
00175 typedef struct apr_thread_once_t      apr_thread_once_t;
00176 
00177 /** Opaque thread private address space. */
00178 typedef struct apr_threadkey_t        apr_threadkey_t;
00179 
00180 /** Opaque record of child process. */
00181 typedef struct apr_other_child_rec_t  apr_other_child_rec_t;
00182 
00183 /**
00184  * The prototype for any APR thread worker functions.
00185  */
00186 typedef void *(APR_THREAD_FUNC *apr_thread_start_t)(apr_thread_t*, void*);
00187 
00188 typedef enum {
00189     APR_KILL_NEVER,             /**< process is never sent any signals */
00190     APR_KILL_ALWAYS,            /**< process is sent SIGKILL on apr_pool_t cleanup */
00191     APR_KILL_AFTER_TIMEOUT,     /**< SIGTERM, wait 3 seconds, SIGKILL */
00192     APR_JUST_WAIT,              /**< wait forever for the process to complete */
00193     APR_KILL_ONLY_ONCE          /**< send SIGTERM and then wait */
00194 } apr_kill_conditions_e;
00195 
00196 /* Thread Function definitions */
00197 
00198 #if APR_HAS_THREADS
00199 
00200 /**
00201  * Create and initialize a new threadattr variable
00202  * @param new_attr The newly created threadattr.
00203  * @param cont The pool to use
00204  */
00205 APR_DECLARE(apr_status_t) apr_threadattr_create(apr_threadattr_t **new_attr, 
00206                                                 apr_pool_t *cont);
00207 
00208 /**
00209  * Set if newly created threads should be created in detached state.
00210  * @param attr The threadattr to affect 
00211  * @param on Thread detach state on or off
00212  */
00213 APR_DECLARE(apr_status_t) apr_threadattr_detach_set(apr_threadattr_t *attr, 
00214                                                    apr_int32_t on);
00215 
00216 /**
00217  * Get the detach state for this threadattr.
00218  * @param attr The threadattr to reference 
00219  */
00220 APR_DECLARE(apr_status_t) apr_threadattr_detach_get(apr_threadattr_t *attr);
00221 
00222 /**
00223  * Set the stack size of newly created threads.
00224  * @param attr The threadattr to affect 
00225  * @param stacksize The stack size in bytes
00226  */
00227 APR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
00228                                                        apr_size_t stacksize);
00229 
00230 /**
00231  * Create a new thread of execution
00232  * @param new_thread The newly created thread handle.
00233  * @param attr The threadattr to use to determine how to create the thread
00234  * @param func The function to start the new thread in
00235  * @param data Any data to be passed to the starting function
00236  * @param cont The pool to use
00237  */
00238 APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new_thread, 
00239                                             apr_threadattr_t *attr, 
00240                                             apr_thread_start_t func, 
00241                                             void *data, apr_pool_t *cont);
00242 
00243 /**
00244  * stop the current thread
00245  * @param thd The thread to stop
00246  * @param retval The return value to pass back to any thread that cares
00247  */
00248 APR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd, 
00249                                           apr_status_t retval);
00250 
00251 /**
00252  * block until the desired thread stops executing.
00253  * @param retval The return value from the dead thread.
00254  * @param thd The thread to join
00255  */
00256 APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval, 
00257                                           apr_thread_t *thd); 
00258 
00259 /**
00260  * force the current thread to yield the processor
00261  */
00262 APR_DECLARE(void) apr_thread_yield(void);
00263 
00264 /**
00265  * Initialize the control variable for apr_thread_once.  If this isn't
00266  * called, apr_initialize won't work.
00267  * @param control The control variable to initialize
00268  * @param p The pool to allocate data from.
00269  */
00270 APR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
00271                                                apr_pool_t *p);
00272 
00273 /**
00274  * Run the specified function one time, regardless of how many threads
00275  * call it.
00276  * @param control The control variable.  The same variable should
00277  *                be passed in each time the function is tried to be
00278  *                called.  This is how the underlying functions determine
00279  *                if the function has ever been called before.
00280  * @param func The function to call.
00281  */
00282 APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
00283                                           void (*func)(void));
00284 
00285 /**
00286  * detach a thread
00287  * @param thd The thread to detach 
00288  */
00289 APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd);
00290 
00291 /**
00292  * Return the pool associated with the current thread.
00293  * @param data The user data associated with the thread.
00294  * @param key The key to associate with the data
00295  * @param thread The currently open thread.
00296  */
00297 APR_DECLARE(apr_status_t) apr_thread_data_get(void **data, const char *key,
00298                                              apr_thread_t *thread);
00299 
00300 /**
00301  * Return the pool associated with the current thread.
00302  * @param data The user data to associate with the thread.
00303  * @param key The key to use for associating the data with the tread
00304  * @param cleanup The cleanup routine to use when the thread is destroyed.
00305  * @param thread The currently open thread.
00306  */
00307 APR_DECLARE(apr_status_t) apr_thread_data_set(void *data, const char *key,
00308                                              apr_status_t (*cleanup) (void *),
00309                                              apr_thread_t *thread);
00310 
00311 /**
00312  * Create and initialize a new thread private address space
00313  * @param key The thread private handle.
00314  * @param dest The destructor to use when freeing the private memory.
00315  * @param cont The pool to use
00316  */
00317 APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key, 
00318                                                     void (*dest)(void *),
00319                                                     apr_pool_t *cont);
00320 
00321 /**
00322  * Get a pointer to the thread private memory
00323  * @param new_mem The data stored in private memory 
00324  * @param key The handle for the desired thread private memory 
00325  */
00326 APR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new_mem, 
00327                                                  apr_threadkey_t *key);
00328 
00329 /**
00330  * Set the data to be stored in thread private memory
00331  * @param priv The data to be stored in private memory 
00332  * @param key The handle for the desired thread private memory 
00333  */
00334 APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv, 
00335                                                  apr_threadkey_t *key);
00336 
00337 /**
00338  * Free the thread private memory
00339  * @param key The handle for the desired thread private memory 
00340  */
00341 APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key);
00342 
00343 /**
00344  * Return the pool associated with the current threadkey.
00345  * @param data The user data associated with the threadkey.
00346  * @param key The key associated with the data
00347  * @param threadkey The currently open threadkey.
00348  */
00349 APR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key,
00350                                                 apr_threadkey_t *threadkey);
00351 
00352 /**
00353  * Return the pool associated with the current threadkey.
00354  * @param data The data to set.
00355  * @param key The key to associate with the data.
00356  * @param cleanup The cleanup routine to use when the file is destroyed.
00357  * @param threadkey The currently open threadkey.
00358  */
00359 APR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key,
00360                                                 apr_status_t (*cleanup) (void *),
00361                                                 apr_threadkey_t *threadkey);
00362 
00363 #endif
00364 
00365 /**
00366  * Create and initialize a new procattr variable
00367  * @param new_attr The newly created procattr. 
00368  * @param cont The pool to use
00369  */
00370 APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new_attr,
00371                                                   apr_pool_t *cont);
00372 
00373 /**
00374  * Determine if any of stdin, stdout, or stderr should be linked to pipes 
00375  * when starting a child process.
00376  * @param attr The procattr we care about. 
00377  * @param in Should stdin be a pipe back to the parent?
00378  * @param out Should stdout be a pipe back to the parent?
00379  * @param err Should stderr be a pipe back to the parent?
00380  */
00381 APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr, 
00382                                              apr_int32_t in, apr_int32_t out,
00383                                              apr_int32_t err);
00384 
00385 /**
00386  * Set the child_in and/or parent_in values to existing apr_file_t values.
00387  * @param attr The procattr we care about. 
00388  * @param child_in apr_file_t value to use as child_in. Must be a valid file.
00389  * @param parent_in apr_file_t value to use as parent_in. Must be a valid file.
00390  * @remark  This is NOT a required initializer function. This is
00391  *          useful if you have already opened a pipe (or multiple files)
00392  *          that you wish to use, perhaps persistently across multiple
00393  *          process invocations - such as a log file. You can save some 
00394  *          extra function calls by not creating your own pipe since this
00395  *          creates one in the process space for you.
00396  */
00397 APR_DECLARE(apr_status_t) apr_procattr_child_in_set(struct apr_procattr_t *attr,
00398                                                   apr_file_t *child_in,
00399                                                   apr_file_t *parent_in);
00400 
00401 /**
00402  * Set the child_out and parent_out values to existing apr_file_t values.
00403  * @param attr The procattr we care about. 
00404  * @param child_out apr_file_t value to use as child_out. Must be a valid file.
00405  * @param parent_out apr_file_t value to use as parent_out. Must be a valid file.
00406  * @remark This is NOT a required initializer function. This is
00407  *         useful if you have already opened a pipe (or multiple files)
00408  *         that you wish to use, perhaps persistently across multiple
00409  *         process invocations - such as a log file. 
00410  */
00411 APR_DECLARE(apr_status_t) apr_procattr_child_out_set(struct apr_procattr_t *attr,
00412                                                    apr_file_t *child_out,
00413                                                    apr_file_t *parent_out);
00414 
00415 /**
00416  * Set the child_err and parent_err values to existing apr_file_t values.
00417  * @param attr The procattr we care about. 
00418  * @param child_err apr_file_t value to use as child_err. Must be a valid file.
00419  * @param parent_err apr_file_t value to use as parent_err. Must be a valid file.
00420  * @remark This is NOT a required initializer function. This is
00421  *         useful if you have already opened a pipe (or multiple files)
00422  *         that you wish to use, perhaps persistently across multiple
00423  *         process invocations - such as a log file. 
00424  */
00425 APR_DECLARE(apr_status_t) apr_procattr_child_err_set(struct apr_procattr_t *attr,
00426                                                    apr_file_t *child_err,
00427                                                    apr_file_t *parent_err);
00428 
00429 /**
00430  * Set which directory the child process should start executing in.
00431  * @param attr The procattr we care about. 
00432  * @param dir Which dir to start in.  By default, this is the same dir as
00433  *            the parent currently resides in, when the createprocess call
00434  *            is made. 
00435  */
00436 APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr, 
00437                                               const char *dir);
00438 
00439 /**
00440  * Set what type of command the child process will call.
00441  * @param attr The procattr we care about. 
00442  * @param cmd The type of command.  One of:
00443  * <PRE>
00444  *            APR_SHELLCMD     --  Anything that the shell can handle
00445  *            APR_PROGRAM      --  Executable program   (default) 
00446  *            APR_PROGRAM_ENV  --  Executable program, copy environment
00447  *            APR_PROGRAM_PATH --  Executable program on PATH, copy env
00448  * </PRE>
00449  */
00450 APR_DECLARE(apr_status_t) apr_procattr_cmdtype_set(apr_procattr_t *attr,
00451                                                   apr_cmdtype_e cmd);
00452 
00453 /**
00454  * Determine if the child should start in detached state.
00455  * @param attr The procattr we care about. 
00456  * @param detach Should the child start in detached state?  Default is no. 
00457  */
00458 APR_DECLARE(apr_status_t) apr_procattr_detach_set(apr_procattr_t *attr, 
00459                                                  apr_int32_t detach);
00460 
00461 #if APR_HAVE_STRUCT_RLIMIT
00462 /**
00463  * Set the Resource Utilization limits when starting a new process.
00464  * @param attr The procattr we care about. 
00465  * @param what Which limit to set, one of:
00466  * <PRE>
00467  *                 APR_LIMIT_CPU
00468  *                 APR_LIMIT_MEM
00469  *                 APR_LIMIT_NPROC
00470  *                 APR_LIMIT_NOFILE
00471  * </PRE>
00472  * @param limit Value to set the limit to.
00473  */
00474 APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr, 
00475                                                 apr_int32_t what,
00476                                                 struct rlimit *limit);
00477 #endif
00478 
00479 /**
00480  * Specify an error function to be called in the child process if APR
00481  * encounters an error in the child prior to running the specified program.
00482  * @param attr The procattr describing the child process to be created.
00483  * @param errfn The function to call in the child process.
00484  * @remark At the present time, it will only be called from apr_proc_create()
00485  *         on platforms where fork() is used.  It will never be called on other
00486  *         platforms, on those platforms apr_proc_create() will return the error
00487  *         in the parent process rather than invoke the callback in the now-forked
00488  *         child process.
00489  */
00490 APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
00491                                                        apr_child_errfn_t *errfn);
00492 
00493 /**
00494  * Specify that apr_proc_create() should do whatever it can to report
00495  * failures to the caller of apr_proc_create(), rather than find out in
00496  * the child.
00497  * @param attr The procattr describing the child process to be created.
00498  * @param chk Flag to indicate whether or not extra work should be done
00499  *            to try to report failures to the caller.
00500  * @remark This flag only affects apr_proc_create() on platforms where
00501  *         fork() is used.  This leads to extra overhead in the calling
00502  *         process, but that may help the application handle such
00503  *         errors more gracefully.
00504  */
00505 APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
00506                                                        apr_int32_t chk);
00507 
00508 #if APR_HAS_FORK
00509 /**
00510  * This is currently the only non-portable call in APR.  This executes 
00511  * a standard unix fork.
00512  * @param proc The resulting process handle. 
00513  * @param cont The pool to use. 
00514  */
00515 APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *cont);
00516 #endif
00517 
00518 /**
00519  * Create a new process and execute a new program within that process.
00520  * @param new_proc The resulting process handle.
00521  * @param progname The program to run 
00522  * @param args the arguments to pass to the new program.  The first 
00523  *             one should be the program name.
00524  * @param env The new environment table for the new process.  This 
00525  *            should be a list of NULL-terminated strings. This argument
00526  *            is ignored for APR_PROGRAM_ENV, APR_PROGRAM_PATH, and
00527  *            APR_SHELLCMD_ENV types of commands.
00528  * @param attr the procattr we should use to determine how to create the new
00529  *         process
00530  * @param cont The pool to use. 
00531  */
00532 APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new_proc,
00533                                              const char *progname,
00534                                              const char * const *args,
00535                                              const char * const *env, 
00536                                              apr_procattr_t *attr, 
00537                                              apr_pool_t *cont);
00538 
00539 /**
00540  * Wait for a child process to die
00541  * @param proc The process handle that corresponds to the desired child process 
00542  * @param exitcode The returned exit status of the child, if a child process 
00543  *                 dies, or the signal that caused the child to die.
00544  *                 On platforms that don't support obtaining this information, 
00545  *                 the status parameter will be returned as APR_ENOTIMPL.
00546  * @param exitwhy Why the child died, the bitwise or of:
00547  * <PRE>
00548  *            APR_PROC_EXIT         -- process terminated normally
00549  *            APR_PROC_SIGNAL       -- process was killed by a signal
00550  *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
00551  *                                     generated a core dump.
00552  * </PRE>
00553  * @param waithow How should we wait.  One of:
00554  * <PRE>
00555  *            APR_WAIT   -- block until the child process dies.
00556  *            APR_NOWAIT -- return immediately regardless of if the 
00557  *                          child is dead or not.
00558  * </PRE>
00559  * @remark The childs status is in the return code to this process.  It is one of:
00560  * <PRE>
00561  *            APR_CHILD_DONE     -- child is no longer running.
00562  *            APR_CHILD_NOTDONE  -- child is still running.
00563  * </PRE>
00564  */
00565 APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
00566                                         int *exitcode, apr_exit_why_e *exitwhy,
00567                                         apr_wait_how_e waithow);
00568 
00569 /**
00570  * Wait for any current child process to die and return information 
00571  * about that child.
00572  * @param proc Pointer to NULL on entry, will be filled out with child's 
00573  *             information 
00574  * @param exitcode The returned exit status of the child, if a child process 
00575  *                 dies, or the signal that caused the child to die.
00576  *                 On platforms that don't support obtaining this information, 
00577  *                 the status parameter will be returned as APR_ENOTIMPL.
00578  * @param exitwhy Why the child died, the bitwise or of:
00579  * <PRE>
00580  *            APR_PROC_EXIT         -- process terminated normally
00581  *            APR_PROC_SIGNAL       -- process was killed by a signal
00582  *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
00583  *                                     generated a core dump.
00584  * </PRE>
00585  * @param waithow How should we wait.  One of:
00586  * <PRE>
00587  *            APR_WAIT   -- block until the child process dies.
00588  *            APR_NOWAIT -- return immediately regardless of if the 
00589  *                          child is dead or not.
00590  * </PRE>
00591  * @param p Pool to allocate child information out of.
00592  * @bug Passing proc as a *proc rather than **proc was an odd choice
00593  * for some platforms... this should be revisited in 1.0
00594  */
00595 APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
00596                                                   int *exitcode,
00597                                                   apr_exit_why_e *exitwhy,
00598                                                   apr_wait_how_e waithow,
00599                                                   apr_pool_t *p);
00600 
00601 #define APR_PROC_DETACH_FOREGROUND 0    /**< Do not detach */
00602 #define APR_PROC_DETACH_DAEMONIZE 1     /**< Detach */
00603 
00604 /**
00605  * Detach the process from the controlling terminal.
00606  * @param daemonize set to non-zero if the process should daemonize
00607  *                  and become a background process, else it will
00608  *                  stay in the foreground.
00609  */
00610 APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize);
00611 
00612 /**
00613  * Register an other_child -- a child associated to its registered 
00614  * maintence callback.  This callback is invoked when the process
00615  * dies, is disconnected or disappears.
00616  * @param proc The child process to register.
00617  * @param maintenance maintenance is a function that is invoked with a 
00618  *                    reason and the data pointer passed here.
00619  * @param data Opaque context data passed to the maintenance function.
00620  * @param write_fd An fd that is probed for writing.  If it is ever unwritable
00621  *                 then the maintenance is invoked with reason 
00622  *                 OC_REASON_UNWRITABLE.
00623  * @param p The pool to use for allocating memory.
00624  * @bug write_fd duplicates the proc->out stream, it's really redundant
00625  * and should be replaced in the APR 1.0 API with a bitflag of which
00626  * proc->in/out/err handles should be health checked.
00627  * @bug no platform currently tests the pipes health.
00628  */
00629 APR_DECLARE(void) apr_proc_other_child_register(apr_proc_t *proc, 
00630                                            void (*maintenance) (int reason, 
00631                                                                 void *, 
00632                                                                 int status),
00633                                            void *data, apr_file_t *write_fd,
00634                                            apr_pool_t *p);
00635 
00636 /**
00637  * Stop watching the specified other child.  
00638  * @param data The data to pass to the maintenance function.  This is
00639  *             used to find the process to unregister.
00640  * @warning Since this can be called by a maintenance function while we're
00641  *          scanning the other_children list, all scanners should protect 
00642  *          themself by loading ocr->next before calling any maintenance 
00643  *          function.
00644  */
00645 APR_DECLARE(void) apr_proc_other_child_unregister(void *data);
00646 
00647 /**
00648  * Notify the maintenance callback of a registered other child process
00649  * that application has detected an event, such as death.
00650  * @param proc The process to check
00651  * @param reason The reason code to pass to the maintenance function
00652  * @param status The status to pass to the maintenance function
00653  * @remark An example of code using this behavior;
00654  * <pre>
00655  * rv = apr_proc_wait_all_procs(&proc, &exitcode, &status, APR_WAIT, p);
00656  * if (APR_STATUS_IS_CHILD_DONE(rv)) {
00657  * #if APR_HAS_OTHER_CHILD
00658  *     if (apr_proc_other_child_alert(&proc, APR_OC_REASON_DEATH, status)
00659  *             == APR_SUCCESS) {
00660  *         ;  (already handled)
00661  *     }
00662  *     else
00663  * #endif
00664  *         [... handling non-otherchild processes death ...]
00665  * </pre>
00666  */
00667 APR_DECLARE(apr_status_t) apr_proc_other_child_alert(apr_proc_t *proc, 
00668                                                      int reason,
00669                                                      int status);
00670 
00671 /**
00672  * Test one specific other child processes and invoke the maintenance callback 
00673  * with the appropriate reason code, if still running, or the appropriate reason 
00674  * code if the process is no longer healthy.
00675  * @param ocr The registered other child
00676  * @param reason The reason code (e.g. APR_OC_REASON_RESTART) if still running
00677  */
00678 APR_DECLARE(void) apr_proc_other_child_refresh(apr_other_child_rec_t *ocr,
00679                                                int reason);
00680 
00681 /**
00682  * Test all registered other child processes and invoke the maintenance callback 
00683  * with the appropriate reason code, if still running, or the appropriate reason 
00684  * code if the process is no longer healthy.
00685  * @param reason The reason code (e.g. APR_OC_REASON_RESTART) to running processes
00686  */
00687 APR_DECLARE(void) apr_proc_other_child_refresh_all(int reason);
00688 
00689 /** @deprecated @see apr_proc_other_child_refresh_all
00690  * @remark Call apr_proc_other_child_refresh_all(APR_OC_REASON_RESTART)
00691  * or apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING) instead.
00692  * @bug The differing implementations of this function on Win32 (_RUNNING checks) 
00693  * and Unix (used only for _RESTART) are the reason it will be dropped with APR 1.0.
00694  */
00695 APR_DECLARE(void) apr_proc_other_child_check(void);
00696 
00697 /** @deprecated @see apr_proc_other_child_alert
00698  * @bug This function's name had nothing to do with it's purpose
00699  */
00700 APR_DECLARE(apr_status_t) apr_proc_other_child_read(apr_proc_t *proc, int status);
00701 
00702 
00703 /** 
00704  * Terminate a process.
00705  * @param proc The process to terminate.
00706  * @param sig How to kill the process.
00707  */
00708 APR_DECLARE(apr_status_t) apr_proc_kill(apr_proc_t *proc, int sig);
00709 
00710 /**
00711  * Register a process to be killed when a pool dies.
00712  * @param a The pool to use to define the processes lifetime 
00713  * @param proc The process to register
00714  * @param how How to kill the process, one of:
00715  * <PRE>
00716  *         APR_KILL_NEVER         -- process is never sent any signals
00717  *         APR_KILL_ALWAYS        -- process is sent SIGKILL on apr_pool_t cleanup
00718  *         APR_KILL_AFTER_TIMEOUT -- SIGTERM, wait 3 seconds, SIGKILL
00719  *         APR_JUST_WAIT          -- wait forever for the process to complete
00720  *         APR_KILL_ONLY_ONCE     -- send SIGTERM and then wait
00721  * </PRE>
00722  */
00723 APR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *a, apr_proc_t *proc,
00724                                            apr_kill_conditions_e how);
00725 
00726 #if APR_HAS_THREADS 
00727 
00728 #if (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2)
00729 
00730 /**
00731  * Setup the process for a single thread to be used for all signal handling.
00732  * @warning This must be called before any threads are created
00733  */
00734 APR_DECLARE(apr_status_t) apr_setup_signal_thread(void);
00735 
00736 /**
00737  * Make the current thread listen for signals.  This thread will loop
00738  * forever, calling a provided function whenever it receives a signal.  That
00739  * functions should return 1 if the signal has been handled, 0 otherwise.
00740  * @param signal_handler The function to call when a signal is received
00741  * apr_status_t apr_signal_thread((int)(*signal_handler)(int signum))
00742  */
00743 APR_DECLARE(apr_status_t) apr_signal_thread(int(*signal_handler)(int signum));
00744 
00745 #endif /* (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2) */
00746 
00747 /**
00748  * Get the child-pool used by the thread from the thread info.
00749  * @return apr_pool_t the pool
00750  */
00751 APR_POOL_DECLARE_ACCESSOR(thread);
00752 
00753 #endif /* APR_HAS_THREADS */
00754 
00755 /** @} */
00756 
00757 #ifdef __cplusplus
00758 }
00759 #endif
00760 
00761 #endif  /* ! APR_THREAD_PROC_H */
00762