Ϫfo2BdZddlZddlmZmZmZmZddlmZddl m Z ddl m Z ddl mZmZmZddlmZdd lmZd d lmZmZgfd ZGd deZdZdeegdfgdfdegdfdegdffdZeeGdde j8e j:Zy)aC This module provides base support for Twisted to interact with the glib/gtk mainloops. The classes in this module should not be used directly, but rather you should import gireactor or gtk3reactor for GObject Introspection based applications, or glib2reactor or gtk2reactor for applications using legacy static bindings. N)AnyCallableDictSet) implementer) posixbase)FileDescriptor) IReactorFDSetIReadDescriptorIWriteDescriptor)log) MonkeyPatcher)_IWaker _UnixWakerc|D],}tjj|#t||D]}dtj|<y)a[ Check whether the given modules were imported, and if requested, ensure they will not be importable in the future. @param moduleNames: A list of module names we make sure aren't imported. @type moduleNames: C{list} of C{str} @param preventImports: A list of module name whose future imports should be prevented. @type preventImports: C{list} of C{str} @param errorMessage: Message to use when raising an C{ImportError}. @type errorMessage: C{str} @raise ImportError: with given error message if a given module name has already been imported. N)sysmodulesget ImportError) moduleNames errorMessagepreventImportsnames NridleAddloopQuitr*cfdS)z Combine the C{glib.idle_add} and C{glib.MainLoop.quit} functions into a function suitable for crashing the reactor. cSr!r9r:srz_loopQuitter..^s 78$rr=r>s``r _loopQuitterr@Ws  %$rc eZdZdZdefdZddedededdffd Zfd Z d Z d Z d Z d Z dZdZdZdZdZdZdZddZdZdZddZdZdZdZxZS)GlibReactorBasea7 Base class for GObject event loop reactors. Notification for I/O events (reads and writes on file descriptors) is done by the gobject-based event loop. File descriptors are registered with gobject with the appropriate flags for read/write/disconnect notification. Time-based events, the results of C{callLater} and C{callFromThread}, are handled differently. Rather than registering each event with gobject, a single gobject timeout is registered for the earliest scheduled event, the output of C{reactor.timeout()}. For example, if there are timeouts in 1, 2 and 3.4 seconds, a single timeout is registered for 1 second in the future. When this timeout is hit, C{_simulate} is called, which calls the appropriate Twisted-level handlers, and a new timeout is added to gobject by the C{_reschedule} method. To handle C{callFromThread} events, we use a custom waker that calls C{_simulate} whenever it wakes up. @ivar _sources: A dictionary mapping L{FileDescriptor} instances to GSource handles. @ivar _reads: A set of L{FileDescriptor} instances currently monitored for reading. @ivar _writes: A set of L{FileDescriptor} instances currently monitored for writing. @ivar _simtag: A GSource handle for the next L{simulate} call. r*ct|Sr!)rr%s r _wakerFactoryzGlibReactorBase._wakerFactorys r glib_module gtk_moduleuseGtkNcd|_t|_t|_i|_||_|j j|j jz|j jz|_ |j j|_ |j j|_|j|jz|_|j|jz|_t"|I|j j&|_|j j*|_|j j/|_|j0j2|_|j0j6|_|j j;|_t?|j j@|j<jB|_"|j<jF|_$yr!)%_simtagset_reads_writes_sources_glib IOConditionHUPERRNVAL_POLL_DISCONNECTEDIN_POLL_INOUT _POLL_OUTINFLAGSOUTFLAGSr"r# source_remove_source_remove timeout_add _timeout_addmain_context_defaultcontextpending_pending iteration _iterationMainLooploopr@idle_addquit_crashrun_run)r%rFrGrHr&s rr#zGlibReactorBase.__init__si ,/E .1e 35     # # ' '%%)) *%%** +  $//22 $0044 }}t'>'>> )@)@@  "jj66 JJ22zz668  ,, ,,00JJ'') "4::#6#6 G IIMM rcRtfd}jd|y)zq Make sure the reactor's signal handlers are installed despite any outside interference. cnjjjjyr!)_signals uninstallinstallrDsr reinitSignalsz:GlibReactorBase._reallyStartRunning..reinitSignalss# MM # # % MM ! ! #rrN)r"_reallyStartRunning callLater)r%rqr&s` rrrz#GlibReactorBase._reallyStartRunnings% #% $ q-(rctdrfd}j}n}}|jj||jj||S)Nfilenoc|Sr!r=)ignored conditioncallbacksources rwrapperz*GlibReactorBase.input_add..wrappers 22r)hasattrrurO io_add_watchPRIORITY_DEFAULT_IDLE)r%rzrxryr{rus ` ` r input_addzGlibReactorBase.input_addsV 68 $ 3]]_FFGzz&&  JJ , ,     rcJtj||j|||y)z@ Called by event loop when an I/O event occurs. T)r callWithLogger_doReadOrWrite)r%rzrxs r_ioEventCallbackz GlibReactorBase._ioEventCallbacks# 64#6#6 Rrc||vry|}||vr#|j|j|||z}|j|||j|j|<|j |y)a Add the given L{FileDescriptor} for monitoring either for reading or writing. If the file is already monitored for the other operation, we delete the previous registration and re-register it for both reading and writing. N)r\rNrradd)r%rzprimaryother primaryFlag otherFlagflagss r_addzGlibReactorBase._addsi W   U?    f 5 6 Y E $vud>S>S T f Frc~|j||j|j|j|jy)zS Add a L{FileDescriptor} for monitoring of data available to read. N)rrLrMrYrZr%readers r addReaderzGlibReactorBase.addReaders( &$++t||T\\4==Qrc~|j||j|j|j|jy)zO Add a L{FileDescriptor} for monitoring ability to write data. N)rrMrLrZrYr%writers r addWriterzGlibReactorBase.addWriters( &$,, T]]DLLQrc,t|jS)zW Retrieve the list of current L{FileDescriptor} monitored for reading. )listrLrDs r getReaderszGlibReactorBase.getReaderssDKK  rc,t|jS)zW Retrieve the list of current L{FileDescriptor} monitored for writing. )rrMrDs r getWriterszGlibReactorBase.getWriterssDLL!!rcN|j|j|jS)zJ Remove monitoring for all registered L{FileDescriptor}s. ) _removeAllrLrMrDs r removeAllzGlibReactorBase.removeAll st{{DLL99rc||vry|j|j||j|||vr+|j|||j|j|<y|jj |y)z Remove monitoring the given L{FileDescriptor} for either reading or writing. If it's still monitored for the other operation, we re-register the L{FileDescriptor} for only that operation. N)r\rNremoverrpop)r%rzrrrs r_removezGlibReactorBase._removesl   DMM&12v U?$(NN65$BWBW$XDMM& ! MM  f %rch|j||j|j|jy)zJ Stop monitoring the given L{FileDescriptor} for reading. N)rrLrMrZrs r removeReaderzGlibReactorBase.removeReaders" VT[[$,, Frch|j||j|j|jy)zJ Stop monitoring the given L{FileDescriptor} for writing. N)rrMrLrYrs r removeWriterzGlibReactorBase.removeWriter$s" VT\\4;; Erc|j|jr#|jd|jr"yy)zv One iteration of the event loop, for trial's use. This is not used for actual reactor runs. rN)runUntilCurrentrbrd)r%delays riteratezGlibReactorBase.iterate*s0 mmo OOA mmorcbtjj||jy)z$ Crash the reactor. N)rPosixReactorBasecrashrirDs rrzGlibReactorBase.crash4s! ""((. rcbtjj||jy)z# Stop the reactor. N)rrstopwakeUprDs rrzGlibReactorBase.stop;s# ""''- rct5|j|j|j||jr|j dddy#1swYyxYw)z" Run the reactor. )installSignalHandlersN)r8callWhenRunning _reschedule startRunning_startedrk)r%rs rrjzGlibReactorBase.runIsT]   !1!1 2   4I  J}}    s A AA'cltjj|g|i|}|j|S)z, Schedule a C{DelayedCall}. )rrrsr)r%argskwargsresults rrszGlibReactorBase.callLaterSs7++55dLTLVL  rc |j"|j|jd|_|j}|D|jt |dz|j |j j|_yy)z; Schedule a glib timeout for C{_simulate}. Ni)priority)rJr\timeoutr^intr)rOr~)r%rs rrzGlibReactorBase._reschedule]st << #    -DL,,.  ,,GdN#99-DL rcD|j|jy)zX Run timers, and then reschedule glib timeout for next scheduled event. N)rrrDs rr)zGlibReactorBase._simulatels  r)F)r)T)r+r,r-r.rrErboolr#rrrrrrrrrrrrrrrrrjrsrr)r/r0s@rrBrBasBw"C"S"$"SW"B)B " R R ! " : &G F   rrB)r.rtypingrrrrzope.interfacertwisted.internetrtwisted.internet.abstractr twisted.internet.interfacesr r r twisted.pythonr twisted.python.monkeyrrnrrrrr8r@r_PollLikeMixinrBr=rrrs  ++&&4XX/)AC!6 ! !$% xD)*D0 1%=Eb$h=O% b$h% ]Oi00)2J2JOOr