@@ -52,12 +52,6 @@ typedef struct {
5252 };
5353} OverlappedObject ;
5454
55- typedef struct {
56- OVERLAPPED * Overlapped ;
57- HANDLE IocpHandle ;
58- char Address [1 ];
59- } WaitNamedPipeAndConnectContext ;
60-
6155/*
6256 * Map Windows error codes to subclasses of OSError
6357 */
@@ -1133,99 +1127,33 @@ Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args)
11331127 }
11341128}
11351129
1136- /* Unfortunately there is no way to do an overlapped connect to a
1137- pipe. We instead use WaitNamedPipe() and CreateFile() in a thread
1138- pool thread. If a connection succeeds within a time limit (10
1139- seconds) then PostQueuedCompletionStatus() is used to return the
1140- pipe handle to the completion port. */
1141-
1142- static DWORD WINAPI
1143- WaitNamedPipeAndConnectInThread (WaitNamedPipeAndConnectContext * ctx )
1144- {
1145- HANDLE PipeHandle = INVALID_HANDLE_VALUE ;
1146- DWORD Start = GetTickCount ();
1147- DWORD Deadline = Start + 10 * 1000 ;
1148- DWORD Error = 0 ;
1149- DWORD Timeout ;
1150- BOOL Success ;
1151-
1152- for ( ; ; ) {
1153- Timeout = Deadline - GetTickCount ();
1154- if ((int )Timeout < 0 )
1155- break ;
1156- Success = WaitNamedPipe (ctx -> Address , Timeout );
1157- Error = Success ? ERROR_SUCCESS : GetLastError ();
1158- switch (Error ) {
1159- case ERROR_SUCCESS :
1160- PipeHandle = CreateFile (ctx -> Address ,
1161- GENERIC_READ | GENERIC_WRITE ,
1162- 0 , NULL , OPEN_EXISTING ,
1163- FILE_FLAG_OVERLAPPED , NULL );
1164- if (PipeHandle == INVALID_HANDLE_VALUE )
1165- continue ;
1166- break ;
1167- case ERROR_SEM_TIMEOUT :
1168- continue ;
1169- }
1170- break ;
1171- }
1172- if (!PostQueuedCompletionStatus (ctx -> IocpHandle , Error ,
1173- (ULONG_PTR )PipeHandle , ctx -> Overlapped ))
1174- CloseHandle (PipeHandle );
1175- free (ctx );
1176- return 0 ;
1177- }
1178-
11791130PyDoc_STRVAR (
1180- Overlapped_WaitNamedPipeAndConnect_doc ,
1181- "WaitNamedPipeAndConnect(addr, iocp_handle) -> Overlapped[pipe_handle]\n\n"
1182- "Start overlapped connection to address, notifying iocp_handle when\n"
1183- "finished" );
1131+ ConnectPipe_doc ,
1132+ "ConnectPipe(addr) -> pipe_handle\n\n"
1133+ "Connect to the pipe for asynchronous I/O (overlapped)." );
11841134
11851135static PyObject *
1186- Overlapped_WaitNamedPipeAndConnect (OverlappedObject * self , PyObject * args )
1136+ ConnectPipe (OverlappedObject * self , PyObject * args )
11871137{
1188- char * Address ;
1189- Py_ssize_t AddressLength ;
1190- HANDLE IocpHandle ;
1191- OVERLAPPED Overlapped ;
1192- BOOL ret ;
1193- DWORD err ;
1194- WaitNamedPipeAndConnectContext * ctx ;
1195- Py_ssize_t ContextLength ;
1138+ PyObject * AddressObj ;
1139+ wchar_t * Address ;
1140+ HANDLE PipeHandle ;
11961141
1197- if (!PyArg_ParseTuple (args , "s#" F_HANDLE F_POINTER ,
1198- & Address , & AddressLength , & IocpHandle , & Overlapped ))
1142+ if (!PyArg_ParseTuple (args , "U" , & AddressObj ))
11991143 return NULL ;
12001144
1201- if ( self -> type != TYPE_NONE ) {
1202- PyErr_SetString ( PyExc_ValueError , "operation already attempted" );
1145+ Address = PyUnicode_AsWideCharString ( AddressObj , NULL );
1146+ if ( Address == NULL )
12031147 return NULL ;
1204- }
12051148
1206- ContextLength = (AddressLength +
1207- offsetof(WaitNamedPipeAndConnectContext , Address ));
1208- ctx = calloc (1 , ContextLength + 1 );
1209- if (ctx == NULL )
1210- return PyErr_NoMemory ();
1211- memcpy (ctx -> Address , Address , AddressLength + 1 );
1212- ctx -> Overlapped = & self -> overlapped ;
1213- ctx -> IocpHandle = IocpHandle ;
1214-
1215- self -> type = TYPE_WAIT_NAMED_PIPE_AND_CONNECT ;
1216- self -> handle = NULL ;
1217-
1218- Py_BEGIN_ALLOW_THREADS
1219- ret = QueueUserWorkItem (WaitNamedPipeAndConnectInThread , ctx ,
1220- WT_EXECUTELONGFUNCTION );
1221- Py_END_ALLOW_THREADS
1222-
1223- mark_as_completed (& self -> overlapped );
1224-
1225- self -> error = err = ret ? ERROR_SUCCESS : GetLastError ();
1226- if (!ret )
1227- return SetFromWindowsErr (err );
1228- Py_RETURN_NONE ;
1149+ PipeHandle = CreateFileW (Address ,
1150+ GENERIC_READ | GENERIC_WRITE ,
1151+ 0 , NULL , OPEN_EXISTING ,
1152+ FILE_FLAG_OVERLAPPED , NULL );
1153+ PyMem_Free (Address );
1154+ if (PipeHandle == INVALID_HANDLE_VALUE )
1155+ return SetFromWindowsErr (0 );
1156+ return Py_BuildValue (F_HANDLE , PipeHandle );
12291157}
12301158
12311159static PyObject *
@@ -1262,9 +1190,6 @@ static PyMethodDef Overlapped_methods[] = {
12621190 METH_VARARGS , Overlapped_DisconnectEx_doc },
12631191 {"ConnectNamedPipe" , (PyCFunction ) Overlapped_ConnectNamedPipe ,
12641192 METH_VARARGS , Overlapped_ConnectNamedPipe_doc },
1265- {"WaitNamedPipeAndConnect" ,
1266- (PyCFunction ) Overlapped_WaitNamedPipeAndConnect ,
1267- METH_VARARGS , Overlapped_WaitNamedPipeAndConnect_doc },
12681193 {NULL }
12691194};
12701195
@@ -1350,6 +1275,9 @@ static PyMethodDef overlapped_functions[] = {
13501275 METH_VARARGS , SetEvent_doc },
13511276 {"ResetEvent" , overlapped_ResetEvent ,
13521277 METH_VARARGS , ResetEvent_doc },
1278+ {"ConnectPipe" ,
1279+ (PyCFunction ) ConnectPipe ,
1280+ METH_VARARGS , ConnectPipe_doc },
13531281 {NULL }
13541282};
13551283
@@ -1394,6 +1322,7 @@ PyInit__overlapped(void)
13941322 WINAPI_CONSTANT (F_DWORD , ERROR_IO_PENDING );
13951323 WINAPI_CONSTANT (F_DWORD , ERROR_NETNAME_DELETED );
13961324 WINAPI_CONSTANT (F_DWORD , ERROR_SEM_TIMEOUT );
1325+ WINAPI_CONSTANT (F_DWORD , ERROR_PIPE_BUSY );
13971326 WINAPI_CONSTANT (F_DWORD , INFINITE );
13981327 WINAPI_CONSTANT (F_HANDLE , INVALID_HANDLE_VALUE );
13991328 WINAPI_CONSTANT (F_HANDLE , NULL );
0 commit comments