Annotation of libwww/Library/src/HTNet.c, revision 2.1

2.1     ! frystyk     1: /*                     Multiple Thread Socket Management
        !             2: **                     =================================
        !             3: **
        !             4: **     This is the implementation of the internal library multi-threading
        !             5: **     functions. This includes an interrupt handler and a event loop.
        !             6: **     
        !             7: ** History:
        !             8: **     12 June 94      Written by Henrik Frystyk, frystyk@dxcern.cern.ch
        !             9: */
        !            10: 
        !            11: /* Implemention dependent include files */
        !            12: #include "tcp.h"
        !            13: 
        !            14: /* Library include files */
        !            15: #include "HTUtils.h"
        !            16: #include "HTAccess.h"
        !            17: #include "HTError.h"
        !            18: #include "HTThread.h"                                   /* Implemented here */
        !            19: 
        !            20: /* Type definitions and global variables etc. local to this module */
        !            21: PRIVATE fd_set HTfd_read;            /* Bit array of sockets ready for read */
        !            22: PRIVATE fd_set HTfd_write;          /* Bit array of sockets ready for write */
        !            23: PRIVATE int    HTMaxfdpl = 0;                  /* Max number of sockets + 1 */
        !            24: 
        !            25: PRIVATE fd_set HTfd_intr;              /* All sockets currently interrupted */
        !            26: PRIVATE fd_set HTfd_set;                /* All sockets currently registered */
        !            27: 
        !            28: PRIVATE HTList *HTThreads = NULL;               /* List of the HTNetInfo structures */
        !            29: 
        !            30: /* ------------------------------------------------------------------------- */
        !            31: 
        !            32: /*                                                                HTThreadInit
        !            33: **
        !            34: **     Initiates the thread socket registers. It is very important that
        !            35: **     this function is called. It is currently done inside HTAccess in the
        !            36: **     HTAccessInit function.
        !            37: */
        !            38: PUBLIC BOOL HTThreadInit NOARGS
        !            39: {
        !            40:     static BOOL done=NO;
        !            41: 
        !            42:     if (done) {
        !            43:        if (THD_TRACE)
        !            44:            fprintf(stderr, "ThreadInit.. Already done\n");
        !            45:        return NO;
        !            46:     }
        !            47:     done = YES;
        !            48: 
        !            49:     /* Initialize the other internal bit arrays */
        !            50:     FD_ZERO(&HTfd_write);
        !            51:     FD_ZERO(&HTfd_set);
        !            52:     FD_ZERO(&HTfd_intr);
        !            53:     return YES;
        !            54: }
        !            55: 
        !            56: 
        !            57: /*                                                           HTThreadGetFDInfo
        !            58: **
        !            59: **     Returns the maximum bit width and the read and write bit array.
        !            60: */
        !            61: PUBLIC int HTThreadGetFDInfo ARGS2(fd_set *, read, fd_set *, write)
        !            62: {
        !            63:     *read = HTfd_read;
        !            64:     *write = HTfd_write;
        !            65:     return HTMaxfdpl;
        !            66: }
        !            67: 
        !            68: 
        !            69: /*                                                               HTThreadState
        !            70: **
        !            71: **     This function registers a socket as waiting for the action given
        !            72: **     (read or write etc.).
        !            73: */
        !            74: PUBLIC void HTThreadState ARGS2(int, sockfd, HTThreadAction, action)
        !            75: {
        !            76:     if (THD_TRACE) {
        !            77:        static char *actionmsg[] = {
        !            78:            "SET WRITE",
        !            79:            "CLEAR WRITE",
        !            80:            "SET READ",
        !            81:            "CLEAR READ",
        !            82:            "INTERRUPT",
        !            83:            "CLOSE"
        !            84:            };
        !            85:        fprintf(stderr,
        !            86:                "Thread...... Register socket number %d for action %s\n",
        !            87:                sockfd, *(actionmsg+action));
        !            88:     }
        !            89:     switch (action) {
        !            90:       case THD_SET_WRITE:
        !            91:        FD_CLR(sockfd, &HTfd_read);
        !            92:        FD_SET(sockfd, &HTfd_write);
        !            93:        FD_SET(sockfd, &HTfd_set);
        !            94:        break;
        !            95: 
        !            96:       case THD_CLR_WRITE:
        !            97:        FD_CLR(sockfd, &HTfd_read);
        !            98:        FD_CLR(sockfd, &HTfd_write);
        !            99:        FD_CLR(sockfd, &HTfd_set);
        !           100:        break;
        !           101: 
        !           102:       case THD_SET_READ:
        !           103:        FD_SET(sockfd, &HTfd_read);
        !           104:        FD_CLR(sockfd, &HTfd_write);
        !           105:        FD_SET(sockfd, &HTfd_set);
        !           106:        break;
        !           107: 
        !           108:       case THD_CLR_READ:
        !           109:        FD_CLR(sockfd, &HTfd_read);
        !           110:        FD_CLR(sockfd, &HTfd_write);
        !           111:        FD_CLR(sockfd, &HTfd_set);
        !           112:        break;
        !           113: 
        !           114:       case THD_CLOSE:
        !           115:        FD_CLR(sockfd, &HTfd_read);
        !           116:        FD_CLR(sockfd, &HTfd_write);
        !           117:        FD_CLR(sockfd, &HTfd_intr);
        !           118:        FD_CLR(sockfd, &HTfd_set);
        !           119:        break;
        !           120: 
        !           121:       case THD_INTR:
        !           122:        FD_CLR(sockfd, &HTfd_read);
        !           123:        FD_CLR(sockfd, &HTfd_write);
        !           124:        FD_SET(sockfd, &HTfd_intr);
        !           125:        break;
        !           126: 
        !           127:       default:
        !           128:        if (THD_TRACE)
        !           129:            fprintf(stderr, "Thread...... Illigal socket action\n");
        !           130:     }
        !           131: 
        !           132:     /* Update max bit width. The method used ignores any other default
        !           133:        opened file descriptors between STDERR_FILENO and the actual set
        !           134:        of file descriptors used. However, they are not registered anyway */
        !           135:     if (action == THD_CLOSE) {
        !           136:        if (sockfd+1 >= HTMaxfdpl) {
        !           137:            while (HTMaxfdpl > STDERR_FILENO+1 &&
        !           138:                   !FD_ISSET(HTMaxfdpl-1, &HTfd_set))
        !           139:                HTMaxfdpl--;
        !           140:        }
        !           141:     } else {
        !           142:        if (sockfd+1 > HTMaxfdpl)
        !           143:            HTMaxfdpl = sockfd+1;
        !           144:     }
        !           145:     if (THD_TRACE)
        !           146:        fprintf(stderr, "Thread...... Max bitwidth is %d\n", HTMaxfdpl);
        !           147: }
        !           148: 
        !           149: 
        !           150: /*                                                                HTThreadIntr
        !           151: **
        !           152: **     This function returns YES or NO to the question
        !           153: */
        !           154: PUBLIC BOOL HTThreadIntr ARGS1(int, sockfd)
        !           155: {
        !           156:     return FD_ISSET(sockfd, &HTfd_intr) ? YES : NO;
        !           157: }
        !           158: 
        !           159: 
        !           160: /*                                                         HTThreadMarkIntrAll
        !           161: **
        !           162: **     Marks all sockets as interrupted
        !           163: */
        !           164: PUBLIC void HTThreadMarkIntrAll NOARGS
        !           165: {
        !           166:     int cnt;
        !           167:     if (THD_TRACE)
        !           168:        fprintf(stderr, "Thread...... Mark all sockets as INTERRUPTED\n");
        !           169:     for (cnt=STDERR_FILENO+1; cnt<HTMaxfdpl; cnt++)
        !           170:        FD_SET(cnt, &HTfd_intr);
        !           171: }
        !           172: 
        !           173: 
        !           174: /*                                                              HTThreadActive
        !           175: **
        !           176: **     Returns yes as long as a socket other than stdin is registered in 
        !           177: **     the total set of sockets.
        !           178: */
        !           179: PUBLIC BOOL HTThreadActive NOARGS
        !           180: {
        !           181:     int cnt;
        !           182:     for (cnt=STDIN_FILENO+1; cnt<HTMaxfdpl; cnt++)
        !           183:        if (FD_ISSET(cnt, &HTfd_set))
        !           184:            return YES;
        !           185:     return NO;
        !           186: }
        !           187: 
        !           188: 
        !           189: /*                                                                HTThread_new
        !           190: **
        !           191: **     Register the HTNetInfo structure in a list so that we can find the 
        !           192: **     request which corresponds to a socket descriptor
        !           193: */
        !           194: PUBLIC void HTThread_new ARGS1(HTNetInfo *, new_net)
        !           195: {
        !           196:     if (!HTThreads)
        !           197:        HTThreads = HTList_new();
        !           198:     HTList_addObject(HTThreads, (void *) new_net);
        !           199: }
        !           200: 
        !           201: 
        !           202: /*                                                              HTThread_clear
        !           203: **
        !           204: **     Remove the HTNetInfo from the list of acrive threads.
        !           205: */
        !           206: PUBLIC int HTThread_clear ARGS1(HTNetInfo *, old_net)
        !           207: {
        !           208:     if (HTThreads)
        !           209:        return HTList_removeObject(HTThreads, (void *) old_net);
        !           210:     return NO;
        !           211: }
        !           212: 
        !           213: 
        !           214: /*                                                        HTThread_getCallBack
        !           215: **
        !           216: **     Finds a socket and makes it the active thread. READ has a higher
        !           217: **     priority than WRITE as it might influence (stop) the WRITE process.
        !           218: **     Returns the request structure of the active thread, NULL on error.
        !           219: **     A interrupted socket has the highest priority
        !           220: */
        !           221: PUBLIC HTRequest *HTThread_getRequest ARGS2(CONST fd_set *,    fd_read,
        !           222:                                            CONST fd_set *,     fd_write)
        !           223: {
        !           224:     HTList *cur = HTThreads;
        !           225:     HTNetInfo *pres;
        !           226:     int cnt;
        !           227:     BOOL found = NO;
        !           228:     for (cnt=STDIN_FILENO+1; cnt<HTMaxfdpl; cnt++) {           /* INTERRUPT */
        !           229:        if (FD_ISSET(cnt, &HTfd_intr)) {
        !           230:            if (THD_TRACE)
        !           231:                fprintf(stderr, "GetSocket... Socket %d INTERRUPTED\n", cnt);
        !           232:            found = YES;
        !           233:            break;
        !           234:        }
        !           235:     }
        !           236:     if (!found) {
        !           237:        for (cnt=STDIN_FILENO+1; cnt<HTMaxfdpl; cnt++) {             /* READ */
        !           238:            if (FD_ISSET(cnt, fd_read)) {
        !           239:                if (THD_TRACE)
        !           240:                    fprintf(stderr, "GetSocket... Socket %d for READ\n", cnt);
        !           241:                found = YES;
        !           242:                break;
        !           243:            }
        !           244:        }
        !           245:     }
        !           246:     if (!found) {
        !           247:        for (cnt=STDIN_FILENO+1; cnt<HTMaxfdpl; cnt++) {            /* WRITE */
        !           248:            if (FD_ISSET(cnt, fd_write)) {
        !           249:                if (THD_TRACE)
        !           250:                    fprintf(stderr, "GetSocket... Socket %d for WRITE\n", cnt);
        !           251:                found = YES;
        !           252:                break;
        !           253:            }
        !           254:        }
        !           255:     }
        !           256:     if (!found || cur == NULL)
        !           257:        return NULL;
        !           258: 
        !           259:     /* Find the corresponding HTNetInfo structure */
        !           260:     while ((pres = (HTNetInfo *) HTList_nextObject(cur)) != NULL) {
        !           261:        if (pres->sockfd == cnt) {
        !           262:            return pres->request;
        !           263:        }
        !           264:     }
        !           265:     return NULL;
        !           266: }

Webmaster