extern "C" {
#endif
+typedef struct ap_slave_t ap_slave_t;
typedef struct ap_listen_rec ap_listen_rec;
typedef apr_status_t (*accept_function)(void **csd, ap_listen_rec *lr, apr_pool_t *ptrans);
* The default protocol for this listening socket.
*/
const char* protocol;
+
+ ap_slave_t *slave;
};
/**
* Loop through the global ap_listen_rec list and close each of the sockets.
*/
AP_DECLARE_NONSTD(void) ap_close_listeners(void);
+AP_DECLARE_NONSTD(int) ap_close_listeners_selected(ap_slave_t*);
/* Although these functions are exported from libmain, they are not really
* public functions. These functions are actually called while parsing the
}
static const char *alloc_listener(process_rec *process, char *addr,
- apr_port_t port, const char* proto)
+ apr_port_t port, const char* proto,
+ void *dummy)
{
ap_listen_rec **walk, *last;
apr_status_t status;
}
if (found_listener) {
+ if (ap_listeners->slave != dummy) {
+ return "Cannot define a slave on the same IP:port as a Listener";
+ }
return NULL;
}
last->next = new;
last = new;
}
+ new->slave = dummy;
}
return NULL;
lr->active = 0;
}
}
+AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *slave)
+{
+ ap_listen_rec *lr;
+ int n = 0;
+
+ for (lr = ap_listeners; lr; lr = lr->next) {
+ if (lr->slave != slave) {
+ apr_socket_close(lr->sd);
+ lr->active = 0;
+ }
+ else {
+ ++n;
+ }
+ }
+ return n;
+}
AP_DECLARE(void) ap_listen_pre_config(void)
{
ap_listenbacklog = DEFAULT_LISTENBACKLOG;
}
-
+/* Hack: populate an extra field
+ * When this gets called from a Listen directive, dummy is null.
+ * So we can use non-null dummy to pass a data pointer without conflict
+ */
AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
int argc, char *const argv[])
{
ap_str_tolower(proto);
}
- return alloc_listener(cmd->server->process, host, port, proto);
+ return alloc_listener(cmd->server->process, host, port, proto, dummy);
}
AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd,