Package: xorg-xserver
Version: 2:1.4.1~git20080131-1
Severity: normal
Tags: patch

We have users that sometimes run xvfb-run multiple times concurrently for
running builds. They tell me there is a >50% chance that doing so will cause a
failure due to a race condition in how the server number is determined.

One of our users provided me with a patch for the problem. Could you please
consider incorporating this into a future release?

-- System Information:
Debian Release: 5.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-1-686 (SMP w/1 CPU core)
Locale: LANG=en_AU.UTF-8, LC_CTYPE=en_AU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
--- xvfb-run.orig       2009-03-17 16:34:38.588489000 +0000
+++ xvfb-run.patched    2009-03-17 16:40:56.682709000 +0000
@@ -109,7 +109,7 @@
 
 while :; do
     case "$1" in
-        -a|--auto-servernum) SERVERNUM=$(find_free_servernum) ;;
+        -a|--auto-servernum) SERVERNUM=$(find_free_servernum); AUTONUM="yes" ;;
         -e|--error-file) ERRORFILE="$2"; shift ;;
         -f|--auth-file) AUTHFILE="$2"; shift ;;
         -h|--help) SHOWHELP="yes" ;;
@@ -155,13 +155,32 @@
     AUTHFILE=$(tempfile -n "$XVFB_RUN_TMPDIR/Xauthority")
 fi
 
-# Start Xvfb.
-MCOOKIE=$(mcookie)
-XAUTHORITY=$AUTHFILE xauth add ":$SERVERNUM" "$XAUTHPROTO" "$MCOOKIE" \
-  >"$ERRORFILE" 2>&1
-XAUTHORITY=$AUTHFILE Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP >"$ERRORFILE" \
-  2>&1 &
-XVFBPID=$!
+# Start Xvfb
+# Loop until we get a match between lock file contents and Xvfb PID
+# (this avoids a race condition when another process starts an Xserver).
+while true; do
+    MCOOKIE=$(mcookie)
+    XAUTHORITY=$AUTHFILE xauth add ":$SERVERNUM" "$XAUTHPROTO" "$MCOOKIE" \
+      >"$ERRORFILE" 2>&1
+    XAUTHORITY=$AUTHFILE Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP \
+      >"$ERRORFILE" 2>&1 &
+    XVFBPID=$!
+    # Test PID of Xvfb and contents of the X server lock file
+    # (use numerical comparison to avoid whitespace issues).
+    # If the display was in use the Xvfb process will die on its own.
+    if [ "$XVFBPID" -eq "$(</tmp/.X${SERVERNUM}-lock)" ]; then
+        break
+    fi
+    # The display is in use so try another one (if '-a' was specified).
+    if [ "$AUTONUM" ]; then
+        SERVERNUM=$(find_free_servernum)
+        continue
+    fi
+    error "display :$SERVERNUM already in use"
+    exit 1
+done
+
+# Xvfb has started without any race conditions.
 sleep "$STARTWAIT"
 if ! kill -0 $XVFBPID 2>/dev/null; then
   echo "Xvfb failed to start" >&2

Reply via email to