⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perchild.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef SIGPIPE    sa.sa_handler = SIG_IGN;    if (sigaction(SIGPIPE, &sa, NULL) < 0)        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,                     "sigaction(SIGPIPE)");#endif    /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy      * processing one */    sigaddset(&sa.sa_mask, SIGHUP);    sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);    sa.sa_handler = restart;    if (sigaction(SIGHUP, &sa, NULL) < 0)        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,                     "sigaction(SIGHUP)");    if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,                     "sigaction(" AP_SIG_GRACEFUL_STRING ")");#else    if (!one_process) {#ifdef SIGXCPU        apr_signal(SIGXCPU, SIG_DFL);#endif /* SIGXCPU */#ifdef SIGXFSZ        apr_signal(SIGXFSZ, SIG_DFL);#endif /* SIGXFSZ */    }    apr_signal(SIGTERM, sig_term);#ifdef SIGHUP    apr_signal(SIGHUP, restart);#endif /* SIGHUP */#ifdef AP_SIG_GRACEFUL    apr_signal(AP_SIG_GRACEFUL, restart);#endif /* AP_SIG_GRACEFUL */#ifdef SIGPIPE    apr_signal(SIGPIPE, SIG_IGN);#endif /* SIGPIPE */#endif}/***************************************************************** * Here follows a long bunch of generic server bookkeeping stuff... */int ap_graceful_stop_signalled(void){    /* XXX - Does this really work? - Manoj */    return is_graceful;}/***************************************************************** * Child process main loop. */static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id,                           apr_bucket_alloc_t *bucket_alloc){    conn_rec *current_conn;    int csd;    apr_status_t rv;    int thread_num = conn_id % thread_limit;    ap_sb_handle_t *sbh;    if ((rv = apr_os_sock_get(&csd, sock)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_os_sock_get");    }    if (thread_socket_table[thread_num] < 0) {        ap_sock_disable_nagle(sock);    }    ap_create_sb_handle(&sbh, p, conn_id / thread_limit, thread_num);    current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id,                                             sbh, bucket_alloc);    if (current_conn) {        ap_process_connection(current_conn, sock);        ap_lingering_close(current_conn);    }}static int perchild_process_connection(conn_rec *c){    ap_filter_t *f;    apr_bucket_brigade *bb;    core_net_rec *net;    apr_pool_userdata_get((void **)&bb, "PERCHILD_SOCKETS", c->pool);    if (bb != NULL) {        for (f = c->output_filters; f != NULL; f = f->next) {            if (!strcmp(f->frec->name, "core")) {                break;            }        }        if (f != NULL) {            net = f->ctx;            net->in_ctx = apr_palloc(c->pool, sizeof(*net->in_ctx));            net->in_ctx->b = bb;        }    }    return DECLINED;}    static void *worker_thread(apr_thread_t *, void *);/* Starts a thread as long as we're below max_threads */static int start_thread(void){    apr_thread_t *thread;    int rc;    apr_thread_mutex_lock(worker_thread_count_mutex);    if (worker_thread_count < max_threads - 1) {        rc = apr_thread_create(&thread, worker_thread_attr, worker_thread,                 &worker_thread_free_ids[worker_thread_count], pchild);        if (rc != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_ALERT, rc, ap_server_conf,                         "apr_thread_create: unable to create worker thread");            /* In case system resources are maxxed out, we don't want               Apache running away with the CPU trying to fork over and               over and over again if we exit. */            sleep(10);            workers_may_exit = 1;            apr_thread_mutex_unlock(worker_thread_count_mutex);            return 0;        }        else {            worker_thread_count++;        }    }    else {        static int reported = 0;                if (!reported) {            ap_log_error(APLOG_MARK, APLOG_ERR, 0,                         ap_server_conf,                         "server reached MaxThreadsPerChild setting, "                         "consider raising the MaxThreadsPerChild or "                         "NumServers settings");            reported = 1;        }        apr_thread_mutex_unlock(worker_thread_count_mutex);        return 0;    }    apr_thread_mutex_unlock(worker_thread_count_mutex);    return 1;}/* Sets workers_may_exit if we received a character on the pipe_of_death */static apr_status_t check_pipe_of_death(void **csd, ap_listen_rec *lr,                                        apr_pool_t *ptrans){    apr_thread_mutex_lock(pipe_of_death_mutex);    if (!workers_may_exit) {        int ret;        char pipe_read_char;        apr_size_t n = 1;        ret = apr_recv(lr->sd, &pipe_read_char, &n);        if (APR_STATUS_IS_EAGAIN(ret)) {            /* It lost the lottery. It must continue to suffer             * through a life of servitude. */        }        else {            /* It won the lottery (or something else is very             * wrong). Embrace death with open arms. */            workers_may_exit = 1;        }    }    apr_thread_mutex_unlock(pipe_of_death_mutex);    return APR_SUCCESS;}static apr_status_t receive_from_other_child(void **csd, ap_listen_rec *lr,                                             apr_pool_t *ptrans){    struct msghdr msg;    struct cmsghdr *cmsg;    char buffer[HUGE_STRING_LEN * 2], *headers, *body;    int headerslen, bodylen;    struct iovec iov;    int ret, dp;    apr_os_sock_t sd;    apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(ptrans);    apr_bucket_brigade *bb = apr_brigade_create(ptrans, alloc);    apr_bucket *bucket;    apr_os_sock_get(&sd, lr->sd);    iov.iov_base = buffer;    iov.iov_len = sizeof(buffer);    msg.msg_name = NULL;    msg.msg_namelen = 0;    msg.msg_iov = &iov;    msg.msg_iovlen = 1;    cmsg = apr_palloc(ptrans, sizeof(*cmsg) + sizeof(sd));    cmsg->cmsg_len = sizeof(*cmsg) + sizeof(sd);    msg.msg_control = cmsg;    msg.msg_controllen = cmsg->cmsg_len;    ret = recvmsg(sd, &msg, 0);    memcpy(&dp, CMSG_DATA(cmsg), sizeof(dp));    *csd = NULL; /* tell apr_os_sock_put() to allocate new apr_socket_t */    apr_os_sock_put((apr_socket_t **)csd, &dp, ptrans);    bucket = apr_bucket_eos_create(alloc);    APR_BRIGADE_INSERT_HEAD(bb, bucket);    bucket = apr_bucket_socket_create(*csd, alloc);    APR_BRIGADE_INSERT_HEAD(bb, bucket);    body = strchr(iov.iov_base, 0);    if (!body) {        return 1;    }    body++;    bodylen = strlen(body);    headers = iov.iov_base;    headerslen = body - headers;    bucket = apr_bucket_heap_create(body, bodylen, NULL, alloc);    APR_BRIGADE_INSERT_HEAD(bb, bucket);    bucket = apr_bucket_heap_create(headers, headerslen, NULL, alloc);    APR_BRIGADE_INSERT_HEAD(bb, bucket);    apr_pool_userdata_set(bb, "PERCHILD_SOCKETS", NULL, ptrans);    return 0;}/* idle_thread_count should be incremented before starting a worker_thread */static void *worker_thread(apr_thread_t *thd, void *arg){    void *csd;    apr_pool_t *tpool;      /* Pool for this thread           */    apr_pool_t *ptrans;     /* Pool for per-transaction stuff */    volatile int thread_just_started = 1;    int srv;    int thread_num = *((int *) arg);    long conn_id = child_num * thread_limit + thread_num;    apr_pollfd_t *pollset;    apr_status_t rv;    ap_listen_rec *lr, *last_lr = ap_listeners;    int n;    apr_bucket_alloc_t *bucket_alloc;    apr_thread_mutex_lock(thread_pool_parent_mutex);    apr_pool_create(&tpool, thread_pool_parent);    apr_thread_mutex_unlock(thread_pool_parent_mutex);    apr_pool_create(&ptrans, tpool);    (void) ap_update_child_status_from_indexes(child_num, thread_num,                                                SERVER_STARTING,                                               (request_rec *) NULL);    bucket_alloc = apr_bucket_alloc_create(apr_thread_pool_get(thd));    apr_poll_setup(&pollset, num_listensocks, tpool);    for(lr = ap_listeners; lr != NULL; lr = lr->next) {        int fd;        apr_poll_socket_add(pollset, lr->sd, APR_POLLIN);        apr_os_sock_get(&fd, lr->sd);    }    while (!workers_may_exit) {        workers_may_exit |= ((ap_max_requests_per_child != 0)                            && (requests_this_child <= 0));        if (workers_may_exit) break;        if (!thread_just_started) {            apr_thread_mutex_lock(idle_thread_count_mutex);            if (idle_thread_count < max_spare_threads) {                idle_thread_count++;                apr_thread_mutex_unlock(idle_thread_count_mutex);            }            else {                apr_thread_mutex_unlock(idle_thread_count_mutex);                break;            }        }        else {            thread_just_started = 0;        }        (void) ap_update_child_status_from_indexes(child_num, thread_num,                                                    SERVER_READY,                                                   (request_rec *) NULL);        apr_thread_mutex_lock(thread_accept_mutex);        if (workers_may_exit) {            apr_thread_mutex_unlock(thread_accept_mutex);            break;        }        if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(process_accept_mutex)))            != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,                         "apr_proc_mutex_lock failed. Attempting to shutdown "                         "process gracefully.");            workers_may_exit = 1;        }        while (!workers_may_exit) {            apr_int16_t event;            srv = apr_poll(pollset, num_listensocks, &n, -1);            if (srv != APR_SUCCESS) {                if (APR_STATUS_IS_EINTR(srv)) {                    continue;                }                /* apr_poll() will only return errors in catastrophic                 * circumstances. Let's try exiting gracefully, for now. */                ap_log_error(APLOG_MARK, APLOG_ERR, srv, (const server_rec *)                             ap_server_conf, "apr_poll: (listen)");                workers_may_exit = 1;            }            if (workers_may_exit) break;            /* find a listener */            lr = last_lr;            do {                lr = lr->next;                if (lr == NULL) {                    lr = ap_listeners;                }                /* XXX: Should we check for POLLERR? */                apr_poll_revents_get(&event, lr->sd, pollset);                if (event & (APR_POLLIN)) {                    last_lr = lr;                    goto got_fd;                }            } while (lr != last_lr);        }    got_fd:        if (!workers_may_exit) {            rv = lr->accept_func(&csd, lr, ptrans);            if (rv == APR_EGENERAL) {                /* E[NM]FILE, ENOMEM, etc */                workers_may_exit = 1;            }            if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(process_accept_mutex)))                != APR_SUCCESS) {                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,                             "apr_proc_mutex_unlock failed. Attempting to shutdown "                             "process gracefully.");                workers_may_exit = 1;            }            apr_thread_mutex_unlock(thread_accept_mutex);            apr_thread_mutex_lock(idle_thread_count_mutex);            if (idle_thread_count > min_spare_threads) {                idle_thread_count--;            }            else {                if (!start_thread()) {                    idle_thread_count--;                }            }            apr_thread_mutex_unlock(idle_thread_count_mutex);            if (setjmp(jmpbuffer) != 1) {                process_socket(ptrans, csd, conn_id, bucket_alloc);            }            else {                thread_socket_table[thread_num] = AP_PERCHILD_THISCHILD;            }              requests_this_child--;        }        else {            if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(process_accept_mutex)))                != APR_SUCCESS) {                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,                             "apr_proc_mutex_unlock failed. Attempting to shutdown "                             "process gracefully.");                workers_may_exit = 1;            }            apr_thread_mutex_unlock(thread_accept_mutex);            apr_thread_mutex_lock(idle_thread_count_mutex);            idle_thread_count--;            apr_thread_mutex_unlock(idle_thread_count_mutex);        break;        }        apr_pool_clear(ptrans);    }    apr_thread_mutex_lock(thread_pool_parent_mutex);    ap_update_child_status_from_indexes(child_num, thread_num, SERVER_DEAD,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -