A Request Scheduling Layer for Apache
by Ramkumar Ramaswamy

Example 1:

recv(csd, peekbuf, PEEKLEN, MSG_PEEK);
peekbuf[PEEKLEN - 1] = '\0'; 
py_PrioritizeAndStoreRequest(csd, peekbuf);


Listing One
static void child_main(int child_num_arg)
 {  ...
if (child_num_arg != 0)
{
    new_child_main(child_num_arg);
    return;
} /* end if child_num_arg >= 0 */
    ...
 }


Listing Two
static void child_main(int child_num_arg)
{
    ...
    int n_fdpair;
    extern int fd[];
    fd_set fdpair;
    FD_ZERO(&fdpair);
    FD_SET(sd, &fdpair); FD_SET(fd[0], &fdpair);
    n_fdpair = (sd > fd[0])?(sd + 1):(fd[0] + 1);
    ap_select(n_fdpair, &fdpair, NULL, NULL, NULL); // block indefinitely
    if(FD_ISSET(fd[0], &fdpair)) // some worker is free, wants food
        if((QNum=feedWorker())>=0 && !FD_ISSET(sd, &fdpair))
            continue;
    // at this point, either you have fed the worker and there is a 
    // waiting connection or the queue is empty (OR ERROR) so you might as 
    // well block on accept
    // or of course, there is no worker, but there IS a connection
    if(QNum >= socket_limit) 
        continue; // don't accept
    ...
    //Apache code for error checking etc..
    ...

    QNum = py_peek_and_store_request(csd);
}


Listing Three
int feedWorker(void)
{
    char buf[CONTROL_SIZ+1];
    int next_csd;
    next_csd = py_GetNextRequest(); // sets QNum
    if(next_csd < 0) return -1;// do not read control data off fd[0]

    recv(fd[0], (void *)buf, CONTROL_SIZ+1, 0); 
    if(send_fd(fd[0], next_csd) < 0)
        return -1;
    if(close(next_csd) < 0) 
    {
        fprintf(stderr, "Error closing sent fd\n");
        return -1;
    }
    return QNum;
}

Listing Four
# file rrpyap.py

csdList = {1:[], 2:[]}  # priority, socket descriptor list 
Qnum  = 0       # total number of queued requests 

def readFileList():
    # this information can be read from a configuration file instead
    PTable  = {"BID": 1, "REGULAR": 2}
    return PTable
def storeRequest(csd, url):
    rType = scanURL(url)

   csdList[PTable[rType]].append(csd)
    Qnum = Qnum + 1

def getNextRequest():
    if Qnum > 0: Qnum = Qnum 1
    else: return 1, 0, 0
    if len(csdList[1])>0:
        return csdList[1].pop(0), 0, QNum
    else return csdList[2].pop(0), 0, Qnum
    # the second return parameter may be used to indicate an error in 
    # accessing the queue; it is usually zero.
     
def scanURL(url):
    # code for scanning the URL to determine request type
    return rType # "BID" or "REGULAR"

 



1

