Archetype2
Archetype2

Reputation: 97

Xvfb IO Error: client killed

I'm running the following pyqt application on an xvfb server on amazon ec2 ubuntu 12.04, I get the correct ouput from the qt application but I always get the aforementioned error when the app is done. Why am I getting this error? I think it may be because the xvfb server is not terminating correctly but I'm not sure.

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtWebKit import *
from xvfbwrapper import Xvfb


args = {"nolisten":"tcp"}
vdisplay = Xvfb(**args)
vdisplay.start()
app = QApplication(sys.argv)
def update():
    print "upd"
t = QTimer()
t.start(500)
t.timeout.connect(update)
stopTimer = QTimer(timeout=app.quit,singleShot=True)
stopTimer.start(4000)
app.exec_()
print "done with app"
vdisplay.stop()

Upvotes: 4

Views: 1335

Answers (3)

BlackJack
BlackJack

Reputation: 4679

You get the error as long as the QApplication instance is alive. One solution is to push the Xvfb.stop() call closer to the exit of the program, for instance with the atexit module:

import atexit

# ...

def main():
    vdisplay = Xvfb()
    vdisplay.start()
    atexit.register(vdisplay.stop)

    # ...

Upvotes: 1

mpenkov
mpenkov

Reputation: 21898

Another ugly way to work around this is to wrap everything in another subprocess:

import xvfbwrapper
import sys
import subprocess as sub

with xvfbwrapper.Xvfb():
    p = sub.Popen(
        ["python", "yourscript.py"] + sys.argv[1:],
        stdout=sub.PIPE, stderr=sub.PIPE
    )
    stdout, stderr = p.communicate()
    print stdout
    print >> sys.stderr, stderr
    sys.exit(p.returncode)

Upvotes: 1

cjauvin
cjauvin

Reputation: 3693

For me @urim's solution does not work because if you don't use vdisplay.stop(), the Xvfb process is not killed when the script exits, which is a problem. My solution is to explicitly kill the process with a background call, after a short while:

# Workaround for a problem preventing vdisplay.stop() to work
# normally, because apparently Qt is still keeping its handle on X
# at this point.
import os
os.system('(sleep 5 && kill -9 %d) &' % vdisplay.proc.pid)

Upvotes: 3

Related Questions