Initial import to Tizen
[profile/ivi/python-twisted.git] / twisted / python / threadable.py
1 # -*- test-case-name: twisted.python.test_threadable -*-
2 # Copyright (c) Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5
6 """
7 A module that will allow your program to be multi-threaded,
8 micro-threaded, and single-threaded.  Currently microthreads are
9 unimplemented.  The idea is to abstract away some commonly used
10 functionality so that I don't have to special-case it in all programs.
11 """
12
13
14
15 from twisted.python import hook
16
17 class DummyLock(object):
18     """
19     Hack to allow locks to be unpickled on an unthreaded system.
20     """
21
22     def __reduce__(self):
23         return (unpickle_lock, ())
24
25 def unpickle_lock():
26     if threadingmodule is not None:
27         return XLock()
28     else:
29         return DummyLock()
30 unpickle_lock.__safe_for_unpickling__ = True
31
32 def _synchPre(self, *a, **b):
33     if '_threadable_lock' not in self.__dict__:
34         _synchLockCreator.acquire()
35         if '_threadable_lock' not in self.__dict__:
36             self.__dict__['_threadable_lock'] = XLock()
37         _synchLockCreator.release()
38     self._threadable_lock.acquire()
39
40 def _synchPost(self, *a, **b):
41     self._threadable_lock.release()
42
43 def synchronize(*klasses):
44     """Make all methods listed in each class' synchronized attribute synchronized.
45
46     The synchronized attribute should be a list of strings, consisting of the
47     names of methods that must be synchronized. If we are running in threaded
48     mode these methods will be wrapped with a lock.
49     """
50     if threadmodule is not None:
51         for klass in klasses:
52             for methodName in klass.synchronized:
53                 hook.addPre(klass, methodName, _synchPre)
54                 hook.addPost(klass, methodName, _synchPost)
55
56 def init(with_threads=1):
57     """Initialize threading.
58
59     Don't bother calling this.  If it needs to happen, it will happen.
60     """
61     global threaded, _synchLockCreator, XLock
62
63     if with_threads:
64         if not threaded:
65             if threadmodule is not None:
66                 threaded = True
67
68                 class XLock(threadingmodule._RLock, object):
69                     def __reduce__(self):
70                         return (unpickle_lock, ())
71
72                 _synchLockCreator = XLock()
73             else:
74                 raise RuntimeError("Cannot initialize threading, platform lacks thread support")
75     else:
76         if threaded:
77             raise RuntimeError("Cannot uninitialize threads")
78         else:
79             pass
80
81 _dummyID = object()
82 def getThreadID():
83     if threadmodule is None:
84         return _dummyID
85     return threadmodule.get_ident()
86
87
88 def isInIOThread():
89     """Are we in the thread responsable for I/O requests (the event loop)?
90     """
91     return ioThread == getThreadID()
92
93
94
95 def registerAsIOThread():
96     """Mark the current thread as responsable for I/O requests.
97     """
98     global ioThread
99     ioThread = getThreadID()
100
101
102 ioThread = None
103 threaded = False
104
105
106
107 try:
108     import thread as threadmodule
109     import threading as threadingmodule
110 except ImportError:
111     threadmodule = None
112     threadingmodule = None
113 else:
114     init(True)
115
116
117
118 __all__ = ['isInIOThread', 'registerAsIOThread', 'getThreadID', 'XLock']