
    Qh=B                     6   S r SSKrSSKrSSKrSSKrSSKrSSKJrJrJ	r	J
r
JrJr  \" S5      rSrSr/ SQr " S S	\5      r " S
 S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      rSqS\\   4S jrSS\R6                  S\4S jjrg)aI  Libvirt event loop implementation using asyncio

Register the implementation of default loop:

    import asyncio
    import libvirtaio

    async def myapp():
      libvirtaio.virEventRegisterAsyncIOImpl()

      conn = libvirt.open("test:///default")

For compatibility with Python < 3.7:

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    loop.run_until_complete(myapp())

    asyncio.set_event_loop(None)
    loop.close()

If Python >= 3.7 can be required then

    asyncio.run(myapp())

.. seealso::
    https://libvirt.org/html/libvirt-libvirt-event.html
    N)AnyCallableDict	GeneratorOptionalTypeVar_Tz,Wojtek Porczyk <woju@invisiblethingslab.com>z	LGPL-2.1+)getCurrentImplvirEventAsyncIOImplvirEventRegisterAsyncIOImplc                      ^  \ rS rSrSr\R                  " 5       rSSS\\	\
/S4   S\
S\S	\S
S4U 4S jjrS
\4S jrSS jrSrU =r$ )CallbackE   zBase class for holding callback

:param virEventAsyncIOImpl impl: the implementation in which we run
:param cb: the callback itself
:param opaque: the opaque tuple passed by libvirt
implr   cbNopaqueargskwargsreturnc                 ~   > [         TU ]  " U0 UD6  [        U R                  5      U l        Xl        X l        X0l        g N)super__init__next_iden_counteridenr   r   r   )selfr   r   r   r   r   	__class__s         ,/usr/lib/python3/dist-packages/libvirtaio.pyr   Callback.__init__P   s6    $)&)++,		    c                 b    SR                  U R                  R                  U R                  5      $ )Nz<{} iden={}>)formatr   __name__r   r   s    r   __repr__Callback.__repr__W   s#    $$T^^%<%<diiHHr!   c                     U R                   R                  R                  SU R                  5        U R                   R	                  U R                  U R
                  5        g)zSchedule *ff* callbackz"callback %d close(), scheduling ffN)r   logdebugr   schedule_ff_callbackr   r%   s    r   closeCallback.closeZ   s;    		@$))L		&&tyy$++>r!   )r   r   r   r   r   N)r$   
__module____qualname____firstlineno____doc__	itertoolscountr   r   intr	   r   r   strr&   r,   __static_attributes____classcell__r   s   @r   r   r   E   ss     OO%M2 #rD8Q [] fi ux   ~B I# I? ?r!   r   c                   f    \ rS rSrSrSSS\SS4S jrS	\SS4S
 jrSS jrSS jr	S\SS4S jr
Srg)
Descriptord   zManager of one file descriptor

