From 366067b7c3678148bff858239e3c16e0d6043e03 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Thu, 16 Feb 2017 15:21:34 +0000 Subject: dix/os: backport various signal handling and smart scheduler changes from X.org Backported from X.org: commit 6178b1c91cfc9e860914acc6f0be2f2d2e07a124 Author: Adam Jackson Date: Tue Jun 7 15:52:11 2016 -0400 dix: Use OsSignal() not signal() As the man page for the latter states: The effects of signal() in a multithreaded process are unspecified. We already have an interface to call sigaction() instead, use it. Signed-off-by: Adam Jackson Reviewed-by: Keith Packard commit e10ba9e4b52269b2ac75c4802dce4ca47d169657 Author: Keith Packard Date: Wed Nov 11 22:02:01 2015 -0800 Remove non-smart scheduler. Don't require setitimer. This allows the server to call GetTimeInMillis() after each request is processed to avoid needing setitimer. -dumbSched now turns off the setitimer. Reviewed-by: Adam Jackson Signed-off-by: Keith Packard commit 1f915e8b524dd02011158aa038935970684c7630 Author: Daniel Drake Date: Wed May 20 13:16:12 2015 -0600 Keep SIGALRM restart flag after Popen Commit 94ab7455 added SA_RESTART to the SIGALRM handler. However, the Popen code tears down and recreates the SIGALRM handler via OsSignal(), and this flag is dropped at this time. Clean the code to use just a single codepath for creating this signal handler, always applying SA_RESTART. [ajax: Fixed commit id] Reviewed-by: Adam Jackson Signed-off-by: Daniel Drake commit 94ab7455abc213fc96760e29ab2e943ec682fb22 Author: Daniel Drake Date: Tue May 12 16:39:22 2015 -0600 Allow system call restarts upon signal interruption The X server frequently deals with SIGIO and SIGALRM interruptions. If process execution is inside certain blocking system calls when these signals arrive, e.g. with the kernel blocked on a contended semaphore, the system calls will be interrupted. Some system calls are automatically restartable (the kernel re-executes them with the same parameters once the signal handler returns) but only if the signal handler allows it. Set SA_RESTART on the signal handlers to enable this convenient behaviour. Reviewed-by: Adam Jackson Signed-off-by: Daniel Drake commit a6c71ce5d2d2fe89e07a2ef5041c915acc3dc686 Author: Tiago Vignatti Date: Mon Mar 28 19:21:28 2011 +0300 os: fix memory and fd leaks in Popen Signed-off-by: Tiago Vignatti Reviewed-by: Peter Hutterer Reviewed-by: Nicolas Peninguy commit c9051b684b524549eab6d5b88ee3e195a6f6fbe8 Author: Alan Coopersmith Date: Wed Nov 5 18:25:57 2008 -0800 Use OsSignal in Popen/Pclose to avoid SysV signal() stupidity commit 0e9ef65fa583bf2393dd0fda82df6f092387b425 Author: Keith Packard Date: Wed Nov 7 16:33:10 2007 -0800 Don't frob timers unless SmartSchedule is running commit 2338d5c9914e2a43c3a4f7ee0f4355ad0a1ad9e7 Author: Arjan van de Ven Date: Sun Oct 28 09:37:52 2007 +0100 reduce wakeups from smart scheduler The smart scheduler itimer currently always fires after each request (which in turn causes the CPU to wake out of idle, burning precious power). Rather than doing this, just stop the timer before going into the select() portion of the WaitFor loop. It's a cheap system call, and it will only get called if there's no more commands batched up from the active fd. This change also allows some of the functions to be simplified; setitimer() will only fail if it's passed invalid data, and we don't do that... so make it void and remove all the conditional code that deals with failure. The change also allows us to remove a few variables that were used for housekeeping between the signal handler and the main loop. Signed-off-by: Keith Packard **Note**: The above change also required ABI changes in hw/nxagent/. commit abe0a51f3f790f8c055289465e130177c4b647cc Author: Ben Byer Date: Fri Sep 21 17:07:36 2007 -0700 So, like, checking return codes of system calls (signal, etc) is good. Also, only restore an old signal handler if one was actually set (prevents the server from dying on OS X). commit 6da39c67905500ab2db00a45cda4a9f756cdde96 Author: Eric Anholt Date: Wed Sep 12 13:23:13 2007 +0000 Fix build on FreeBSD after Popen changes. commit a5b8053606d6e786cdcf6734f271acc05f9cc588 Author: Adam Jackson Date: Tue Sep 11 11:37:06 2007 -0400 Ignore - not just block - SIGALRM around Popen()/Pclose(). Because our "popen" implementation uses stdio, and because nobody's stdio library is capable of surviving signals, we need to make absolutely sure that we hide the SIGALRM from the smart scheduler. Otherwise, when you open a menu in openoffice, and it recompiles XKB to deal with the accelerators, and you popen xkbcomp because we suck, then the scheduler will tell you you're taking forever doing something stupid, and the wait() code will get confused, and input will hang and your CPU usage slams to 100%. Down, not across. Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/utils.c | 164 +++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 71 deletions(-) (limited to 'nx-X11/programs/Xserver/os/utils.c') diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index af793454f..25cbb1e87 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -290,7 +290,8 @@ OsSignal(sig, handler) sigaddset(&act.sa_mask, sig); act.sa_flags = 0; act.sa_handler = handler; - sigaction(sig, &act, &oact); + if (sigaction(sig, &act, &oact)) + perror("sigaction"); return oact.sa_handler; #endif } @@ -1026,10 +1027,12 @@ ProcessCommandLine(int argc, char *argv[]) i = skip - 1; } #endif +#if HAVE_SETITIMER else if ( strcmp( argv[i], "-dumbSched") == 0) { - SmartScheduleDisable = TRUE; + SmartScheduleSignalEnable = FALSE; } +#endif else if ( strcmp( argv[i], "-schedInterval") == 0) { if (++i < argc) @@ -1353,30 +1356,15 @@ XNFstrdup(const char *s) return ret; } -unsigned long SmartScheduleIdleCount; -Bool SmartScheduleIdle; -Bool SmartScheduleTimerStopped; - -#ifdef SIGVTALRM -#define SMART_SCHEDULE_POSSIBLE -#endif - -#ifdef SMART_SCHEDULE_POSSIBLE -#define SMART_SCHEDULE_SIGNAL SIGALRM -#define SMART_SCHEDULE_TIMER ITIMER_REAL -#endif - -#ifdef NX_TRANS_SOCKET void SmartScheduleStopTimer (void) -#else -static void -SmartScheduleStopTimer (void) -#endif { -#ifdef SMART_SCHEDULE_POSSIBLE +#if HAVE_SETITIMER struct itimerval timer; + if (!SmartScheduleSignalEnable) + return; + #ifdef NX_TRANS_TEST fprintf(stderr, "SmartScheduleStopTimer: Stopping timer.\n"); #endif @@ -1386,96 +1374,101 @@ SmartScheduleStopTimer (void) timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 0; (void) setitimer (ITIMER_REAL, &timer, 0); - SmartScheduleTimerStopped = TRUE; #endif } -Bool +void SmartScheduleStartTimer (void) { -#ifdef SMART_SCHEDULE_POSSIBLE +#if HAVE_SETITIMER struct itimerval timer; - #ifdef NX_TRANS_SOCKET - - if (SmartScheduleDisable) - { - return FALSE; - } - - #endif + if (!SmartScheduleSignalEnable) + return; #ifdef NX_TRANS_TEST fprintf(stderr, "SmartScheduleStartTimer: Starting timer with [%ld] ms.\n", SmartScheduleInterval); #endif - SmartScheduleTimerStopped = FALSE; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = SmartScheduleInterval * 1000; timer.it_value.tv_sec = 0; timer.it_value.tv_usec = SmartScheduleInterval * 1000; - return setitimer (ITIMER_REAL, &timer, 0) >= 0; + setitimer (ITIMER_REAL, &timer, 0); #endif - return FALSE; } -#ifdef SMART_SCHEDULE_POSSIBLE +#if HAVE_SETITIMER static void SmartScheduleTimer (int sig) { - int olderrno = errno; - SmartScheduleTime += SmartScheduleInterval; #ifdef NX_TRANS_TEST fprintf(stderr, "SmartScheduleTimer: Got timer with time [%ld] ms.\n", SmartScheduleTime); #endif - - if (SmartScheduleIdle) - { - SmartScheduleStopTimer (); - } - errno = olderrno; } -#endif -Bool -SmartScheduleInit (void) +int +SmartScheduleEnable (void) { -#ifdef SMART_SCHEDULE_POSSIBLE + int ret = 0; struct sigaction act; - if (SmartScheduleDisable) - return TRUE; - + if (!SmartScheduleSignalEnable) + return 0; + #ifdef NX_TRANS_TEST - fprintf(stderr, "SmartScheduleInit: Initializing the smart scheduler.\n"); + fprintf(stderr, "SmartScheduleEnable: Enabling the smart scheduler.\n"); #endif - bzero ((char *) &act, sizeof(struct sigaction)); + memset((char *) &act, 0, sizeof(struct sigaction)); /* Set up the timer signal function */ + act.sa_flags = SA_RESTART; act.sa_handler = SmartScheduleTimer; sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SMART_SCHEDULE_SIGNAL); - if (sigaction (SMART_SCHEDULE_SIGNAL, &act, 0) < 0) - { - perror ("sigaction for smart scheduler"); - return FALSE; - } - /* Set up the virtual timer */ - if (!SmartScheduleStartTimer ()) - { - perror ("scheduling timer"); - return FALSE; + sigaddset (&act.sa_mask, SIGALRM); + ret = sigaction(SIGALRM, &act, 0); + return ret; +} + +static int +SmartSchedulePause(void) +{ + int ret = 0; + struct sigaction act; + + if (!SmartScheduleSignalEnable) + return 0; + + #ifdef NX_TRANS_TEST + fprintf(stderr, "SmartSchedulePause: Pausing the smart scheduler.\n"); + #endif + + memset((char *) &act, 0, sizeof(struct sigaction)); + + act.sa_handler = SIG_IGN; + sigemptyset(&act.sa_mask); + ret = sigaction(SIGALRM, &act, 0); + return ret; +} +#endif + +void +SmartScheduleInit(void) +{ +#if HAVE_SETITIMER + #ifdef NX_TRANS_TEST + fprintf(stderr, "SmartScheduleInit: Initializing the smart scheduler.\n"); + #endif + + if (SmartScheduleEnable() < 0) { + perror("sigaction for smart scheduler"); + SmartScheduleSignalEnable = FALSE; } - /* stop the timer and wait for WaitForSomething to start it */ - SmartScheduleStopTimer (); - return TRUE; -#else - return FALSE; #endif } @@ -1558,7 +1551,11 @@ System(char *command) return(1); #ifdef SIGCHLD - csig = signal(SIGCHLD, SIG_DFL); + csig = OsSignal(SIGCHLD, SIG_DFL); + if (csig == SIG_ERR) { + perror("signal"); + return -1; + } #endif #ifdef DEBUG @@ -1596,7 +1593,10 @@ System(char *command) #endif #ifdef SIGCHLD - signal(SIGCHLD, csig); + if (OsSignal(SIGCHLD, csig) == SIG_ERR) { + perror("signal"); + return -1; + } #endif return p == -1 ? -1 : status; @@ -1629,6 +1629,17 @@ Popen(char *command, char *type) return NULL; } + /* Ignore the smart scheduler while this is going on */ +#if HAVE_SETITIMER + if (SmartSchedulePause() < 0) { + close(pdes[0]); + close(pdes[1]); + free(cur); + perror("signal"); + return NULL; + } +#endif + #ifdef NX_TRANS_EXIT if (OsVendorStartRedirectErrorFProc != NULL) { OsVendorStartRedirectErrorFProc(); @@ -1640,6 +1651,10 @@ Popen(char *command, char *type) close(pdes[0]); close(pdes[1]); free(cur); +#if HAVE_SETITIMER + if (SmartScheduleEnable() < 0) + perror("signal"); +#endif #ifdef NX_TRANS_EXIT if (OsVendorEndRedirectErrorFProc != NULL) { OsVendorEndRedirectErrorFProc(); @@ -1714,6 +1729,13 @@ Popen(char *command, char *type) OsReleaseSignals (); #endif +#if HAVE_SETITIMER + if (SmartScheduleEnable() < 0) { + perror("signal"); + return NULL; + } +#endif + execl("/bin/sh", "sh", "-c", command, (char *)NULL); _exit(127); } -- cgit v1.2.3 From 89496d987dc6a21250c9fdda2cd3668516061f5c Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Wed, 15 Mar 2017 14:10:24 +0000 Subject: os: Add -displayfd option commit 88bacc49f06da5927f716869f5a32672a8297ed0 Author: Chase Douglas Date: Wed Apr 4 15:29:42 2012 -0700 os: Add -displayfd option This option specifies a file descriptor in the launching process. X will scan for an available display number and write that number back to the launching process, at the same time as SIGUSR1 generation. This means display managers don't need to guess at available display numbers. As a consequence, if X fails to start when using -displayfd, it's not because the display was in use, so there's no point in retrying the X launch on a higher display number. Signed-off-by: Adam Jackson Signed-off-by: Chase Douglas Reviewed-by: Julien Cristau Tested-by: Julien Cristau Reviewed-by: Alan Coopersmith Signed-off-by: Peter Hutterer Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/utils.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'nx-X11/programs/Xserver/os/utils.c') diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index 25cbb1e87..929549168 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -780,6 +780,16 @@ ProcessCommandLine(int argc, char *argv[]) else UseMsg(); } + else if (strcmp(argv[i], "-displayfd") == 0) { + if (++i < argc) { + displayfd = atoi(argv[i]); + display = NULL; + nolock = TRUE; + } + else + UseMsg(); + } + #ifdef DPMSExtension else if ( strcmp( argv[i], "dpms") == 0) DPMSEnabledSwitch = TRUE; -- cgit v1.2.3 From e8bc4c7e2f42d21e41328b68d5dc2a15db73d47a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 15 Mar 2017 14:56:17 +0000 Subject: os: Add a mechanism to prevent creating any listen sockets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 44fe1b8ea284df6bbaef67e246016d104665b2fe Author: Kristian Høgsberg Date: Wed Mar 19 14:03:13 2014 -0700 os: Add a mechanism to prevent creating any listen sockets A socket-activated server will receive its listening sockets from the parent process and should not create its own sockets. This patch introduces a NoListen flag that can be set by a DDX to prevent the server from creating the sockets. When NoListen is enabled, we also disable the server lock checking, since the parent process is responsible for checking the lock before picking the display name and creating the sockets. Signed-off-by: Kristian Høgsberg Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nx-X11/programs/Xserver/os/utils.c') diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index 929549168..74acb53ef 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -338,7 +338,7 @@ LockServer(void) int len; char port[20]; - if (nolock) return; + if (nolock || NoListenAll) return; /* * Path names */ @@ -464,7 +464,7 @@ LockServer(void) void UnlockServer(void) { - if (nolock) return; + if (nolock || NoListenAll) return; if (!StillLocking){ -- cgit v1.2.3 From 506aedbcd3f56cf255b397f1e586f16f97e3619a Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 15 Mar 2017 15:00:27 +0000 Subject: Xserver/os/utils.c: Add NXAGENT_SERVER specific -nolisten parameter: ANY. This allows us to trigger the NoListenAll := TRUE code path in nxagent. --- nx-X11/programs/Xserver/os/utils.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'nx-X11/programs/Xserver/os/utils.c') diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index 74acb53ef..dce04e942 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -902,6 +902,11 @@ ProcessCommandLine(int argc, char *argv[]) else if ( strcmp( argv[i], "-nolisten") == 0) { if(++i < argc) { +#ifdef NXAGENT_SERVER + if (strcmp( argv[i], "ANY" ) == 0) + NoListenAll = TRUE; + else +#endif /* NXAGENT_SERVER */ if (_XSERVTransNoListen(argv[i])) FatalError ("Failed to disable listen for %s transport", argv[i]); -- cgit v1.2.3 From 3be144ffde5f35df21ad115cbdedb8a072420edb Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 15 Mar 2017 15:05:18 +0000 Subject: Handle -displayfd and an explicit display number sensibly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit bc348bd2c42f3f18786085ccef2f010eff5bf3d2 Author: Jon TURNEY Date: Mon Mar 11 14:34:32 2013 +0000 Handle -displayfd and an explicit display number sensibly Handle -displayfd and an explicit display number sensibly, e.g. use the explicitly specified display number, and write it to the displayfd v2: displayfd might be 0, so use -1 as invalid value v3: Rebase for addition of NoListenAll flag Signed-off-by: Jon TURNEY Reviewed-by: Kristian Høgsberg Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nx-X11/programs/Xserver/os/utils.c') diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index dce04e942..6995d05d5 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -704,6 +704,7 @@ ProcessCommandLine(int argc, char *argv[]) { /* initialize display */ display = argv[i]; + explicit_display = TRUE; display++; if( ! VerifyDisplayName( display ) ) { ErrorF("Bad display name: %s\n", display); @@ -783,7 +784,6 @@ ProcessCommandLine(int argc, char *argv[]) else if (strcmp(argv[i], "-displayfd") == 0) { if (++i < argc) { displayfd = atoi(argv[i]); - display = NULL; nolock = TRUE; } else -- cgit v1.2.3 From 565421ba18a09d20620e01fc877915a8b09a3735 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 20 Mar 2017 13:22:50 +0100 Subject: os: Remove the useless -x option commit cbb165ab88cb0810268001e84d87671440baf837 Author: Adam Jackson Date: Fri Apr 3 18:34:45 2009 -0400 os: Remove the useless -x option Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/utils.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'nx-X11/programs/Xserver/os/utils.c') diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index 6995d05d5..31ea55bc3 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -622,7 +622,6 @@ void UseMsg(void) ErrorF("v video blanking for screen-saver\n"); ErrorF("-v screen-saver without video blanking\n"); ErrorF("-wm WhenMapped default backing-store\n"); - ErrorF("-x string loads named extension at init time \n"); ErrorF("-maxbigreqsize set maximal bigrequest size \n"); #ifdef PANORAMIX ErrorF("+xinerama Enable XINERAMA (PanoramiX) extension\n"); @@ -1012,14 +1011,6 @@ ProcessCommandLine(int argc, char *argv[]) noRRXineramaExtension = TRUE; } #endif - else if ( strcmp( argv[i], "-x") == 0) - { - if(++i >= argc) - UseMsg(); - /* For U**x, which doesn't support dynamic loading, there's nothing - * to do when we see a -x. Either the extension is linked in or - * it isn't */ - } else if ( strcmp( argv[i], "-I") == 0) { /* ignore all remaining arguments */ -- cgit v1.2.3