Annotation of libwww/Library/src/HTMuxCh.c, revision 1.1.2.2

1.1.2.1   frystyk     1: /*
                      2: **     MUX CHANNEL
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
1.1.2.2 ! frystyk     6: **     @(#) $Id: HTMuxCh.c,v 1.1.2.1 1996/10/30 23:21:59 frystyk Exp $
1.1.2.1   frystyk     7: **
                      8: **     Handles a MUX Channel
                      9: **
                     10: ** Authors
                     11: **     HFN     Henrik Frystyk Nielsen <frystyk@w3.org>
                     12: **
                     13: ** HISTORY:
                     14: **     Oct 96 HFN      Written
                     15: */
                     16: 
                     17: /* Library Include files */
                     18: #include "sysdep.h"
                     19: #include "WWWUtil.h"
                     20: #include "WWWCore.h"
                     21: #include "WWWTrans.h"
                     22: #include "HTMuxTx.h"
                     23: #include "HTDemux.h"
                     24: #include "HTSession.h"
                     25: #include "HTMuxCh.h"                                    /* Implemented here */
                     26: 
                     27: #define HASH_SIZE      67
                     28: #define HASH(s)                ((s) % HASH_SIZE)
                     29: 
                     30: #define MAX_SESSIONS   0xFF                             /* Max 256 sessions */
                     31: 
                     32: #define SID_BASE       2
                     33: #define RECEIVER_OFFSET        0                          /* Client control session */
                     34: #define SENDER_OFFSET  1                          /* Server control session */
                     35: 
1.1.2.2 ! frystyk    36: typedef struct _HTMuxProtocol {
        !            37:     HTAtom *           name;
        !            38:     HTProtocolId       pid;
        !            39: } HTMuxProtocol;
        !            40: 
1.1.2.1   frystyk    41: struct _HTMuxChannel {
                     42:     int                        hash;
                     43:     HTChannel *                ch;
                     44:     int                        max_sid;                /* A la max_sockfd in select */
                     45:     HTNet *            net;
1.1.2.2 ! frystyk    46:     HTList *           protocols;              /* List of defined protocols */
1.1.2.1   frystyk    47:     HTSession *                sessions[MAX_SESSIONS];
                     48: };
                     49: 
