home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / fonts / server / os / waitfor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  5.5 KB  |  206 lines

  1. /* $XConsortium: waitfor.c,v 1.8 91/09/11 11:59:39 rws Exp $ */
  2. /*
  3.  * waits for input
  4.  */
  5. /*
  6.  * Copyright 1990, 1991 Network Computing Devices;
  7.  * Portions Copyright 1987 by Digital Equipment Corporation and the
  8.  * Massachusetts Institute of Technology
  9.  *
  10.  * Permission to use, copy, modify, and distribute this protoype software
  11.  * and its documentation to Members and Affiliates of the MIT X Consortium
  12.  * any purpose and without fee is hereby granted, provided
  13.  * that the above copyright notice appear in all copies and that both that
  14.  * copyright notice and this permission notice appear in supporting
  15.  * documentation, and that the names of Network Computing Devices, Digital or
  16.  * MIT not be used in advertising or publicity pertaining to distribution of
  17.  * the software without specific, written prior permission.
  18.  *
  19.  * NETWORK COMPUTING DEVICES, DIGITAL AND MIT DISCLAIM ALL WARRANTIES WITH
  20.  * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  21.  * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT BE
  22.  * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  23.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  24.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  25.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  26.  *
  27.  * $NCDId: @(#)waitfor.c,v 4.5 1991/06/24 11:59:20 lemke Exp $
  28.  *
  29.  */
  30.  
  31. #include    <stdio.h>
  32. #include    <errno.h>
  33. #include    <sys/param.h>
  34.  
  35. #include    <X11/Xos.h>    /* strings, time, etc */
  36.  
  37. #include    "clientstr.h"
  38. #include    "globals.h"
  39. #include    "osdep.h"
  40.  
  41. extern WorkQueuePtr workQueue;
  42.  
  43. extern int  errno;
  44.  
  45. extern void MakeNewConnections();
  46. extern void FlushAllOutput();
  47.  
  48. extern long WellKnownConnections;
  49. extern long LastSelectMask[];
  50. extern long WriteMask[];
  51. extern long ClientsWithInput[];
  52. extern long ClientsWriteBlocked[];
  53. extern long AllSockets[];
  54. extern long AllClients[];
  55. extern long OutputPending[];
  56.  
  57. extern Bool AnyClientsWriteBlocked;
  58. extern Bool NewOutputPending;
  59.  
  60. extern int  ConnectionTranslation[];
  61.  
  62. long        LastReapTime;
  63.  
  64. /*
  65.  * wait_for_something
  66.  *
  67.  * server suspends until
  68.  * - data from clients
  69.  * - new client connects
  70.  * - room to write data to clients
  71.  */
  72.  
  73. WaitForSomething(pClientsReady)
  74.     int        *pClientsReady;
  75. {
  76.     struct timeval *wt,
  77.                 waittime;
  78.     long        clientsReadable[mskcnt];
  79.     long        clientsWriteable[mskcnt];
  80.     long        curclient;
  81.     int         selecterr;
  82.     long        current_time = 0;
  83.     long        timeout;
  84.     int         nready,
  85.                 i;
  86.  
  87.     while (1) {
  88.     /* handle the work Q */
  89.     if (workQueue)
  90.         ProcessWorkQueue();
  91.  
  92.     if (ANYSET(ClientsWithInput)) {
  93.         COPYBITS(ClientsWithInput, clientsReadable);
  94.         break;
  95.     }
  96.     /*
  97.      * deal with KeepAlive timeouts.  if this seems to costly, SIGALRM
  98.      * could be used, but its more dangerous since some it could catch us
  99.      * at an inopportune moment (like inside un-reentrant malloc()).
  100.      */
  101.     current_time = GetTimeInMillis();
  102.     timeout = current_time - LastReapTime;
  103.     if (timeout > ReapClientTime) {
  104.         ReapAnyOldClients();
  105.         LastReapTime = current_time;
  106.         timeout = ReapClientTime;
  107.     }
  108.     timeout = ReapClientTime - timeout;
  109.     waittime.tv_sec = timeout / MILLI_PER_SECOND;
  110.     waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
  111.         (1000000 / MILLI_PER_SECOND);
  112.     wt = &waittime;
  113.  
  114.     COPYBITS(AllSockets, LastSelectMask);
  115.  
  116.     BlockHandler((pointer) &wt, (pointer) LastSelectMask);
  117.     if (NewOutputPending)
  118.         FlushAllOutput();
  119.  
  120.     if (AnyClientsWriteBlocked) {
  121.         COPYBITS(ClientsWriteBlocked, clientsWriteable);
  122.         i = select(MAXSOCKS, (int *) LastSelectMask,
  123.                (int *) clientsWriteable, (int *) NULL, wt);
  124.     } else {
  125.         i = select(MAXSOCKS, (int *) LastSelectMask, (int *) NULL,
  126.                (int *) NULL, wt);
  127.     }
  128.     selecterr = errno;
  129.  
  130.     WakeupHandler((unsigned long) i, (pointer) LastSelectMask);
  131.     if (i <= 0) {        /* error or timeout */
  132.         CLEARBITS(clientsWriteable);
  133.         if (i < 0) {
  134.         if (selecterr == EBADF) {    /* somebody disconnected */
  135.             CheckConnections();
  136.         } else if (selecterr != EINTR) {
  137.             ErrorF("WaitForSomething: select(): errno %d\n", selecterr);
  138.         } else {
  139.             /*
  140.              * must have been broken by a signal.  go deal with any
  141.              * exception flags
  142.              */
  143.             return 0;
  144.         }
  145.         } else {        /* must have timed out */
  146.         ReapAnyOldClients();
  147.         LastReapTime = GetTimeInMillis();
  148.         }
  149.     } else {
  150.         if (AnyClientsWriteBlocked && ANYSET(clientsWriteable)) {
  151.         NewOutputPending = TRUE;
  152.         ORBITS(OutputPending, clientsWriteable, OutputPending);
  153.         UNSETBITS(ClientsWriteBlocked, clientsWriteable);
  154.         if (!ANYSET(ClientsWriteBlocked))
  155.             AnyClientsWriteBlocked = FALSE;
  156.         }
  157.         MASKANDSETBITS(clientsReadable, LastSelectMask, AllClients);
  158.         if (LastSelectMask[0] & WellKnownConnections)
  159.         MakeNewConnections();
  160.         if (ANYSET(clientsReadable))
  161.         break;
  162.  
  163.     }
  164.     }
  165.     nready = 0;
  166.  
  167.     if (ANYSET(clientsReadable)) {
  168.     ClientPtr   client;
  169.     int         conn;
  170.  
  171.     if (current_time)    /* may not have been set */
  172.         current_time = GetTimeInMillis();
  173.     for (i = 0; i < mskcnt; i++) {
  174.         while (clientsReadable[i]) {
  175.         curclient = ffs(clientsReadable[i]) - 1;
  176.         conn = ConnectionTranslation[curclient + (i << 5)];
  177.         clientsReadable[i] &= ~(1 << curclient);
  178.         client = clients[conn];
  179.         if (!client)
  180.             continue;
  181.         pClientsReady[nready++] = conn;
  182.         client->last_request_time = current_time;
  183.         client->clientGone = CLIENT_ALIVE;
  184.         }
  185.     }
  186.     }
  187.     return nready;
  188. }
  189.  
  190. #ifndef ANYSET
  191. /*
  192.  * This is not always a macro
  193.   */
  194. ANYSET(src)
  195.     long       *src;
  196. {
  197.     int         i;
  198.  
  199.     for (i = 0; i < mskcnt; i++)
  200.     if (src[i])
  201.         return (1);
  202.     return (0);
  203. }
  204.  
  205. #endif
  206.