mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-08 23:08:04 +02:00
Improve reply processing and sync batch handling.
This commit is contained in:
parent
e43b271db3
commit
7903f53f78
3 changed files with 108 additions and 76 deletions
|
|
@ -745,13 +745,6 @@ dmxScreenEventCheckIgnore (ScreenPtr pScreen,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
dmxScreenReplyCheckIgnore (ScreenPtr pScreen,
|
||||
xcb_generic_reply_t *reply)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
dmxScreenCheckForIOError (ScreenPtr pScreen)
|
||||
{
|
||||
|
|
@ -781,7 +774,8 @@ dmxBEDispatch (ScreenPtr pScreen)
|
|||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
xcb_generic_event_t *event;
|
||||
xcb_generic_reply_t *reply;
|
||||
xcb_generic_error_t *error;
|
||||
void *reply;
|
||||
|
||||
dmxScreen->inDispatch = TRUE;
|
||||
|
||||
|
|
@ -807,28 +801,32 @@ dmxBEDispatch (ScreenPtr pScreen)
|
|||
while (dmxScreen->request.head &&
|
||||
xcb_poll_for_reply (dmxScreen->connection,
|
||||
dmxScreen->request.head->sequence,
|
||||
(void *) &reply,
|
||||
NULL))
|
||||
(void **) &reply,
|
||||
&error))
|
||||
{
|
||||
DMXSequence *head = dmxScreen->request.head;
|
||||
static xcb_generic_reply_t _default_rep = { 1 };
|
||||
DMXSequence *head = dmxScreen->request.head;
|
||||
xcb_generic_reply_t *rep = &_default_rep;
|
||||
|
||||
if (error)
|
||||
rep = (xcb_generic_reply_t *) error;
|
||||
if (reply)
|
||||
{
|
||||
if (!dmxScreenReplyCheckSync (pScreen, reply) &&
|
||||
!dmxScreenReplyCheckIgnore (pScreen, reply))
|
||||
{
|
||||
dmxLogOutput (dmxScreen,
|
||||
"unhandled reply sequence %d\n",
|
||||
reply->sequence);
|
||||
}
|
||||
rep = (xcb_generic_reply_t *) reply;
|
||||
|
||||
free (reply);
|
||||
}
|
||||
else
|
||||
if (!dmxScreenReplyCheckSync (pScreen, head->sequence, rep))
|
||||
{
|
||||
dmxLogOutput (dmxScreen, "error sequence %d\n", head->sequence);
|
||||
/* error response */
|
||||
if (rep->response_type == 0)
|
||||
dmxLogOutput (dmxScreen, "error %d sequence %d\n",
|
||||
((xcb_generic_error_t *) rep)->error_code,
|
||||
head->sequence);
|
||||
}
|
||||
|
||||
if (reply)
|
||||
free (reply);
|
||||
if (error)
|
||||
free (error);
|
||||
|
||||
dmxScreen->request.head = head->next;
|
||||
if (!dmxScreen->request.head)
|
||||
dmxScreen->request.tail = &dmxScreen->request.head;
|
||||
|
|
|
|||
137
hw/dmx/dmxsync.c
137
hw/dmx/dmxsync.c
|
|
@ -63,20 +63,73 @@ static OsTimerPtr dmxSyncTimer;
|
|||
static int dmxSyncPending = 0;
|
||||
static int dmxSyncRequest = 0;
|
||||
|
||||
/* dispatch all pending back-end server responses */
|
||||
void
|
||||
dmxDispatch (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
if (dmxScreens[i].alive)
|
||||
dmxBEDispatch (screenInfo.screens[i]);
|
||||
}
|
||||
|
||||
/* non-blocking wait for back-end server response. returns 0 when no
|
||||
more reponses can arrive */
|
||||
int
|
||||
dmxWaitForResponse (void)
|
||||
{
|
||||
fd_set rfds;
|
||||
int nfd = 0;
|
||||
int i, ret = 0;
|
||||
|
||||
FD_ZERO (&rfds);
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
{
|
||||
if (dmxScreens[i].beDisplay && dmxScreens[i].alive)
|
||||
{
|
||||
xcb_flush (dmxScreens[i].connection);
|
||||
|
||||
if (xcb_connection_has_error (dmxScreens[i].connection))
|
||||
{
|
||||
dmxScreens[i].alive = FALSE;
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FD_SET (dmxScreens[i].fd, &rfds);
|
||||
|
||||
if (dmxScreens[i].fd > nfd)
|
||||
nfd = dmxScreens[i].fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && nfd)
|
||||
{
|
||||
do {
|
||||
ret = select (nfd + 1, &rfds, 0, 0, 0);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
/* screens with broken connections are detached in the
|
||||
block handler */
|
||||
}
|
||||
|
||||
return nfd;
|
||||
}
|
||||
|
||||
static void dmxDoSync(DMXScreenInfo *dmxScreen)
|
||||
{
|
||||
dmxScreen->needsSync = FALSE;
|
||||
|
||||
if (!dmxScreen->beDisplay)
|
||||
{
|
||||
dmxScreen->sync.sequence = 0;
|
||||
if (!dmxScreen->alive)
|
||||
return; /* FIXME: Is this correct behavior for sync stats? */
|
||||
}
|
||||
|
||||
if (dmxScreen->sync.sequence)
|
||||
return;
|
||||
|
||||
dmxScreen->sync = xcb_get_input_focus_unchecked (dmxScreen->connection);
|
||||
dmxScreen->sync = xcb_get_input_focus (dmxScreen->connection);
|
||||
dmxAddSequence (&dmxScreen->request, dmxScreen->sync.sequence);
|
||||
dmxSyncRequest++;
|
||||
}
|
||||
|
|
@ -85,54 +138,26 @@ static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
|
|||
{
|
||||
int i;
|
||||
|
||||
while (dmxSyncRequest)
|
||||
/* make sure TimerFree is not called from while waiting for
|
||||
pending replies */
|
||||
dmxSyncTimer = NULL;
|
||||
|
||||
while (dmxSyncRequest && dmxWaitForResponse ())
|
||||
{
|
||||
fd_set rfds;
|
||||
int ret, fd = 0;
|
||||
dmxDispatch ();
|
||||
|
||||
/* timer expired and there is pending sync replies that need
|
||||
to be waited for before we can allow further processing
|
||||
of client requests */
|
||||
|
||||
FD_ZERO (&rfds);
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
{
|
||||
if (dmxScreens[i].beDisplay)
|
||||
if (!dmxScreens[i].alive)
|
||||
{
|
||||
xcb_flush (dmxScreens[i].connection);
|
||||
if (xcb_connection_has_error (dmxScreens[i].connection))
|
||||
/* remove pending replies from disconnected screens */
|
||||
if (dmxScreens[i].sync.sequence)
|
||||
{
|
||||
if (dmxScreens[i].sync.sequence)
|
||||
{
|
||||
dmxScreens[i].sync.sequence = 0;
|
||||
dmxSyncRequest--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FD_SET (dmxScreens[i].fd, &rfds);
|
||||
|
||||
if (dmxScreens[i].fd > fd)
|
||||
fd = dmxScreens[i].fd;
|
||||
dmxScreens[i].sync.sequence = 0;
|
||||
dmxSyncRequest--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd)
|
||||
{
|
||||
do {
|
||||
ret = select (fd + 1, &rfds, 0, 0, 0);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
}
|
||||
|
||||
dmxSyncPending++;
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++)
|
||||
if (dmxScreens[i].beDisplay)
|
||||
dmxBEDispatch (screenInfo.screens[i]);
|
||||
|
||||
dmxSyncPending--;
|
||||
}
|
||||
|
||||
if (dmxSyncPending)
|
||||
|
|
@ -144,11 +169,12 @@ static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
|
|||
dmxSyncPending = 0;
|
||||
|
||||
if (dmxSyncRequest)
|
||||
{
|
||||
dmxSyncTimer = timer;
|
||||
return dmxSyncInterval;
|
||||
}
|
||||
}
|
||||
|
||||
dmxSyncTimer = NULL;
|
||||
|
||||
return 0; /* Do not place on queue again */
|
||||
}
|
||||
|
||||
|
|
@ -246,8 +272,11 @@ void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
|
|||
}
|
||||
else if (!dmxSyncTimer)
|
||||
{
|
||||
dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
|
||||
dmxSyncCallback, NULL);
|
||||
dmxSyncTimer = TimerSet (dmxSyncTimer,
|
||||
0,
|
||||
dmxSyncInterval,
|
||||
dmxSyncCallback,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -257,19 +286,22 @@ void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
|
|||
* up-to-date. */
|
||||
if (dmxScreen)
|
||||
{
|
||||
dmxDoSync(dmxScreen);
|
||||
dmxSyncCallback(NULL, 0, NULL);
|
||||
dmxDoSync (dmxScreen);
|
||||
dmxSyncCallback (NULL, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* error or reply doesn't matter, all we need is some response
|
||||
from the back-end server */
|
||||
Bool
|
||||
dmxScreenReplyCheckSync (ScreenPtr pScreen,
|
||||
unsigned int sequence,
|
||||
xcb_generic_reply_t *reply)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
if (reply->sequence != dmxScreen->sync.sequence)
|
||||
if (sequence != dmxScreen->sync.sequence)
|
||||
return FALSE;
|
||||
|
||||
dmxScreen->sync.sequence = 0;
|
||||
|
|
@ -277,7 +309,7 @@ dmxScreenReplyCheckSync (ScreenPtr pScreen,
|
|||
dmxSyncRequest--;
|
||||
if (dmxSyncRequest == 0)
|
||||
{
|
||||
if (dmxSyncPending == 0)
|
||||
if (dmxSyncPending == 0 && dmxSyncTimer)
|
||||
{
|
||||
TimerFree (dmxSyncTimer);
|
||||
dmxSyncTimer = NULL;
|
||||
|
|
@ -286,4 +318,3 @@ dmxScreenReplyCheckSync (ScreenPtr pScreen,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,9 +37,12 @@
|
|||
#ifndef _DMXSYNC_H_
|
||||
#define _DMXSYNC_H_
|
||||
|
||||
extern void dmxDispatch (void);
|
||||
extern int dmxWaitForResponse (void);
|
||||
extern void dmxSyncActivate(const char *interval);
|
||||
extern void dmxSyncInit(void);
|
||||
extern void dmxSync(DMXScreenInfo *dmxScreen, Bool now);
|
||||
extern Bool dmxScreenReplyCheckSync (ScreenPtr pScreen,
|
||||
unsigned int sequence,
|
||||
xcb_generic_reply_t *reply);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue