Annotation of Amaya/amaya/AHTBridge.c, revision 1.28
1.9 cvs 1: /*
2: *
3: * (c) COPYRIGHT MIT and INRIA, 1996.
4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
7:
1.14 cvs 8: /*
9: * AHTBridge.c : This module implements the callback setup and
10: * handlers between the Xt, libwww, and Amaya procedures. It's responsible
11: * for assigning, modifying, and supressing Xt events to the active
12: * requests.
13: *
14: * Author: J Kahan
1.28 ! cvs 15: * R. Guetari/J. Kahan Windows NT/95 routines
1.14 cvs 16: *
17: */
1.23 cvs 18: #ifndef AMAYA_JAVA
19:
1.16 cvs 20: #define THOT_EXPORT extern
1.4 cvs 21: #include "amaya.h"
1.10 cvs 22: #include "AHTBridge_f.h"
23: #include "AHTFWrite_f.h"
24: #include "query_f.h"
25: #include "answer_f.h"
1.4 cvs 26:
1.22 cvs 27: #ifndef _WINDOWS
1.4 cvs 28: /* Amaya's X appcontext */
1.16 cvs 29: extern ThotAppContext app_cont;
1.4 cvs 30: #endif
31:
32: /*
1.7 cvs 33: * Private functions
34: */
1.4 cvs 35: #ifdef __STDC__
1.18 cvs 36: static void RequestRegisterReadXtevent (AHTReqContext *, SOCKET);
1.7 cvs 37: static void RequestKillReadXtevent (AHTReqContext *);
1.18 cvs 38: static void RequestRegisterWriteXtevent (AHTReqContext *, SOCKET);
1.7 cvs 39: static void RequestKillWriteXtevent (AHTReqContext *);
1.18 cvs 40: static void RequestRegisterExceptXtevent (AHTReqContext *, SOCKET);
1.7 cvs 41: static void RequestKillExceptXtevent (AHTReqContext *);
42:
1.27 cvs 43: #else /* __STDC__ */
1.18 cvs 44: static void RequesAddReadXtevent ();
1.7 cvs 45: static void RequestKillReadXtevent ();
1.18 cvs 46: static void RequesAddWriteXtevent ();
1.7 cvs 47: static void RequestKillWriteXtevent ();
1.18 cvs 48: static void RequestRegisterExceptXtevent ();
1.7 cvs 49: static void RequestKillExceptXtevent ();
50:
1.27 cvs 51: #endif /* __STDC__ */
1.4 cvs 52:
1.24 cvs 53: #ifdef _WINDOWS
54: static void WIN_ResetMaxSock (void);
55: static int WIN_ProcessFds (fd_set * fdsp, SockOps ops);
1.26 cvs 56: #if 0
1.25 cvs 57: static int VerifySocketState (AHTReqContext *me, SOCKET sock);
58: PUBLIC LRESULT CALLBACK ASYNCWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
1.26 cvs 59: #endif /* 0 */
1.24 cvs 60: #endif /* _WINDOWS */
61:
1.4 cvs 62: /*
63: * Private variables
64: */
65:
66: /*
67: * this set of SockOps map our WinSock "socket event SockOps" into
68: * our read and write sets. Note that under the canonical Unix model,
69: * a non-blocking socket passed to an accept() call will appear as readable,
70: * whilst a non-blocking call to connect() will appear as writeable. In add.
71: * if the connection has been closed, the socket will appear readable under
72: * BSD Unix semantics
73: */
1.10 cvs 74: static const SockOps ReadBits = FD_READ | FD_ACCEPT | FD_CLOSE;
75: static const SockOps WriteBits = FD_WRITE | FD_CONNECT;
76: static const SockOps ExceptBits = FD_OOB;
1.4 cvs 77:
1.24 cvs 78: #ifdef _WINDOWS
79: static fd_set read_fds, write_fds, except_fds, all_fds;
1.26 cvs 80: static int maxfds = 0;
1.24 cvs 81: #endif /* _WINDOWS */
1.19 cvs 82:
83: /*
1.4 cvs 84: * Private functions
85: */
86:
1.10 cvs 87: /*--------------------------------------------------------------------
88: AHTCallback_bridge
1.11 cvs 89: this function acts as a bridge between Xt and libwww. From the Xt
90: point of view, this function is the callback handler whenever there's
91: any activity on the sockets associated with the active requests. From
92: the libwww point of view, this is the function that takes the initiative
93: to invoke the callback function associated with an active request,
94: whenever there's an activity in the socket associated to it.
95: In this latter aspect, this function is similar to the library's
96: own __DoCallback() function.
97: Upon activation, the function looks up the request associated with the
98: active socket and then looks up the cbf associated with that request.
99: Upon completion of the execution of the request's cbf, it verifies
100: the state of the request and, if it's an asynchronous request, deletes
101: the memory allocated to it.
1.10 cvs 102: -------------------------------------------------------------------*/
1.24 cvs 103: #ifdef _WINDOWS
1.26 cvs 104: #ifdef __STDC__
105: static void* WIN_AHTCallback_bridge (SockOps _ops, int *s)
106: #else /* __STDC__ */
107: static void* WIN_AHTCallback_bridge (_ops, s)
108: SockOps _ops;
109: int* s;
110: #endif /* __STDC__ */
111: #else /* _WINDOWS */
1.4 cvs 112: #ifdef __STDC__
1.12 cvs 113: void *AHTCallback_bridge (caddr_t cd, int *s, XtInputId * id)
1.26 cvs 114: #else /* __STDC__ */
1.12 cvs 115: void *AHTCallback_bridge (cd, s, id)
1.7 cvs 116: caddr_t cd;
117: int *s;
118: XtInputId *id;
1.4 cvs 119: #endif /* __STDC__ */
1.24 cvs 120: #endif /* _WINDOWS */
1.4 cvs 121: {
1.11 cvs 122: int status; /* the status result of the libwwww call */
1.7 cvs 123: HTRequest *rqp = NULL;
124: AHTReqContext *me;
1.11 cvs 125: SockOps ops;
1.4 cvs 126:
1.10 cvs 127: /* Libwww 5.0a does not take into account the ops parameter
1.11 cvs 128: in the invocation of for this function call */
1.4 cvs 129:
130: #ifdef HACK_WWW
1.7 cvs 131: HTEventCallback *cbf;
132:
1.4 cvs 133: #else
1.13 cvs 134: HTEventCallback *cbf;
1.7 cvs 135:
1.13 cvs 136: ops = FD_WRITE;
137: cbf = (HTEventCallback *) __RetrieveCBF (*s, ops, &rqp);
1.4 cvs 138: #endif
1.13 cvs 139:
1.7 cvs 140: me = HTRequest_context (rqp);
141: if (THD_TRACE)
1.10 cvs 142: fprintf (stderr, "AHTBridge: Processing url %s \n", me->urlName);
1.4 cvs 143:
1.17 cvs 144: /* verify if there's any callback associated with the request */
145: if (!cbf || !rqp || rqp->priority == HT_PRIORITY_OFF)
146: {
147: if (THD_TRACE)
148: HTTrace ("Callback.... No callback found\n");
1.18 cvs 149: /* experimental */
150: /* remove the Xt input which caused this callback */
1.21 cvs 151: #ifdef WWW_XWINDOWS
1.18 cvs 152: XtRemoveInput (*id);
1.21 cvs 153: #endif
1.17 cvs 154: /* put some more code to correctly destroy this request ?*/
155: return (0);
156: }
1.4 cvs 157:
1.26 cvs 158: # ifdef _WINDOWS
1.24 cvs 159: ops = _ops;
1.26 cvs 160: # else
1.7 cvs 161: switch ((XtInputId) cd)
162: {
1.19 cvs 163: case XtInputReadMask:
164: ops = me->read_ops;
165: ops = FD_READ;
166: break;
1.7 cvs 167: case XtInputWriteMask:
168: ops = me->write_ops;
169: ops = FD_WRITE;
170: break;
171: case XtInputExceptMask:
172: ops = me->except_ops;
173: ops = FD_OOB;
174: break;
1.11 cvs 175: default:
1.19 cvs 176: break;
1.7 cvs 177: } /* switch */
1.26 cvs 178: # endif /* _WINDOWS */
1.17 cvs 179:
1.11 cvs 180: /* Invokes the callback associated to the requests */
181:
182: /* first we change the status of the request, to say it
183: has entered a critical section */
1.15 cvs 184:
185: if((HTRequest_outputStream(me->request) == (HTStream *) NULL))
186: fprintf(stderr,"\n **ERROR** opening %s\n\n",me->urlName);
187:
1.11 cvs 188: me->reqStatus = HT_BUSY;
189: if ((status = (*cbf) (*s, rqp, ops)) != HT_OK)
190: HTTrace ("Callback.... received != HT_OK");
1.4 cvs 191:
1.7 cvs 192: /* Several states can happen after this callback. They
193: * are indicated by the me->reqStatus structure member and
194: * the fds external variables. The following lines examine
195: * the states and correspondly update the Xt event register
196: *
197: * Regarding the me->reqStatus member, we have the following
198: * possible states:
199: *
200: * HT_BUSY: Request has blocked
201: * HT_WAITING: Request has been reissued
202: * HT_ABORT: Request has been stopped
203: * HT_END: Request has ended
204: */
205:
206: if (me->reqStatus == HT_ABORT)
1.11 cvs 207: /* Has the user stopped the request? */
1.7 cvs 208: {
1.4 cvs 209: me->reqStatus = HT_WAITING;
210: StopRequest (me->docid);
1.7 cvs 211: return (0);
212: }
213:
1.11 cvs 214: if (me->reqStatus == HT_WAITING)
1.7 cvs 215: /* the request is being reissued */
216: {
217: /*
218: * (1) The old request has ended and the library
219: * assigned the old socket number to a pending
220: * request.
221: *
222: * (2) The request has been reissued after an
223: * authentication or redirection directive and
224: * we are using the same old socket number.
225: */
1.11 cvs 226:
227: if (THD_TRACE)
228: fprintf (stderr, "*** detected a reissue of request \n");
229: return (0);
1.7 cvs 230: }
1.4 cvs 231:
1.11 cvs 232: /* we verify if the request exists. If it has ended, we will have
233: a reqStatus with an HT_END value */
1.7 cvs 234:
235: if ((me->request->net == (HTNet *) NULL) || (me->reqStatus == HT_END || me->reqStatus == HT_ERR))
1.11 cvs 236: /* request has ended */
1.7 cvs 237: {
1.26 cvs 238: # ifndef _WINDOWS
1.7 cvs 239: if (THD_TRACE)
1.11 cvs 240: fprintf (stderr, "(BF) removing Xtinput %lu !RWE, sock %d (Request has ended)\n", *id, *s);
1.26 cvs 241: # endif
1.7 cvs 242: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
1.11 cvs 243: /* free the memory allocated for async requests */
1.7 cvs 244: {
245: AHTPrintPendingRequestStatus (me->docid, YES);
246: AHTReqContext_delete (me);
247: }
248: else if (me->reqStatus != HT_END && HTError_hasSeverity (HTRequest_error (me->request), ERR_NON_FATAL))
1.11 cvs 249: /* did the SYNC request end because of an error? If yes, report it back to the caller */
1.4 cvs 250: me->reqStatus = HT_ERR;
1.7 cvs 251: return (0);
252: }
1.11 cvs 253:
254: /* The request is still alive, so change it's status to indicate it's out of the
255: critical section */
1.7 cvs 256: me->reqStatus = HT_WAITING;
257: return (0);
1.4 cvs 258: }
259:
260:
1.10 cvs 261: /*----------------------------------------------------------------
262: Add_NewSocket_to_Loop
1.11 cvs 263: when there are more open requests than available sockets, the
264: requests are put in a "pending state." When a socket becomes
265: available, libwww associates it with a pending request and then
266: calls this callback function. This function is responsible for
267: opening the temporary file where the GET and POST results
268: will be stored. The function is also responsible for
269: registering the socket with the Xt event loop.
270: Consult the libwww manual for more details on the signature
271: of this function.
1.10 cvs 272: ----------------------------------------------------------------*/
1.4 cvs 273: #ifdef __STDC__
1.7 cvs 274: int Add_NewSocket_to_Loop (HTRequest * request, HTAlertOpcode op, int msgnum, const char *dfault, void *input, HTAlertPar * reply)
1.4 cvs 275: #else
1.7 cvs 276: int Add_NewSocket_to_Loop (request, op, msgnum, dfault, input, reply)
277: HTRequest *request;
278: HTAlertOpcode op;
279: int msgnum;
280: const char *dfault;
281: void *input;
282: HTAlertPar *reply;
283:
284: #endif /* __STDC__ */
1.4 cvs 285: {
1.7 cvs 286: AHTReqContext *me = HTRequest_context (request);
1.4 cvs 287:
1.15 cvs 288: if (me->reqStatus == HT_BUSY)
289: /* request was aborted and now is is being reissued */
1.7 cvs 290: {
1.15 cvs 291: rewind (me->output);
292: HTRequest_setOutputStream (me->request, AHTFWriter_new (me->request, me->output, YES));
293: } else if (me->reqStatus == HT_NEW_PENDING)
294: {
295: /* we are dequeing a pending request */
296: if (me->outputfile && (me->output = fopen (me->outputfile, "w")) == NULL)
297: {
298: /* the request is associated with a file */
1.7 cvs 299: me->outputfile[0] = '\0'; /* file could not be opened */
300: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
301: me->outputfile);
302: me->reqStatus = HT_ERR;
303: return (HT_ERROR);
1.15 cvs 304: }
305: if (THD_TRACE)
1.7 cvs 306: fprintf (stderr, "Add_NewSocket_to_Loop: Activating pending %s . Open fd %d\n", me->urlName, (int) me->output);
1.15 cvs 307: HTRequest_setOutputStream (me->request,
308: AHTFWriter_new (me->request, me->output, YES));
309: }
1.4 cvs 310:
1.11 cvs 311: /*change the status of the request */
1.7 cvs 312: me->reqStatus = HT_WAITING;
1.4 cvs 313:
1.7 cvs 314: if (THD_TRACE)
1.15 cvs 315: fprintf (stderr, "(Activating a pending request\n");
1.4 cvs 316:
1.7 cvs 317: return (HT_OK);
1.4 cvs 318: }
319:
320:
1.11 cvs 321: /*----------------------------------------------------------------------
322: AHTEvent_register
323: callback called by libwww whenever a socket is open and associated
324: to a request. It sets the pertinent Xt events so that the Xt Event
325: loops gets an interruption whenever there's action of the socket.
326: In addition, it registers the request with libwww.
327: ----------------------------------------------------------------------*/
1.4 cvs 328: #ifdef __STDC__
1.7 cvs 329: int AHTEvent_register (SOCKET sock, HTRequest * rqp, SockOps ops, HTEventCallback * cbf, HTPriority p)
1.4 cvs 330: #else
1.7 cvs 331: int AHTEvent_register (sock, rqp, ops, cbf, p)
332: SOCKET sock;
333: HTRequest *rqp;
334: SockOps ops;
335: HTEventCallback *cbf;
336: HTPriority p;
337:
338: #endif /* __STDC__ */
1.4 cvs 339: {
1.11 cvs 340: AHTReqContext *me; /* current request */
341: int status; /* libwww status associated with the socket number */
1.7 cvs 342:
343: if (sock == INVSOC)
1.4 cvs 344: return (0);
345:
1.7 cvs 346: /* get the request associated to the socket number */
347:
348: if ((status = HTEventrg_register (sock, rqp, ops,
349: cbf, p)) != HT_OK)
1.4 cvs 350: return (status);
351:
1.7 cvs 352: if (rqp)
353: {
354: me = HTRequest_context (rqp);
1.4 cvs 355:
1.7 cvs 356: /* verify if we need to open the fd */
357: if (me->reqStatus == HT_NEW_PENDING)
358: {
359: /* we are opening a pending request */
360: if ((me->output = fopen (me->outputfile, "w")) == NULL)
361: {
362: me->outputfile[0] = '\0'; /* file could not be opened */
363: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
364: me->outputfile);
365: me->reqStatus = HT_ERR;
366: return (HT_ERROR);
367: }
368: HTRequest_setOutputStream (me->request,
369: AHTFWriter_new (me->request, me->output, YES));
370: me->reqStatus = HT_WAITING;
371:
372: if (THD_TRACE)
373: fprintf (stderr, "AHTEvent_register: Activating pending request url %s, fd %d\n", me->urlName, (int) me->output);
374: }
1.4 cvs 375:
1.7 cvs 376: if (THD_TRACE)
377: fprintf (stderr, "AHTEvent_register: url %s, sock %d, ops %lu \n",
378: me->urlName, sock, ops);
1.4 cvs 379:
1.7 cvs 380: /* add the input */
381: if (me->reqStatus == HT_NEW)
382: me->reqStatus = HT_WAITING;
383:
384: if (ops & ReadBits)
385: {
386: me->read_ops = ops;
1.18 cvs 387: RequestRegisterReadXtevent (me, sock);
1.7 cvs 388: }
389:
390: if (ops & WriteBits)
391: {
392: me->write_ops = ops;
1.18 cvs 393: RequestRegisterWriteXtevent (me, sock);
1.7 cvs 394: }
395:
396: if (ops & ExceptBits)
397: {
398: me->except_ops = ops;
1.18 cvs 399: RequestRegisterExceptXtevent (me, sock);
1.7 cvs 400: }
401: }
1.4 cvs 402:
1.7 cvs 403: return (status);
1.4 cvs 404: }
405:
1.11 cvs 406:
407: /*----------------------------------------------------------------------
408: AHTEvent_unregister
409: callback called by libwww each time a request is unregistered. This
410: function takes care of unregistering the pertinent Xt events
411: associated with the request's socket. In addition, it unregisters
412: the request from libwww.
413: ----------------------------------------------------------------------*/
1.4 cvs 414: #ifdef __STDC__
1.7 cvs 415: int AHTEvent_unregister (SOCKET sock, SockOps ops)
1.4 cvs 416: #else
1.7 cvs 417: int AHTEvent_unregister (sock, ops)
418: SOCKET sock;
419: SockOps ops;
420:
421: #endif /* __STDC__ */
1.4 cvs 422: {
1.7 cvs 423: int status;
424:
425: HTRequest *rqp = NULL;
426: AHTReqContext *me;
1.4 cvs 427:
1.11 cvs 428: /* Libwww 5.0a does not take into account the third parameter
1.7 cvs 429: ** for this function call */
1.4 cvs 430:
1.7 cvs 431: HTEventCallback *cbf = (HTEventCallback *) __RetrieveCBF (sock, (SockOps) NULL, &rqp);
1.4 cvs 432:
1.7 cvs 433: if (cbf)
434: {
435: if (rqp)
436: {
437: me = HTRequest_context (rqp);
438:
439: if (ops & ReadBits)
440: RequestKillReadXtevent (me);
1.4 cvs 441:
1.7 cvs 442: if (ops & WriteBits)
443: RequestKillWriteXtevent (me);
444:
445: if (ops & ExceptBits)
446: RequestKillExceptXtevent (me);
447: }
448: }
449:
450: status = HTEventrg_unregister (sock, ops);
451: return (status);
1.4 cvs 452: }
453:
1.11 cvs 454:
455: /*----------------------------------------------------------------------
456: RequestKillAllXtevents
457: front-end for kill all Xt events associated with the request pointed
458: to by "me".
459: ----------------------------------------------------------------------*/
1.4 cvs 460: #ifdef __STDC__
1.7 cvs 461: void RequestKillAllXtevents (AHTReqContext * me)
1.4 cvs 462: #else
1.7 cvs 463: void RequestKillAllXtevents (me)
464: AHTReqContext *me;
465:
466: #endif /* __STDC__ */
1.4 cvs 467: {
1.7 cvs 468: if (THD_TRACE)
469: fprintf (stderr, "Request_kill: Clearing Xtinputs\n");
1.4 cvs 470:
1.7 cvs 471: RequestKillReadXtevent (me);
472: RequestKillWriteXtevent (me);
473: RequestKillExceptXtevent (me);
1.4 cvs 474: }
475:
1.11 cvs 476: /*----------------------------------------------------------------------
1.18 cvs 477: RequestRegisterReadXtevent
478: Registers with Xt the read events associated with socket sock
479: ----------------------------------------------------------------------*/
480: #ifdef __STDC__
481: static void RequestRegisterReadXtevent (AHTReqContext * me, SOCKET sock)
482: #else
483: static void RequestRegisterReadXtevent (me, sock)
484: AHTReqContext *me;
485: SOCKET sock;
486:
487: #endif /* __STDC__ */
488: {
1.26 cvs 489: # ifdef _WINDOWS
490: FD_SET (sock, &read_fds);
491: FD_SET (sock, &all_fds);
492: me->read_sock = sock;
493: if (sock > maxfds)
1.25 cvs 494: maxfds = sock;
1.26 cvs 495:
496: /*
497: me->read_sock = sock;
498: me->read_fd_state |= FD_READ;
499: WSAAsyncSelect (sock, HTSocketWin, HTwinMsg, me->read_fd_state);
500: */
501: # else
1.18 cvs 502: if (me->read_xtinput_id)
503: {
504: if (THD_TRACE)
505: fprintf (stderr, "Request_kill: Clearing Xtinput %lu Socket %d R\n", me->read_xtinput_id, sock);
506: XtRemoveInput (me->read_xtinput_id);
507: }
508:
509: me->read_xtinput_id =
510: XtAppAddInput (app_cont,
511: sock,
512: (XtPointer) XtInputReadMask,
513: (XtInputCallbackProc) AHTCallback_bridge,
514: (XtPointer) XtInputReadMask);
515:
1.26 cvs 516: if (THD_TRACE)
1.18 cvs 517: fprintf (stderr, "(BT) adding Xtinput %lu Socket %d R\n",
518: me->read_xtinput_id, sock);
1.26 cvs 519: # endif /* !_WINDOWS */
1.18 cvs 520:
521: }
522:
523: /*----------------------------------------------------------------------
1.11 cvs 524: RequestKillReadXtevent
525: kills any read Xt event associated with the request pointed to by "me".
526: ----------------------------------------------------------------------*/
1.4 cvs 527: #ifdef __STDC__
1.7 cvs 528: static void RequestKillReadXtevent (AHTReqContext * me)
1.4 cvs 529: #else
1.7 cvs 530: static void RequestKillReadXtevent (me)
531: AHTReqContext *me;
532:
533: #endif /* __STDC__ */
1.4 cvs 534: {
1.26 cvs 535: # ifdef _WINDOWS
536: int new_fd;
1.25 cvs 537:
1.26 cvs 538: if (me->read_sock != INVSOC) {
539: FD_CLR (me->read_sock, &read_fds);
540: FD_CLR (me->read_sock, &all_fds);
541: me->read_sock = INVSOC;
542: WIN_ResetMaxSock();
543: /*
544: me->read_fd_state &= ~FD_READ;
545: new_fd = VerifySocketState (me, me->read_sock);
546: if (new_fd)
547: WSAAsyncSelect (me->read_sock, HTSocketWin, HTwinMsg, new_fd);
548: else
549: WSAAsyncSelect (me->read_sock, HTSocketWin, 0, 0);
550: me->read_sock = INVSOC;
551: */
552: }
553: # else
1.7 cvs 554: if (me->read_xtinput_id)
555: {
556: if (THD_TRACE)
1.18 cvs 557: fprintf (stderr, "Request_kill: Clearing Xtinput %lu R\n", me->read_xtinput_id);
1.7 cvs 558: XtRemoveInput (me->read_xtinput_id);
559: me->read_xtinput_id = (XtInputId) NULL;
560: }
1.26 cvs 561: # endif /* !_WINDOWS */
1.18 cvs 562: }
563:
564: /*----------------------------------------------------------------------
565: RequestRegisterWriteXtevent
566: Registers with Xt the write events associated with socket sock
567: ----------------------------------------------------------------------*/
568: #ifdef __STDC__
569: static void RequestRegisterWriteXtevent (AHTReqContext * me, SOCKET sock)
570: #else
571: static void RequestRegisterWriteXtevent (me, sock)
572: AHTReqContext *me;
573: SOCKET sock;
574:
575: #endif /* __STDC__ */
576: {
1.26 cvs 577: # ifdef _WINDOWS
578: FD_SET (sock, &write_fds);
579: FD_SET (sock, &all_fds);
580: me->write_sock = sock;
581:
582: if (sock > maxfds)
583: maxfds = sock ;
584: /*
585: me->write_sock = sock;
586: me->write_fd_state |= FD_WRITE;
587: WSAAsyncSelect (sock, HTSocketWin, HTwinMsg, me->write_fd_state);
588: */
589: # else
1.18 cvs 590: if (me->write_xtinput_id)
591: {
592: if (THD_TRACE)
593: fprintf (stderr, "Request_kill: Clearing Xtinput %lu Socket %d W\n", me->write_xtinput_id, sock);
594: XtRemoveInput (me->write_xtinput_id);
595: }
596:
597: me->write_xtinput_id =
598: XtAppAddInput (app_cont,
599: sock,
600: (XtPointer) XtInputWriteMask,
601: (XtInputCallbackProc) AHTCallback_bridge,
602: (XtPointer) XtInputWriteMask);
603:
604: if (THD_TRACE)
605: fprintf (stderr, "(BT) adding Xtinput %lu Socket %d W\n",
606: me->write_xtinput_id, sock);
1.26 cvs 607: # endif /* !_WINDOWS */
1.4 cvs 608: }
609:
1.11 cvs 610: /*----------------------------------------------------------------------
611: RequestKillWriteXtevent
612: kills any write Xt event associated with the request pointed to
613: by "me".
614: ----------------------------------------------------------------------*/
1.4 cvs 615: #ifdef __STDC__
1.7 cvs 616: static void RequestKillWriteXtevent (AHTReqContext * me)
1.4 cvs 617: #else
1.7 cvs 618: static void RequestKillWriteXtevent (me)
619: AHTReqContext *me;
620:
621: #endif /* __STDC__ */
1.4 cvs 622: {
1.26 cvs 623: # ifdef _WINDOWS
624: int new_fd;
1.25 cvs 625:
1.26 cvs 626: if (me->write_sock != INVSOC) {
627: FD_CLR (me->write_sock, &write_fds);
628: FD_CLR (me->write_sock, &all_fds);
629: me->write_sock = INVSOC;
630: WIN_ResetMaxSock();
631: /*
632: me->write_fd_state &= ~FD_WRITE;
633: new_fd = VerifySocketState (me, me->write_sock);
634: if (new_fd)
635: WSAAsyncSelect (me->write_sock, HTSocketWin, HTwinMsg, new_fd);
636: else
637: WSAAsyncSelect (me->write_sock, HTSocketWin, 0, 0);
638: me->write_sock = INVSOC;
639: */
640: }
641: # else
1.7 cvs 642: if (me->write_xtinput_id)
643: {
644: if (THD_TRACE)
645: fprintf (stderr, "Request_kill: Clearing Write Xtinputs %lu\n", me->write_xtinput_id);
646: XtRemoveInput (me->write_xtinput_id);
647: me->write_xtinput_id = (XtInputId) NULL;
648: }
1.26 cvs 649: # endif /* !_WINDOWS */
1.18 cvs 650: }
651:
652: /*----------------------------------------------------------------------
653: RequestRegisterExceptXtevent
654: Registers with Xt the except events associated with socket sock
655: ----------------------------------------------------------------------*/
656: #ifdef __STDC__
657: static void RequestRegisterExceptXtevent (AHTReqContext * me, SOCKET sock)
658: #else
659: static void RequestRegisterExceptXtevent (me, sock)
660: AHTReqContext *me;
661: SOCKET sock;
662:
663: #endif /* __STDC__ */
664: {
1.26 cvs 665: # ifdef _WINDOWS
666: FD_SET (sock, &except_fds);
667: FD_SET (sock, &all_fds);
668: me->except_sock = sock;
669: if (sock > maxfds)
670: maxfds = sock ;
671: /*
672: me->except_sock = sock;
673: me->except_fd_state |= FD_OOB;
674: WSAAsyncSelect (sock, HTSocketWin, HTwinMsg, me->except_fd_state);
675: */
676: # else
1.18 cvs 677: if (me->except_xtinput_id)
678: {
679: if (THD_TRACE)
680: fprintf (stderr, "Request_kill: Clearing Xtinput %lu Socket %d E\n", me->except_xtinput_id, sock);
681: XtRemoveInput (me->except_xtinput_id);
682: }
683:
684: me->except_xtinput_id =
685: XtAppAddInput (app_cont,
686: sock,
687: (XtPointer) XtInputExceptMask,
688: (XtInputCallbackProc) AHTCallback_bridge,
689: (XtPointer) XtInputExceptMask);
690:
691: if (THD_TRACE)
692: fprintf (stderr, "(BT) adding Xtinput %lu Socket %d E\n",
693: me->write_xtinput_id, sock);
694:
1.26 cvs 695: # endif /* !_WINDOWS */
1.4 cvs 696: }
697:
1.11 cvs 698: /*----------------------------------------------------------------------
699: RequestKillExceptXtevent
700: kills any exception Xt event associated with the request pointed to
701: by "me".
702: ----------------------------------------------------------------------*/
1.4 cvs 703: #ifdef __STDC__
1.7 cvs 704: static void RequestKillExceptXtevent (AHTReqContext * me)
1.4 cvs 705: #else
1.7 cvs 706: static void RequestKillExceptXtevent (me)
707: AHTReqContext *me;
708:
709: #endif /* __STDC__ */
1.4 cvs 710: {
1.26 cvs 711: # ifdef _WINDOWS
712: int new_fd;
713: if (me->except_sock != INVSOC) {
714: FD_CLR (me->except_sock, &except_fds);
715: FD_CLR (me->except_sock, &all_fds);
716: me->except_sock = INVSOC;
717: WIN_ResetMaxSock();
718: /*
719: me->except_fd_state &= ~FD_WRITE;
720: new_fd = VerifySocketState (me, me->except_sock);
721: if (new_fd)
722: WSAAsyncSelect (me->except_sock, HTSocketWin, HTwinMsg, new_fd);
723: else
724: WSAAsyncSelect (me->except_sock, HTSocketWin, 0, 0);
725: me->except_sock = INVSOC;
726: */
727: }
728: # else
1.7 cvs 729: if (me->except_xtinput_id)
730: {
731: if (THD_TRACE)
732: fprintf (stderr, "Request_kill: Clearing Except Xtinputs %lu\n", me->except_xtinput_id);
733: XtRemoveInput (me->except_xtinput_id);
734: me->except_xtinput_id = (XtInputId) NULL;
735: }
1.26 cvs 736: # endif /* !_WINDOWS */
1.4 cvs 737: }
1.11 cvs 738:
1.24 cvs 739: #ifdef _WINDOWS
1.26 cvs 740: #ifdef __STDC__
741: static void WIN_ResetMaxSock (void)
742: #else /* __STDC__ */
743: static void WIN_ResetMaxSock ()
744: #endif /* __STDC__ */
1.24 cvs 745: {
746: SOCKET s ;
747: SOCKET t_max = 0;
748:
749: for (s = 0 ; s <= maxfds; s++) {
1.26 cvs 750: if (FD_ISSET(s, &all_fds)) {
751: if (s > t_max)
752: t_max = s ;
753: } /* scope */
1.24 cvs 754: } /* for */
755:
756: maxfds = t_max ;
757: }
758:
1.26 cvs 759: #ifdef __STDC__
760: void WIN_ProcessSocketActivity (void)
761: #else /* __STDC__ */
762: void WIN_ProcessSocketActivity ()
763: #endif /* __STDC__ */
1.24 cvs 764: {
765: int active_sockets;
766: SOCKET s;
767: struct timeval tv;
768: int exceptions, readings, writings;
769: fd_set treadset, twriteset, texceptset ;
770:
771: treadset = read_fds;
772: twriteset = write_fds ;
773: texceptset = except_fds ;
774:
775: /* do a non-blocking select */
776: tv.tv_sec = 0;
777: tv.tv_usec = 0;
778:
1.25 cvs 779: if (maxfds == 0)
1.26 cvs 780: return; /* there are no active connections */
1.24 cvs 781:
1.26 cvs 782: active_sockets = select(maxfds+1, &treadset, &twriteset, &texceptset, (struct timeval *) &tv);
1.24 cvs 783:
1.26 cvs 784: switch (active_sockets) {
785: case 0: /* no activity - timeout - allowed */
786: case -1: /* error has occurred */
787: return;
788: default:
789: break;
1.24 cvs 790: } /* switch */
791:
792: exceptions = 0;
1.26 cvs 793: readings = 0;
794: writings = 0;
795:
796: for (s = 0 ; s <= maxfds ; s++) {
797: if (FD_ISSET(s, &texceptset))
798: exceptions++;
799: if (FD_ISSET(s, &treadset))
800: readings++;
801: if (FD_ISSET(s, &twriteset))
802: writings++;
803: } /* for */
804:
805: if (exceptions)
806: WIN_ProcessFds (&texceptset, FD_OOB);
1.24 cvs 807:
1.26 cvs 808: if (readings)
809: WIN_ProcessFds (&treadset, FD_READ);
1.24 cvs 810:
1.26 cvs 811: if (writings)
812: WIN_ProcessFds (&twriteset, FD_WRITE);
1.24 cvs 813: }
814:
1.26 cvs 815: #ifdef __STDC__
816: void WIN_InitializeSockets (void)
817: #else /* __STDC__ */
818: void WIN_InitializeSockets ()
819: #endif /* __STDC__ */
1.25 cvs 820: {
821: maxfds = 0 ;
822:
823: FD_ZERO(&read_fds);
824: FD_ZERO(&write_fds);
825: FD_ZERO(&except_fds) ;
826: FD_ZERO(&all_fds);
1.26 cvs 827: /*
1.25 cvs 828: AHTEventInit ();
1.26 cvs 829: */
1.25 cvs 830: }
831:
1.26 cvs 832: #if 0
833: #ifdef __STDC__
1.25 cvs 834: static BOOL AHTEventInit (void)
1.26 cvs 835: #else /* __STDC__ */
836: static BOOL AHTEventInit ()
837: #endif /* __STDC__ */
1.25 cvs 838: {
839: /*
840: ** We are here starting a hidden window to take care of events from
841: ** the async select() call in the async version of the event loop in
842: ** the Internal event manager (HTEvntrg.c)
843: */
1.26 cvs 844: static char className[] = "AsyncWindowClass";
845: WNDCLASS wc;
1.25 cvs 846: OSVERSIONINFO osInfo;
847: WSADATA wsadata;
848:
1.26 cvs 849: wc.style = 0;
850: wc.lpfnWndProc = (WNDPROC) ASYNCWindowProc;
851: wc.cbClsExtra = 0;
852: wc.cbWndExtra = 0;
853: wc.hIcon = 0;
854: wc.hCursor = 0;
855: wc.hbrBackground = 0;
856: wc.lpszMenuName = (LPSTR) 0;
857: wc.lpszClassName = className;
858:
859: osInfo.dwOSVersionInfoSize = sizeof (osInfo);
860: GetVersionEx (&osInfo);
861: if (osInfo.dwPlatformId == VER_PLATFORM_WIN32s || osInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
862: wc.hInstance = GetModuleHandle (NULL); /* 95 and non threaded platforms */
1.25 cvs 863: else
1.26 cvs 864: wc.hInstance = GetCurrentProcess (); /* NT and hopefully everything following */
1.25 cvs 865:
1.26 cvs 866: RegisterClass (&wc);
867: if (!(HTSocketWin = CreateWindow (className, "WWW_WIN_ASYNC", WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
868: CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, wc.hInstance,0))) {
1.25 cvs 869: return NO;
870: }
871: HTwinMsg = WM_USER; /* use first available message since app uses none */
872:
873: /*
874: ** Initialise WinSock DLL. This must also be shut down! PMH
875: */
1.26 cvs 876: if (WSAStartup (DESIRED_WINSOCK_VERSION, &wsadata)) {
877: WSACleanup ();
1.25 cvs 878: return NO;
879: }
1.26 cvs 880:
1.25 cvs 881: if (wsadata.wVersion < MINIMUM_WINSOCK_VERSION) {
1.26 cvs 882: WSACleanup ();
1.25 cvs 883: return NO;
884: }
885:
886: return YES;
887: }
888:
1.26 cvs 889: #ifdef __STDC__
890: PUBLIC LRESULT CALLBACK ASYNCWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
891: #else /* __STDC__ */
892: PUBLIC LRESULT CALLBACK ASYNCWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
893: HWND hwnd;
894: UINT uMsg;
895: WPARAM wParam;
896: LPARAM lParam;
897: #endif /* __STDC__ */
1.25 cvs 898: {
899: WORD event;
900: SOCKET sock;
901:
902: if (uMsg != HTwinMsg) /* not our async message */
1.26 cvs 903: return (DefWindowProc (hwnd, uMsg, wParam, lParam));
1.25 cvs 904:
1.26 cvs 905: event = LOWORD (lParam);
906: sock = (SOCKET) wParam;
1.25 cvs 907:
908: if (event & (FD_READ | FD_ACCEPT | FD_CLOSE))
1.26 cvs 909: WIN_AHTCallback_bridge (FD_READ, &sock);
1.25 cvs 910:
911: if (event & (FD_WRITE | FD_CONNECT))
1.26 cvs 912: WIN_AHTCallback_bridge (FD_WRITE, &sock);
1.25 cvs 913:
914: if (event & FD_OOB)
1.26 cvs 915: WIN_AHTCallback_bridge (FD_OOB, &sock);
1.25 cvs 916:
917: return (0);
918: }
1.24 cvs 919:
1.26 cvs 920: #ifdef __STDC__
1.25 cvs 921: static int VerifySocketState (AHTReqContext *me, SOCKET sock)
1.26 cvs 922: #else /* __STDC__ */
923: static int VerifySocketState (me, sock)
924: AHTReqContext* me;
925: SOCKET sock;
926: #endif /* __STDC__ */
1.25 cvs 927: {
1.26 cvs 928: int fd_state = 0;
1.25 cvs 929:
1.26 cvs 930: if (sock == me->read_sock)
931: fd_state |= me->read_fd_state;
1.25 cvs 932:
1.26 cvs 933: if (sock == me->write_sock)
934: fd_state |= me->write_fd_state;
1.25 cvs 935:
1.26 cvs 936: if (sock == me->except_sock)
937: fd_state |= me->except_fd_state;
1.25 cvs 938:
1.26 cvs 939: return (fd_state);
1.25 cvs 940: }
1.26 cvs 941: #endif /* 0 */
1.25 cvs 942:
1.26 cvs 943: #ifdef __STDC__
944: static int WIN_ProcessFds (fd_set* fdsp, SockOps ops)
945: #else /* __STDC__ */
946: static int WIN_ProcessFds (fdsp, ops)
947: fd_set* fdsp;
948: SockOps ops;
949: #endif /* __STDC__ */
950: {
951: SOCKET s ;
1.24 cvs 952:
1.26 cvs 953: for (s = 0 ; s <= maxfds; s++) {
954: if (FD_ISSET( s, fdsp)) {
955: WIN_AHTCallback_bridge (ops, &s);
956: return;
957: }
958: }
959: return HT_OK;
960: }
1.24 cvs 961: #endif /* _WINDOWS */
1.23 cvs 962: #endif /* !AMAYA_JAVA */
1.11 cvs 963:
964:
965:
966:
Webmaster