CVS diff for cow.c between 1.19 and 1.12:

Revision 1.12 Revision 1.19
Line 33 Line 33
pth_t tid_main; 
reqnode* new_req; 
 
pth_t tid_main; 
reqnode* new_req; 
 
 
int zero = 0;
int one  = 1;
 
/* 
* And the server main procedure 
*/ 
/* 
* And the server main procedure 
*/ 
// COW_NOHAND = max # hands
#define COW_NOHAND_X COW_NOHAND*3
 
 
/* pool of pmsg's used to avoid malloc overhead */ 
reqnode* pmsgpool; 
reqnode* pmsgpool_first = NULL; 
 
int cow_nohands_running = 0; // number of handler running
/* pool of pmsg's used to avoid malloc overhead */ 
reqnode* pmsgpool; 
reqnode* pmsgpool_first = NULL; 
 
int cow_nohands_running = 0; // number of handler running
int cow_nohands = COW_NOHAND;   // max numbef or handler (see defines.h for val) 
int cow_nohands = COW_NOHAND;   // max number of handlers (see defines.h for val)
 
int server_root_len = 0;
 
static int s_socket; 
pth_attr_t attr; 
 
static int s_socket; 
pth_attr_t attr; 
/* these values are "number of hands running at the same time" */ 
 
unsigned long cow_max_conn = 0;  /* max simultaneous connection of session */ 
unsigned long cow_cur_conn = 0; /* current simultaneous connection */
unsigned long cow_max_conn = 0;  /* max simultaneous connection of session */ 
unsigned long cow_cur_conn = 0; /* current simultaneous connection */
 
unsigned long cow_tot_conn = 0;  /* total connections accepted */
unsigned long cow_tot_parsed = 0; /* total completed parses */
unsigned long cow_tot_served = 0; /* total completed serves */ 
 
char* cfgfile = NULL; 
char cwd[400]; 
 
