
    fL                    @    d Z ddlmZ ddlZddlmZmZ  G d d      Zy)zWin32 compatibility utilities.    )annotationsN)AnyCallablec                  ,    e Zd ZdZdddZd Zd Zd Zy)	allow_interruptaD  Utility for fixing CTRL-C events on Windows.

    On Windows, the Python interpreter intercepts CTRL-C events in order to
    translate them into ``KeyboardInterrupt`` exceptions.  It (presumably)
    does this by setting a flag in its "console control handler" and
    checking it later at a convenient location in the interpreter.

    However, when the Python interpreter is blocked waiting for the ZMQ
    poll operation to complete, it must wait for ZMQ's ``select()``
    operation to complete before translating the CTRL-C event into the
    ``KeyboardInterrupt`` exception.

    The only way to fix this seems to be to add our own "console control
    handler" and perform some application-defined operation that will
    unblock the ZMQ polling operation in order to force ZMQ to pass control
    back to the Python interpreter.

    This context manager performs all that Windows-y stuff, providing you
    with a hook that is called when a CTRL-C event is intercepted.  This
    hook allows you to unblock your ZMQ poll operation immediately, which
    will then result in the expected ``KeyboardInterrupt`` exception.

    Without this context manager, your ZMQ-based application will not
    respond normally to CTRL-C events on Windows.  If a CTRL-C event occurs
    while blocked on ZMQ socket polling, the translation to a
    ``KeyboardInterrupt`` exception will be delayed until the I/O completes
    and control returns to the Python interpreter (this may never happen if
    you use an infinite timeout).

    A no-op implementation is provided on non-Win32 systems to avoid the
    application from having to conditionally use it.

    Example usage:

    .. sourcecode:: python

       def stop_my_application():
           # ...

       with allow_interrupt(stop_my_application):
           # main polling loop.

    In a typical ZMQ application, you would use the "self pipe trick" to
    send message to a ``PAIR`` socket in order to interrupt your blocking
    socket polling operation.

    In a Tornado event loop, you can use the ``IOLoop.stop`` method to
    unblock your I/O loop.
    Nc                N    t         j                  dk7  ry| j                  |       y)a  Translate ``action`` into a CTRL-C handler.

        ``action`` is a callable that takes no arguments and returns no
        value (returned value is ignored).  It must *NEVER* raise an
        exception.

        If unspecified, a no-op will be used.
        ntN)osname_init_action)selfactions     J/var/www/cvtools/html/venv/lib/python3.12/site-packages/zmq/utils/win32.py__init__zallow_interrupt.__init__@   s      77d?&!    c                    ddl m}m} ddlm}m} |j                  d      } |||      }|j                  x}| _        ||f|_	        ||_
        d | _        |fd       }	|	| _        y )Nr   )WINFUNCTYPEwindll)BOOLDWORDkernel32c                      y N r   r   r   r   z,allow_interrupt._init_action.<locals>.action]   s    r   c                    | dk(  r         y)Nr   r   )eventr   s    r   handlez,allow_interrupt._init_action.<locals>.handleb   s    z r   )ctypesr   r   ctypes.wintypesr   r   LoadLibrarySetConsoleCtrlHandler_SetConsoleCtrlHandlerargtypesrestyper   r   )
r   r   r   r   r   r   r   PHANDLER_ROUTINEr!   r   s
    `        r   r   zallow_interrupt._init_actionM   s    ./%%j1 'tU3**	
 ; +;D)A&(,%> 			 
		 r   c                    t         j                  dk7  ry| j                  | j                  d      }|dk(  r
t	               y)z"Install the custom CTRL-C handler.r	   N   r   r
   r   r"   r   OSError)r   results     r   	__enter__zallow_interrupt.__enter__p   ;    77d?,,T[[!<Q; )O r   c                    t         j                  dk7  ry| j                  | j                  d      }|dk(  r
t	               y)z!Remove the custom CTRL-C handler.r	   Nr   r(   )r   argsr*   s      r   __exit__zallow_interrupt.__exit__z   r,   r   r   )r   zCallable[[], Any] | NonereturnNone)__name__
__module____qualname____doc__r   r   r+   r/   r   r   r   r   r      s    0d"!Fr   r   )r5   
__future__r   r
   typingr   r   r   r   r   r   <module>r8      s    $ # 	  u ur   