1.1.2.2 ! frystyk    50: PRIVATE HTList ** muxchs = NULL;                      /* List of mux muxchs */
1.1.2.1   frystyk    51: 
                     52: /* ------------------------------------------------------------------------- */
                     53: 
                     54: PRIVATE BOOL free_channel (HTMuxChannel * ch)
                     55: {
                     56:     if (ch) {
                     57:        HT_FREE(ch);
                     58:        return YES;
                     59:     }
                     60:     return NO;
                     61: }
                     62: 
                     63: PUBLIC HTMuxChannel * HTMuxChannel_new (HTHost * host, HTChannel * ch)
                     64: {
                     65:     if (host && ch) {
                     66:        HTMuxChannel * me = NULL;
                     67: 
                     68:        /* Create new object */
                     69:        if ((me = (HTMuxChannel *) HT_CALLOC(1, sizeof(HTMuxChannel))) == NULL)
                     70:            HT_OUTOFMEM("HTMuxChannel_new");
                     71:        me->hash = HASH(HTChannel_socket(ch));
                     72:        me->ch = ch;
                     73: 
                     74:        /*
                     75:        **  Get a special MUX Net object that we keep to our selves. We don't
                     76:        **  associate a request object as the Net object lives longer.
                     77:        */
                     78:        me->net = HTNet_new(NULL);
1.1.2.2 ! frystyk    79:        HTNet_setReadStream(me->net, HTDemux_new(host, ch, me));
1.1.2.1   frystyk    80: 
                     81:        /* Insert into hash table */
                     82:        if (!muxchs) {
                     83:            if ((muxchs = (HTList **) HT_CALLOC(HASH_SIZE, sizeof(HTList *))) == NULL)
                     84:                HT_OUTOFMEM("HTMuxChannel_new");
                     85:        }
                     86:        if (!muxchs[me->hash]) muxchs[me->hash] = HTList_new();
                     87:        HTList_addObject(muxchs[me->hash], (void *) me);
                     88:        if (CORE_TRACE)
                     89:            HTTrace("Mux Channel. %p created with hash %d\n",me, me->hash);
                     90:        return me;
                     91:     }
                     92:     return NULL;
                     93: }
                     94: 
                     95: PUBLIC HTMuxChannel * HTMuxChannel_find (HTChannel * ch)
                     96: {
                     97:     if (muxchs && ch) {
                     98:        int hash = HASH(HTChannel_socket(ch));
                     99:        HTList * list = muxchs[hash];
                    100:        if (list) {
                    101:            HTMuxChannel * pres = NULL;
                    102:            while ((pres = (HTMuxChannel *) HTList_nextObject(list)))
                    103:                if (pres->ch == ch) return pres;
                    104:        }
                    105:     }
                    106:     return NULL;
                    107: }
                    108: 
                    109: PUBLIC BOOL HTMuxChannel_delete (HTMuxChannel * me)
                    110: {
                    111:     if (me) {
                    112:        HTList * list = NULL;
                    113:        if (PROT_TRACE) HTTrace("Mux Channel. Deleting %p\n", me);
                    114:        if (muxchs && (list = muxchs[me->hash])) {
                    115:            HTList_removeObject(list, (void *) me);
                    116:            free_channel(me);
                    117:            return YES;
                    118:        }
                    119:     }
                    120:     return NO;
                    121: }
                    122: 
                    123: PUBLIC BOOL HTMuxChannel_deleteAll (void)
                    124: {
                    125:     if (muxchs) {
                    126:        HTList * cur;
                    127:        int cnt;
                    128:        for (cnt=0; cnt<HASH_SIZE; cnt++) {
                    129:            if ((cur = muxchs[cnt])) { 
                    130:                HTMuxChannel * pres;
                    131:                while ((pres = (HTMuxChannel *) HTList_nextObject(cur)))
                    132:                    free_channel(pres);
                    133:            }
                    134:            HTList_delete(muxchs[cnt]);
                    135:        }
                    136:        HT_FREE(muxchs);
                    137:     }
                    138:     return YES;
                    139: }
                    140: 
                    141: PUBLIC HTNet * HTMuxChannel_net (HTMuxChannel * me)
                    142: {
                    143:     return me ? me->net : NULL;
                    144: }
                    145: 
1.1.2.2 ! frystyk   146: PUBLIC HTSessionId HTMuxChannel_connectSession (HTMuxChannel *         me,
        !           147:                                                HTSession *     session)
1.1.2.1   frystyk   148: {
                    149:     if (me && session) {
                    150:        HTSessionId sid = SID_BASE + SENDER_OFFSET;
1.1.2.2 ! frystyk   151:        for (; sid<MAX_SESSIONS; sid+=2)
        !           152:            if (me->sessions[sid] == NULL) break;
1.1.2.1   frystyk   153:            
                    154:        /*
                    155:        **  If we ran out of sessions then we can't accept the new 
                    156:        **  connection right now.
                    157:        */
                    158:        if (sid >= MAX_SESSIONS) {
                    159:            if (PROT_TRACE) HTTrace("Mux Channel. No available sessions\n");
                    160:            return INVSID;
                    161:        }
                    162: 
                    163:        if (PROT_TRACE)
                    164:            HTTrace("Mux Channel. Adding %p as active session to %p with sid %d\n",
                    165:                    session, me, sid);
                    166:        me->sessions[sid] = session;
                    167:                return sid;
                    168:     }
                    169:     return INVSID;
                    170: }
                    171: 
