#include "httpd.h"
#include "http_config.h"
+#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
+#include "util_mutex.h"
#include "ap_config.h"
-#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
-#include "unixd.h"
-#define MOD_EXIPC_SET_MUTEX_PERMS /* XXX Apache should define something */
-#endif
-
#if APR_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
apr_shm_t *exipc_shm; /* Pointer to shared memory block */
char *shmfilename; /* Shared memory file name, used on some systems */
apr_global_mutex_t *exipc_mutex; /* Lock around shared memory segment access */
-char *mutexfilename; /* Lock file name, used on some systems */
+static const char *exipc_mutex_type = "example-ipc-shm";
/* Data structure for shared memory block */
typedef struct exipc_data {
return OK;
}
+/*
+ * This routine is called in the parent; we must register our
+ * mutex type before the config is processed so that users can
+ * adjust the mutex settings using the Mutex directive.
+ */
+
+static int exipc_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+ ap_mutex_register(pconf, exipc_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
+ return OK;
+}
/*
* This routine is called in the parent, so we'll set up the shared
static int exipc_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s)
{
- void *data; /* These two help ensure that we only init once. */
- const char *userdata_key;
apr_status_t rs;
exipc_data *base;
const char *tempdir;
/*
- * The following checks if this routine has been called before.
- * This is necessary because the parent process gets initialized
- * a couple of times as the server starts up, and we don't want
- * to create any more mutexes and shared memory segments than
- * we're actually going to use.
- *
- * The key needs to be unique for the entire web server, so put
- * the module name in it.
+ * Do nothing if we are not creating the final configuration.
+ * The parent process gets initialized a couple of times as the
+ * server starts up, and we don't want to create any more mutexes
+ * and shared memory segments than we're actually going to use.
*/
- userdata_key = "example_ipc_init_module";
- apr_pool_userdata_get(&data, userdata_key, s->process->pool);
- if (!data) {
- /*
- * If no data was found for our key, this must be the first
- * time the module is initialized. Put some data under that
- * key and return.
- */
- apr_pool_userdata_set((const void *) 1, userdata_key,
- apr_pool_cleanup_null, s->process->pool);
+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
return OK;
- } /* Kilroy was here */
/*
- * Both the shared memory and mutex allocation routines take a
- * file name. Depending on system-specific implementation of these
+ * The shared memory allocation routines take a file name.
+ * Depending on system-specific implementation of these
* routines, that file may or may not actually be created. We'd
* like to store those files in the operating system's designated
* temporary directory, which APR can point us to.
/* Create global mutex */
- /*
- * Create another unique filename to lock upon. Note that
- * depending on OS and locking mechanism of choice, the file
- * may or may not be actually created.
- */
- mutexfilename = apr_psprintf(pconf, "%s/httpd_mutex.%ld", tempdir,
- (long int) getpid());
-
- rs = apr_global_mutex_create(&exipc_mutex, (const char *) mutexfilename,
- APR_LOCK_DEFAULT, pconf);
- if (APR_SUCCESS != rs) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rs, s,
- "Failed to create mutex on file %s",
- mutexfilename);
- return HTTP_INTERNAL_SERVER_ERROR;
- }
-
- /*
- * After the mutex is created, its permissions need to be adjusted
- * on unix platforms so that the child processe can acquire
- * it. This call takes care of that. The preprocessor define was
- * set up early in this source file since Apache doesn't provide
- * it.
- */
-#ifdef MOD_EXIPC_SET_MUTEX_PERMS
- rs = ap_unixd_set_global_mutex_perms(exipc_mutex);
+ rs = ap_global_mutex_create(&exipc_mutex, NULL, exipc_mutex_type, NULL,
+ s, pconf, 0);
if (APR_SUCCESS != rs) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s,
- "Parent could not set permissions on Example IPC "
- "mutex: check User and Group directives");
return HTTP_INTERNAL_SERVER_ERROR;
}
-#endif /* MOD_EXIPC_SET_MUTEX_PERMS */
/*
* Destroy the shm segment when the configuration pool gets destroyed. This
* the mutex pointer global here.
*/
rs = apr_global_mutex_child_init(&exipc_mutex,
- (const char *) mutexfilename,
+ apr_global_mutex_lockfile(exipc_mutex),
p);
if (APR_SUCCESS != rs) {
ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s,
- "Failed to reopen mutex on file %s",
- shmfilename);
+ "Failed to reopen mutex %s in child",
+ exipc_mutex_type);
/* There's really nothing else we can do here, since This
* routine doesn't return a status. If this ever goes wrong,
* it will turn Apache into a fork bomb. Let's hope it never
static void exipc_register_hooks(apr_pool_t *p)
{
+ ap_hook_pre_config(exipc_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_post_config(exipc_post_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_child_init(exipc_child_init, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(exipc_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
/* Dispatch list for API hooks */
-module AP_MODULE_DECLARE_DATA example_ipc_module = {
+AP_DECLARE_MODULE(example_ipc) = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */