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