Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
Arquivo: io.c Projeto: theqvd/vcxsrv
void
FlushIfCriticalOutputPending(void)
{
    if (CriticalOutputPending)
        FlushAllOutput();
}
Exemplo n.º 4
0
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 ();
}