Implement fallback for multiprocessing module

module is not working on Android
This commit is contained in:
Unrud 2018-11-03 21:51:09 +00:00
parent e5c4373606
commit edc20ed510
2 changed files with 43 additions and 4 deletions

View File

@ -29,8 +29,11 @@ import logging
import multiprocessing
import os
import sys
import tempfile
import threading
from radicale import pathutils
try:
import systemd.journal
except ImportError:
@ -72,6 +75,27 @@ class IdentLogRecordFactory:
return record
class RwLockWrapper():
def __init__(self):
self._file = tempfile.NamedTemporaryFile()
self._lock = pathutils.RwLock(self._file.name)
self._cm = None
def acquire(self, blocking=True):
assert self._cm is None
if not blocking:
raise NotImplementedError
cm = self._lock.acquire("w")
cm.__enter__()
self._cm = cm
def release(self):
assert self._cm is not None
self._cm.__exit__(None, None, None)
self._cm = None
class ThreadStreamsHandler(logging.Handler):
terminator = "\n"
@ -83,7 +107,11 @@ class ThreadStreamsHandler(logging.Handler):
self.fallback_handler = fallback_handler
def createLock(self):
self.lock = multiprocessing.Lock()
try:
self.lock = multiprocessing.Lock()
except Exception:
# HACK: Workaround for Android
self.lock = RwLockWrapper()
def setFormatter(self, form):
super().setFormatter(form)

View File

@ -30,6 +30,7 @@ import socket
import socketserver
import ssl
import sys
import threading
import wsgiref.simple_server
from configparser import ConfigParser
from urllib.parse import unquote
@ -42,7 +43,14 @@ try:
except ImportError:
systemd = None
if hasattr(os, "fork"):
USE_FORKING = hasattr(os, "fork")
try:
multiprocessing.BoundedSemaphore()
except Exception:
# HACK: Workaround for Android
USE_FORKING = False
if USE_FORKING:
ParallelizationMixIn = socketserver.ForkingMixIn
else:
ParallelizationMixIn = socketserver.ThreadingMixIn
@ -84,9 +92,12 @@ class ParallelHTTPServer(ParallelizationMixIn,
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if USE_FORKING:
sema_class = multiprocessing.BoundedSemaphore
else:
sema_class = threading.BoundedSemaphore
if self.max_connections:
self.connections_guard = multiprocessing.BoundedSemaphore(
self.max_connections)
self.connections_guard = sema_class(self.max_connections)
else:
# use dummy context manager
self.connections_guard = contextlib.ExitStack()