:param virEventAsyncIOImpl impl: the implementation in which we run
:param int fd: the file descriptor
r   r   fdr   Nc                 *    Xl         X l        0 U l        g r   )r   r=   	callbacks)r   r   r=   s      r   r   Descriptor.__init__j   s    	r!   eventc                    [        U R                  R                  5       5       HY  nUR                  c  M  UR                  U-  (       d  M(  UR	                  UR
                  U R                  XR                  5        M[     g)zoDispatch the event to the descriptors

:param int event: The event (from libvirt's constants) being dispatched
N)listr?   valuesrA   r   r   r=   r   )r   rA   callbacks      r   _handleDescriptor._handleo   sT    
 T^^2245H~~)hnnu.D.DHMM477E??K 6r!   c                 8   [        S U R                  R                  5        5       5      (       a  [        R                  " S[
        5        [        S U R                  R                  5        5       5      (       aJ  U R                  R                  R                  U R                  U R                  [        R                  5        O/U R                  R                  R                  U R                  5        [        S U R                  R                  5        5       5      (       aJ  U R                  R                  R                  U R                  U R                  [        R                  5        gU R                  R                  R!                  U R                  5        g)zsRegister or unregister callbacks at event loop

This should be called after change of any ``.event`` in callbacks.
c              3      #    U  H4  nUR                   [        R                  [        R                  -  ) -  v   M6     g 7fr   )rA   libvirtVIR_EVENT_HANDLE_READABLEVIR_EVENT_HANDLE_WRITABLE.0rE   s     r   	<genexpr>$Descriptor.update.<locals>.<genexpr>   s@      9 !8H ~~----.!/ / !8s   <>zTThe only event supported are VIR_EVENT_HANDLE_READABLE and VIR_EVENT_HANDLE_WRITABLEc              3   \   #    U  H"  nUR                   [        R                  -  v   M$     g 7fr   )rA   rJ   rK   rM   s     r   rO   rP      &      9 7H ~~ A AA 7   *,c              3   \   #    U  H"  nUR                   [        R                  -  v   M$     g 7fr   )rA   rJ   rL   rM   s     r   rO   rP      rR   rS   N)anyr?   rD   warningswarnUserWarningr   loop
add_readerr=   rF   rJ   rK   remove_reader
add_writerrL   remove_writerr%   s    r   updateDescriptor.updatex   s#     9 !% 5 5 79 9 9 MM0
  9 $ 5 5 79 9 9IINN%%w'H'HJ IINN((1 9 $ 5 5 79 9 9IINN%%w'H'HJ IINN((1r!   c                 T    XR                   UR                  '   U R                  5         g)zAdd a callback to the descriptor

:param FDCallback callback: the callback to add
:rtype: None

After adding the callback, it is immediately watched.
N)r?   r   r^   )r   rE   s     r   
add_handleDescriptor.add_handle   s     )1x}}%r!   r   c                 \    U R                   R                  U5      nU R                  5         U$ )zRemove a callback from the descriptor

:param int iden: the identifier of the callback
:returns: the callback
:rtype: FDCallback

After removing the callback, the descriptor may be unwatched, if there
are no more handles for it.
)r?   popr^   )r   r   rE   s      r   remove_handleDescriptor.remove_handle   s&     >>%%d+r!   )r?   r=   r   r.   )rE   
FDCallbackr   N)r$   r/   r0   r1   r2   r5   r   rF   r^   ra   re   r7    r!   r   r;   r;   d   sV    
2   
LS LT L 2D	# $ r!   r;   c                   B   ^  \ rS rSrSrSU 4S jjrS\S\4S jrSr	U =r
$ )	DescriptorDict   z\Descriptors collection

This is used internally by virEventAsyncIOImpl to hold descriptors.
r   c                 .   > [         TU ]  5         Xl        g r   )r   r   r   )r   r   r   s     r   r   DescriptorDict.__init__   s    	r!   r=   c                 :    [        U R                  U5      nX U'   U$ r   )r;   r   )r   r=   
descriptors      r   __missing__DescriptorDict.__missing__   s    		2.
Rr!   )r   )r   r   r   N)r$   r/   r0   r1   r2   r   r5   r;   rp   r7   r8   r9   s   @r   rj   rj      s%    c j  r!   rj   c            
       d   ^  \ rS rSrSrS\S\S\S\SS4
U 4S	 jjrS\	4S
 jr
S\SS4S jrSrU =r$ )rg      zCallback for file descriptor (watcher)

:param Descriptor descriptor: the descriptor manager
:param int event: bitset of events on which to fire the callback
r   ro   rA   r   r   Nc                >   > [         TU ]  " U0 UD6  Xl        X l        g r   )r   r   ro   rA   )r   ro   rA   r   r   r   s        r   r   FDCallback.__init__   s    $)&)$
r!   c                     SR                  U R                  R                  U R                  U R                  R
                  U R                  5      $ )Nz<{} iden={} fd={} event={}>)r#   r   r$   r   ro   r=   rA   r%   s    r   r&   FDCallback.__repr__   s<    ,33NN##TYY0B0BDJJP 	Pr!   c                 D    Xl         U R                  R                  5         g)z1Update the callback and fix descriptor's watchersN)rA   ro   r^   )r   rA   s     r   r^   FDCallback.update   s    
 r!   ro   rA   )r$   r/   r0   r1   r2   r   r;   r5   r   r6   r&   r^   r7   r8   r9   s   @r   rg   rg      sX    c z # QT Y] 
