mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 22:42:25 -04:00
refactor second instance detection
- get rid of shared memory check as it was causing problems when an existing session was forcefully closed; instead we rely on the socket - include a hash of the user's name in the key so that multiple users can run anki at the same time
This commit is contained in:
parent
f64c07ca40
commit
0f7000db83
1 changed files with 20 additions and 20 deletions
|
@ -1,5 +1,6 @@
|
||||||
# Copyright: Damien Elmes <anki@ichi2.net>
|
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
import getpass
|
||||||
|
|
||||||
import os, sys, optparse, atexit, tempfile, __builtin__
|
import os, sys, optparse, atexit, tempfile, __builtin__
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
|
@ -29,6 +30,8 @@ except ImportError, e:
|
||||||
print
|
print
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
from anki.utils import checksum
|
||||||
|
|
||||||
# Dialog manager - manages modeless windows
|
# Dialog manager - manages modeless windows
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
@ -110,46 +113,43 @@ class AnkiApp(QApplication):
|
||||||
# Single instance support on Win32/Linux
|
# Single instance support on Win32/Linux
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
KEY = "anki"
|
KEY = "anki"+checksum(getpass.getuser())
|
||||||
TMOUT = 5000
|
TMOUT = 5000
|
||||||
|
|
||||||
def __init__(self, argv):
|
def __init__(self, argv):
|
||||||
QApplication.__init__(self, argv)
|
QApplication.__init__(self, argv)
|
||||||
self._argv = argv
|
self._argv = argv
|
||||||
self._shmem = QSharedMemory(self.KEY)
|
|
||||||
self.alreadyRunning = self._shmem.attach()
|
|
||||||
|
|
||||||
def secondInstance(self):
|
def secondInstance(self):
|
||||||
if not self.alreadyRunning:
|
# we accept only one command line argument. if it's missing, send
|
||||||
# use a 1 byte shared memory instance to signal we exist
|
# a blank screen to just raise the existing window
|
||||||
if not self._shmem.create(1):
|
opts, args = parseArgs(self._argv)
|
||||||
raise Exception("shared memory not supported")
|
buf = "raise"
|
||||||
atexit.register(self._shmem.detach)
|
if args and args[0]:
|
||||||
# and a named pipe/unix domain socket for ipc
|
buf = os.path.abspath(args[0])
|
||||||
|
if self.sendMsg(buf):
|
||||||
|
print "Already running; reusing existing instance."
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
# send failed, so we're the first instance or the
|
||||||
|
# previous instance died
|
||||||
QLocalServer.removeServer(self.KEY)
|
QLocalServer.removeServer(self.KEY)
|
||||||
self._srv = QLocalServer(self)
|
self._srv = QLocalServer(self)
|
||||||
self.connect(self._srv, SIGNAL("newConnection()"), self.onRecv)
|
self.connect(self._srv, SIGNAL("newConnection()"), self.onRecv)
|
||||||
self._srv.listen(self.KEY)
|
self._srv.listen(self.KEY)
|
||||||
else:
|
return False
|
||||||
print "Raising existing window."
|
|
||||||
# we accept only one command line argument. if it's missing, send
|
|
||||||
# a blank screen to just raise the existing window
|
|
||||||
opts, args = parseArgs(self._argv)
|
|
||||||
buf = "raise"
|
|
||||||
if args and args[0]:
|
|
||||||
buf = os.path.abspath(args[0])
|
|
||||||
self.sendMsg(buf)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def sendMsg(self, txt):
|
def sendMsg(self, txt):
|
||||||
sock = QLocalSocket(self)
|
sock = QLocalSocket(self)
|
||||||
sock.connectToServer(self.KEY, QIODevice.WriteOnly)
|
sock.connectToServer(self.KEY, QIODevice.WriteOnly)
|
||||||
if not sock.waitForConnected(self.TMOUT):
|
if not sock.waitForConnected(self.TMOUT):
|
||||||
raise Exception("existing instance not responding")
|
# first instance or previous instance dead
|
||||||
|
return False
|
||||||
sock.write(txt)
|
sock.write(txt)
|
||||||
if not sock.waitForBytesWritten(self.TMOUT):
|
if not sock.waitForBytesWritten(self.TMOUT):
|
||||||
raise Exception("existing instance not emptying")
|
raise Exception("existing instance not emptying")
|
||||||
sock.disconnectFromServer()
|
sock.disconnectFromServer()
|
||||||
|
return True
|
||||||
|
|
||||||
def onRecv(self):
|
def onRecv(self):
|
||||||
sock = self._srv.nextPendingConnection()
|
sock = self._srv.nextPendingConnection()
|
||||||
|
|
Loading…
Reference in a new issue