mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
...
This commit is contained in:
parent
70f23a4c76
commit
a514dc4fd7
@ -12,10 +12,9 @@ from Queue import Queue, Full
|
|||||||
from threading import Thread, current_thread, Lock
|
from threading import Thread, current_thread, Lock
|
||||||
from io import DEFAULT_BUFFER_SIZE, BytesIO
|
from io import DEFAULT_BUFFER_SIZE, BytesIO
|
||||||
|
|
||||||
from calibre.constants import iswindows
|
|
||||||
from calibre.srv.errors import MaxSizeExceeded
|
from calibre.srv.errors import MaxSizeExceeded
|
||||||
from calibre.srv.opts import Options
|
from calibre.srv.opts import Options
|
||||||
from calibre.srv.utils import socket_errors_to_ignore, socket_error_eintr, socket_errors_nonblocking, Corked
|
from calibre.srv.utils import socket_errors_to_ignore, socket_error_eintr, socket_errors_nonblocking, Corked, HandleInterrupt
|
||||||
from calibre.utils.socket_inheritance import set_socket_inherit
|
from calibre.utils.socket_inheritance import set_socket_inherit
|
||||||
from calibre.utils.logging import ThreadSafeLog
|
from calibre.utils.logging import ThreadSafeLog
|
||||||
|
|
||||||
@ -321,54 +320,6 @@ class SocketFile(object): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class HandleInterrupt(object): # {{{
|
|
||||||
|
|
||||||
# On windows socket functions like accept(), recv(), send() are not
|
|
||||||
# interrupted by a Ctrl-C in the console. So to make Ctrl-C work we have to
|
|
||||||
# use this special context manager. See the echo server example at the
|
|
||||||
# bottom of this file for how to use it.
|
|
||||||
|
|
||||||
def __init__(self, action):
|
|
||||||
if not iswindows:
|
|
||||||
return # Interrupts work fine on POSIX
|
|
||||||
self.action = action
|
|
||||||
from ctypes import WINFUNCTYPE, windll
|
|
||||||
from ctypes.wintypes import BOOL, DWORD
|
|
||||||
|
|
||||||
kernel32 = windll.LoadLibrary('kernel32')
|
|
||||||
|
|
||||||
# <http://msdn.microsoft.com/en-us/library/ms686016.aspx>
|
|
||||||
PHANDLER_ROUTINE = WINFUNCTYPE(BOOL, DWORD)
|
|
||||||
self.SetConsoleCtrlHandler = kernel32.SetConsoleCtrlHandler
|
|
||||||
self.SetConsoleCtrlHandler.argtypes = (PHANDLER_ROUTINE, BOOL)
|
|
||||||
self.SetConsoleCtrlHandler.restype = BOOL
|
|
||||||
|
|
||||||
@PHANDLER_ROUTINE
|
|
||||||
def handle(event):
|
|
||||||
if event == 0: # CTRL_C_EVENT
|
|
||||||
if self.action is not None:
|
|
||||||
self.action()
|
|
||||||
self.action = None
|
|
||||||
# Typical C implementations would return 1 to indicate that
|
|
||||||
# the event was processed and other control handlers in the
|
|
||||||
# stack should not be executed. However, that would
|
|
||||||
# prevent the Python interpreter's handler from translating
|
|
||||||
# CTRL-C to a `KeyboardInterrupt` exception, so we pretend
|
|
||||||
# that we didn't handle it.
|
|
||||||
return 0
|
|
||||||
self.handle = handle
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
if iswindows:
|
|
||||||
if self.SetConsoleCtrlHandler(self.handle, 1) == 0:
|
|
||||||
raise WindowsError()
|
|
||||||
|
|
||||||
def __exit__(self, *args):
|
|
||||||
if iswindows:
|
|
||||||
if self.SetConsoleCtrlHandler(self.handle, 0) == 0:
|
|
||||||
raise WindowsError()
|
|
||||||
# }}}
|
|
||||||
|
|
||||||
class Connection(object): # {{{
|
class Connection(object): # {{{
|
||||||
|
|
||||||
' A thin wrapper around an active socket '
|
' A thin wrapper around an active socket '
|
||||||
|
@ -12,6 +12,8 @@ from urlparse import parse_qs
|
|||||||
import repr as reprlib
|
import repr as reprlib
|
||||||
from email.utils import formatdate
|
from email.utils import formatdate
|
||||||
|
|
||||||
|
from calibre.constants import iswindows
|
||||||
|
|
||||||
def http_date(timeval=None):
|
def http_date(timeval=None):
|
||||||
return type('')(formatdate(timeval=timeval, usegmt=True))
|
return type('')(formatdate(timeval=timeval, usegmt=True))
|
||||||
|
|
||||||
@ -176,3 +178,52 @@ def eintr_retry_call(func, *args, **kwargs):
|
|||||||
if getattr(e, 'errno', None) in socket_errors_eintr:
|
if getattr(e, 'errno', None) in socket_errors_eintr:
|
||||||
continue
|
continue
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
class HandleInterrupt(object): # {{{
|
||||||
|
|
||||||
|
# On windows socket functions like accept(), recv(), send() are not
|
||||||
|
# interrupted by a Ctrl-C in the console. So to make Ctrl-C work we have to
|
||||||
|
# use this special context manager. See the echo server example at the
|
||||||
|
# bottom of this file for how to use it.
|
||||||
|
|
||||||
|
def __init__(self, action):
|
||||||
|
if not iswindows:
|
||||||
|
return # Interrupts work fine on POSIX
|
||||||
|
self.action = action
|
||||||
|
from ctypes import WINFUNCTYPE, windll
|
||||||
|
from ctypes.wintypes import BOOL, DWORD
|
||||||
|
|
||||||
|
kernel32 = windll.LoadLibrary('kernel32')
|
||||||
|
|
||||||
|
# <http://msdn.microsoft.com/en-us/library/ms686016.aspx>
|
||||||
|
PHANDLER_ROUTINE = WINFUNCTYPE(BOOL, DWORD)
|
||||||
|
self.SetConsoleCtrlHandler = kernel32.SetConsoleCtrlHandler
|
||||||
|
self.SetConsoleCtrlHandler.argtypes = (PHANDLER_ROUTINE, BOOL)
|
||||||
|
self.SetConsoleCtrlHandler.restype = BOOL
|
||||||
|
|
||||||
|
@PHANDLER_ROUTINE
|
||||||
|
def handle(event):
|
||||||
|
if event == 0: # CTRL_C_EVENT
|
||||||
|
if self.action is not None:
|
||||||
|
self.action()
|
||||||
|
self.action = None
|
||||||
|
# Typical C implementations would return 1 to indicate that
|
||||||
|
# the event was processed and other control handlers in the
|
||||||
|
# stack should not be executed. However, that would
|
||||||
|
# prevent the Python interpreter's handler from translating
|
||||||
|
# CTRL-C to a `KeyboardInterrupt` exception, so we pretend
|
||||||
|
# that we didn't handle it.
|
||||||
|
return 0
|
||||||
|
self.handle = handle
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
if iswindows:
|
||||||
|
if self.SetConsoleCtrlHandler(self.handle, 1) == 0:
|
||||||
|
raise WindowsError()
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
if iswindows:
|
||||||
|
if self.SetConsoleCtrlHandler(self.handle, 0) == 0:
|
||||||
|
raise WindowsError()
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user