P# P!C !D ! !r!   rg   c                      ^  \ rS rSrSrS\S\SS4U 4S jjrS\4S jrS\	\SS4   4S	 jr
S
\SS4S jrSU 4S jjrSrU =r$ )TimeoutCallback   zCallback for timerr   r   r   Nc                 B   > [         TU ]  " U0 UD6  SU l        S U l        g )N)r   r   timeout_task)r   r   r   r   s      r   r   TimeoutCallback.__init__   s#    $)&)
r!   c                 x    SR                  U R                  R                  U R                  U R                  5      $ )Nz<{} iden={} timeout={}>)r#   r   r$   r   r   r%   s    r   r&   TimeoutCallback.__repr__   s.    (//NN##TYY> 	>r!   c                 `  #      U R                   S:  aT  U R                   S-  nU R                  R                  R                  SU5        [        R
                  " U5      I Sh  vN   O[        R
                  " S5      I Sh  vN    U R                  U R                  U R                  5        U R                  R                  R                  SU R                  5        M   N| N_! [        R                   a3    U R                  R                  R                  SU R                  5         gf = f7f)zAAn actual timer running on the event loop.

This is a coroutine.
r   gMbP?zsleeping %rNztimer %d cancelledztimer %r callback ended)
r   r   r)   r*   asynciosleepCancelledErrorr   r   r   r   r   s     r   _timerTimeoutCallback._timer   s     
 <<!#"llT1GIIMM''w?!--000 "--*** GGDIIt{{+IIMM 9499E 
 1 +)) 		##$8$))Ds[   D.AC$ #C $C$ (D.)C$ C"C$ AD. C$ "C$ $AD+(D.*D++D.r   c                    Xl         U R                   S:  az  U R                  cm  U R                  R                  R	                  SU R
                  5        [        R                  " U R                  5       U R                  R                  S9U l        gU R                   S:  a`  U R                  bR  U R                  R                  R	                  SU R
                  5        U R                  R                  5         SU l        ggg)z-Start or the timer, possibly updating timeoutr   Nztimer %r startrY   ztimer %r stop)r   r   r   r)   r*   r   r   ensure_futurer   rY   cancelr   s     r   r^   TimeoutCallback.update   s    <<1!3IIMM 0$))< ..t{{}48IINNDDJ \\A$**"8IIMM;JJDJ #9r!   c                 H   > U R                  SS9  [        [        U ]  5         g)z#Stop the timer and call ff callbackr   r   N)r^   r   r|   r,   )r   r   s    r   r,   TimeoutCallback.close  s    Bot*,r!   )r   r   r.   )r$   r/   r0   r1   r2   r   r   r6   r&   r   r   r5   r^   r,   r7   r8   r9   s   @r   r|   r|      sb    c S T 
># >FiT48 F,c d - -r!   r|   c            
       b   \ rS rSrSrSS\R                  SS4S jjrS\4S jr	SS jr
SS	 jrS S
 jrS\S\SS4S jrS\S\SS4S jrSS jrS\4S jrS\S\S\R*                  S\S\4
S jrS\S\SS4S jrS\S\4S jrS\S\R2                  S\S\4S jrS\S\SS4S jrS\S\4S jrSrg)!r   i  zLibvirt event adapter to asyncio.

:param loop: asyncio's event loop

If *loop* is not specified, the current (or default) event loop is used.
NrY   r   c                     U=(       d    [         R                  " 5       U l        0 U l        [	        U 5      U l        [        R                  " U R                  R                  5      U l
        SU l        S U l        g )Nr   )r   get_event_looprY   r?   rj   descriptorslogging	getLoggerr   r$   r)   _pending	_finished)r   rY   s     r   r   virEventAsyncIOImpl.__init__  sW    4G224	)$/$$T^^%<%<= r!   c                 v    SR                  [        U 5      R                  U R                  U R                  5      $ )Nz <{} callbacks={} descriptors={}>)r#   typer$   r?   r   r%   s    r   r&   virEventAsyncIOImpl.__repr__+  s2    188J1A1AC 	Cr!   c                 ~    U =R                   S-  sl         U R                  b  U R                  R                  5         gg)z;Increase the count of pending affairs. Do not use directly.   N)r   r   clearr%   s    r   _pending_inc virEventAsyncIOImpl._pending_inc/  s/    >>%NN  " &r!   c                     U R                   S:  d   eU =R                   S-  sl         U R                   S:X  a)  U R                  b  U R                  R                  5         ggg)z;Decrease the count of pending affairs. Do not use directly.r   r   N)r   r   setr%   s    r   _pending_dec virEventAsyncIOImpl._pending_dec5  sO    }}q   ==A$.."<NN  #=r!   c                     U R                   R                  S5        [        R                  " U R                  U R
                  U R                  U R                  U R                  U R                  5        U $ )z3Register this instance as event loop implementationz
