From 46ec003667487d244828babe43884555fbe7322b Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 16 Jan 2020 22:50:18 +0100 Subject: nxagent: re-implement timeout handling Option -timeout used the screensaver facility. This patch changes that to an own timer that is independent. This effectly means we can drop most of the derived screensaving stuff in a follow-up commit. --- nx-X11/programs/Xserver/hw/nxagent/Args.c | 2 - nx-X11/programs/Xserver/hw/nxagent/Init.c | 94 +++++++++++++++++++++++++ nx-X11/programs/Xserver/hw/nxagent/Init.h | 4 ++ nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c | 12 ++-- nx-X11/programs/Xserver/hw/nxagent/Reconnect.c | 3 + nx-X11/programs/Xserver/hw/nxagent/Screen.c | 85 ++-------------------- nx-X11/programs/Xserver/hw/nxagent/Screen.h | 2 - 7 files changed, 114 insertions(+), 88 deletions(-) (limited to 'nx-X11/programs/Xserver') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c index 0336be822..44856ae19 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Args.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c @@ -2081,8 +2081,6 @@ FIXME: In rootless mode the backing-store support is not functional yet. { fprintf(stderr, "Info: Using auto-disconnect timeout of %d seconds.\n", nxagentOption(Timeout)); - - nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND; } #ifdef WATCH diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c index 0b6b36547..cf156c35f 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Init.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c @@ -40,11 +40,13 @@ is" without express or implied warranty. #include #include #include +#include #include "X.h" #include "Xproto.h" #include "screenint.h" #include "input.h" +#include "inputstr.h" #include "misc.h" #include "scrnintstr.h" #include "windowstr.h" @@ -137,6 +139,8 @@ extern void nxagentSetSelectionCallback(CallbackListPtr *callbacks, void *data, void *args); #endif +OsTimerPtr nxagentTimeoutTimer = NULL; + extern const char *nxagentProgName; void ddxInitGlobals(void) @@ -476,6 +480,96 @@ void ddxBeforeReset(void) { } +CARD32 nxagentTimeoutCallback(OsTimerPtr timer, CARD32 now, void *arg) +{ + CARD32 idle = now - lastDeviceEventTime.milliseconds; + + #ifdef TEST + fprintf(stderr, "%s: called, idle [%d] timeout [%d]\n", __func__, idle, nxagentOption(Timeout) * MILLI_PER_SECOND); + #endif + + /* Set the time to exactly match the remaining time until timeout */ + if (idle < nxagentOption(Timeout) * MILLI_PER_SECOND) + { + return nxagentOption(Timeout) * MILLI_PER_SECOND - idle; + } + + /* + * The lastDeviceEventTime is updated every time a device event is + * received, and it is used by WaitForSomething() to know when the + * SaveScreens() function should be called. This solution doesn't + * take care of a pointer button not being released, so we have to + * handle this case by ourselves. + */ + +/* +FIXME: Do we need to check the key grab if the + autorepeat feature is disabled? +*/ + if (inputInfo.pointer -> button -> buttonsDown > 0) + { + #ifdef TEST + fprintf(stderr, "%s: Prolonging timeout - there is a pointer button down.\n", __func__); + #endif + + /* wait 10s more */ + return 10 * MILLI_PER_SECOND; + } + + if (nxagentSessionState == SESSION_UP ) + { + if (nxagentClients == 0) + { + fprintf(stderr, "Info: Auto-terminating session with no client running.\n"); + raise(SIGTERM); + } + else if (nxagentOption(Persistent) == 0) + { + fprintf(stderr, "Info: Auto-terminating session with persistence not allowed.\n"); + raise(SIGTERM); + } + else + { + fprintf(stderr, "Info: Auto-suspending session with %d clients running.\n", + nxagentClients); + raise(SIGHUP); + } + } + + /* + * we do not need the timer anymore, so do not set a new time. The + * signals above will either terminate or suspend the session. At + * resume we will re-init the timer. + */ + return 0; +} + +void nxagentSetTimeoutTimer(unsigned int millis) +{ + if (nxagentOption(Timeout) > 0) + { + if (millis == 0) + { + millis = nxagentOption(Timeout) * MILLI_PER_SECOND; + } + + #ifdef TEST + fprintf(stderr, "%s: Setting auto-disconnect timeout to [%dms]\n", __func__, millis); + #endif + nxagentTimeoutTimer = TimerSet(nxagentTimeoutTimer, 0, millis, nxagentTimeoutCallback, NULL); + } +} + +void nxagentFreeTimeoutTimer(void) +{ + #ifdef TEST + fprintf(stderr, "%s: freeing timeout timer\n", __func__); + #endif + TimerFree(nxagentTimeoutTimer); + nxagentTimeoutTimer = NULL; +} + + void OsVendorInit(void) { return; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h index 246f600cf..6fa1bedd7 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Init.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h @@ -52,4 +52,8 @@ extern ServerGrabInfoRec nxagentGrabServerInfo; void nxagentNotifyConnection(int fd, int ready, void *data); +CARD32 nxagentTimeoutCallback(OsTimerPtr timer, CARD32 now, void *arg); +void nxagentSetTimeoutTimer(unsigned int millis); +void nxagentFreeTimeoutTimer(void); + #endif /* __Init_H__ */ diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c index e804acbd2..329a8cbcb 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c @@ -125,6 +125,7 @@ Equipment Corporation. #include #include "Handlers.h" #include "Keyboard.h" +#include "Init.h" const int nxagentMaxFontNames = 10000; @@ -139,12 +140,6 @@ void nxagentWaitDisplay(void); void nxagentListRemoteFonts(const char *, int); -/* - * Timeouts based on screen saver time. - */ - -int nxagentAutoDisconnectTimeout = 0; - #include "Xatom.h" /* @@ -312,6 +307,9 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio if (!(dispatchException & DE_TERMINATE)) dispatchException = 0; + + /* Init TimeoutTimer if requested */ + nxagentSetTimeoutTimer(0); #endif /* NXAGENT_SERVER */ while (!dispatchException) @@ -547,6 +545,8 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio #endif #ifdef NXAGENT_SERVER + nxagentFreeTimeoutTimer(); + /* FIXME: maybe move the code up to the KillAllClients() call to ddxBeforeReset? */ if ((dispatchException & DE_RESET) && (serverGeneration > nxagentMaxAllowedResets)) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c index cfa0ec804..98db9ca92 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c @@ -54,6 +54,7 @@ #include "Error.h" #include "Keystroke.h" #include "Utils.h" +#include "Init.h" #ifdef XKB #include "XKBsrv.h" @@ -361,6 +362,8 @@ void nxagentDisconnectSession(void) DECODE_SESSION_STATE(nxagentSessionState)); #endif + nxagentFreeTimeoutTimer(); + /* * Force an I/O error on the display * and wait until the NX transport diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index bf614ffdc..da1f0d962 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -37,12 +37,6 @@ is" without express or implied warranty. */ -/* - * Used by the auto-disconnect feature. - */ - -#include - #include "scrnintstr.h" #include "dix.h" #include "dixstruct.h" @@ -517,19 +511,6 @@ void nxagentSetScreenSaverTime(void) (long unsigned int)ScreenSaverTime, (long unsigned int)ScreenSaverInterval); #endif - /* - * More than one timeout could be used here, - * to make use of screen-saver handler not - * only for the timeout feature. In a case - * like this, the lower timeout have to be - * used as ScreenSaverTime. - */ - - if (nxagentAutoDisconnectTimeout > 0) - { - ScreenSaverTime = nxagentAutoDisconnectTimeout; - } - ScreenSaverInterval = ScreenSaverTime; #ifdef TEST @@ -550,15 +531,8 @@ static Bool nxagentSaveScreen(ScreenPtr pScreen, int what) SCREEN_SAVER_CYCLE); #endif - /* - * We need only to reset the timeouts - * in this case. - */ - if (what == SCREEN_SAVER_OFF) { - nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND; - return 1; } @@ -592,56 +566,6 @@ FIXME: Do we need to check the key grab if the return 1; } - /* - * Handling the auto-disconnect feature. - * If there is any client attached and the persisten- - * ce is allowed then leave the session running, else - * terminate it. It should use something less brutal, - * though raising a signal should ensure that the code - * follows the usual execution path. - */ - - if (nxagentOption(Timeout) > 0) - { - #ifdef TEST - fprintf(stderr, "nxagentSaveScreen: Auto-disconnect timeout was [%d].\n", - nxagentAutoDisconnectTimeout); - #endif - - nxagentAutoDisconnectTimeout -= ScreenSaverTime; - - #ifdef TEST - fprintf(stderr, "nxagentSaveScreen: Auto-disconnect timeout is [%d].\n", - nxagentAutoDisconnectTimeout); - #endif - - if (nxagentSessionState == SESSION_UP && - nxagentAutoDisconnectTimeout <= 0) - { - nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND; - - if (nxagentClients == 0) - { - fprintf(stderr, "Info: Terminating session with no client running.\n"); - - raise(SIGTERM); - } - else if (nxagentOption(Persistent) == 0) - { - fprintf(stderr, "Info: Terminating session with persistence not allowed.\n"); - - raise(SIGTERM); - } - else - { - fprintf(stderr, "Info: Suspending session with %d clients running.\n", - nxagentClients); - - raise(SIGHUP); - } - } - } - return 1; } @@ -3490,14 +3414,19 @@ Bool nxagentReconnectScreen(void *p0) XSelectInput(nxagentDisplay, nxagentDefaultWindows[0], mask); /* - * Turn off the screen-saver and reset the - * time to the next auto-disconnection. + * Turn off the screen-saver */ SaveScreens(SCREEN_SAVER_OFF, ScreenSaverActive); + /* + * reset the time to the next auto-disconnection. + */ + lastDeviceEventTime.milliseconds = GetTimeInMillis(); + nxagentSetTimeoutTimer(0); + return True; } diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h index 1b24bfbd6..104da1cea 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h @@ -57,8 +57,6 @@ extern XlibAtom nxagentReadyAtom; extern int nxagentClients; -extern int nxagentAutoDisconnectTimeout; - extern ScreenPtr nxagentDefaultScreen; extern Pixmap nxagentPixmapLogo; -- cgit v1.2.3