hw/xwin: Introduce winProcessXEventsTimeout() to the concept of fractions of a second

Oh this is terrible.

Currently we only compute the select timeout in whole seconds.  This means if we
have less than 1 second remaining, we select with a timeout of 0 (i.e. poll)
which causes the task to spin, burning 100% CPU for the remaining timeout (and
possibly preventing the process we are waiting for from running :S)

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
This commit is contained in:
Jon TURNEY 2012-07-21 14:13:37 +01:00
parent 23cd4d0174
commit 45c432871d

View File

@ -74,10 +74,10 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
int iConnNumber; int iConnNumber;
struct timeval tv; struct timeval tv;
int iReturn; int iReturn;
DWORD dwStopTime = (GetTickCount() / 1000) + iTimeoutSec; DWORD dwStopTime = GetTickCount() + iTimeoutSec * 1000;
/* We need to ensure that all pending events are processed */ winDebug("winProcessXEventsTimeout () - pumping X events for %d seconds\n",
XSync(pDisplay, FALSE); iTimeoutSec);
/* Get our connection number */ /* Get our connection number */
iConnNumber = ConnectionNumber(pDisplay); iConnNumber = ConnectionNumber(pDisplay);
@ -85,17 +85,24 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
/* Loop for X events */ /* Loop for X events */
while (1) { while (1) {
fd_set fdsRead; fd_set fdsRead;
long remainingTime;
/* We need to ensure that all pending events are processed */
XSync(pDisplay, FALSE);
/* Setup the file descriptor set */ /* Setup the file descriptor set */
FD_ZERO(&fdsRead); FD_ZERO(&fdsRead);
FD_SET(iConnNumber, &fdsRead); FD_SET(iConnNumber, &fdsRead);
/* Adjust timeout */ /* Adjust timeout */
tv.tv_sec = dwStopTime - (GetTickCount() / 1000); remainingTime = dwStopTime - GetTickCount();
tv.tv_usec = 0; tv.tv_sec = remainingTime / 1000;
tv.tv_usec = (remainingTime % 1000) * 1000;
winDebug("winProcessXEventsTimeout () - %d milliseconds left\n",
remainingTime);
/* Break out if no time left */ /* Break out if no time left */
if (tv.tv_sec < 0) if (remainingTime <= 0)
return WIN_XEVENTS_SUCCESS; return WIN_XEVENTS_SUCCESS;
/* Wait for an X event */ /* Wait for an X event */
@ -103,7 +110,7 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
&fdsRead, /* Read mask */ &fdsRead, /* Read mask */
NULL, /* No write mask */ NULL, /* No write mask */
NULL, /* No exception mask */ NULL, /* No exception mask */
&tv); /* No timeout */ &tv); /* Timeout */
if (iReturn < 0) { if (iReturn < 0) {
ErrorF("winProcessXEventsTimeout - Call to select () failed: %d. " ErrorF("winProcessXEventsTimeout - Call to select () failed: %d. "
"Bailing.\n", iReturn); "Bailing.\n", iReturn);
@ -116,11 +123,19 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
/* Exit when we see that server is shutting down */ /* Exit when we see that server is shutting down */
iReturn = winClipboardFlushXEvents(hwnd, iReturn = winClipboardFlushXEvents(hwnd,
iWindow, pDisplay, fUseUnicode); iWindow, pDisplay, fUseUnicode);
winDebug
("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
iReturn);
if (WIN_XEVENTS_NOTIFY == iReturn) { if (WIN_XEVENTS_NOTIFY == iReturn) {
/* Bail out if notify processed */ /* Bail out if notify processed */
return iReturn; return iReturn;
} }
} }
else {
winDebug("winProcessXEventsTimeout - Spurious wake\n");
}
} }
return WIN_XEVENTS_SUCCESS; return WIN_XEVENTS_SUCCESS;