diff options
author | 2015-11-30 01:45:08 -0500 | |
---|---|---|
committer | 2015-11-30 01:45:08 -0500 | |
commit | e8ec7aa8e38a93f5b034ac74cebce5de23710317 (patch) | |
tree | aa031937bf856c1f8d6ad7877b8d2cb0224da5ef /rubbos/app/httpd-2.0.64/srclib/apr/misc/unix/otherchild.c | |
parent | cc40af334e619bb549038238507407866f774f8f (diff) |
upload http
JIRA: BOTTLENECK-10
Change-Id: I7598427ff904df438ce77c2819ee48ac75ffa8da
Signed-off-by: hongbotian <hongbo.tianhongbo@huawei.com>
Diffstat (limited to 'rubbos/app/httpd-2.0.64/srclib/apr/misc/unix/otherchild.c')
-rw-r--r-- | rubbos/app/httpd-2.0.64/srclib/apr/misc/unix/otherchild.c | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/rubbos/app/httpd-2.0.64/srclib/apr/misc/unix/otherchild.c b/rubbos/app/httpd-2.0.64/srclib/apr/misc/unix/otherchild.c new file mode 100644 index 00000000..0ea57739 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/srclib/apr/misc/unix/otherchild.c @@ -0,0 +1,246 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_arch_misc.h" +#include "apr_arch_threadproc.h" +#include "apr_arch_file_io.h" + +#if APR_HAS_OTHER_CHILD + +#ifdef HAVE_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif +#if APR_HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif +#ifdef BEOS +#include <sys/socket.h> /* for fd_set definition! */ +#endif + +static apr_other_child_rec_t *other_children = NULL; + +static apr_status_t other_child_cleanup(void *data) +{ + apr_other_child_rec_t **pocr, *nocr; + + for (pocr = &other_children; *pocr; pocr = &(*pocr)->next) { + if ((*pocr)->data == data) { + nocr = (*pocr)->next; + (*(*pocr)->maintenance) (APR_OC_REASON_UNREGISTER, (*pocr)->data, -1); + *pocr = nocr; + /* XXX: um, well we've just wasted some space in pconf ? */ + return APR_SUCCESS; + } + } + return APR_SUCCESS; +} + +APR_DECLARE(void) apr_proc_other_child_register(apr_proc_t *proc, + void (*maintenance) (int reason, void *, int status), + void *data, apr_file_t *write_fd, apr_pool_t *p) +{ + apr_other_child_rec_t *ocr; + + ocr = apr_palloc(p, sizeof(*ocr)); + ocr->p = p; + ocr->proc = proc; + ocr->maintenance = maintenance; + ocr->data = data; + if (write_fd == NULL) { + ocr->write_fd = (apr_os_file_t) -1; + } + else { +#ifdef WIN32 + /* This should either go away as part of eliminating apr_proc_probe_writable_fds + * or write_fd should point to an apr_file_t + */ + ocr->write_fd = write_fd->filehand; +#else + ocr->write_fd = write_fd->filedes; +#endif + + } + ocr->next = other_children; + other_children = ocr; + apr_pool_cleanup_register(p, ocr->data, other_child_cleanup, + apr_pool_cleanup_null); +} + +APR_DECLARE(void) apr_proc_other_child_unregister(void *data) +{ + apr_other_child_rec_t *cur; + + cur = other_children; + while (cur) { + if (cur->data == data) { + break; + } + cur = cur->next; + } + + /* segfault if this function called with invalid parm */ + apr_pool_cleanup_kill(cur->p, cur->data, other_child_cleanup); + other_child_cleanup(data); +} + +APR_DECLARE(apr_status_t) apr_proc_other_child_alert(apr_proc_t *proc, + int reason, + int status) +{ + apr_other_child_rec_t *ocr, *nocr; + + for (ocr = other_children; ocr; ocr = nocr) { + nocr = ocr->next; + if (ocr->proc->pid != proc->pid) + continue; + + ocr->proc = NULL; + (*ocr->maintenance) (reason, ocr->data, status); + return APR_SUCCESS; + } + return APR_EPROC_UNKNOWN; +} + +APR_DECLARE(void) apr_proc_other_child_refresh(apr_other_child_rec_t *ocr, + int reason) +{ + /* Todo: + * Implement code to detect if pipes are still alive. + */ +#ifdef WIN32 + DWORD status; + + if (ocr->proc == NULL) + return; + + if (!ocr->proc->hproc) { + /* Already mopped up, perhaps we apr_proc_kill'ed it, + * they should have already unregistered! + */ + ocr->proc = NULL; + (*ocr->maintenance) (APR_OC_REASON_LOST, ocr->data, -1); + } + else if (!GetExitCodeProcess(ocr->proc->hproc, &status)) { + CloseHandle(ocr->proc->hproc); + ocr->proc->hproc = NULL; + ocr->proc = NULL; + (*ocr->maintenance) (APR_OC_REASON_LOST, ocr->data, -1); + } + else if (status == STILL_ACTIVE) { + (*ocr->maintenance) (reason, ocr->data, -1); + } + else { + CloseHandle(ocr->proc->hproc); + ocr->proc->hproc = NULL; + ocr->proc = NULL; + (*ocr->maintenance) (APR_OC_REASON_DEATH, ocr->data, status); + } + +#else /* ndef Win32 */ + pid_t waitret; + int status; + + if (ocr->proc == NULL) + return; + + waitret = waitpid(ocr->proc->pid, &status, WNOHANG); + if (waitret == ocr->proc->pid) { + ocr->proc = NULL; + (*ocr->maintenance) (APR_OC_REASON_DEATH, ocr->data, status); + } + else if (waitret == 0) { + (*ocr->maintenance) (reason, ocr->data, -1); + } + else if (waitret == -1) { + /* uh what the heck? they didn't call unregister? */ + ocr->proc = NULL; + (*ocr->maintenance) (APR_OC_REASON_LOST, ocr->data, -1); + } +#endif +} + +APR_DECLARE(void) apr_proc_other_child_refresh_all(int reason) +{ + apr_other_child_rec_t *ocr, *next_ocr; + + for (ocr = other_children; ocr; ocr = next_ocr) { + next_ocr = ocr->next; + apr_proc_other_child_refresh(ocr, reason); + } +} + +#else /* !APR_HAS_OTHER_CHILD */ + +APR_DECLARE(void) apr_proc_other_child_register(apr_proc_t *proc, + void (*maintenance) (int reason, void *, int status), + void *data, apr_file_t *write_fd, apr_pool_t *p) +{ + return; +} + +APR_DECLARE(void) apr_proc_other_child_unregister(void *data) +{ + return; +} + +APR_DECLARE(apr_status_t) apr_proc_other_child_alert(apr_proc_t *proc, + int reason, + int status) +{ + return APR_ENOTIMPL; +} + +APR_DECLARE(void) apr_proc_other_child_refresh(apr_other_child_rec_t *ocr, + int reason) +{ + return; +} + +APR_DECLARE(void) apr_proc_other_child_refresh_all(int reason) +{ + return; +} + +#endif /* APR_HAS_OTHER_CHILD */ + + +/* XXX: deprecated for removal in 1.0 + * The checks behaved differently between win32 and unix, while + * the old win32 code did a health check, the unix code called + * other_child_check only at restart. + */ +APR_DECLARE(void) apr_proc_other_child_check(void) +{ +#ifdef WIN32 + apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING); +#else + apr_proc_other_child_refresh_all(APR_OC_REASON_RESTART); +#endif +} + +/* XXX: deprecated for removal in 1.0 + * This really didn't test any sort of read - it simply notified + * the maintenance function that the process had died. + */ +APR_DECLARE(apr_status_t) apr_proc_other_child_read(apr_proc_t *proc, int status) +{ + return apr_proc_other_child_alert(proc, APR_OC_REASON_DEATH, status); +} + |