Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Commit

Permalink
Merge pull request #4715 from golemfactory/b0.21-locked-monkey
Browse files Browse the repository at this point in the history
Protect asyncio add/remove Reader/Writer against multithreading
  • Loading branch information
jiivan authored Sep 12, 2019
2 parents 5da95d5 + 09f7dd1 commit 091078f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
23 changes: 9 additions & 14 deletions golem/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import subprocess
import sys
import threading
from calendar import timegm
from datetime import datetime
from functools import wraps
Expand All @@ -11,6 +12,7 @@
import pytz

from golem.core import simpleenv
from golem.decorators import locked

F = TypeVar('F', bound=Callable[..., Any])

Expand Down Expand Up @@ -322,27 +324,20 @@ def install_reactor():
asyncioreactor.install(asyncio.get_event_loop())

from twisted.internet import reactor
_patch_remove_writer(reactor)
_patch_modify_io(reactor)

from golem.core.variables import REACTOR_THREAD_POOL_SIZE
reactor.suggestThreadPoolSize(REACTOR_THREAD_POOL_SIZE)
return reactor


def _patch_remove_writer(reactor):
import logging
import types
def _patch_modify_io(reactor):
lock = threading.Lock()

logger = logging.getLogger('golem.core')

def patched_remove_writer(_, writer):
try:
reactor_remove_writer(writer)
except KeyError as err:
logger.debug("Reactor removeWriter error: %r", err)

reactor_remove_writer = reactor.removeWriter
reactor.removeWriter = types.MethodType(patched_remove_writer, reactor)
reactor.removeWriter = locked(lock)(reactor.removeWriter)
reactor.addWriter = locked(lock)(reactor.addWriter)
reactor.removeReader = locked(lock)(reactor.removeReader)
reactor.addReader = locked(lock)(reactor.addReader)


if is_windows():
Expand Down
14 changes: 13 additions & 1 deletion golem/decorators.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import functools
import logging

from golem import model

log = logging.getLogger('golem.decorators')


def run_with_db():
"""Run only when DB is active"""
from golem import model

def wrapped(f):
@functools.wraps(f)
def curry(*args, **kwargs):
Expand All @@ -21,3 +22,14 @@ def curry(*args, **kwargs):
return f(*args, **kwargs)
return curry
return wrapped


def locked(lock):
"""Run under a threadsafe lock"""
def wrapped(f):
@functools.wraps(f)
def curry(*args, **kwargs):
with lock:
return f(*args, **kwargs)
return curry
return wrapped

0 comments on commit 091078f

Please sign in to comment.