Detect whether wineserver is fully started? Signal? File?
Sebastian M. Ernst
ernst at pleiszenburg.de
Sat Jun 17 05:20:25 CDT 2017
@Bruno
> Not sure if I got the problem you are describing exactly but what
> about doing the opposite direction? Make a very simple socket program
> for Windows that is launched and this program connects to your python
> application instead. When python notices the connection it is sure
> that wineserver is running because it just received the connection
> from an app running inside Wine. Also as long as this small utility is
> up wineserver won't close too.
Thanks, yes, I have considered this approach (and will likely follow it
if everything else does not work). I'd prefer a "pythonic" solution
without adding dependencies like a cross-compiler (for compiling the
utility) to my module. I am already doing this for tests, but I'd really
like to keep the module itself "clean" and easy to install. Just as a
theoretical question, could such a utility be implemented as a batch
file which wine (cmd) could handle "out of the box"?
@Sebastian
thanks again, this is really helpful.
> If you disconnect before the real command is started the wineserver will
> assume it is no longer needed and terminate automatically. I would say
> this is a bug, because the user definitely does not expect that when
> passing "-p".
Is this worth opening a ticket?
> Nevertheless, when you keep the connection open, it should
> actually work (and also does work for me, according to a quick test).
Once my wineserver is up, I try to do a number of path conversion using
"winepath -w /some/path" etc. first before I fire up any exe-files. Am I
correct in assuming that winepath should also use my wineserver (if run
with the same prefix)? Can you check whether your quick test also works
with winepath (eliminating a potential source of error)? I managed to
turn winepath directly into a zombie a number of times by running
winepath (too early) while wineserver was still starting. It does not
produce any error messages whatsoever.
> A slightly better solution which does not trigger this problem would be
> to wait for the wineserver lock (which will also appear in the server dir).
I used your code and implemented a routine which waits for the lock-file
to be locked - see below this email. Usually, it requires two attempts /
about 0.01 seconds until it succeeds. The PID returned by your code
matches the PID of my wineserver. The problem is, just after I have
confirmed the lock, winepath becomes a zombie again and again and ...
occasionally, it works. Is this a bug or a lack of understanding on my part?
> There is still a small race-condition (the lock is acquired but the socket
> has not been created yet), but Wine will be able to deal with that. It will
> retry a couple of times until it finally succeeds.
Could a failure in this mechanism be the reason for my zombies? (Happens
with Wine 2.5, 2.6 and 2.10.)
> BTW: As I saw, you replaced the "/tmp" with tempfile.gettempdir(), but this
> is actually not correct. Wineserver sockets will always be created in /tmp
> (hardcoded in the source) to ensure the correct socket is found, no matter
> which environment variables are set.
I did not expect that ... thanks.
Best regards,
Sebastian
# Get full path of socket
lock_path = os.path.join(self.server_path, 'lock')
# Status log
self.log.out('[wine session] Expecting wineserver lock at %s ...' %
lock_path)
# Status variable
got_lock_pid = False
# Time-step
wait_for_seconds = 0.01
# Timeout
timeout_after_seconds = 30.0
# Already waited for ...
started_waiting_at = time.time()
# Connection trys
tried_this_many_times = 0
# Run loop until socket appears
while True:
# Does socket file exist?
if os.path.exists(lock_path):
# Count attempts
tried_this_many_times += 1
# Open lock file
lock_file = open(lock_path, 'rb')
# Can I retrieve a PID?
lock_pid = self.__get_lock_pid__(lock_file)
# Close lock file
lock_file.close()
# Check result
if lock_pid is not None:
got_lock_pid = True
break
# Break the loop after timeout
if time.time() >= (started_waiting_at + timeout_after_seconds):
break
# Wait before trying again
time.sleep(wait_for_seconds)
# Evaluate the result
if not got_lock_pid:
self.log.out(
'[wine session] ... was not locked %d (after %0.2f seconds & %d
attempts)! Quit.' % (
timeout_after_seconds, tried_this_many_times
)
)
sys.exit()
else:
# Log status
self.log.out(
'[wine session] ... is locked by PID %d (after %0.2f seconds & %d
attempts)!' % (
lock_pid, time.time() - started_waiting_at, tried_this_many_times
)
)
More information about the wine-devel
mailing list