Changeset 3670
- Timestamp:
- 18/11/08 20:29:19 (7 weeks ago)
- Location:
- trunk/base
- Files:
-
- 4 modified
-
doc/notifier/mainloop.rst (modified) (5 diffs)
-
doc/notifier/threads.rst (modified) (4 diffs)
-
src/notifier/gobject.py (modified) (1 diff)
-
src/notifier/thread.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/base/doc/notifier/mainloop.rst
r3634 r3670 40 40 right now, you should use the kaa main loop. 41 41 42 GTK 43 --- 42 43 GObject / GTK Integration 44 ------------------------- 44 45 45 46 The generic notifier is compatible with the GTK/Glib mainloop and kaa … … 49 50 force the notifier loop to use GTK/Glib by calling init:: 50 51 51 import kaa .notifier52 kaa. notifier.init('gtk')52 import kaa 53 kaa.main.select_notifier('gtk') 53 54 54 55 This will the the GTK mainloop (the GTK mainloop is based on the glib … … 59 60 of packages requiring pyNotifier and not kaa.notifier is possible. 60 61 61 Twisted 62 ------- 62 A different approuch is to use the generic mainloop and start the 63 gobject mainloop in a thread. This may be useful when one loop is 64 extremly timing depended and it is a bad idea to block for even a 65 short time. As an example, kaa.candy uses this to keep the gobject 66 loop small and the animations alive even when the real mainloop is 67 very busy. 68 69 .. autofunction:: kaa.gobject_set_threaded 70 71 Note that callbacks from the gobject mainloop are called in that loop 72 and not the kaa mainloop. Make sure you decorate the mainloop with the 73 threaded decorator if necessary. For details about thread support see 74 :ref:`threads`. The `threaded` decorator can be used to force 75 execution of a function in the gobject mainloop. Use `kaa.GOBJECT` as 76 thread name:: 77 78 import kaa 79 80 @kaa.threaded(kaa.MAINTHREAD) 81 def executed_in_kaa_mainloop(): 82 ... 83 84 @kaa.threaded(kaa.GOBJECT) 85 def executed_in_gobject_mainloop(): 86 ... 87 88 kaa.main.select_notifier('generic') 89 kaa.gobject_set_threaded() 90 kaa.main.run() 91 92 93 Twisted Integration 94 ------------------- 63 95 64 96 Kaa.notifier defines a Twisted reactor to integrate the Twisted 65 97 mainloop into the kaa mainloop. After installing the reactor you can 66 either run kaa.main () or reactor.run() to start the mainloop. Due to67 t he internal design of Twisted you can not stop the mainloop from68 Twisted callbacks by calling sys.exit() or kaa. notifier.shutdown(),69 youneed to call reactor.stop(). From kaa callbacks sys.exit() and70 kaa. notifier.stop() is supported::98 either run kaa.main.run() or reactor.run() to start the mainloop. Due 99 to the internal design of Twisted you can not stop the mainloop from 100 Twisted callbacks by calling sys.exit() or kaa.main.shutdown(), you 101 need to call reactor.stop(). From kaa callbacks sys.exit() and 102 kaa.main.stop() is supported:: 71 103 72 104 # install special kaa reactor 73 105 import kaa.notifier.reactor 74 106 kaa.notifier.reactor.install() 75 107 76 108 # get reactor 77 109 from twisted.internet import reactor 78 110 79 111 # add callbacks to Twisted or kaa.notifier 80 112 # see test/twisted_in_kaa.py in the kaa.base package 81 82 # you can either call kaa.main () or reactor.run()83 kaa.main ()113 114 # you can either call kaa.main.run() or reactor.run() 115 kaa.main.run() 84 116 85 117 The Twisted reactor will work with any kaa.notifier backend (generic … … 92 124 # get reactor 93 125 from twisted.internet import reactor 94 95 import kaa .notifier96 kaa. notifier.init('twisted')97 126 127 import kaa 128 kaa.main.select_notifier('twisted') 129 98 130 # add callbacks to Twisted or kaa.notifier 99 131 # see test/kaa_in_twisted.py in the kaa.base package 100 132 101 133 # run Twisted mainloop 102 134 reactor.run() 135 103 136 104 137 Other mainloops … … 123 156 The following example will integrate the kaa mainloop in the normal 124 157 Twisted reactor. In this case the Twisted mainloop is running, 125 kaa.main () should not be called::158 kaa.main.run() should not be called:: 126 159 127 160 # get reactor 128 161 from twisted.internet import reactor 129 162 130 163 # start thread based mainloop and add Twisted callback 131 164 import kaa.notifier 132 kaa.notifier.init('thread', handler = reactor.callFromThread, 165 kaa.notifier.init('thread', handler = reactor.callFromThread, 133 166 shutdown = reactor.stop) 134 167 135 168 # add callbacks to Twisted or kaa.notifier 136 169 # see test/kaa_in_twisted.py in the kaa.base package 137 170 138 171 # run Twisted mainloop 139 172 reactor.run() -
trunk/base/doc/notifier/threads.rst
r3668 r3670 1 .. _threads: 2 1 3 Thread Support 2 4 ============== 3 5 4 FIXME: this section is just copied from the Wiki 6 .. autofunction:: kaa.is_mainthread 5 7 6 ThreadCallback 7 -------------- 8 .. function:: kaa.main.wakeup() 9 10 Wake up main thread. A thread can use this function to wake up a 11 mainloop waiting on a select. 12 13 14 Callback Classes for Threads 15 ---------------------------- 8 16 9 17 Kaa provides a ThreadCallback class which can be used to invoke a … … 42 50 print cb(3).wait() 43 51 44 As a rule of thumb, if you have a function that must always be called45 in the main thread, you would use @kaa.threaded(kaa.MAINTHREAD) as46 mentioned above, if you need to decide case-by-case, don't decorate it47 and use MainThreadCallback when needed.48 49 52 .. autoclass:: kaa.MainThreadCallback 50 53 54 55 .. _threaded: 51 56 52 57 The threaded decorator 53 58 ---------------------- 54 59 55 Any function or method may be decorated with @kaa.threaded()which60 Any function or method may be decorated with `@kaa.threaded()` which 56 61 takes two optional arguments: a thread name, and a priority. If a 57 62 thread name is specified, the decorated function is wrapped in 58 63 NamedThreadCallback, and invocations of that function are queued to be 59 executed in a single thread. If the thread name is kaa.MAINTHREAD the 60 decorated function is invoked from the main thread. If no thread name 61 is specified, the function is wrapped in ThreadCallback so that each 62 invocation is executed in a separate thread. Because these callbacks 63 returns InProgress objects, they may be yielded from coroutines. 64 executed in a single thread. If the thread name is `kaa.MAINTHREAD` 65 the decorated function is invoked from the main thread. If no thread 66 name is specified, the function is wrapped in ThreadCallback so that 67 each invocation is executed in a separate thread. Because these 68 callbacks returns InProgress objects, they may be yielded from 69 coroutines. 64 70 65 71 (This example uses Python 2.5 syntax.):: … … 79 85 print "Thread returned", result 80 86 81 The @kaa.threaded decorator also supports a async kwarg, which is by87 The threaded decorator also supports a async kwarg, which is by 82 88 default True. When True, the decorated function returns an InProgress 83 89 object. When False, however, invocation of the function blocks until … … 88 94 .. autofunction:: kaa.threaded 89 95 96 As a rule of thumb, if you have a function that must always be called 97 in the main thread, you would use `@kaa.threaded(kaa.MAINTHREAD)` as 98 mentioned above, if you need to decide case-by-case, don't decorate it 99 and use `MainThreadCallback` when needed. 90 100 91 Helper Functions92 ----------------93 101 94 .. autofunction:: kaa.is_mainthread 95 .. autofunction:: kaa.notifier.main.wakeup 102 The synchronized statement 103 -------------------------- 104 96 105 .. autoclass:: kaa.synchronized 97 106 98 Generic Mainloop and GObject Interaction 99 ---------------------------------------- 107 Some functions may be aware of threads and block simultaneous access 108 to specific functions. For this task, kaa has a synchronized class:: 100 109 101 FIXME: this section is not yet written 110 class Test(object): 102 111 103 .. autofunction:: kaa.gobject_set_threaded 112 def foo(self): 113 #unprotected 114 do_something() 115 with kaa.synchronized(self): 116 # protected block 117 do_something_else() 118 119 @kaa.synchronized() 120 def bar(self, x, y): 121 # protected function 122 do_something_else() 123 124 The decorator will synchronize on the actual object. Two different 125 objects can access the same function in two threads. On the other hand 126 it is not possible that one thread is in the protected block of `foo` 127 and another one calling `bar`. 128 129 The decorator can also be used for functions outside a class. In that 130 case the decorator only protects this one function. If more functions 131 should be protected against each other, a Python RLock object can be 132 provided:: 133 134 # threading.Lock does NOT work 135 lock = threading.RLock() 136 137 @kaa.synchronized(lock) 138 def foo(): 139 # foo and bar synchronized 140 do_something() 141 142 @kaa.synchronized(lock) 143 def bar(x): 144 # foo and bar synchronized 145 do_something() 146 147 @kaa.synchronized() 148 def baz(): 149 # only_baz_synchronized 150 do_something() 151 -
trunk/base/src/notifier/gobject.py
r3668 r3670 73 73 def set_threaded(self, mainloop=None): 74 74 """ 75 Start the gobject mainloop in a thread. This function should always 76 be used together with the generic notifier:: 77 78 kaa.main.select_notifier('generic') 79 kaa.gobject_set_threaded() 80 81 It is possible to jump between the gobject and the generic 82 mainloop with the threaded decorator. 75 Start the gobject mainloop in a thread. This function should 76 always be used together with the generic notifier. It is 77 possible to jump between the gobject and the generic mainloop 78 with the threaded decorator. 83 79 84 80 :param mainloop: the mainloop object to use a mainloop based on gobject -
trunk/base/src/notifier/thread.py
r3666 r3670 140 140 class synchronized(object): 141 141 """ 142 synchronized decorator and withstatement similar to synchronized142 synchronized decorator and `with` statement similar to synchronized 143 143 in Java. When decorating a non-member function, a lock or any class 144 inheriting from object must be provided. 144 inheriting from object may be provided. 145 146 :param obj: object were all calls should be synchronized to. 147 if not provided it will be the object for member functions 148 or an RLock for functions. 145 149 """ 146 150 def __init__(self, obj=None): 147 151 """ 148 Create a synchronized object. 149 @param obj: object were all calls should be synchronized to. 150 If not provided it will be the object for member functions 151 or an RLock for functions. 152 @note: when used on classes a new member C{_kaa_synchronized_lock} 153 will be added to that class. 152 Create a synchronized object. Note: when used on classes a new 153 member _kaa_synchronized_lock will be added to that class. 154 154 """ 155 155 if obj is None: … … 208 208 def is_mainthread(): 209 209 """ 210 Check if the current thread is the main thread 211 212 @return: True if the caller is in the main thread right now 210 Return True if the current thread is the main thread 213 211 """ 214 212 # If threading module is None, assume main thread. (Silences pointless
