Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions pyvirtualdisplay/abstractdisplay.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import time
import tempfile
from threading import Lock
import select
import fcntl

from pyvirtualdisplay import xauth

Expand All @@ -22,7 +24,7 @@
MIN_DISPLAY_NR = 1000
USED_DISPLAY_NR_LIST=[]

X_START_TIMEOUT = 1
X_START_TIMEOUT = 10
X_START_TIME_STEP = 0.1
X_START_WAIT = 0.1

Expand All @@ -34,7 +36,7 @@ class AbstractDisplay(EasyProcess):
Common parent for Xvfb and Xephyr
'''

def __init__(self, use_xauth=False):
def __init__(self, use_xauth=False, check_startup=False):
mutex.acquire()
try:
self.display = self.search_for_display()
Expand All @@ -48,6 +50,15 @@ def __init__(self, use_xauth=False):
self.use_xauth = use_xauth
self._old_xauth = None
self._xauth_filename = None
self.check_startup = check_startup
if self.check_startup:
rp, wp = os.pipe()
fcntl.fcntl(rp, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
#to properly allow to inherit fds to subprocess on
#python 3.2+ the easyprocess needs small fix..
fcntl.fcntl(wp, fcntl.F_SETFD, 0)
self.check_startup_fd = wp
self._check_startup_fd = rp
EasyProcess.__init__(self, self._cmd)

@property
Expand Down Expand Up @@ -115,9 +126,25 @@ def start(self):

# wait until X server is active
start_time = time.time()
ok = False
if self.check_startup:
rp = self._check_startup_fd
display_check = None
rlist, wlist, xlist = select.select((rp,), (), (), X_START_TIMEOUT)
if rlist:
display_check = os.read(rp, 10).rstrip()
else:
msg = 'No display number returned by X server'
raise XStartTimeoutError(msg)
dnbs = str(self.display)
if bytes != str:
dnbs = bytes(dnbs, 'ascii')
if display_check != dnbs:
msg = 'Display number "%s" not returned by X server' + str(display_check)
raise XStartTimeoutError(msg % self.display)

d = self.new_display_var
while time.time() - start_time < X_START_TIMEOUT:
ok = False
while True:
try:
exit_code = EasyProcess('xdpyinfo').call().return_code
except EasyProcessError:
Expand All @@ -133,6 +160,8 @@ def start(self):
ok = True
break

if time.time() - start_time >= X_START_TIMEOUT:
break
time.sleep(X_START_TIME_STEP)
if not ok:
msg = 'Failed to start X on display "%s" (xdpyinfo check failed).'
Expand Down
7 changes: 5 additions & 2 deletions pyvirtualdisplay/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Display(AbstractDisplay):
:param backend: 'xvfb', 'xvnc' or 'xephyr', ignores ``visible``
:param xauth: If a Xauthority file should be created.
'''
def __init__(self, backend=None, visible=False, size=(1024, 768), color_depth=24, bgcolor='black', use_xauth=False, **kwargs):
def __init__(self, backend=None, visible=False, size=(1024, 768), color_depth=24, bgcolor='black', use_xauth=False, check_startup=False, **kwargs):
self.color_depth = color_depth
self.size = size
self.bgcolor = bgcolor
Expand All @@ -36,7 +36,7 @@ def __init__(self, backend=None, visible=False, size=(1024, 768), color_depth=24
color_depth=color_depth,
bgcolor=bgcolor,
**kwargs)
AbstractDisplay.__init__(self, use_xauth=use_xauth)
AbstractDisplay.__init__(self, use_xauth=use_xauth, check_startup=check_startup)

@property
def display_class(self):
Expand All @@ -56,4 +56,7 @@ def display_class(self):
@property
def _cmd(self):
self._obj.display = self.display
self._obj.check_startup = self.check_startup
if self.check_startup:
self._obj.check_startup_fd = self.check_startup_fd
return self._obj._cmd
2 changes: 2 additions & 0 deletions pyvirtualdisplay/xephyr.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ def _cmd(self):
'-resizeable',
self.new_display_var,
]
if self.check_startup:
cmd += ['-displayfd', str(self.check_startup_fd)]
return cmd
2 changes: 2 additions & 0 deletions pyvirtualdisplay/xvfb.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,6 @@ def _cmd(self):
]
if self.fbdir:
cmd += ['-fbdir', self.fbdir]
if self.check_startup:
cmd += ['-displayfd', str(self.check_startup_fd)]
return [PROGRAM] + cmd
2 changes: 2 additions & 0 deletions pyvirtualdisplay/xvnc.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ def _cmd(self):
'-rfbport', str(self.rfbport),
self.new_display_var,
]
if self.check_startup:
cmd += ['-displayfd', str(self.check_startup_fd)]
return cmd