summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <joffrey@docker.com>2016-10-26 18:04:25 -0700
committerJoffrey F <joffrey@docker.com>2016-10-26 18:04:25 -0700
commit163a1ce371f8a661e2e170293d8cd9312121da35 (patch)
treeb061c40ff1c9d297122086962ec2f62042d2b2ac
parentc7dabbfa37e7251d018af4ef65e24e24764dbf80 (diff)
downloaddocker-py-npipe-socket-busy-retry.tar.gz
Implement retry logic when the npipe open procedure failsnpipe-socket-busy-retry
with ERROR_PIPE_BUSY Signed-off-by: Joffrey F <joffrey@docker.com>
-rw-r--r--docker/transport/npipesocket.py34
1 files changed, 24 insertions, 10 deletions
diff --git a/docker/transport/npipesocket.py b/docker/transport/npipesocket.py
index a9bf0cc..509cabf 100644
--- a/docker/transport/npipesocket.py
+++ b/docker/transport/npipesocket.py
@@ -5,9 +5,11 @@ import six
import win32file
import win32pipe
+cERROR_PIPE_BUSY = 0xe7
cSECURITY_SQOS_PRESENT = 0x100000
cSECURITY_ANONYMOUS = 0
-cPIPE_READMODE_MESSAGE = 2
+
+RETRY_WAIT_TIMEOUT = 10000
def check_closed(f):
@@ -46,15 +48,27 @@ class NpipeSocket(object):
@check_closed
def connect(self, address):
win32pipe.WaitNamedPipe(address, self._timeout)
- handle = win32file.CreateFile(
- address,
- win32file.GENERIC_READ | win32file.GENERIC_WRITE,
- 0,
- None,
- win32file.OPEN_EXISTING,
- cSECURITY_ANONYMOUS | cSECURITY_SQOS_PRESENT,
- 0
- )
+ try:
+ handle = win32file.CreateFile(
+ address,
+ win32file.GENERIC_READ | win32file.GENERIC_WRITE,
+ 0,
+ None,
+ win32file.OPEN_EXISTING,
+ cSECURITY_ANONYMOUS | cSECURITY_SQOS_PRESENT,
+ 0
+ )
+ except win32pipe.error as e:
+ # See Remarks:
+ # https://msdn.microsoft.com/en-us/library/aa365800.aspx
+ if e.winerror == cERROR_PIPE_BUSY:
+ # Another program or thread has grabbed our pipe instance
+ # before we got to it. Wait for availability and attempt to
+ # connect again.
+ win32pipe.WaitNamedPipe(address, RETRY_WAIT_TIMEOUT)
+ return self.connect(address)
+ raise e
+
self.flags = win32pipe.GetNamedPipeInfo(handle)[0]
self._handle = handle