static ClientPtr AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) { OsCommPtr oc; ClientPtr client; if ( #ifndef WIN32 fd >= lastfdesc #else XFD_SETCOUNT(&AllClients) >= MaxClients #endif ) return NullClient; oc = malloc(sizeof(OsCommRec)); if (!oc) return NullClient; oc->trans_conn = trans_conn; oc->fd = fd; oc->input = (ConnectionInputPtr)NULL; oc->output = (ConnectionOutputPtr)NULL; oc->auth_id = None; oc->conn_time = conn_time; if (!(client = NextAvailableClient((pointer)oc))) { free(oc); return NullClient; } oc->local_client = ComputeLocalClient(client); #if !defined(WIN32) ConnectionTranslation[fd] = client->index; #else SetConnectionTranslation(fd, client->index); #endif if (GrabInProgress) { FD_SET(fd, &SavedAllClients); FD_SET(fd, &SavedAllSockets); } else { FD_SET(fd, &AllClients); FD_SET(fd, &AllSockets); } #ifdef DEBUG ErrorF("AllocNewConnection: client index = %d, socket fd = %d\n", client->index, fd); #endif #ifdef XSERVER_DTRACE XSERVER_CLIENT_CONNECT(client->index, fd); #endif return client; }
/*ARGSUSED*/ Bool EstablishNewConnections(ClientPtr clientUnused, pointer closure) { fd_set readyconnections; /* set of listeners that are ready */ int curconn; /* fd of listener that's ready */ register int newconn; /* fd of new client */ CARD32 connect_time; register int i; register ClientPtr client; register OsCommPtr oc; fd_set tmask; XFD_ANDSET (&tmask, (fd_set*)closure, &WellKnownConnections); XFD_COPYSET(&tmask, &readyconnections); if (!XFD_ANYSET(&readyconnections)) return TRUE; connect_time = GetTimeInMillis(); /* kill off stragglers */ for (i=1; i<currentMaxClients; i++) { if ((client = clients[i])) { oc = (OsCommPtr)(client->osPrivate); if ((oc && (oc->conn_time != 0) && (connect_time - oc->conn_time) >= TimeOutValue) || (client->noClientException != Success && !client->clientGone)) CloseDownClient(client); } } #ifndef WIN32 for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { while (readyconnections.fds_bits[i]) #else for (i = 0; i < XFD_SETCOUNT(&readyconnections); i++) #endif { XtransConnInfo trans_conn, new_trans_conn; int status; #ifndef WIN32 curconn = mffs (readyconnections.fds_bits[i]) - 1; readyconnections.fds_bits[i] &= ~((fd_mask)1 << curconn); curconn += (i * (sizeof(fd_mask)*8)); #else curconn = XFD_FD(&readyconnections, i); #endif if ((trans_conn = lookup_trans_conn (curconn)) == NULL) continue; if ((new_trans_conn = _XSERVTransAccept (trans_conn, &status)) == NULL) continue; newconn = _XSERVTransGetConnectionNumber (new_trans_conn); if (newconn < lastfdesc) { int clientid; #if !defined(WIN32) clientid = ConnectionTranslation[newconn]; #else clientid = GetConnectionTranslation(newconn); #endif if(clientid && (client = clients[clientid])) CloseDownClient(client); } _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); if (!AllocNewConnection (new_trans_conn, newconn, connect_time)) { ErrorConnMax(new_trans_conn); _XSERVTransClose(new_trans_conn); } if(trans_conn->flags & TRANS_NOXAUTH) new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH; } #ifndef WIN32 } #endif return TRUE; }
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 */ }