Skip to content

Commit

Permalink
Hmm, check_tid_w_ordering through re-entrancy errors on Windows. Fix …
Browse files Browse the repository at this point in the history
…that.
  • Loading branch information
jamadden committed Jul 11, 2019
1 parent 3436db7 commit 2493d70
Showing 1 changed file with 24 additions and 8 deletions.
32 changes: 24 additions & 8 deletions src/relstorage/tests/reltestbase.py
Expand Up @@ -13,6 +13,7 @@
##############################################################################
"""A foundation for RelStorage tests"""
from __future__ import absolute_import
from __future__ import print_function

# pylint:disable=too-many-ancestors,abstract-method,too-many-public-methods,too-many-lines
# pylint:disable=too-many-statements,too-many-locals
Expand All @@ -22,6 +23,7 @@
import shutil
import tempfile
import time
import threading
import unittest

import transaction
Expand Down Expand Up @@ -139,27 +141,37 @@ class ExtStorageClientThread(StorageClientThread, MTStorage.ExtStorageClientThre
class ThreadWrapper(object):

def __init__(self, storage):
import threading
self.__storage = storage
# We can't use an RLock, which verifies that the thread that
# acquired is the one that releases; check_tid_ordering_w_commit
# deliberately spreads these actions across threads (for same reason).
self.__lock = threading.Lock()
self.__txn = None

def __getattr__(self, name):
return getattr(self.__storage, name)

def tpc_begin(self, *args, **kwargs):
def tpc_begin(self, txn):
self.__lock.acquire()
return self.__storage.tpc_begin(*args, **kwargs)
assert not self.__txn
self.__txn = txn

def tpc_finish(self, *args, **kwargs):
return self.__storage.tpc_begin(txn)

def tpc_finish(self, txn, callback=None):
assert txn is self.__txn
try:
return self.__storage.tpc_finish(*args, **kwargs)
return self.__storage.tpc_finish(txn, callback)
finally:
self.__txn = None
self.__lock.release()

def tpc_abort(self, *args, **kwargs):
def tpc_abort(self, txn):
assert txn is self.__txn
try:
return self.__storage.tpc_abort(*args, **kwargs)
return self.__storage.tpc_abort(txn)
finally:
self.__txn = None
self.__lock.release()

class UsesThreadsOnASingleStorageMixin(object):
Expand Down Expand Up @@ -190,6 +202,7 @@ def make_func(name): # pylint:disable=no-self-argument

for bad_test in (
'check_checkCurrentSerialInTransaction',
'check_tid_ordering_w_commit',
):
locals()[bad_test] = make_func(bad_test)

Expand Down Expand Up @@ -973,7 +986,6 @@ def updater():
finally:
thread_c.close()

import threading
threads = []
for _ in range(thread_count):
t = threading.Thread(target=updater)
Expand Down Expand Up @@ -1177,6 +1189,10 @@ def check_tid_ordering_w_commit(self):
# The implementation in BasicStorage.BasicStorage is
# racy: it uses multiple threads to access a single
# RelStorage instance, which doesn't make sense.
#
# Even when we wrap this with a ThreadWrapper,
# it doesn't prevent the races (indeed, we had the races
# when RelStorage itself natively used thread locks).
try:
super(GenericRelStorageTests, self).check_tid_ordering_w_commit()
except AssertionError as e:
Expand Down

0 comments on commit 2493d70

Please sign in to comment.