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 */
CallbackListPtr ClientStateCallback;
OsTimerPtr dispatchExceptionTimer;
/* dispatchException & isItTimeToYield must be declared volatile since they
* are modified by signal handlers - otherwise optimizer may assume it doesn't
@ -400,6 +401,42 @@ SmartScheduleClient(void)
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
ShouldDisconnectRemainingClients(void)
{
@ -3436,6 +3473,7 @@ ProcNoOperation(ClientPtr client)
*********************/
char dispatchExceptionAtReset = DE_RESET;
int terminateDelay = 0;
void
CloseDownClient(ClientPtr client)
@ -3492,7 +3530,7 @@ CloseDownClient(ClientPtr client)
if (really_close_down) {
if (client->clientState == ClientStateRunning && nClients == 0)
dispatchException |= dispatchExceptionAtReset;
SetDispatchExceptionTimer();
client->clientState = ClientStateGone;
if (ClientStateCallback) {
@ -3523,7 +3561,7 @@ CloseDownClient(ClientPtr client)
}
if (ShouldDisconnectRemainingClients())
dispatchException |= dispatchExceptionAtReset;
SetDispatchExceptionTimer();
}
static void
@ -3725,6 +3763,7 @@ SendConnSetup(ClientPtr client, const char *reason)
clientinfo.setup = (xConnSetup *) lConnectionInfo;
CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
}
CancelDispatchExceptionTimer();
return Success;
}

View File

@ -10,3 +10,4 @@ have_eglstream=@have_eglstream@
have_initfd=true
have_listenfd=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 int currentMaxClients;
extern _X_EXPORT char dispatchExceptionAtReset;
extern _X_EXPORT int terminateDelay;
typedef int HWEventQueueType;
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
pointer acceleration should take effect).
.TP 8
.B \-terminate
.B \-terminate \fI[delay]\fP
causes the server to terminate at server reset, instead of continuing to run.
This overrides a previous
.B \-noreset
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
.B \-tst
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("-seat string seat to run on\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("ttyxx server started from init on /dev/ttyxx\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) {
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) {
noTestExtensions = TRUE;