int WaitForSomething(int *pClientsReady) { struct timeval *wt, waittime; fd_set clientsReadable; fd_set clientsWriteable; long curclient; int selecterr; long current_time = 0; long timeout; int nready, i; while (1) { /* handle the work Q */ if (workQueue) ProcessWorkQueue(); if (XFD_ANYSET(&ClientsWithInput)) { XFD_COPYSET(&ClientsWithInput, &clientsReadable); break; } /* * deal with KeepAlive timeouts. if this seems to costly, SIGALRM * could be used, but its more dangerous since some it could catch us * at an inopportune moment (like inside un-reentrant malloc()). */ current_time = GetTimeInMillis(); timeout = current_time - LastReapTime; if (timeout > ReapClientTime) { ReapAnyOldClients(); LastReapTime = current_time; timeout = ReapClientTime; } timeout = ReapClientTime - timeout; waittime.tv_sec = timeout / MILLI_PER_SECOND; waittime.tv_usec = (timeout % MILLI_PER_SECOND) * (1000000 / MILLI_PER_SECOND); wt = &waittime; XFD_COPYSET(&AllSockets, &LastSelectMask); BlockHandler(&wt, (pointer) &LastSelectMask); if (NewOutputPending) FlushAllOutput(); if (AnyClientsWriteBlocked) { XFD_COPYSET(&ClientsWriteBlocked, &clientsWriteable); i = Select(MAXSOCKS, &LastSelectMask, &clientsWriteable, NULL, wt); } else { i = Select(MAXSOCKS, &LastSelectMask, NULL, NULL, wt); } selecterr = errno; WakeupHandler(i, (unsigned long *) &LastSelectMask); if (i <= 0) { /* error or timeout */ FD_ZERO(&clientsWriteable); if (i < 0) { if (selecterr == EBADF) { /* somebody disconnected */ CheckConnections(); } else if (selecterr != EINTR) { ErrorF("WaitForSomething: select(): errno %d\n", selecterr); } else { /* * must have been broken by a signal. go deal with any * exception flags */ return 0; } } else { /* must have timed out */ ReapAnyOldClients(); LastReapTime = GetTimeInMillis(); } } else { if (AnyClientsWriteBlocked && XFD_ANYSET(&clientsWriteable)) { NewOutputPending = TRUE; XFD_ORSET(&OutputPending, &clientsWriteable, &OutputPending); XFD_UNSET(&ClientsWriteBlocked, &clientsWriteable); if (!XFD_ANYSET(&ClientsWriteBlocked)) AnyClientsWriteBlocked = FALSE; } XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); if (LastSelectMask.fds_bits[0] & WellKnownConnections.fds_bits[0]) MakeNewConnections(); if (XFD_ANYSET(&clientsReadable)) break; } } nready = 0; if (XFD_ANYSET(&clientsReadable)) { ClientPtr client; int conn; if (current_time) /* may not have been set */ current_time = GetTimeInMillis(); for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { while (clientsReadable.fds_bits[i]) { curclient = xfd_ffs(clientsReadable.fds_bits[i]) - 1; conn = ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))]; clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient); client = clients[conn]; if (!client) continue; pClientsReady[nready++] = conn; client->last_request_time = current_time; client->clientGone = CLIENT_ALIVE; if (nready >= MaxClients) { /* pClientsReady buffer has no more room, get the rest on the next time through select() loop */ return nready; } } } } return nready; }
Dispatch() { int nready, result; int *clientReady; ClientPtr client; int op; nextFreeClientID = MINCLIENT; nClients = 0; clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients); if (!clientReady) return; while (1) { /* wait for something */ nready = WaitForSomething(clientReady); while (!dispatchException && (--nready >= 0)) { client = currentClient = clients[clientReady[nready]]; /* Client can be NULL if CloseDownClient() is called during this dispatchException loop. */ if (client == (ClientPtr)NULL) continue; isItTimeToYield = FALSE; while (!isItTimeToYield) { result = ReadRequest(client); if (result <= 0) { if (result < 0) CloseDownClient(client); break; } client->sequence++; if (result > (MAX_REQUEST_SIZE << 2)) result = FSBadLength; else { op = MAJOROP; if (op >= NUM_PROC_VECTORS) result = ProcBadRequest (client); else result = (*client->requestVector[op]) (client); } if (result != FSSuccess) { if (client->noClientException != FSSuccess) CloseDownClient(client); break; } } FlushAllOutput (); } /* reset if server is a drone and has run out of clients */ if (drone_server && nClients == 0) { dispatchException |= DE_RESET; } if (dispatchException) { /* re-read the config file */ if (dispatchException & DE_RECONFIG) { NoticeF("Re-reading config file\n"); if (ReadConfigFile(configfilename) != FSSuccess) ErrorF("couldn't parse config file\n"); SetConfigValues(); dispatchException &= ~DE_RECONFIG; } /* flush all the caches */ if (dispatchException & DE_FLUSH) { NoticeF("flushing all caches\n"); CacheReset(); dispatchException &= ~DE_FLUSH; } /* reset */ if (dispatchException & DE_RESET) { NoticeF("resetting\n"); break; } /* die *now* */ if (dispatchException & DE_TERMINATE) { NoticeF("terminating\n"); kill_all_clients(); exit(0); break; } } } kill_all_clients(); dispatchException = 0; }
void FlushIfCriticalOutputPending(void) { if (CriticalOutputPending) FlushAllOutput(); }
static void xf86SetRootClip (ScreenPtr pScreen, Bool enable) { #if XORG < 19 WindowPtr pWin = WindowTable[pScreen->myNum]; #else WindowPtr pWin = pScreen->root; #endif WindowPtr pChild; Bool WasViewable = (Bool)(pWin->viewable); Bool anyMarked = FALSE; #if XORG < 110 RegionPtr pOldClip = NULL, bsExposed; #ifdef DO_SAVE_UNDERS Bool dosave = FALSE; #endif #endif WindowPtr pLayerWin; BoxRec box; if (WasViewable) { for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { (void) (*pScreen->MarkOverlappedWindows)(pChild, pChild, &pLayerWin); } (*pScreen->MarkWindow) (pWin); anyMarked = TRUE; if (pWin->valdata) { if (HasBorder (pWin)) { RegionPtr borderVisible; borderVisible = REGION_CREATE(pScreen, NullBox, 1); REGION_SUBTRACT(pScreen, borderVisible, &pWin->borderClip, &pWin->winSize); pWin->valdata->before.borderVisible = borderVisible; } pWin->valdata->before.resized = TRUE; } } /* * Use REGION_BREAK to avoid optimizations in ValidateTree * that assume the root borderClip can't change well, normally * it doesn't...) */ if (enable) { box.x1 = 0; box.y1 = 0; box.x2 = pScreen->width; box.y2 = pScreen->height; REGION_INIT (pScreen, &pWin->winSize, &box, 1); REGION_INIT (pScreen, &pWin->borderSize, &box, 1); if (WasViewable) REGION_RESET(pScreen, &pWin->borderClip, &box); pWin->drawable.width = pScreen->width; pWin->drawable.height = pScreen->height; REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); } else { REGION_EMPTY(pScreen, &pWin->borderClip); REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); } ResizeChildrenWinSize (pWin, 0, 0, 0, 0); if (WasViewable) { #if XORG < 110 if (pWin->backStorage) { pOldClip = REGION_CREATE(pScreen, NullBox, 1); REGION_COPY(pScreen, pOldClip, &pWin->clipList); } #endif if (pWin->firstChild) { anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, pWin->firstChild, (WindowPtr *)NULL); } else { (*pScreen->MarkWindow) (pWin); anyMarked = TRUE; } #if XORG < 110 && defined(DO_SAVE_UNDERS) if (DO_SAVE_UNDERS(pWin)) { dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin); } #endif /* DO_SAVE_UNDERS */ if (anyMarked) (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); } #if XORG < 110 if (pWin->backStorage && ((pWin->backingStore == Always) || WasViewable)) { if (!WasViewable) pOldClip = &pWin->clipList; /* a convenient empty region */ bsExposed = (*pScreen->TranslateBackingStore) (pWin, 0, 0, pOldClip, pWin->drawable.x, pWin->drawable.y); if (WasViewable) REGION_DESTROY(pScreen, pOldClip); if (bsExposed) { RegionPtr valExposed = NullRegion; if (pWin->valdata) valExposed = &pWin->valdata->after.exposed; (*pScreen->WindowExposures) (pWin, valExposed, bsExposed); if (valExposed) REGION_EMPTY(pScreen, valExposed); REGION_DESTROY(pScreen, bsExposed); } } #endif if (WasViewable) { if (anyMarked) (*pScreen->HandleExposures)(pWin); #if XORG < 110 && defined(DO_SAVE_UNDERS) if (dosave) (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin); #endif /* DO_SAVE_UNDERS */ if (anyMarked && pScreen->PostValidateTree) (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); } if (pWin->realized) WindowsRestructured (); FlushAllOutput (); }