register())
r)   r*   rJ   virEventRegisterImpl_add_handle_update_handle_remove_handle_add_timeout_update_timeout_remove_timeoutr%   s    r   registervirEventAsyncIOImpl.register<  s\     	|$$$d1143F3Ft33T5I5I	K r!   r   r   c                 `    [         R                  " U R                  X5      U R                  S9  g)z8Schedule a ff callback from one of the handles or timersr   N)r   r   _ff_callbackrY   r   r   r   s      r   r+   (virEventAsyncIOImpl.schedule_ff_callbackE  s!    d//=DIINr!   c                    #    U R                   R                  SU5        [        R                  " U5        U R	                  5         g7f)z6Directly free the opaque object

This is a coroutine.
z ff_callback(iden=%d, opaque=...)N)r)   r*   rJ   virEventInvokeFreeCallbackr   r   s      r   r    virEventAsyncIOImpl._ff_callbackI  s4     
 	94@**62s   AAc                 f  #    U R                   R                  S5        U R                  (       ad  U R                  b   e[        R
                  " 5       U l        U R                  R                  5       I Sh  vN   SU l        U R                  S:X  d   eU R                   R                  S5        g N97f)zBWait for the implementation to become idle.

This is a coroutine.
zdrain()Nr   zdrain ended)r)   r*   r   r   r   Eventwaitr%   s    r   drainvirEventAsyncIOImpl.drainR  s     
 	y!==>>)))$]]_DN..%%'''!DN==A%%%}% (s   A3B15B/6:B1c                 T    U R                   (       + =(       a    U R                  (       + $ )zReturns False if there are leftovers from a connection

Those may happen if there are sematical problems while closing
a connection. For example, not deregistered events before .close().
)r?   r   r%   s    r   is_idlevirEventAsyncIOImpl.is_idle`  s     >>!7$--&77r!   r=   rA   r   c                 ^   [        XUU R                  U   US9nUR                  U R                  ;  d   eU R                  R                  SXUR                  5        XPR                  UR                  '   U R                  U   R                  U5        U R                  5         UR                  $ )a  Register a callback for monitoring file handle events

:param int fd: file descriptor to listen on
:param int event: bitset of events on which to fire the callback
:param cb: the callback to be called when an event occurrs
:param opaque: user data to pass to the callback
:rtype: int
:returns: handle watch number to be used for updating and unregistering for events

.. seealso::
    https://libvirt.org/html/libvirt-libvirt-event.html#virEventAddHandleFuncFunc
rz   z4add_handle(fd=%d, event=%d, cb=..., opaque=...) = %d)rg   r   r   r?   r)   r*   ra   r   )r   r=   rA   r   r   rE   s         r   r   virEventAsyncIOImpl._add_handleh  s     d)-)9)9")=UL}}DNN222M(--	1(0x}}%''1}}r!   watchc                     U R                   R                  SX5        U R                  U   n[        U[        5      (       d   eUR                  US9  g)zChange event set for a monitored file handle

:param int watch: file descriptor watch to modify
:param int event: new events to listen on

.. seealso::
    https://libvirt.org/html/libvirt-libvirt-event.html#virEventUpdateHandleFunc
z!update_handle(watch=%d, event=%d))rA   N)r)   r*   r?   
isinstancerg   r^   )r   r   rA   rE   s       r   r   "virEventAsyncIOImpl._update_handle  sF     	:EI>>%((J////e$r!   c                    U R                   R                  SU5         U R                  R                  U5      n[        U[        5      (       d   eUR                  R                  nX R                  U   R                  U5      L d   e[        U R                  U   R                  5      S:X  a  U R                  U	 UR                  5         g! [         a3  nU R                   R                  SUR                  S   5         SnAgSnAff = f)zUnregister a callback from a file handle.

