-
Notifications
You must be signed in to change notification settings - Fork 6
/
Threading.py
87 lines (62 loc) · 2.07 KB
/
Threading.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import sys
import weakref
from threading import current_thread, Event, RLock, Lock
mainThread = current_thread() # expect that we import this from the main thread
def do_in_main_thread(func, wait):
import TaskSystem
if not wait: # don't wait
TaskSystem.mainLoopQueue.put(func)
return
if current_thread() is mainThread:
return func()
else:
class Result:
doneEvent = Event()
returnValue = None
excInfo = None
def wrapped():
try:
Result.returnValue = func()
except BaseException:
Result.excInfo = sys.exc_info()
Result.doneEvent.set()
TaskSystem.mainLoopQueue.put(wrapped)
Result.doneEvent.wait()
if Result.excInfo:
raise Result.excInfo[1]
return Result.returnValue
class Caller:
def __init__(self, func, *args, **kwargs):
self.func = func
self.args = args
self.kwargs = kwargs
def __call__(self):
self.func()
class DoInMainThreadDecoratorWait:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return do_in_main_thread(Caller(self.func, *args, **kwargs), wait=True)
class DoInMainThreadDecoratorNowait:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return do_in_main_thread(Caller(self.func, *args, **kwargs), wait=False)
class LocksDict:
def __init__(self, lock_clazz=RLock):
self.lockClazz = lock_clazz
self.lock = Lock()
self.weakKeyDict = weakref.WeakKeyDictionary()
def __getitem__(self, item):
with self.lock:
if item in self.weakKeyDict:
return self.weakKeyDict[item]
lock = self.lockClazz()
self.weakKeyDict[item] = lock
return lock
def synced_on_obj(func):
locks = LocksDict()
def decorated_func(self, *args, **kwargs):
with locks[self]:
return func(self, *args, **kwargs)
return decorated_func