1.1.2.2 ! frystyk   172: PUBLIC HTSession * HTMuxChannel_acceptSession (HTMuxChannel * me, HTProtocolId pid)
1.1.2.1   frystyk   173: {
1.1.2.2 ! frystyk   174:     if (me && pid!=INVPID) {
        !           175:        HTSessionId sid = SID_BASE + RECEIVER_OFFSET;
        !           176:        for (; sid<MAX_SESSIONS; sid+=2) {
        !           177:            HTSession * session = me->sessions[sid];
        !           178:            if (session && HTSession_pid(session) == pid &&
        !           179:                HTSession_net(session) == NULL) {
        !           180:                if (PROT_TRACE)
        !           181:                    HTTrace("Mux Channel. Accepting session %p\n", session);
        !           182:                return session;
        !           183:            }
        !           184:        }
        !           185:     }
        !           186:     return NULL;
1.1.2.1   frystyk   187: }
                    188: 
                    189: PUBLIC BOOL HTMuxChannel_deleteSession (HTMuxChannel * me, HTSessionId sid)
                    190: {
                    191:     if (me) {
                    192:        if (PROT_TRACE)
                    193:            HTTrace("Mux Channel. Deleting session %d from %p\n", sid, me);
                    194:        me->sessions[sid] = NULL;
                    195:        return YES;
                    196:     }
                    197:     return NO;
                    198: }
                    199: 
                    200: PUBLIC HTSession * HTMuxChannel_findSessionFromId (HTMuxChannel * me,
                    201:                                                   HTSessionId sid)
                    202: {
                    203:     return (me) ? me->sessions[sid] : NULL;
                    204: }
                    205: 
                    206: PUBLIC HTSession * HTMuxChannel_findSessionFromNet (HTMuxChannel * me,
                    207:                                                    HTNet * net)
                    208: {
                    209:     if (me && net) {
                    210:        int cnt = 0;
                    211:        HTSession **session = me->sessions;
                    212:        while (cnt<MAX_SESSIONS) {
                    213:            if (HTSession_net(*session) == net) return *session;
                    214:            session++, cnt++;
                    215:        }           
                    216:     }
                    217:     return NULL;
                    218: }
                    219: 
                    220: PUBLIC HTChannel * HTMuxChannel_channel (HTMuxChannel * muxch)
                    221: {
                    222:     return muxch ? muxch->ch : NULL;
1.1.2.2 ! frystyk   223: }
        !           224: 
        !           225: /* ------------------------------------------------------------------------- */
        !           226: 
        !           227: PUBLIC BOOL HTMuxProtocol_new (HTMuxChannel * muxch,
        !           228:                               HTProtocolId pid, const char * protocol)
        !           229: {
        !           230:     if (muxch && protocol) {   
        !           231:        HTMuxProtocol * ms;
        !           232:        if ((ms = (HTMuxProtocol *) HT_CALLOC(1, sizeof(HTMuxProtocol))) == NULL)
        !           233:            HT_OUTOFMEM("HTMuxProtocol_new");
        !           234:        ms->name = HTAtom_caseFor(protocol);
        !           235:        ms->pid = pid;
        !           236:        if (!muxch->protocols) muxch->protocols = HTList_new();
        !           237:        return HTList_addObject(muxch->protocols, ms);
        !           238:     }
        !           239:     return NO;
        !           240: }
        !           241: 
        !           242: PUBLIC BOOL HTMuxProtocol_delete (HTMuxChannel * muxch, HTProtocolId pid)
        !           243: {
        !           244:     if (muxch && muxch->protocols) {
        !           245:        HTList * cur = muxch->protocols;
        !           246:        HTMuxProtocol * pres;
        !           247:        while ((pres = (HTMuxProtocol *) HTList_nextObject(cur))) {
        !           248:            if (pres->pid == pid) {
        !           249:                HTList_removeObject(muxch->protocols, pres);
        !           250:                HT_FREE(pres);
        !           251:                return YES;
        !           252:            }
        !           253:        }
        !           254:     }
        !           255:     return NO;
1.1.2.1   frystyk   256: }

Webmaster