:param int watch: file descriptor watch to stop listening on
:returns: -1 on error, 0 on success

.. seealso::
    https://libvirt.org/html/libvirt-libvirt-event.html#virEventRemoveHandleFunc
zremove_handle(watch=%d)z#remove_handle(): no such handle: %rr   Nr   )r)   r*   r?   rd   KeyErrorwarningr   r   rg   ro   r=   r   re   lenr,   )r   r   rE   errr=   s        r   r   "virEventAsyncIOImpl._remove_handle  s     	0%8	~~))%0H (J////  ##++B/==eDDDDt#--.!3  $  	HHBCHHQKP	s   C 
D	)DD	r   c                 $   [        XU5      nUR                  U R                  ;  d   eU R                  R	                  SXR                  5        X@R                  UR                  '   UR                  US9  U R                  5         UR                  $ )a=  Register a callback for a timer event

:param int timeout: the timeout to monitor
:param cb: the callback to call when timeout has expired
:param opaque: user data to pass to the callback
:rtype: int
:returns: a timer value

.. seealso::
    https://libvirt.org/html/libvirt-libvirt-event.html#virEventAddTimeoutFunc
z0add_timeout(timeout=%d, cb=..., opaque=...) = %dr   )r|   r   r?   r)   r*   r^   r   )r   r   r   r   rE   s        r   r    virEventAsyncIOImpl._add_timeout  st     #4V4}}DNN222I	/(0x}}%(}}r!   timerc                     U R                   R                  SX5        U R                  U   n[        U[        5      (       d   eUR                  US9  g)zChange frequency for a timer

:param int timer: the timer to modify
:param int timeout: the new timeout value in ms

.. seealso::
    https://libvirt.org/html/libvirt-libvirt-event.html#virEventUpdateTimeoutFunc
z$update_timeout(timer=%d, timeout=%d)r   N)r)   r*   r?   r   r|   r^   )r   r   r   rE   s       r   r   #virEventAsyncIOImpl._update_timeout  sF     	=uN>>%((O4444(r!   c                    U R                   R                  SU5         U R                  R                  U5      nUR                  5         g! [         a3  nU R                   R                  SUR                  S   5         SnAgSnAff = f)zUnregister a callback for a timer

:param int timer: the timer to remove
:returns: -1 on error, 0 on success

.. seealso::
    https://libvirt.org/html/libvirt-libvirt-event.html#virEventRemoveTimeoutFunc
zremove_timeout(timer=%d)z%remove_timeout(): no such timeout: %rr   Nr   )r)   r*   r?   rd   r   r   r   r,   )r   r   rE   r   s       r   r   #virEventAsyncIOImpl._remove_timeout  sq     	159	~~))%0H 		  	HHDchhqkR	s   A
 

B)BB)r   r   r?   r   r)   rY   r   r.   )r   r   )r$   r/   r0   r1   r2   r   AbstractEventLoopr   r6   r&   r   r   r   r5   r	   r+   r   r   boolr   rJ   _EventCBr   r   r   _TimerCBr   r   r   r7   rh   r!   r   r   r     s6   
W66 
$ 
C# C#!O Ob OT Os B 4 &8 8c # 73C3C R TW 0%C % % %C C .C W-=-= r c ,)S )3 )4 )S S r!   r   r   c                      [         $ )z@Return the current implementation, or None if not yet registered)_current_implrh   r!   r   r
   r
     s    r!   rY   c                 <    [        U S9R                  5       q[        $ )zArrange for libvirt's callbacks to be dispatched via asyncio event loop

The implementation object is returned, but in normal usage it can safely be
discarded.
r   )r   r   r   r   s    r   r   r     s     (T2;;=Mr!   r   )r2   r   r3   r   rV   rJ   typingr   r   r   r   r   r   r	   
__author____license____all__objectr   r;   dictrj   rg   r|   r   r   r
   r   r   rh   r!   r   <module>r      s   (<      D DT];
?v ?>M M`T ! !62-h 2-rB& BJ !45 
g&?&? K^ r!   