fix media server port allocation

the old code was allowing the main thread to read .port before it had
been updated, and was binding to sockets that were already in use on
Windows. instead, we use a system-assigned free port and block the main
thread until it's been allocated
This commit is contained in:
Damien Elmes 2017-08-08 14:56:34 +10:00
parent bee6931dc9
commit c74cbf6108
3 changed files with 11 additions and 14 deletions

View File

@ -1195,4 +1195,4 @@ Please ensure a profile is open and Anki is not busy, then try again."""),
self.mediaServer.start() self.mediaServer.start()
def baseHTML(self): def baseHTML(self):
return '<base href="http://localhost:%d/">' % self.mediaServer.port return '<base href="http://localhost:%d/">' % self.mediaServer.getPort()

View File

@ -32,21 +32,18 @@ class ThreadedHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
class MediaServer(threading.Thread): class MediaServer(threading.Thread):
_port = None
_ready = threading.Event()
def run(self): def run(self):
self.port = 10000 self.server = ThreadedHTTPServer(("localhost", 0), RequestHandler)
self.server = None self._ready.set()
while not self.server:
try:
self.server = ThreadedHTTPServer(
("localhost", self.port), RequestHandler)
except OSError as e:
if e.errno == errno.EADDRINUSE:
self.port += 1
continue
raise
break
self.server.serve_forever() self.server.serve_forever()
def getPort(self):
self._ready.wait()
return self.server.server_port
def shutdown(self): def shutdown(self):
self.server.shutdown() self.server.shutdown()

View File

@ -197,7 +197,7 @@ body { zoom: %f; %s }
def webBundlePath(self, path): def webBundlePath(self, path):
from aqt import mw from aqt import mw
return "http://localhost:%d/_anki/%s" % (mw.mediaServer.port, path) return "http://localhost:%d/_anki/%s" % (mw.mediaServer.getPort(), path)
def bundledScript(self, fname): def bundledScript(self, fname):
return '<script src="%s"></script>' % self.webBundlePath(fname) return '<script src="%s"></script>' % self.webBundlePath(fname)