Annotation of libwww/Library/src/HTMuxCh.c, revision 1.1.2.1
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.
! 6: ** @(#) $Id: HTChannl.c,v 2.12 1996/08/24 18:09:48 frystyk Exp $
! 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:
! 36: struct _HTMuxChannel {
! 37: int hash;
! 38: HTChannel * ch;
! 39: int max_sid; /* A la max_sockfd in select */
! 40: HTNet * net;
! 41: HTSession * sessions[MAX_SESSIONS];
! 42: };
! 43:
! 44: PRIVATE HTList ** muxchs = NULL; /* List of mux muxchs */
! 45:
! 46: /* ------------------------------------------------------------------------- */
! 47:
! 48: PRIVATE BOOL free_channel (HTMuxChannel * ch)
! 49: {
! 50: if (ch) {
! 51: HT_FREE(ch);
! 52: return YES;
! 53: }
! 54: return NO;
! 55: }
! 56:
! 57: PUBLIC HTMuxChannel * HTMuxChannel_new (HTHost * host, HTChannel * ch)
! 58: {
! 59: if (host && ch) {
! 60: HTMuxChannel * me = NULL;
! 61:
! 62: /* Create new object */
! 63: if ((me = (HTMuxChannel *) HT_CALLOC(1, sizeof(HTMuxChannel))) == NULL)
! 64: HT_OUTOFMEM("HTMuxChannel_new");
! 65: me->hash = HASH(HTChannel_socket(ch));
! 66: me->ch = ch;
! 67:
! 68: /*
! 69: ** Get a special MUX Net object that we keep to our selves. We don't
! 70: ** associate a request object as the Net object lives longer.
! 71: */
! 72: me->net = HTNet_new(NULL);
! 73: HTNet_setReadStream(me->net, HTDemux_new(host, me));
! 74:
! 75: /* Insert into hash table */
! 76: if (!muxchs) {
! 77: if ((muxchs = (HTList **) HT_CALLOC(HASH_SIZE, sizeof(HTList *))) == NULL)
! 78: HT_OUTOFMEM("HTMuxChannel_new");
! 79: }
! 80: if (!muxchs[me->hash]) muxchs[me->hash] = HTList_new();
! 81: HTList_addObject(muxchs[me->hash], (void *) me);
! 82: if (CORE_TRACE)
! 83: HTTrace("Mux Channel. %p created with hash %d\n",me, me->hash);
! 84: return me;
! 85: }
! 86: return NULL;
! 87: }
! 88:
! 89: PUBLIC HTMuxChannel * HTMuxChannel_find (HTChannel * ch)
! 90: {
! 91: if (muxchs && ch) {
! 92: int hash = HASH(HTChannel_socket(ch));
! 93: HTList * list = muxchs[hash];
! 94: if (list) {
! 95: HTMuxChannel * pres = NULL;
! 96: while ((pres = (HTMuxChannel *) HTList_nextObject(list)))
! 97: if (pres->ch == ch) return pres;
! 98: }
! 99: }
! 100: return NULL;
! 101: }
! 102:
! 103: PUBLIC BOOL HTMuxChannel_delete (HTMuxChannel * me)
! 104: {
! 105: if (me) {
! 106: HTList * list = NULL;
! 107: if (PROT_TRACE) HTTrace("Mux Channel. Deleting %p\n", me);
! 108: if (muxchs && (list = muxchs[me->hash])) {
! 109: HTList_removeObject(list, (void *) me);
! 110: free_channel(me);
! 111: return YES;
! 112: }
! 113: }
! 114: return NO;
! 115: }
! 116:
! 117: PUBLIC BOOL HTMuxChannel_deleteAll (void)
! 118: {
! 119: if (muxchs) {
! 120: HTList * cur;
! 121: int cnt;
! 122: for (cnt=0; cnt<HASH_SIZE; cnt++) {
! 123: if ((cur = muxchs[cnt])) {
! 124: HTMuxChannel * pres;
! 125: while ((pres = (HTMuxChannel *) HTList_nextObject(cur)))
! 126: free_channel(pres);
! 127: }
! 128: HTList_delete(muxchs[cnt]);
! 129: }
! 130: HT_FREE(muxchs);
! 131: }
! 132: return YES;
! 133: }
! 134:
! 135: PUBLIC HTNet * HTMuxChannel_net (HTMuxChannel * me)
! 136: {
! 137: return me ? me->net : NULL;
! 138: }
! 139:
! 140: PUBLIC HTSessionId HTMuxChannel_connectSession (HTMuxChannel * me,
! 141: HTSession * session)
! 142: {
! 143: if (me && session) {
! 144: HTSessionId sid = SID_BASE + SENDER_OFFSET;
! 145: for (; sid<MAX_SESSIONS; sid++) if (me->sessions[sid] == NULL) break;
! 146:
! 147: /*
! 148: ** If we ran out of sessions then we can't accept the new
! 149: ** connection right now.
! 150: */
! 151: if (sid >= MAX_SESSIONS) {
! 152: if (PROT_TRACE) HTTrace("Mux Channel. No available sessions\n");
! 153: return INVSID;
! 154: }
! 155:
! 156: if (PROT_TRACE)
! 157: HTTrace("Mux Channel. Adding %p as active session to %p with sid %d\n",
! 158: session, me, sid);
! 159: me->sessions[sid] = session;
! 160: return sid;
! 161: }
! 162: return INVSID;
! 163: }
! 164:
! 165: PUBLIC HTSessionId HTMuxChannel_acceptSession (HTMuxChannel * me,
! 166: HTSession * session)
! 167: {
! 168:
! 169: /* MORE */
! 170:
! 171: return INVSID;
! 172:
! 173: }
! 174:
! 175: PUBLIC BOOL HTMuxChannel_deleteSession (HTMuxChannel * me, HTSessionId sid)
! 176: {
! 177: if (me) {
! 178: if (PROT_TRACE)
! 179: HTTrace("Mux Channel. Deleting session %d from %p\n", sid, me);
! 180: me->sessions[sid] = NULL;
! 181:
! 182: /* Update max sid */
! 183:
! 184: return YES;
! 185: }
! 186: return NO;
! 187: }
! 188:
! 189: PUBLIC HTSession * HTMuxChannel_findSessionFromId (HTMuxChannel * me,
! 190: HTSessionId sid)
! 191: {
! 192: return (me) ? me->sessions[sid] : NULL;
! 193: }
! 194:
! 195: PUBLIC HTSession * HTMuxChannel_findSessionFromNet (HTMuxChannel * me,
! 196: HTNet * net)
! 197: {
! 198: if (me && net) {
! 199: int cnt = 0;
! 200: HTSession **session = me->sessions;
! 201: while (cnt<MAX_SESSIONS) {
! 202: if (HTSession_net(*session) == net) return *session;
! 203: session++, cnt++;
! 204: }
! 205: }
! 206: return NULL;
! 207: }
! 208:
! 209: PUBLIC HTChannel * HTMuxChannel_channel (HTMuxChannel * muxch)
! 210: {
! 211: return muxch ? muxch->ch : NULL;
! 212: }
Webmaster