aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/os
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/os')
-rw-r--r--xorg-server/os/connection.c4
-rw-r--r--xorg-server/os/io.c27
-rw-r--r--xorg-server/os/osdep.h1
-rw-r--r--xorg-server/os/osinit.c10
-rw-r--r--xorg-server/os/utils.c56
5 files changed, 41 insertions, 57 deletions
diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c
index 0b46097ef..6378edade 100644
--- a/xorg-server/os/connection.c
+++ b/xorg-server/os/connection.c
@@ -146,6 +146,8 @@ Bool NewOutputPending; /* not yet attempted to write some new output */
Bool AnyClientsWriteBlocked; /* true if some client blocked on write */
static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
+Bool RunFromSigStopParent; /* send SIGSTOP to our own process; Upstart (or
+ equivalent) will send SIGCONT back. */
Bool PartialNetwork; /* continue even if unable to bind all addrs */
static Pid_t ParentProcess;
@@ -357,6 +359,8 @@ NotifyParentProcess(void)
kill (ParentProcess, SIGUSR1);
}
}
+ if (RunFromSigStopParent)
+ raise (SIGSTOP);
#endif
}
diff --git a/xorg-server/os/io.c b/xorg-server/os/io.c
index c9488b280..dc83d3a34 100644
--- a/xorg-server/os/io.c
+++ b/xorg-server/os/io.c
@@ -251,7 +251,14 @@ ReadRequestFromClient(ClientPtr client)
need_header = FALSE;
move_header = FALSE;
gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
- if (gotnow < sizeof(xReq))
+
+ if (oci->ignoreBytes > 0) {
+ if (oci->ignoreBytes > oci->size)
+ needed = oci->size;
+ else
+ needed = oci->ignoreBytes;
+ }
+ else if (gotnow < sizeof(xReq))
{
/* We don't have an entire xReq yet. Can't tell how big
* the request will be until we get the whole xReq.
@@ -294,8 +301,13 @@ ReadRequestFromClient(ClientPtr client)
if (needed > maxBigRequestSize << 2)
{
/* request is too big for us to handle */
- YieldControlDeath();
- return -1;
+ /*
+ * Mark the rest of it as needing to be ignored, and then return
+ * the full size. Dispatch() will turn it into a BadLength error.
+ */
+ oci->ignoreBytes = needed - gotnow;
+ oci->lenLastReq = gotnow;
+ return needed;
}
if ((gotnow == 0) ||
((oci->bufptr - oci->buffer + needed) > oci->size))
@@ -400,6 +412,14 @@ ReadRequestFromClient(ClientPtr client)
}
oci->lenLastReq = needed;
+ /* If there are bytes to ignore, ignore them now. */
+
+ if (oci->ignoreBytes > 0) {
+ assert(needed == oci->ignoreBytes || needed == oci->size);
+ oci->ignoreBytes -= gotnow;
+ needed = gotnow = 0;
+ }
+
/*
* Check to see if client has at least one whole request in the
* buffer beyond the request we're returning to the caller.
@@ -1030,6 +1050,7 @@ AllocateInputBuffer(void)
oci->bufptr = oci->buffer;
oci->bufcnt = 0;
oci->lenLastReq = 0;
+ oci->ignoreBytes = 0;
return oci;
}
diff --git a/xorg-server/os/osdep.h b/xorg-server/os/osdep.h
index 32b4a6763..491a746d4 100644
--- a/xorg-server/os/osdep.h
+++ b/xorg-server/os/osdep.h
@@ -125,6 +125,7 @@ typedef struct _connectionInput {
int bufcnt; /* count of bytes in buffer */
int lenLastReq;
int size;
+ unsigned int ignoreBytes; /* bytes to ignore before the next request */
} ConnectionInput, *ConnectionInputPtr;
typedef struct _connectionOutput {
diff --git a/xorg-server/os/osinit.c b/xorg-server/os/osinit.c
index 6d61d6200..57cd2c511 100644
--- a/xorg-server/os/osinit.c
+++ b/xorg-server/os/osinit.c
@@ -168,15 +168,9 @@ OsInit(void)
struct sigaction act, oact;
int i;
int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS,
-#ifdef SIGSYS
SIGSYS,
-#endif
-#ifdef SIGXCPU
SIGXCPU,
-#endif
-#ifdef SIGXFSZ
SIGXFSZ,
-#endif
#ifdef SIGEMT
SIGEMT,
#endif
@@ -311,9 +305,7 @@ OsInit(void)
* log file name if logging to a file is desired.
*/
LogInit(NULL, NULL);
- if (!SmartScheduleDisable)
- if (!SmartScheduleInit ())
- SmartScheduleDisable = TRUE;
+ SmartScheduleInit ();
}
void
diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c
index a6ae27bda..179a4b089 100644
--- a/xorg-server/os/utils.c
+++ b/xorg-server/os/utils.c
@@ -527,6 +527,7 @@ void UseMsg(void)
#endif
ErrorF("-dumbSched Disable smart scheduling, enable old behavior\n");
ErrorF("-schedInterval int Set scheduler interval in msec\n");
+ ErrorF("-sigstop Enable SIGSTOP based startup\n");
ErrorF("+extension name Enable extension\n");
ErrorF("-extension name Disable extension\n");
#ifdef XDMCP
@@ -922,6 +923,10 @@ ProcessCommandLine(int argc, char *argv[])
else
UseMsg ();
}
+ else if ( strcmp( argv[i], "-sigstop") == 0)
+ {
+ RunFromSigStopParent = TRUE;
+ }
else if ( strcmp( argv[i], "+extension") == 0)
{
if (++i < argc)
@@ -1116,20 +1121,9 @@ XNFstrdup(const char *s)
return ret;
}
-
-#ifdef SIGVTALRM
-#define SMART_SCHEDULE_POSSIBLE
-#endif
-
-#ifdef SMART_SCHEDULE_POSSIBLE
-#define SMART_SCHEDULE_SIGNAL SIGALRM
-#define SMART_SCHEDULE_TIMER ITIMER_REAL
-#endif
-
void
SmartScheduleStopTimer (void)
{
-#ifdef SMART_SCHEDULE_POSSIBLE
struct itimerval timer;
if (SmartScheduleDisable)
@@ -1139,13 +1133,11 @@ SmartScheduleStopTimer (void)
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 0;
(void) setitimer (ITIMER_REAL, &timer, 0);
-#endif
}
void
SmartScheduleStartTimer (void)
{
-#ifdef SMART_SCHEDULE_POSSIBLE
struct itimerval timer;
if (SmartScheduleDisable)
@@ -1155,41 +1147,33 @@ SmartScheduleStartTimer (void)
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = SmartScheduleInterval * 1000;
setitimer (ITIMER_REAL, &timer, 0);
-#endif
}
-#ifdef SMART_SCHEDULE_POSSIBLE
static void
SmartScheduleTimer (int sig)
{
SmartScheduleTime += SmartScheduleInterval;
}
-#endif
-Bool
+void
SmartScheduleInit (void)
{
-#ifdef SMART_SCHEDULE_POSSIBLE
struct sigaction act;
if (SmartScheduleDisable)
- return TRUE;
-
+ return;
+
memset((char *) &act, 0, sizeof(struct sigaction));
/* Set up the timer signal function */
act.sa_handler = SmartScheduleTimer;
sigemptyset (&act.sa_mask);
- sigaddset (&act.sa_mask, SMART_SCHEDULE_SIGNAL);
- if (sigaction (SMART_SCHEDULE_SIGNAL, &act, 0) < 0)
+ sigaddset (&act.sa_mask, SIGALRM);
+ if (sigaction (SIGALRM, &act, 0) < 0)
{
perror ("sigaction for smart scheduler");
- return FALSE;
+ SmartScheduleDisable = TRUE;
}
- return TRUE;
-#else
- return FALSE;
-#endif
}
#ifdef SIG_BLOCK
@@ -1206,30 +1190,18 @@ OsBlockSignals (void)
sigset_t set;
sigemptyset (&set);
-#ifdef SIGALRM
sigaddset (&set, SIGALRM);
-#endif
-#ifdef SIGVTALRM
sigaddset (&set, SIGVTALRM);
-#endif
#ifdef SIGWINCH
sigaddset (&set, SIGWINCH);
#endif
#ifdef SIGIO
sigaddset (&set, SIGIO);
#endif
-#ifdef SIGTSTP
sigaddset (&set, SIGTSTP);
-#endif
-#ifdef SIGTTIN
sigaddset (&set, SIGTTIN);
-#endif
-#ifdef SIGTTOU
sigaddset (&set, SIGTTOU);
-#endif
-#ifdef SIGCHLD
sigaddset (&set, SIGCHLD);
-#endif
sigprocmask (SIG_BLOCK, &set, &PreviousSignalMask);
}
#endif
@@ -1275,21 +1247,17 @@ int
System(char *command)
{
int pid, p;
-#ifdef SIGCHLD
void (*csig)(int);
-#endif
int status;
if (!command)
return 1;
-#ifdef SIGCHLD
csig = signal(SIGCHLD, SIG_DFL);
if (csig == SIG_ERR) {
perror("signal");
return -1;
}
-#endif
#ifdef DEBUG
ErrorF("System: `%s'\n", command);
@@ -1312,12 +1280,10 @@ System(char *command)
}
-#ifdef SIGCHLD
if (signal(SIGCHLD, csig) == SIG_ERR) {
perror("signal");
return -1;
}
-#endif
return p == -1 ? -1 : status;
}