Closed mudassirkhan19 closed 1 year ago
Could you try to reset that attribute before the second use of MSS?
from mss.linux import MSS
# (...)
xvfb.stop()
MSS._display_dict.clear()
xvfb = Xvfb(width=1920, height=1080, colordepth=24)
# (...)
thanks @BoboTiG ! I have been trying to resolve this bug since two days.
Great!
I could introduce a mss.reset_internal_state()
to hide implementation details. Or maybe shorter: mss.reset()
.
With a good documentation it should help with such situation.
Shouldn't the context manager take care of this? this can just happen behind the scenes, just a thought.
Actually those internal details were added for performance and memory leak reasons. Your situation is not so frequent, so I would go with the new function to clear the internal state.
Encountered another issue with this, this time its a too many open files error, the open connection originates here:
self.xlib.XOpenDisplay(disp)
So basically we aren't closing our connection to the X11 server, a little digging led me to an XCloseDisplay
function from here.
So wrote a wrapper for my usecase:
from contextlib import contextmanager
import sys
@contextmanager
def mss_wrapper():
try:
with mss.mss() as sct:
yield sct
finally:
if sys.platform == "linux":
from mss.linux import MSS
import ctypes
x11 = ctypes.util.find_library("X11") # type: ignore
xlib = ctypes.cdll.LoadLibrary(x11)
for _, display in MSS._display_dict.items():
xlib.XCloseDisplay(display)
MSS._display_dict.clear()
I've run into the same issue as @mudassirkhan19 (thanks for the wrapper by the way!).
I feel like it makes a lot of sense for the display to get closed and the dict cleared on the context exit, in which case would someone avoid this?
Also, out of curiosity, why share the display among all MSS instances in a thread instead of each MSS instance having it's own? Right now one can only use MSS to connect to one display per thread, clearing the dict solves this partially but you can't have two MSS instances connected to different displays in the same thread. X apparently doesn't mind multiple connections to the same display per thread since I'm using other libraries each with their own display.
@dp-alvarez
Also, out of curiosity, why share the display among all MSS instances in a thread instead of each MSS instance having it's own?
At first, it was to workaround resource leaks. But I now see that it's not a good way, and there may be no way to handle all cases. So I refactored the whole part in #234, and it should be better for most of us.
General information:
For GNU/Linux users:
Description of the warning/error
The error comes when I try to call mss.mss() in a single python session with two different Xvfb screens.
Full message
XIO: fatal IO error 0 (Success) on X server ":3" after 8 requests (8 known processed) with 0 events remaining.
Other details
Steps to reproduce:
The error pops up exactly on this line