Exemple #1
0
int os2ClientSelect(int nfds, fd_set *readfds, fd_set *writefds,
        fd_set *exceptfds, struct timeval *timeout)
{
static BOOL FirstTime=TRUE;
static haveTCPIP=TRUE;
ULONG timeout_ms;
ULONG postCount, start_millis,now_millis;
char faildata[16];
struct select_data sd;
BOOL any_ready;
int np,ns, i,ready_handles,n;
APIRET rc;

sd.have_read=FALSE; sd.have_write=FALSE; 
sd.socket_nread=0; sd.socket_nwrite=0; sd.socket_ntotal=0;
sd.max_fds=31; ready_handles=0; any_ready=FALSE;
sd.pipe_ntotal=0; sd.pipe_have_write=FALSE;

if(FirstTime){
   /* First load the so32dll.dll module and get a pointer to the SELECT fn */

   if((rc=DosLoadModule(faildata,sizeof(faildata),"SO32DLL",&hmod_so32dll))!=0){
        fprintf(stderr, "Could not load module so32dll.dll, rc = %d. Error note %s\n",rc,faildata);
        haveTCPIP=FALSE;
        }
   if((rc = DosQueryProcAddr(hmod_so32dll, 0, "SELECT", (PPFN)&os2_tcp_select))!=0){
        fprintf(stderr, "Could not query address of SELECT, rc = %d.\n",rc);
        haveTCPIP=FALSE;
        }
   /* Call these a first time to set the semaphore */
    rc = DosCreateEventSem(NULL, &hPipeSem, DC_SEM_SHARED, FALSE);
    if(rc) { 
             fprintf(stderr, "Could not create event semaphore, rc=%d\n",rc);
             return(-1);
             }
    rc = DosResetEventSem(hPipeSem, &postCount);
    FirstTime = FALSE;
}

/* Set up the time delay structs */

    if(timeout!=NULL) {
	timeout_ms=timeout->tv_sec*1000+timeout->tv_usec/1000;
	}
    else { timeout_ms=1000000; }  /* This should be large enough... */
    if(timeout_ms>0) start_millis=os2_get_sys_millis();

/* Copy the masks */
    {FD_ZERO(&sd.read_copy);}
    {FD_ZERO(&sd.write_copy);}
    if(readfds!=NULL){ XFD_COPYSET(readfds,&sd.read_copy); sd.have_read=TRUE;}
    if(writefds!=NULL) {XFD_COPYSET(writefds,&sd.write_copy);sd.have_write=TRUE;}

/* And zero the original masks */
    if(sd.have_read){ FD_ZERO(readfds);}
    if(sd.have_write) {FD_ZERO(writefds);}
    if(exceptfds != NULL) {FD_ZERO(exceptfds);}

/* Now we parse the fd_sets passed to select and separate pipe/sockets */
        n = os2_parse_select(&sd,nfds);
        if(n == -1) {
           errno = EBADF;
           return (-1);
           }

/* Now we have three cases: either we have sockets, pipes, or both */
/* We handle all three cases differently to optimize things */

/* Case 1: only pipes! */
        if((sd.pipe_ntotal >0) && (!sd.socket_ntotal)){
            np = os2_check_pipes(&sd,readfds,writefds);
            if(np > 0){
               return (np);
               }
            else if (np == -1) { return(-1); }
            while(!any_ready){
                 rc = DosWaitEventSem(hPipeSem, timeout_ms);
                 if(rc == 640)  {
                     return(0);
                     }
                 if((rc != 0) && (rc != 95)) {errno= EBADF; return(-1);}
                 np = os2_check_pipes(&sd,readfds,writefds);
                 if (np > 0){
                    return(np);
                    }
                 else if (np < 0){ return(-1); }
                 }
          }

/* Case 2: only sockets. Just let the os/2 tcp select do the work */
        if((sd.socket_ntotal > 0) && (!sd.pipe_ntotal)){
                ns = os2_check_sockets(&sd, readfds, writefds, timeout_ms);
                return (ns);
                }

/* Case 3: combination of both */
        if((sd.socket_ntotal > 0) && (sd.pipe_ntotal)){
           np = os2_check_pipes(&sd,readfds,writefds);
              if(np > 0){
                 any_ready=TRUE;
                 ready_handles += np;
                 }
              else if (np == -1) { return(-1); }

           ns = os2_check_sockets(&sd,readfds,writefds, 0);
           if(ns>0){
               ready_handles+=ns;
               any_ready = TRUE;
               }
           else if (ns == -1) {return(-1);}

           while (!any_ready && timeout_ms){

                rc = DosWaitEventSem(hPipeSem, 10L);
                if(rc == 0){
                        np = os2_check_pipes(&sd,readfds,writefds);
                        if(np > 0){
                        ready_handles+=np;
                        any_ready = TRUE;
                        }
                        else if (np == -1) { 
                                return(-1); }
                      }

                 ns = os2_check_sockets(&sd,readfds,writefds,exceptfds, 0);
                 if(ns>0){
                      ready_handles+=ns;
                      any_ready = TRUE;
                     }
                 else if (ns == -1) {return(-1);}

                  if (i%8 == 0) { 
                    now_millis = os2_get_sys_millis();
                    if((now_millis-start_millis) > timeout_ms) timeout_ms = 0;
                    }
                   i++;
                  }
        }

return(ready_handles);
}
Exemple #2
0
void
FlushAllOutput(void)
{
    register int index, base;
    register fd_mask mask;      /* raphael */
    OsCommPtr oc;
    register ClientPtr client;
    Bool newoutput = NewOutputPending;

#if defined(WIN32)
    fd_set newOutputPending;
#endif

    if (FlushCallback)
        CallCallbacks(&FlushCallback, NULL);

    if (!newoutput)
        return;

    /*
     * It may be that some client still has critical output pending,
     * but he is not yet ready to receive it anyway, so we will
     * simply wait for the select to tell us when he's ready to receive.
     */
    CriticalOutputPending = FALSE;
    NewOutputPending = FALSE;

#ifndef WIN32
    for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++) {
        mask = OutputPending.fds_bits[base];
        OutputPending.fds_bits[base] = 0;
        while (mask) {
            index = ffs(mask) - 1;
            mask &= ~lowbit(mask);
            if ((index =
                 ConnectionTranslation[(base * (sizeof(fd_mask) * 8)) +
                                       index]) == 0)
                continue;
            client = clients[index];
            if (client->clientGone)
                continue;
            oc = (OsCommPtr) client->osPrivate;
            if (FD_ISSET(oc->fd, &ClientsWithInput)) {
                FD_SET(oc->fd, &OutputPending); /* set the bit again */
                NewOutputPending = TRUE;
            }
            else
                (void) FlushClient(client, oc, (char *) NULL, 0);
        }
    }
#else                           /* WIN32 */
    FD_ZERO(&newOutputPending);
    for (base = 0; base < XFD_SETCOUNT(&OutputPending); base++) {
        index = XFD_FD(&OutputPending, base);
        if ((index = GetConnectionTranslation(index)) == 0)
            continue;
        client = clients[index];
        if (client->clientGone)
            continue;
        oc = (OsCommPtr) client->osPrivate;
        if (FD_ISSET(oc->fd, &ClientsWithInput)) {
            FD_SET(oc->fd, &newOutputPending);  /* set the bit again */
            NewOutputPending = TRUE;
        }
        else
            (void) FlushClient(client, oc, (char *) NULL, 0);
    }
    XFD_COPYSET(&newOutputPending, &OutputPending);
#endif                          /* WIN32 */
}