Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: third_party/twisted_8_1/twisted/internet/gtk2reactor.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.internet.test.test_gtk2reactor -*-
2 # Copyright (c) 2001-2008 Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5
6 """
7 This module provides support for Twisted to interact with the glib/gtk2
8 mainloop.
9
10 In order to use this support, simply do the following::
11
12 | from twisted.internet import gtk2reactor
13 | gtk2reactor.install()
14
15 Then use twisted.internet APIs as usual. The other methods here are not
16 intended to be called directly.
17
18 When installing the reactor, you can choose whether to use the glib
19 event loop or the GTK+ event loop which is based on it but adds GUI
20 integration.
21
22 Maintainer: U{Itamar Shtull-Trauring<mailto:twisted@itamarst.org>}
23 """
24
25 # System Imports
26 import sys
27 from zope.interface import implements
28 try:
29 if not hasattr(sys, 'frozen'):
30 # Don't want to check this for py2exe
31 import pygtk
32 pygtk.require('2.0')
33 except (ImportError, AttributeError):
34 pass # maybe we're using pygtk before this hack existed.
35 import gobject
36 if hasattr(gobject, "threads_init"):
37 # recent versions of python-gtk expose this. python-gtk=2.4.1
38 # (wrapping glib-2.4.7) does. python-gtk=2.0.0 (wrapping
39 # glib-2.2.3) does not.
40 gobject.threads_init()
41
42 # Twisted Imports
43 from twisted.python import log, runtime, failure
44 from twisted.internet.interfaces import IReactorFDSet
45 from twisted.internet import main, posixbase, error, selectreactor
46
47 POLL_DISCONNECTED = gobject.IO_HUP | gobject.IO_ERR | gobject.IO_NVAL
48
49 # glib's iochannel sources won't tell us about any events that we haven't
50 # asked for, even if those events aren't sensible inputs to the poll()
51 # call.
52 INFLAGS = gobject.IO_IN | POLL_DISCONNECTED
53 OUTFLAGS = gobject.IO_OUT | POLL_DISCONNECTED
54
55 def _our_mainquit():
56 # XXX: gtk.main_quit() (which is used for crash()) raises an exception if
57 # gtk.main_level() == 0; however, all the tests freeze if we use this
58 # function to stop the reactor. what gives? (I believe this may have been
59 # a stupid mistake where I forgot to import gtk here... I will remove this
60 # comment if the tests pass)
61 import gtk
62 if gtk.main_level():
63 gtk.main_quit()
64
65 class Gtk2Reactor(posixbase.PosixReactorBase):
66 """
67 GTK+-2 event loop reactor.
68
69 @ivar _reads: A dictionary mapping L{FileDescriptor} instances to gtk
70 INPUT_READ watch handles.
71
72 @ivar _writes: A dictionary mapping L{FileDescriptor} instances to gtk
73 INTPUT_WRITE watch handles.
74
75 @ivar _simtag: A gtk timeout handle for the next L{simulate} call.
76 """
77 implements(IReactorFDSet)
78
79 def __init__(self, useGtk=True):
80 self.context = gobject.main_context_default()
81 self.loop = gobject.MainLoop()
82 self._simtag = None
83 self._reads = {}
84 self._writes = {}
85 posixbase.PosixReactorBase.__init__(self)
86 # pre 2.3.91 the glib iteration and mainloop functions didn't release
87 # global interpreter lock, thus breaking thread and signal support.
88 if (hasattr(gobject, "pygtk_version") and gobject.pygtk_version >= (2, 3 , 91)
89 and not useGtk):
90 self.__pending = self.context.pending
91 self.__iteration = self.context.iteration
92 self.__crash = self.loop.quit
93 self.__run = self.loop.run
94 else:
95 import gtk
96 self.__pending = gtk.events_pending
97 self.__iteration = gtk.main_iteration
98 self.__crash = _our_mainquit
99 self.__run = gtk.main
100
101 # The input_add function in pygtk1 checks for objects with a
102 # 'fileno' method and, if present, uses the result of that method
103 # as the input source. The pygtk2 input_add does not do this. The
104 # function below replicates the pygtk1 functionality.
105
106 # In addition, pygtk maps gtk.input_add to _gobject.io_add_watch, and
107 # g_io_add_watch() takes different condition bitfields than
108 # gtk_input_add(). We use g_io_add_watch() here in case pygtk fixes this
109 # bug.
110 def input_add(self, source, condition, callback):
111 if hasattr(source, 'fileno'):
112 # handle python objects
113 def wrapper(source, condition, real_s=source, real_cb=callback):
114 return real_cb(real_s, condition)
115 return gobject.io_add_watch(source.fileno(), condition, wrapper)
116 else:
117 return gobject.io_add_watch(source, condition, callback)
118
119 def addReader(self, reader):
120 if reader not in self._reads:
121 self._reads[reader] = self.input_add(reader, INFLAGS, self.callback)
122
123 def addWriter(self, writer):
124 if writer not in self._writes:
125 self._writes[writer] = self.input_add(writer, OUTFLAGS, self.callbac k)
126
127
128 def getReaders(self):
129 return self._reads.keys()
130
131
132 def getWriters(self):
133 return self._writes.keys()
134
135
136 def removeAll(self):
137 return self._removeAll(self._reads, self._writes)
138
139 def removeReader(self, reader):
140 if reader in self._reads:
141 gobject.source_remove(self._reads[reader])
142 del self._reads[reader]
143
144 def removeWriter(self, writer):
145 if writer in self._writes:
146 gobject.source_remove(self._writes[writer])
147 del self._writes[writer]
148
149 doIterationTimer = None
150
151 def doIterationTimeout(self, *args):
152 self.doIterationTimer = None
153 return 0 # auto-remove
154
155 def doIteration(self, delay):
156 # flush some pending events, return if there was something to do
157 # don't use the usual "while self.context.pending(): self.context.iterat ion()"
158 # idiom because lots of IO (in particular test_tcp's
159 # ProperlyCloseFilesTestCase) can keep us from ever exiting.
160 log.msg(channel='system', event='iteration', reactor=self)
161 if self.__pending():
162 self.__iteration(0)
163 return
164 # nothing to do, must delay
165 if delay == 0:
166 return # shouldn't delay, so just return
167 self.doIterationTimer = gobject.timeout_add(int(delay * 1000),
168 self.doIterationTimeout)
169 # This will either wake up from IO or from a timeout.
170 self.__iteration(1) # block
171 # note: with the .simulate timer below, delays > 0.1 will always be
172 # woken up by the .simulate timer
173 if self.doIterationTimer:
174 # if woken by IO, need to cancel the timer
175 gobject.source_remove(self.doIterationTimer)
176 self.doIterationTimer = None
177
178 def crash(self):
179 posixbase.PosixReactorBase.crash(self)
180 self.__crash()
181
182 def run(self, installSignalHandlers=1):
183 self.startRunning(installSignalHandlers=installSignalHandlers)
184 gobject.timeout_add(0, self.simulate)
185 if not self._stopped:
186 self.__run()
187
188 def _doReadOrWrite(self, source, condition, faildict={
189 error.ConnectionDone: failure.Failure(error.ConnectionDone()),
190 error.ConnectionLost: failure.Failure(error.ConnectionLost()),
191 }):
192 why = None
193 didRead = None
194 if condition & POLL_DISCONNECTED and \
195 not (condition & gobject.IO_IN):
196 why = main.CONNECTION_LOST
197 else:
198 try:
199 if condition & gobject.IO_IN:
200 why = source.doRead()
201 didRead = source.doRead
202 if not why and condition & gobject.IO_OUT:
203 # if doRead caused connectionLost, don't call doWrite
204 # if doRead is doWrite, don't call it again.
205 if not source.disconnected and source.doWrite != didRead:
206 why = source.doWrite()
207 didRead = source.doWrite # if failed it was in write
208 except:
209 why = sys.exc_info()[1]
210 log.msg('Error In %s' % source)
211 log.deferr()
212
213 if why:
214 self._disconnectSelectable(source, why, didRead == source.doRead)
215
216 def callback(self, source, condition):
217 log.callWithLogger(source, self._doReadOrWrite, source, condition)
218 self.simulate() # fire Twisted timers
219 return 1 # 1=don't auto-remove the source
220
221 def simulate(self):
222 """Run simulation loops and reschedule callbacks.
223 """
224 if self._simtag is not None:
225 gobject.source_remove(self._simtag)
226 self.runUntilCurrent()
227 timeout = min(self.timeout(), 0.1)
228 if timeout is None:
229 timeout = 0.1
230 # grumble
231 self._simtag = gobject.timeout_add(int(timeout * 1010), self.simulate)
232
233
234 class PortableGtkReactor(selectreactor.SelectReactor):
235 """Reactor that works on Windows.
236
237 input_add is not supported on GTK+ for Win32, apparently.
238 """
239
240 def crash(self):
241 selectreactor.SelectReactor.crash(self)
242 import gtk
243 # mainquit is deprecated in newer versions
244 if hasattr(gtk, 'main_quit'):
245 gtk.main_quit()
246 else:
247 gtk.mainquit()
248
249 def run(self, installSignalHandlers=1):
250 import gtk
251 self.startRunning(installSignalHandlers=installSignalHandlers)
252 self.simulate()
253 # mainloop is deprecated in newer versions
254 if hasattr(gtk, 'main'):
255 gtk.main()
256 else:
257 gtk.mainloop()
258
259 def simulate(self):
260 """Run simulation loops and reschedule callbacks.
261 """
262 if self._simtag is not None:
263 gobject.source_remove(self._simtag)
264 self.iterate()
265 timeout = min(self.timeout(), 0.1)
266 if timeout is None:
267 timeout = 0.1
268 # grumble
269 self._simtag = gobject.timeout_add(int(timeout * 1010), self.simulate)
270
271
272 def install(useGtk=True):
273 """Configure the twisted mainloop to be run inside the gtk mainloop.
274
275 @param useGtk: should glib rather than GTK+ event loop be
276 used (this will be slightly faster but does not support GUI).
277 """
278 reactor = Gtk2Reactor(useGtk)
279 from twisted.internet.main import installReactor
280 installReactor(reactor)
281 return reactor
282
283 def portableInstall(useGtk=True):
284 """Configure the twisted mainloop to be run inside the gtk mainloop.
285 """
286 reactor = PortableGtkReactor()
287 from twisted.internet.main import installReactor
288 installReactor(reactor)
289 return reactor
290
291 if runtime.platform.getType() != 'posix':
292 install = portableInstall
293
294
295 __all__ = ['install']
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/internet/glib2reactor.py ('k') | third_party/twisted_8_1/twisted/internet/gtkreactor.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698