2008-06-13 16:28:21 -03:00
|
|
|
/*
|
|
|
|
* A type which wraps a pipe handle in message oriented mode
|
|
|
|
*
|
|
|
|
* pipe_connection.c
|
|
|
|
*
|
|
|
|
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "multiprocessing.h"
|
|
|
|
|
|
|
|
#define CLOSE(h) CloseHandle(h)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Send string to the pipe; assumes in message oriented mode
|
|
|
|
*/
|
|
|
|
|
|
|
|
static Py_ssize_t
|
|
|
|
conn_send_string(ConnectionObject *conn, char *string, size_t length)
|
|
|
|
{
|
2010-05-09 13:14:21 -03:00
|
|
|
DWORD amount_written;
|
|
|
|
BOOL ret;
|
2008-06-13 16:28:21 -03:00
|
|
|
|
2010-05-09 13:14:21 -03:00
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
|
|
ret = WriteFile(conn->handle, string, length, &amount_written, NULL);
|
|
|
|
Py_END_ALLOW_THREADS
|
Merged revisions 70908,70939,71009,71022,71036 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line
Issue 5619: Pass MS CRT debug flags into subprocesses
........
r70939 | jesse.noller | 2009-03-31 22:45:50 -0500 (Tue, 31 Mar 2009) | 1 line
Fix multiprocessing.event to match the new threading.Event API
........
r71009 | jesse.noller | 2009-04-01 19:03:28 -0500 (Wed, 01 Apr 2009) | 1 line
issue5545: Switch to Autoconf for multiprocessing; special thanks to Martin Lowis for help
........
r71022 | jesse.noller | 2009-04-01 21:32:55 -0500 (Wed, 01 Apr 2009) | 1 line
Issue 3110: Additional protection for SEM_VALUE_MAX on platforms, thanks to Martin Loewis
........
r71036 | jesse.noller | 2009-04-01 23:22:09 -0500 (Wed, 01 Apr 2009) | 1 line
Issue 3551: Raise ValueError if the size causes ERROR_NO_SYSTEM_RESOURCES
........
2009-04-05 18:24:58 -03:00
|
|
|
|
2010-05-09 13:14:21 -03:00
|
|
|
if (ret == 0 && GetLastError() == ERROR_NO_SYSTEM_RESOURCES) {
|
|
|
|
PyErr_Format(PyExc_ValueError, "Cannnot send %" PY_FORMAT_SIZE_T "d bytes over connection", length);
|
|
|
|
return MP_STANDARD_ERROR;
|
|
|
|
}
|
Merged revisions 70908,70939,71009,71022,71036 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line
Issue 5619: Pass MS CRT debug flags into subprocesses
........
r70939 | jesse.noller | 2009-03-31 22:45:50 -0500 (Tue, 31 Mar 2009) | 1 line
Fix multiprocessing.event to match the new threading.Event API
........
r71009 | jesse.noller | 2009-04-01 19:03:28 -0500 (Wed, 01 Apr 2009) | 1 line
issue5545: Switch to Autoconf for multiprocessing; special thanks to Martin Lowis for help
........
r71022 | jesse.noller | 2009-04-01 21:32:55 -0500 (Wed, 01 Apr 2009) | 1 line
Issue 3110: Additional protection for SEM_VALUE_MAX on platforms, thanks to Martin Loewis
........
r71036 | jesse.noller | 2009-04-01 23:22:09 -0500 (Wed, 01 Apr 2009) | 1 line
Issue 3551: Raise ValueError if the size causes ERROR_NO_SYSTEM_RESOURCES
........
2009-04-05 18:24:58 -03:00
|
|
|
|
2010-05-09 13:14:21 -03:00
|
|
|
return ret ? MP_SUCCESS : MP_STANDARD_ERROR;
|
2008-06-13 16:28:21 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Attempts to read into buffer, or if buffer too small into *newbuffer.
|
|
|
|
*
|
|
|
|
* Returns number of bytes read. Assumes in message oriented mode.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static Py_ssize_t
|
2010-05-09 13:14:21 -03:00
|
|
|
conn_recv_string(ConnectionObject *conn, char *buffer,
|
|
|
|
size_t buflength, char **newbuffer, size_t maxlength)
|
2008-06-13 16:28:21 -03:00
|
|
|
{
|
2010-05-09 13:14:21 -03:00
|
|
|
DWORD left, length, full_length, err;
|
|
|
|
BOOL ret;
|
|
|
|
*newbuffer = NULL;
|
|
|
|
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
|
|
ret = ReadFile(conn->handle, buffer, MIN(buflength, maxlength),
|
|
|
|
&length, NULL);
|
|
|
|
Py_END_ALLOW_THREADS
|
|
|
|
if (ret)
|
|
|
|
return length;
|
|
|
|
|
|
|
|
err = GetLastError();
|
|
|
|
if (err != ERROR_MORE_DATA) {
|
|
|
|
if (err == ERROR_BROKEN_PIPE)
|
|
|
|
return MP_END_OF_FILE;
|
|
|
|
return MP_STANDARD_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, NULL, &left))
|
|
|
|
return MP_STANDARD_ERROR;
|
|
|
|
|
|
|
|
full_length = length + left;
|
|
|
|
if (full_length > maxlength)
|
|
|
|
return MP_BAD_MESSAGE_LENGTH;
|
|
|
|
|
|
|
|
*newbuffer = PyMem_Malloc(full_length);
|
|
|
|
if (*newbuffer == NULL)
|
|
|
|
return MP_MEMORY_ERROR;
|
|
|
|
|
|
|
|
memcpy(*newbuffer, buffer, length);
|
|
|
|
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
|
|
ret = ReadFile(conn->handle, *newbuffer+length, left, &length, NULL);
|
|
|
|
Py_END_ALLOW_THREADS
|
|
|
|
if (ret) {
|
|
|
|
assert(length == left);
|
|
|
|
return full_length;
|
|
|
|
} else {
|
|
|
|
PyMem_Free(*newbuffer);
|
|
|
|
return MP_STANDARD_ERROR;
|
|
|
|
}
|
2008-06-13 16:28:21 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check whether any data is available for reading
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int
|
2009-01-19 20:23:01 -04:00
|
|
|
conn_poll(ConnectionObject *conn, double timeout, PyThreadState *_save)
|
2008-06-13 16:28:21 -03:00
|
|
|
{
|
2010-05-09 13:14:21 -03:00
|
|
|
DWORD bytes, deadline, delay;
|
|
|
|
int difference, res;
|
|
|
|
BOOL block = FALSE;
|
|
|
|
|
|
|
|
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
|
|
|
|
return MP_STANDARD_ERROR;
|
|
|
|
|
|
|
|
if (timeout == 0.0)
|
|
|
|
return bytes > 0;
|
|
|
|
|
|
|
|
if (timeout < 0.0)
|
|
|
|
block = TRUE;
|
|
|
|
else
|
|
|
|
/* XXX does not check for overflow */
|
|
|
|
deadline = GetTickCount() + (DWORD)(1000 * timeout + 0.5);
|
|
|
|
|
|
|
|
Sleep(0);
|
|
|
|
|
|
|
|
for (delay = 1 ; ; delay += 1) {
|
|
|
|
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
|
|
|
|
return MP_STANDARD_ERROR;
|
|
|
|
else if (bytes > 0)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (!block) {
|
|
|
|
difference = deadline - GetTickCount();
|
|
|
|
if (difference < 0)
|
|
|
|
return FALSE;
|
|
|
|
if ((int)delay > difference)
|
|
|
|
delay = difference;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (delay > 20)
|
|
|
|
delay = 20;
|
|
|
|
|
|
|
|
Sleep(delay);
|
|
|
|
|
|
|
|
/* check for signals */
|
|
|
|
Py_BLOCK_THREADS
|
|
|
|
res = PyErr_CheckSignals();
|
|
|
|
Py_UNBLOCK_THREADS
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
return MP_EXCEPTION_HAS_BEEN_SET;
|
|
|
|
}
|
2008-06-13 16:28:21 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "connection.h" defines the PipeConnection type using the definitions above
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define CONNECTION_NAME "PipeConnection"
|
|
|
|
#define CONNECTION_TYPE PipeConnectionType
|
|
|
|
|
|
|
|
#include "connection.h"
|