ó
L]c           @   sÕ   d  Z  d d l Z d e f d „  ƒ  YZ e j d k r» d d l m Z m Z d d l m	 Z	 m
 Z
 e j d ƒ Z e e	 e
 ƒ Z e j Z e e	 f e _ e	 e _ d	 e f d
 „  ƒ  YZ n d	 e f d „  ƒ  YZ d S(   s   Win32 compatibility utilities.iÿÿÿÿNt   _allow_interruptc           B   s5   e  Z d  Z d d „ Z d „  Z d „  Z d „  Z RS(   sD  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.
    c         C   s   |  j  | ƒ d S(   s  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.
        N(   t   _init_action(   t   selft   action(    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyt   __init__>   s    	c         C   s   d  S(   N(    (   R   R   (    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyR   I   s    c         C   s   |  S(   N(    (   R   (    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyt	   __enter__L   s    c         G   s   d  S(   N(    (   R   t   args(    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyt   __exit__O   s    N(   t   __name__t
   __module__t   __doc__t   NoneR   R   R   R   (    (    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyR       s
   1		t   nt(   t   WINFUNCTYPEt   windll(   t   BOOLt   DWORDt   kernel32t   allow_interruptc           B   s,   e  Z e j Z d  „  Z d „  Z d „  Z RS(   c            sC   ˆ  d  k r d „  ‰  n  ˆ  |  _ t ‡  f d †  ƒ } | |  _ d  S(   Nc           S   s   d  S(   N(   R   (    (    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyt   <lambda>c   t    c            s   |  d k r ˆ  ƒ  n  d S(   Ni    (    (   t   event(   R   (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyt   handlee   s    
(   R   R   t   PHANDLER_ROUTINER   (   R   R   R   (    (   R   s.   lib/python2.7/site-packages/zmq/utils/win32.pyR   a   s
    	c         C   s.   t  |  j d ƒ } | d k r* t ƒ  ‚ n  d S(   s"   Install the custom CTRL-C handler.i   i    N(   t   SetConsoleCtrlHandlerR   t   WindowsError(   R   t   result(    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyR   r   s    c         G   s.   t  |  j d ƒ } | d k r* t ƒ  ‚ n  d S(   s!   Remove the custom CTRL-C handler.i    N(   R   R   R   (   R   R   R   (    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyR   z   s    (   R   R	   R    R
   R   R   R   (    (    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyR   ^   s   			c           B   s   e  Z e j Z RS(    (   R   R	   R    R
   (    (    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyR   ‚   s   	(   R
   t   ost   objectR    t   namet   ctypesR   R   t   ctypes.wintypesR   R   t   LoadLibraryR   R   R   t   argtypest   restypeR   (    (    (    s.   lib/python2.7/site-packages/zmq/utils/win32.pyt   <module>   s   G		$