dix: Add optional terminate delay

When the command line option "-terminate" is used, it could be
interesting to give it an optional grace period to let the Xserver
running for a little longer in case a new connection occurs.

This adds an optional parameter to the "-terminate" command line option
for this purpose.

v2: Use a delay in seconds instead of milliseconds
    (Martin Peres <martin.peres@mupuf.org>)
v3: Clarify man page entry, ensure terminateDelay is always >= 0,
    simplify TimerFree(). (Peter Hutterer <peter.hutterer@who-t.net>)

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Olivier Fourdan 2021-04-28 13:33:29 +02:00
parent e167299f60
commit 6b47321bc6
5 changed files with 52 additions and 4 deletions

View File

@ -165,6 +165,7 @@ static int nextFreeClientID; /* always MIN free client ID */
static int nClients; /* number of authorized clients */ static int nClients; /* number of authorized clients */
CallbackListPtr ClientStateCallback; CallbackListPtr ClientStateCallback;
OsTimerPtr dispatchExceptionTimer;
/* dispatchException & isItTimeToYield must be declared volatile since they /* dispatchException & isItTimeToYield must be declared volatile since they
* are modified by signal handlers - otherwise optimizer may assume it doesn't * are modified by signal handlers - otherwise optimizer may assume it doesn't
@ -400,6 +401,42 @@ SmartScheduleClient(void)
return best; return best;
} }
static CARD32
DispatchExceptionCallback(OsTimerPtr timer, CARD32 time, void *arg)
{
dispatchException |= dispatchExceptionAtReset;
/* Don't re-arm the timer */
return 0;
}
static void
CancelDispatchExceptionTimer(void)
{
TimerFree(dispatchExceptionTimer);
dispatchExceptionTimer = NULL;
}
static void
SetDispatchExceptionTimer(void)
{
/* The timer delay is only for terminate, not reset */
if (!(dispatchExceptionAtReset & DE_TERMINATE)) {
dispatchException |= dispatchExceptionAtReset;
return;
}
CancelDispatchExceptionTimer();
if (terminateDelay == 0)
dispatchException |= dispatchExceptionAtReset;
else
dispatchExceptionTimer = TimerSet(dispatchExceptionTimer,
0, terminateDelay * 1000 /* msec */,
&DispatchExceptionCallback,
NULL);
}
static Bool static Bool
ShouldDisconnectRemainingClients(void) ShouldDisconnectRemainingClients(void)
{ {
@ -3436,6 +3473,7 @@ ProcNoOperation(ClientPtr client)
*********************/ *********************/
char dispatchExceptionAtReset = DE_RESET; char dispatchExceptionAtReset = DE_RESET;
int terminateDelay = 0;
void void
CloseDownClient(ClientPtr client) CloseDownClient(ClientPtr client)
@ -3492,7 +3530,7 @@ CloseDownClient(ClientPtr client)
if (really_close_down) { if (really_close_down) {
if (client->clientState == ClientStateRunning && nClients == 0) if (client->clientState == ClientStateRunning && nClients == 0)
dispatchException |= dispatchExceptionAtReset; SetDispatchExceptionTimer();
client->clientState = ClientStateGone; client->clientState = ClientStateGone;
if (ClientStateCallback) { if (ClientStateCallback) {
@ -3523,7 +3561,7 @@ CloseDownClient(ClientPtr client)
} }
if (ShouldDisconnectRemainingClients()) if (ShouldDisconnectRemainingClients())
dispatchException |= dispatchExceptionAtReset; SetDispatchExceptionTimer();
} }
static void static void
@ -3725,6 +3763,7 @@ SendConnSetup(ClientPtr client, const char *reason)
clientinfo.setup = (xConnSetup *) lConnectionInfo; clientinfo.setup = (xConnSetup *) lConnectionInfo;
CallCallbacks((&ClientStateCallback), (void *) &clientinfo); CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
} }
CancelDispatchExceptionTimer();
return Success; return Success;
} }

View File

@ -10,3 +10,4 @@ have_eglstream=@have_eglstream@
have_initfd=true have_initfd=true
have_listenfd=true have_listenfd=true
have_verbose=true have_verbose=true
have_terminate_delay=true

View File

@ -130,6 +130,7 @@ extern _X_EXPORT ClientPtr clients[MAXCLIENTS];
extern _X_EXPORT ClientPtr serverClient; extern _X_EXPORT ClientPtr serverClient;
extern _X_EXPORT int currentMaxClients; extern _X_EXPORT int currentMaxClients;
extern _X_EXPORT char dispatchExceptionAtReset; extern _X_EXPORT char dispatchExceptionAtReset;
extern _X_EXPORT int terminateDelay;
typedef int HWEventQueueType; typedef int HWEventQueueType;
typedef HWEventQueueType *HWEventQueuePtr; typedef HWEventQueueType *HWEventQueuePtr;

View File

@ -263,11 +263,14 @@ connected to the system.
sets pointer acceleration threshold in pixels (i.e. after how many pixels sets pointer acceleration threshold in pixels (i.e. after how many pixels
pointer acceleration should take effect). pointer acceleration should take effect).
.TP 8 .TP 8
.B \-terminate .B \-terminate \fI[delay]\fP
causes the server to terminate at server reset, instead of continuing to run. causes the server to terminate at server reset, instead of continuing to run.
This overrides a previous This overrides a previous
.B \-noreset .B \-noreset
command line option. command line option.
If a delay in seconds is specified, the server waits for at least
the delay. At the end of this grace period if no client is
connected, the server terminates immediately.
.TP 8 .TP 8
.B \-tst .B \-tst
disables all testing extensions (e.g., XTEST, XTrap, XTestExtension1, RECORD). disables all testing extensions (e.g., XTEST, XTrap, XTestExtension1, RECORD).

View File

@ -561,7 +561,7 @@ UseMsg(void)
ErrorF("-s # screen-saver timeout (minutes)\n"); ErrorF("-s # screen-saver timeout (minutes)\n");
ErrorF("-seat string seat to run on\n"); ErrorF("-seat string seat to run on\n");
ErrorF("-t # default pointer threshold (pixels/t)\n"); ErrorF("-t # default pointer threshold (pixels/t)\n");
ErrorF("-terminate terminate at server reset\n"); ErrorF("-terminate [delay] terminate at server reset (optional delay in sec)\n");
ErrorF("-tst disable testing extensions\n"); ErrorF("-tst disable testing extensions\n");
ErrorF("ttyxx server started from init on /dev/ttyxx\n"); ErrorF("ttyxx server started from init on /dev/ttyxx\n");
ErrorF("v video blanking for screen-saver\n"); ErrorF("v video blanking for screen-saver\n");
@ -917,6 +917,10 @@ ProcessCommandLine(int argc, char *argv[])
} }
else if (strcmp(argv[i], "-terminate") == 0) { else if (strcmp(argv[i], "-terminate") == 0) {
dispatchExceptionAtReset = DE_TERMINATE; dispatchExceptionAtReset = DE_TERMINATE;
terminateDelay = -1;
if ((i + 1 < argc) && (isdigit(*argv[i + 1])))
terminateDelay = atoi(argv[++i]);
terminateDelay = max(0, terminateDelay);
} }
else if (strcmp(argv[i], "-tst") == 0) { else if (strcmp(argv[i], "-tst") == 0) {
noTestExtensions = TRUE; noTestExtensions = TRUE;