char* cfgfile = NULL; 
char cwd[400]; 
Line 73 Line 77
    if (verbose) { 
printf("cow_max_conn = %lu\n", cow_max_conn); 
printf("cow_cur_conn = %lu\n", cow_cur_conn); 
    if (verbose) { 
printf("cow_max_conn = %lu\n", cow_max_conn); 
printf("cow_cur_conn = %lu\n", cow_cur_conn); 
 
        printf("cow_tot_conn = %lu\n", cow_tot_conn);
        printf("cow_tot_parsed = %lu\n", cow_tot_parsed);
        printf("cow_tot_served = %lu\n", cow_tot_served); 
        printf("cow_noof = %d\n", cow_noof); 

 
        printf("cow_noof = %d\n", cow_noof); 

 
Line 91 Line 98
    struct sockaddr_in sar; 
struct protoent *pe; 
struct sockaddr_in peer_addr; 
    struct sockaddr_in sar; 
struct protoent *pe; 
struct sockaddr_in peer_addr; 
    socklen_t peer_len; 
    socklen_t peer_len = sizeof(peer_addr); 
    int sr; 
int c; /* command line arg */ 
FILE *mime_fp; 
pth_msgport_t mp_depot; // port to the depot 
int i; 
int one = 1;
    int sr; 
int c; /* command line arg */ 
FILE *mime_fp; 
pth_msgport_t mp_depot; // port to the depot 
int i; 
int one = 1;
 
#ifdef SENDBUFSIZE
    int bufsize = SENDBUFSIZE;
#endif
    int backlog;
    int numforks = 1; 
 
/* 
* Takashi had hardcoded MAX_OPEN_FD into defines.h to 1024, but that 
 
/* 
* Takashi had hardcoded MAX_OPEN_FD into defines.h to 1024, but that 
Line 120 Line 132

 
/* Parse command line options */ 

 
/* Parse command line options */ 
    while (-1 != (c = getopt(argc, argv, "c:dr:p:v"))) { 
    while (-1 != (c = getopt(argc, argv, "b:c:df:r:p:v"))) { 
        switch (c) {
        switch (c) {
 
        case 'b':
            backlog = atoi(optarg);
            break; 
        case 'c': 
cfgfile = optarg; 
break; 
case 'd': 
stay_in_foreground = 1;
        case 'c': 
cfgfile = optarg; 
break; 
case 'd': 
stay_in_foreground = 1;
 
            break;
        case 'f':
            numforks = atoi(optarg); 
            break; 
case 'r': 
server_root = strdup(optarg); 
            break; 
case 'r': 
server_root = strdup(optarg); 
Line 143 Line 161
            break; 
default: 
fprintf(stderr, "Usage: %s [-c <cfg file>] [-d] [-p <port>] " 
            break; 
default: 
fprintf(stderr, "Usage: %s [-c <cfg file>] [-d] [-p <port>] " 
                            "[-r <dir>]\n", argv[0]); 
                            "[-r <dir>] [-f <numprocs>] [-b <backlog>]\n", argv[0]); 
            exit(1); 

            exit(1); 

Line 187 Line 205
 
printf("\n" PACKAGE_STRING "\n"); 
printf("Send feedback and bugreports to " PACKAGE_BUGREPORT "\n"); 
 
printf("\n" PACKAGE_STRING "\n"); 
printf("Send feedback and bugreports to " PACKAGE_BUGREPORT "\n"); 
 
    if (numforks > 1)
        printf("Forked %d CoW processes.\n", numforks); 
    if (stay_in_foreground)
    if (stay_in_foreground)
        printf("Hit CTRL-C to stop the server.\n\n"); 
        printf("Hit CTRL-C to stop the foreground server.\n\n"); 
    if (verbose) { 
printf("Using server port = %d\n", server_port); 
printf("Using server root = %s\n", server_root); 
printf("PthVersion 0x V RR T LL is %lX\n", pth_version());
    if (verbose) { 
printf("Using server port = %d\n", server_port); 
printf("Using server root = %s\n", server_root); 
printf("PthVersion 0x V RR T LL is %lX\n", pth_version());
 
#ifdef USE_TCPCORK
        printf("TCP corking enabled\n");
#else
        printf("Network buffering code enabled\n");
#endif 

 
/* initialize scheduler */ 

 
/* initialize scheduler */ 
Line 258 Line 283

 
/* start listening on the socket */ 

 
/* start listening on the socket */ 
    if (listen(s_socket, SOMAXCONN) == -1) { 
    //if (listen(s_socket, SOMAXCONN) == -1) {
 
    //if (listen(s_socket, cow_nohands) == -1) {
    if (listen(s_socket, backlog)) {
        perror("listen"); 
exit(1); 

        perror("listen"); 
exit(1); 

    /* initialize static reply message */ 
    /* initialize static reply messages */ 
    if (response_init()) { 
perror("response_init"); 
exit(1); 
}
    if (response_init()) { 
perror("response_init"); 
exit(1); 
}
#include "schedule.h"           // defines use POOL or not
#ifdef USE_POOL 
 
 
spawn_threads(); 
 
 
spawn_threads(); 
 
Line 281 Line 305
        exit(1); 

 
        exit(1); 

 
 
    /* Fork off extra processes so that we can handle more connections (FD's) */
    while (--numforks > 0) {
        int pid;
        if ((pid = fork()) < 0) {
            perror("fork");
            exit(1);
        } else if (pid == 0) {
            break;
        }
    }
 
    /* loop for requests */ 
for (;;) {
    /* loop for requests */ 
for (;;) {
 
#ifndef ENABLE_503
        /* Wait until we actually have a free handler thread */
        while (cow_cur_conn >= cow_nohands)
            pth_yield(NULL);
#endif
         
        /* accept next connection */
        /* accept next connection */
        peer_len = sizeof(peer_addr); 
 
        if (-1 == (sr = pth_accept(s_socket, (struct sockaddr *)&peer_addr, &peer_len))) { 
if (EMFILE == errno) { 
perror("EMFILE in accept"); 
continue; 
} else { 
perror("accept");
        if (-1 == (sr = pth_accept(s_socket, (struct sockaddr *)&peer_addr, &peer_len))) { 
if (EMFILE == errno) { 
perror("EMFILE in accept"); 
continue; 
} else { 
perror("accept");
 
                printf("errno = %d\n", errno); 
                myexit(sr); 


++cow_noof; 
++cow_cur_conn;
                myexit(sr); 


++cow_noof; 
++cow_cur_conn;
 
        ++cow_tot_conn; 
        cow_max_conn = cow_max_conn < cow_cur_conn ? 
cow_cur_conn : cow_max_conn; 
        cow_max_conn = cow_max_conn < cow_cur_conn ? 
cow_cur_conn : cow_max_conn; 
 
        /*
         * We can't use TCP_CORK together with TCP_NODELAY (wouldn't make any
         * sense).  If we have TCP_CORK, use it; if not, turn off Nagle and
         * use our own buffering scheme (stolen from Apache).
         */
#ifdef USE_TCPCORK
        {
            int one = 1;
            setsockopt(sr, IPPROTO_TCP, TCP_CORK, &one, sizeof(one));
        }
#else 
        /* Optional: Disable Nagle algorithm */ 
if (disable_nagle) { 
int one = 1; 
setsockopt(sr, IPPROTO_TCP, TCP_NODELAY, 
(void*)&one, sizeof(one)); 
}
        /* Optional: Disable Nagle algorithm */ 
if (disable_nagle) { 
int one = 1; 
setsockopt(sr, IPPROTO_TCP, TCP_NODELAY, 
(void*)&one, sizeof(one)); 
}
 
#endif

        /* Optional: Change outgoing buffer size */
#ifdef SENDBUFSIZE
        if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
                    &bufsize, sizeof(bufsize)) < 0) {
            perror("Error setting send buffer size");
        }
#endif 
 
/* 
* Stick the information about the incoming connection in a pmsg 
 
/* 
* Stick the information about the incoming connection in a pmsg 
Line 323 Line 385
        new_req->next = NULL; 
 
/* Fill in the pmsg fields and then send it */ 
        new_req->next = NULL; 
 
/* Fill in the pmsg fields and then send it */ 
 
#ifdef USE_TCPCORK
        /* TCP_CORK will take care of all buffering needs; just pass the FD */ 
        (new_req->m).fd  = sr;
        (new_req->m).fd  = sr;
 
#else
        /* Create a buffer wrapper around the file descriptor and pass that */
        (new_req->m).buf = ap_bcreate(B_RDWR);
        ap_bpushfd((new_req->m).buf, sr, sr);
#endif 
        (new_req->m).act = POP; 
if (TRUE != pth_msgport_put(mp_depot, (pth_message_t*)new_req)) { 
fprintf(stderr, "Couldn't send request to depot (msgport_put)\n"); 
exit(-2); 

}
        (new_req->m).act = POP; 
if (TRUE != pth_msgport_put(mp_depot, (pth_message_t*)new_req)) { 
fprintf(stderr, "Couldn't send request to depot (msgport_put)\n"); 
exit(-2); 

}
#else /* NON POOL VERSION */
#ifdef NON_POOL_SINGLE
    if (verbose)
        printf("using NON POOL && NO SPAWNING THREAD.\n");
    for (;;) {
        if ((sr =
             pth_accept(s_socket, (struct sockaddr *)&peer_addr,
                        &peer_len)) == -1) {
            perror("accept");
            continue;
        }

        {
            msg req;
            req.fdp = sr;
            ++cow_noof;
            read_request(&req);
            if (cow_noof > 100 && verbose)
                printf("--- cow_noof == %d ---\n", cow_noof);
        DEB_FD}
    }
#else
    if (verbose)
        printf("using NON POOL (i.e. spawn a new thread per request.\n");

    /* finally loop for requests */

    pth_attr_set(attr, PTH_ATTR_NAME, "handler");
    pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE);
    if (verbose)
        printf("listening on port %d (max %d simultaneous connections)\n",
                server_port, cow_nohands);

/* to increase|decrease the priority of the main thread
  {
    pth_attr_t this_attr = NULL;
    pth_t this_id = pth_self();
    int *prio;
    this_attr = pth_attr_of(this_id);
    // pth_attr_get(this_id, PTH_ATTR_PRIO, prio);
    // printf("prio = %d\n", *prio);
    pth_attr_set(this_id, PTH_ATTR_PRIO, 100);
  }
*/

    for (;;) {
        /* accept next connection */
        peer_len = sizeof(peer_addr);
        if ((sr =
             pth_accept(s_socket, (struct sockaddr *)&peer_addr,
                        &peer_len)) == -1) {
            if (EMFILE == errno) {
                // simply yield or sleep is no good.
                // so let the hands process some, then yield.
                while (pth_ctrl
                       (PTH_CTRL_GETTHREADS_READY
                        | PTH_CTRL_GETTHREADS_WAITING) > cow_nohands / 4)
                    pth_yield(NULL);
                // tune this number
                continue;
            }
            else {
                // really bad. (not simply out of fd).
                perror("accept");
                exit(errno);
            }
        }

/* debug :
    {
      int cthreads = pth_ctrl (PTH_CTRL_GETTHREADS);
      int cnew = pth_ctrl (PTH_CTRL_GETTHREADS_NEW);
      int cready = pth_ctrl (PTH_CTRL_GETTHREADS_READY);
      int cwaiting = pth_ctrl (PTH_CTRL_GETTHREADS_WAITING);
      int crunning = pth_ctrl (PTH_CTRL_GETTHREADS_RUNNING);    // always 1
      int csuspend = pth_ctrl (PTH_CTRL_GETTHREADS_SUSPENDED);  // should be 0
      int cdead = pth_ctrl (PTH_CTRL_GETTHREADS_DEAD);
      printf ("[ <new %d><ready %d><waiting %d><dead %d> ]\n",
              cnew, cready, cwaiting, cdead);
    }
 * end of debug */

        if (pth_ctrl
            (PTH_CTRL_GETTHREADS_READY
             | PTH_CTRL_GETTHREADS_NEW
             | PTH_CTRL_GETTHREADS_WAITING
             | PTH_CTRL_GETTHREADS_RUNNING
             | PTH_CTRL_GETTHREADS_SUSPENDED) >= cow_nohands) {
            fprintf(ERROR_LOG, "currently no more connections acceptable\n");
            COW_CLOSE(sr);
            pth_yield(NULL);
            continue;
        }
        fprintf(ERROR_LOG,
                "connection established (fd: %d, ip: %s, port: %d)\n",
                sr, inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));

        /* spawn new handling thread for connection */
        {
            pth_t tid;
            tid = pth_spawn(attr, handler, (void *)((long)sr));
            if (0 > tid) {
                perror("pth_spawn (non-pool version in cow.c)");
            }
            pth_yield(NULL);
        }
    }
# endif /* NON_POOL_SINGLE */
# endif /* USE_POOL */ 
 
 
pth_exit(0); 
 
pth_exit(0); 
Line 471 Line 430
        exit(1); 

 
        exit(1); 

 
    if ('/' == server_root[0]) 
    if ('/' == server_root[0]) { 
        /* Absolute path; no problem. */
        /* Absolute path; no problem. */
 
        server_root_len = strlen(server_root); 
        return;
        return;
 
 
/* 
* If server_root is a relative path, then we need to make it absolute 
 
/* 
* If server_root is a relative path, then we need to make it absolute 
Line 505 Line 466
 
free(server_root); 
server_root = dirbuf; 
 
free(server_root); 
server_root = dirbuf; 
 
    server_root_len = strlen(server_root); 

 
 

 
 
Line 517 Line 479
    int i = 0; 
pth_attr_t attr; 
 
    int i = 0; 
pth_attr_t attr; 
 
    pth_barrier_init(&init_bar, (cow_nohands + 2));   // +2 for main and depot 
    /*
 
     * Create a barrier which will wait for the main thread, the depot thread,
     * and all handler threads.
     */
    pth_barrier_init(&init_bar, (cow_nohands + 2));
    if (verbose) 
printf("using POOL of hands (thread) of size %d\n", cow_nohands); 
 
    if (verbose) 
printf("using POOL of hands (thread) of size %d\n", cow_nohands); 
 
Line 537 Line 503
    pth_attr_set(attr, PTH_ATTR_NAME, "hand"); 
pth_attr_set(attr, PTH_ATTR_PRIO, PTH_PRIO_MAX); 
for (i = 0; i < cow_nohands; i++) { 
    pth_attr_set(attr, PTH_ATTR_NAME, "hand"); 
pth_attr_set(attr, PTH_ATTR_PRIO, PTH_PRIO_MAX); 
for (i = 0; i < cow_nohands; i++) { 
        if (0 > (int)pth_spawn(attr, hand, (void *)NULL)) { 
        if (0 > (int)pth_spawn(attr, hand, (void *)i)) { 
            perror("Failed to spawn handler"); 
exit(errno); 
            perror("Failed to spawn handler"); 
exit(errno); 
Line 549 Line 515
    pth_barrier_reach(&init_bar); 

 
    pth_barrier_reach(&init_bar); 

 


Legend
Lines deleted from 1.19  
Lines Modified
  Lines added in revision 1.12