2 * A type which wraps a pipe handle in message oriented mode
6 * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
9 #include "multiprocessing.h"
11 #define CLOSE(h) CloseHandle(h)
14 * Send string to the pipe; assumes in message oriented mode
18 conn_send_string(ConnectionObject
*conn
, char *string
, size_t length
)
23 Py_BEGIN_ALLOW_THREADS
24 ret
= WriteFile(conn
->handle
, string
, length
, &amount_written
, NULL
);
27 if (ret
== 0 && GetLastError() == ERROR_NO_SYSTEM_RESOURCES
) {
28 PyErr_Format(PyExc_ValueError
, "Cannnot send %" PY_FORMAT_SIZE_T
"d bytes over connection", length
);
29 return MP_STANDARD_ERROR
;
32 return ret
? MP_SUCCESS
: MP_STANDARD_ERROR
;
36 * Attempts to read into buffer, or if buffer too small into *newbuffer.
38 * Returns number of bytes read. Assumes in message oriented mode.
42 conn_recv_string(ConnectionObject
*conn
, char *buffer
,
43 size_t buflength
, char **newbuffer
, size_t maxlength
)
45 DWORD left
, length
, full_length
, err
;
49 Py_BEGIN_ALLOW_THREADS
50 ret
= ReadFile(conn
->handle
, buffer
, MIN(buflength
, maxlength
),
57 if (err
!= ERROR_MORE_DATA
) {
58 if (err
== ERROR_BROKEN_PIPE
)
59 return MP_END_OF_FILE
;
60 return MP_STANDARD_ERROR
;
63 if (!PeekNamedPipe(conn
->handle
, NULL
, 0, NULL
, NULL
, &left
))
64 return MP_STANDARD_ERROR
;
66 full_length
= length
+ left
;
67 if (full_length
> maxlength
)
68 return MP_BAD_MESSAGE_LENGTH
;
70 *newbuffer
= PyMem_Malloc(full_length
);
71 if (*newbuffer
== NULL
)
72 return MP_MEMORY_ERROR
;
74 memcpy(*newbuffer
, buffer
, length
);
76 Py_BEGIN_ALLOW_THREADS
77 ret
= ReadFile(conn
->handle
, *newbuffer
+length
, left
, &length
, NULL
);
80 assert(length
== left
);
83 PyMem_Free(*newbuffer
);
84 return MP_STANDARD_ERROR
;
89 * Check whether any data is available for reading
93 conn_poll(ConnectionObject
*conn
, double timeout
, PyThreadState
*_save
)
95 DWORD bytes
, deadline
, delay
;
99 if (!PeekNamedPipe(conn
->handle
, NULL
, 0, NULL
, &bytes
, NULL
))
100 return MP_STANDARD_ERROR
;
108 /* XXX does not check for overflow */
109 deadline
= GetTickCount() + (DWORD
)(1000 * timeout
+ 0.5);
113 for (delay
= 1 ; ; delay
+= 1) {
114 if (!PeekNamedPipe(conn
->handle
, NULL
, 0, NULL
, &bytes
, NULL
))
115 return MP_STANDARD_ERROR
;
120 difference
= deadline
- GetTickCount();
123 if ((int)delay
> difference
)
132 /* check for signals */
134 res
= PyErr_CheckSignals();
138 return MP_EXCEPTION_HAS_BEEN_SET
;
143 * "connection.h" defines the PipeConnection type using the definitions above
146 #define CONNECTION_NAME "PipeConnection"
147 #define CONNECTION_TYPE PipeConnectionType
149 #include "connection.h"