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

📄 mpm_netware.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 3 页
字号:
                        listen state. */                    if (!APR_STATUS_IS_EAGAIN(stat)) {                        break;                    }                    if (wouldblock_retry--) {                        apr_thread_yield();                    }                }            }            /* If we got a new socket, set it to non-blocking mode and process                it.  Otherwise handle the error. */            if (stat == APR_SUCCESS) {                apr_socket_opt_set(csd, APR_SO_NONBLOCK, 0);#ifdef DBINFO_ON                if (wouldblock_retry < MAX_WB_RETRIES) {                    retry_success++;                    avg_retries += (MAX_WB_RETRIES-wouldblock_retry);                }#endif                break;       /* We have a socket ready for reading */            }            else {#ifdef DBINFO_ON                if (APR_STATUS_IS_EAGAIN(stat)) {                        would_block++;                        retry_fail++;                }                else#else                if (APR_STATUS_IS_EAGAIN(stat) ||#endif                    APR_STATUS_IS_ECONNRESET(stat) ||                    APR_STATUS_IS_ETIMEDOUT(stat) ||                    APR_STATUS_IS_EHOSTUNREACH(stat) ||                    APR_STATUS_IS_ENETUNREACH(stat)) {                        ;                }                else if (APR_STATUS_IS_ENETDOWN(stat)) {                       /*                        * When the network layer has been shut down, there                        * is not much use in simply exiting: the parent                        * would simply re-create us (and we'd fail again).                        * Use the CHILDFATAL code to tear the server down.                        * @@@ Martin's idea for possible improvement:                        * A different approach would be to define                        * a new APEXIT_NETDOWN exit code, the reception                        * of which would make the parent shutdown all                        * children, then idle-loop until it detected that                        * the network is up again, and restart the children.                        * Ben Hyde noted that temporary ENETDOWN situations                        * occur in mobile IP.                        */                        ap_log_error(APLOG_MARK, APLOG_EMERG, stat, ap_server_conf,                            "apr_accept: giving up.");                        clean_child_exit(APEXIT_CHILDFATAL, my_worker_num, ptrans,                                          bucket_alloc);                }                else {                        ap_log_error(APLOG_MARK, APLOG_ERR, stat, ap_server_conf,                            "apr_accept: (client socket)");                        clean_child_exit(1, my_worker_num, ptrans, bucket_alloc);                }            }        }        ap_create_sb_handle(&sbh, ptrans, 0, my_worker_num);        /*        * We now have a connection, so set it up with the appropriate        * socket options, file descriptors, and read/write buffers.        */        current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd,                                                 my_worker_num, sbh,                                                bucket_alloc);        if (current_conn) {            ap_process_connection(current_conn, csd);            ap_lingering_close(current_conn);        }        request_count++;    }    clean_child_exit(0, my_worker_num, ptrans, bucket_alloc);}static int make_child(server_rec *s, int slot){    int tid;    int err=0;    NXContext_t ctx;    if (slot + 1 > ap_max_workers_limit) {        ap_max_workers_limit = slot + 1;    }    ap_update_child_status_from_indexes(0, slot, WORKER_STARTING,                                         (request_rec *) NULL);    if (ctx = NXContextAlloc((void (*)(void *)) worker_main, (void*)slot, NX_PRIO_MED, ap_thread_stack_size, NX_CTX_NORMAL, &err)) {        char threadName[32];        sprintf (threadName, "Apache_Worker %d", slot);        NXContextSetName(ctx, threadName);        err = NXThreadCreate(ctx, NX_THR_BIND_CONTEXT, &tid);        if (err) {            NXContextFree (ctx);        }    }    if (err) {        /* create thread didn't succeed. Fix the scoreboard or else        * it will say SERVER_STARTING forever and ever        */        ap_update_child_status_from_indexes(0, slot, WORKER_DEAD,                                             (request_rec *) NULL);        /* 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. */        apr_thread_yield();        return -1;    }    ap_scoreboard_image->servers[0][slot].tid = tid;    return 0;}/* start up a bunch of worker threads */static void startup_workers(int number_to_start){    int i;    for (i = 0; number_to_start && i < ap_threads_limit; ++i) {        if (ap_scoreboard_image->servers[0][i].status != WORKER_DEAD) {            continue;        }        if (make_child(ap_server_conf, i) < 0) {            break;        }        --number_to_start;    }}/* * idle_spawn_rate is the number of children that will be spawned on the * next maintenance cycle if there aren't enough idle servers.  It is * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by * without the need to spawn. */static int idle_spawn_rate = 1;#ifndef MAX_SPAWN_RATE#define MAX_SPAWN_RATE (64)#endifstatic int hold_off_on_exponential_spawning;static void perform_idle_server_maintenance(apr_pool_t *p){    int i;    int to_kill;    int idle_count;    worker_score *ws;    int free_length;    int free_slots[MAX_SPAWN_RATE];    int last_non_dead;    int total_non_dead;    /* initialize the free_list */    free_length = 0;    to_kill = -1;    idle_count = 0;    last_non_dead = -1;    total_non_dead = 0;    for (i = 0; i < ap_threads_limit; ++i) {        int status;        if (i >= ap_max_workers_limit && free_length == idle_spawn_rate)            break;        ws = &ap_scoreboard_image->servers[0][i];        status = ws->status;        if (status == WORKER_DEAD) {            /* try to keep children numbers as low as possible */            if (free_length < idle_spawn_rate) {                free_slots[free_length] = i;                ++free_length;            }        }        else if (status == WORKER_IDLE_KILL) {            /* If it is already marked to die, skip it */            continue;        }        else {            /* We consider a starting server as idle because we started it            * at least a cycle ago, and if it still hasn't finished starting            * then we're just going to swamp things worse by forking more.            * So we hopefully won't need to fork more if we count it.            * This depends on the ordering of SERVER_READY and SERVER_STARTING.            */            if (status <= WORKER_READY) {                ++ idle_count;                /* always kill the highest numbered child if we have to...                * no really well thought out reason ... other than observing                * the server behaviour under linux where lower numbered children                * tend to service more hits (and hence are more likely to have                * their data in cpu caches).                */                to_kill = i;            }            ++total_non_dead;            last_non_dead = i;        }    }    DBPRINT2("Total: %d Idle Count: %d  \r", total_non_dead, idle_count);    ap_max_workers_limit = last_non_dead + 1;    if (idle_count > ap_threads_max_free) {        /* kill off one child... we use the pod because that'll cause it to        * shut down gracefully, in case it happened to pick up a request        * while we were counting        */        idle_spawn_rate = 1;        ap_update_child_status_from_indexes(0, last_non_dead, WORKER_IDLE_KILL,                                             (request_rec *) NULL);        DBPRINT1("\nKilling idle thread: %d\n", last_non_dead);    }    else if (idle_count < ap_threads_min_free) {        /* terminate the free list */        if (free_length == 0) {            /* only report this condition once */            static int reported = 0;            if (!reported) {                ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,                    "server reached MaxClients setting, consider"                    " raising the MaxClients setting");                reported = 1;            }            idle_spawn_rate = 1;        }        else {            if (idle_spawn_rate >= 8) {                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,                    "server seems busy, (you may need "                    "to increase StartServers, or Min/MaxSpareServers), "                    "spawning %d children, there are %d idle, and "                    "%d total children", idle_spawn_rate,                    idle_count, total_non_dead);            }            DBPRINT0("\n");            for (i = 0; i < free_length; ++i) {                DBPRINT1("Spawning additional thread slot: %d\n", free_slots[i]);                make_child(ap_server_conf, free_slots[i]);            }            /* the next time around we want to spawn twice as many if this            * wasn't good enough, but not if we've just done a graceful            */            if (hold_off_on_exponential_spawning) {                --hold_off_on_exponential_spawning;            }            else if (idle_spawn_rate < MAX_SPAWN_RATE) {                idle_spawn_rate *= 2;            }        }    }    else {        idle_spawn_rate = 1;    }}static void display_settings (){    int status_array[SERVER_NUM_STATUS];    int i, status, total=0;    int reqs = request_count;#ifdef DBINFO_ON    int wblock = would_block;        would_block = 0;#endif        request_count = 0;    ClearScreen (getscreenhandle());    printf("%s \n", ap_get_server_version());    for (i=0;i<SERVER_NUM_STATUS;i++) {        status_array[i] = 0;    }    for (i = 0; i < ap_threads_limit; ++i) {        status = (ap_scoreboard_image->servers[0][i]).status;        status_array[status]++;    }    for (i=0;i<SERVER_NUM_STATUS;i++) {        switch(i)        {        case SERVER_DEAD:            printf ("Available:\t%d\n", status_array[i]);            break;        case SERVER_STARTING:            printf ("Starting:\t%d\n", status_array[i]);            break;        case SERVER_READY:            printf ("Ready:\t\t%d\n", status_array[i]);            break;        case SERVER_BUSY_READ:            printf ("Busy:\t\t%d\n", status_array[i]);            break;        case SERVER_BUSY_WRITE:            printf ("Busy Write:\t%d\n", status_array[i]);            break;        case SERVER_BUSY_KEEPALIVE:            printf ("Busy Keepalive:\t%d\n", status_array[i]);            break;        case SERVER_BUSY_LOG:            printf ("Busy Log:\t%d\n", status_array[i]);            break;        case SERVER_BUSY_DNS:            printf ("Busy DNS:\t%d\n", status_array[i]);            break;        case SERVER_CLOSING:            printf ("Closing:\t%d\n", status_array[i]);            break;        case SERVER_GRACEFUL:            printf ("Restart:\t%d\n", status_array[i]);            break;        case SERVER_IDLE_KILL:            printf ("Idle Kill:\t%d\n", status_array[i]);            break;        default:            printf ("Unknown Status:\t%d\n", status_array[i]);            break;        }        if (i != SERVER_DEAD)            total+=status_array[i];    }    printf ("Total Running:\t%d\tout of: \t%d\n", total, ap_threads_limit);    printf ("Requests per interval:\t%d\n", reqs);    #ifdef DBINFO_ON    printf ("Would blocks:\t%d\n", wblock);    printf ("Successful retries:\t%d\n", retry_success);    printf ("Failed retries:\t%d\n", retry_fail);    printf ("Avg retries:\t%d\n", retry_success == 0 ? 0 : avg_retries / retry_success);#endif}static void show_server_data(){    ap_listen_rec *lr;    module **m;    printf("%s\n", ap_get_server_version());    if (ap_my_addrspace && (ap_my_addrspace[0] != 'O') && (ap_my_addrspace[1] != 'S'))        printf("   Running in address space %s\n", ap_my_addrspace);    /* Display listening ports */    printf("   Listening on port(s):");    lr = ap_listeners;    do {       printf(" %d", lr->bind_addr->port);       lr = lr->next;    } while(lr && lr != ap_listeners);        /* Display dynamic modules loaded */    printf("\n");        for (m = ap_loaded_modules; *m != NULL; m++) {        if (((module*)*m)->dynamic_load_handle) {            printf("   Loaded dynamic module %s\n", ((module*)*m)->name);        }    }}static int setup_listeners(server_rec *s){    ap_listen_rec *lr;    int sockdes;    if (ap_setup_listeners(s) < 1 ) {        ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,            "no listening sockets available, shutting down");        return -1;    }    listenmaxfd = -1;    FD_ZERO(&listenfds);    for (lr = ap_listeners; lr; lr = lr->next) {        apr_os_sock_get(&sockdes, lr->sd);        FD_SET(sockdes, &listenfds);        if (sockdes > listenmaxfd) {            listenmaxfd = sockdes;        }    }    return 0;}static int shutdown_listeners(){    ap_listen_rec *lr;    for (lr = ap_listeners; lr; lr = lr->next) {        apr_socket_close(lr->sd);    }    ap_listeners = NULL;    return 0;}/***************************************************************** * Executive routines. */int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s){    apr_status_t status=0;    pconf = _pconf;    ap_server_conf = s;    if (setup_listeners(s)) {        ap_log_error(APLOG_MARK, APLOG_ALERT, status, s,            "no listening sockets available, shutting down");        return -1;    }

⌨️ 快捷键说明

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