VOID ServiceConnection(IACP *iacp) { THREAD tid; CLIENT *client; static CHAR *fid = "ServiceConnection"; BlockOnShutdown(); /* Grab the next available CLIENT slot */ if ((client = NextAvailableClient(iacp)) == NULL) { LogMsg(LOG_WARN, "WARNING: new connection rejected (threshold reached)"); BreakNewConnection(iacp, IACP_ALERT_SERVER_BUSY); return; } /* Otherwise, leave behind a thread to deal with it */ if (!THREAD_CREATE(&tid, ServiceThread, client)) { LogMsg(LOG_ERR, "%s: %s: THREAD_CREATE: %s", client->ident, fid, strerror(errno)); BreakNewConnection(iacp, IACP_ALERT_SERVER_FAULT); return; } THREAD_DETACH(tid); }
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; }
/* * accepts new connections */ void MakeNewConnections(void) { fd_mask readyconnections; int curconn; int newconn; long connect_time; int i; ClientPtr client; OsCommPtr oc; fd_set tmask; XFD_ANDSET (&tmask, &LastSelectMask, &WellKnownConnections); readyconnections = tmask.fds_bits[0]; if (!readyconnections) return; connect_time = GetTimeInMillis(); /* kill off stragglers */ for (i = MINCLIENT; i < currentMaxClients; i++) { if ((client = clients[i]) != NullClient) { oc = (OsCommPtr) client->osPrivate; if ((oc && (oc->conn_time != 0) && (connect_time - oc->conn_time) >= TimeOutValue) || ((client->noClientException != FSSuccess) && (client->clientGone != CLIENT_GONE))) CloseDownClient(client); } } while (readyconnections) { XtransConnInfo trans_conn, new_trans_conn; int status; curconn = ffs(readyconnections) - 1; readyconnections &= ~(1 << curconn); if ((trans_conn = lookup_trans_conn (curconn)) == NULL) continue; if ((new_trans_conn = _FontTransAccept (trans_conn, &status)) == NULL) continue; newconn = _FontTransGetConnectionNumber (new_trans_conn); _FontTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); oc = (OsCommPtr) fsalloc(sizeof(OsCommRec)); if (!oc) { fsfree(oc); error_conn_max(new_trans_conn); _FontTransClose(new_trans_conn); continue; } FD_SET(newconn, &AllClients); FD_SET(newconn, &AllSockets); oc->fd = newconn; oc->trans_conn = new_trans_conn; oc->input = (ConnectionInputPtr) NULL; oc->output = (ConnectionOutputPtr) NULL; oc->conn_time = connect_time; if ((newconn < lastfdesc) && (client = NextAvailableClient((pointer) oc))) { ConnectionTranslation[newconn] = client->index; } else { error_conn_max(new_trans_conn); close_fd(oc); } } }