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