fix multiprocessing line endings in py3k
This commit is contained in:
parent
53a5b0d351
commit
fa268032c9
|
@ -1,328 +1,328 @@
|
||||||
/*
|
/*
|
||||||
* Extension module used by multiprocessing package
|
* Extension module used by multiprocessing package
|
||||||
*
|
*
|
||||||
* multiprocessing.c
|
* multiprocessing.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
|
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "multiprocessing.h"
|
#include "multiprocessing.h"
|
||||||
|
|
||||||
PyObject *create_win32_namespace(void);
|
PyObject *create_win32_namespace(void);
|
||||||
|
|
||||||
PyObject *pickle_dumps, *pickle_loads, *pickle_protocol;
|
PyObject *pickle_dumps, *pickle_loads, *pickle_protocol;
|
||||||
PyObject *ProcessError, *BufferTooShort;
|
PyObject *ProcessError, *BufferTooShort;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function which raises exceptions based on error codes
|
* Function which raises exceptions based on error codes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
mp_SetError(PyObject *Type, int num)
|
mp_SetError(PyObject *Type, int num)
|
||||||
{
|
{
|
||||||
switch (num) {
|
switch (num) {
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
case MP_STANDARD_ERROR:
|
case MP_STANDARD_ERROR:
|
||||||
if (Type == NULL)
|
if (Type == NULL)
|
||||||
Type = PyExc_WindowsError;
|
Type = PyExc_WindowsError;
|
||||||
PyErr_SetExcFromWindowsErr(Type, 0);
|
PyErr_SetExcFromWindowsErr(Type, 0);
|
||||||
break;
|
break;
|
||||||
case MP_SOCKET_ERROR:
|
case MP_SOCKET_ERROR:
|
||||||
if (Type == NULL)
|
if (Type == NULL)
|
||||||
Type = PyExc_WindowsError;
|
Type = PyExc_WindowsError;
|
||||||
PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
|
PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
|
||||||
break;
|
break;
|
||||||
#else /* !MS_WINDOWS */
|
#else /* !MS_WINDOWS */
|
||||||
case MP_STANDARD_ERROR:
|
case MP_STANDARD_ERROR:
|
||||||
case MP_SOCKET_ERROR:
|
case MP_SOCKET_ERROR:
|
||||||
if (Type == NULL)
|
if (Type == NULL)
|
||||||
Type = PyExc_OSError;
|
Type = PyExc_OSError;
|
||||||
PyErr_SetFromErrno(Type);
|
PyErr_SetFromErrno(Type);
|
||||||
break;
|
break;
|
||||||
#endif /* !MS_WINDOWS */
|
#endif /* !MS_WINDOWS */
|
||||||
case MP_MEMORY_ERROR:
|
case MP_MEMORY_ERROR:
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
break;
|
break;
|
||||||
case MP_END_OF_FILE:
|
case MP_END_OF_FILE:
|
||||||
PyErr_SetNone(PyExc_EOFError);
|
PyErr_SetNone(PyExc_EOFError);
|
||||||
break;
|
break;
|
||||||
case MP_EARLY_END_OF_FILE:
|
case MP_EARLY_END_OF_FILE:
|
||||||
PyErr_SetString(PyExc_IOError,
|
PyErr_SetString(PyExc_IOError,
|
||||||
"got end of file during message");
|
"got end of file during message");
|
||||||
break;
|
break;
|
||||||
case MP_BAD_MESSAGE_LENGTH:
|
case MP_BAD_MESSAGE_LENGTH:
|
||||||
PyErr_SetString(PyExc_IOError, "bad message length");
|
PyErr_SetString(PyExc_IOError, "bad message length");
|
||||||
break;
|
break;
|
||||||
case MP_EXCEPTION_HAS_BEEN_SET:
|
case MP_EXCEPTION_HAS_BEEN_SET:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_Format(PyExc_RuntimeError,
|
PyErr_Format(PyExc_RuntimeError,
|
||||||
"unkown error number %d", num);
|
"unkown error number %d", num);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Windows only
|
* Windows only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
|
|
||||||
/* On Windows we set an event to signal Ctrl-C; compare with timemodule.c */
|
/* On Windows we set an event to signal Ctrl-C; compare with timemodule.c */
|
||||||
|
|
||||||
HANDLE sigint_event = NULL;
|
HANDLE sigint_event = NULL;
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
ProcessingCtrlHandler(DWORD dwCtrlType)
|
ProcessingCtrlHandler(DWORD dwCtrlType)
|
||||||
{
|
{
|
||||||
SetEvent(sigint_event);
|
SetEvent(sigint_event);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unix only
|
* Unix only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#else /* !MS_WINDOWS */
|
#else /* !MS_WINDOWS */
|
||||||
|
|
||||||
#if HAVE_FD_TRANSFER
|
#if HAVE_FD_TRANSFER
|
||||||
|
|
||||||
/* Functions for transferring file descriptors between processes.
|
/* Functions for transferring file descriptors between processes.
|
||||||
Reimplements some of the functionality of the fdcred
|
Reimplements some of the functionality of the fdcred
|
||||||
module at http://www.mca-ltd.com/resources/fdcred_1.tgz. */
|
module at http://www.mca-ltd.com/resources/fdcred_1.tgz. */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
multiprocessing_sendfd(PyObject *self, PyObject *args)
|
multiprocessing_sendfd(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int conn, fd, res;
|
int conn, fd, res;
|
||||||
char dummy_char;
|
char dummy_char;
|
||||||
char buf[CMSG_SPACE(sizeof(int))];
|
char buf[CMSG_SPACE(sizeof(int))];
|
||||||
struct msghdr msg = {0};
|
struct msghdr msg = {0};
|
||||||
struct iovec dummy_iov;
|
struct iovec dummy_iov;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ii", &conn, &fd))
|
if (!PyArg_ParseTuple(args, "ii", &conn, &fd))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dummy_iov.iov_base = &dummy_char;
|
dummy_iov.iov_base = &dummy_char;
|
||||||
dummy_iov.iov_len = 1;
|
dummy_iov.iov_len = 1;
|
||||||
msg.msg_control = buf;
|
msg.msg_control = buf;
|
||||||
msg.msg_controllen = sizeof(buf);
|
msg.msg_controllen = sizeof(buf);
|
||||||
msg.msg_iov = &dummy_iov;
|
msg.msg_iov = &dummy_iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
cmsg->cmsg_level = SOL_SOCKET;
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
cmsg->cmsg_type = SCM_RIGHTS;
|
cmsg->cmsg_type = SCM_RIGHTS;
|
||||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||||
msg.msg_controllen = cmsg->cmsg_len;
|
msg.msg_controllen = cmsg->cmsg_len;
|
||||||
*(int*)CMSG_DATA(cmsg) = fd;
|
*(int*)CMSG_DATA(cmsg) = fd;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
res = sendmsg(conn, &msg, 0);
|
res = sendmsg(conn, &msg, 0);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return PyErr_SetFromErrno(PyExc_OSError);
|
return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
multiprocessing_recvfd(PyObject *self, PyObject *args)
|
multiprocessing_recvfd(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int conn, fd, res;
|
int conn, fd, res;
|
||||||
char dummy_char;
|
char dummy_char;
|
||||||
char buf[CMSG_SPACE(sizeof(int))];
|
char buf[CMSG_SPACE(sizeof(int))];
|
||||||
struct msghdr msg = {0};
|
struct msghdr msg = {0};
|
||||||
struct iovec dummy_iov;
|
struct iovec dummy_iov;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "i", &conn))
|
if (!PyArg_ParseTuple(args, "i", &conn))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dummy_iov.iov_base = &dummy_char;
|
dummy_iov.iov_base = &dummy_char;
|
||||||
dummy_iov.iov_len = 1;
|
dummy_iov.iov_len = 1;
|
||||||
msg.msg_control = buf;
|
msg.msg_control = buf;
|
||||||
msg.msg_controllen = sizeof(buf);
|
msg.msg_controllen = sizeof(buf);
|
||||||
msg.msg_iov = &dummy_iov;
|
msg.msg_iov = &dummy_iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
cmsg->cmsg_level = SOL_SOCKET;
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
cmsg->cmsg_type = SCM_RIGHTS;
|
cmsg->cmsg_type = SCM_RIGHTS;
|
||||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||||
msg.msg_controllen = cmsg->cmsg_len;
|
msg.msg_controllen = cmsg->cmsg_len;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
res = recvmsg(conn, &msg, 0);
|
res = recvmsg(conn, &msg, 0);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return PyErr_SetFromErrno(PyExc_OSError);
|
return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
|
||||||
fd = *(int*)CMSG_DATA(cmsg);
|
fd = *(int*)CMSG_DATA(cmsg);
|
||||||
return Py_BuildValue("i", fd);
|
return Py_BuildValue("i", fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_FD_TRANSFER */
|
#endif /* HAVE_FD_TRANSFER */
|
||||||
|
|
||||||
#endif /* !MS_WINDOWS */
|
#endif /* !MS_WINDOWS */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All platforms
|
* All platforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
multiprocessing_address_of_buffer(PyObject *self, PyObject *obj)
|
multiprocessing_address_of_buffer(PyObject *self, PyObject *obj)
|
||||||
{
|
{
|
||||||
void *buffer;
|
void *buffer;
|
||||||
Py_ssize_t buffer_len;
|
Py_ssize_t buffer_len;
|
||||||
|
|
||||||
if (PyObject_AsWriteBuffer(obj, &buffer, &buffer_len) < 0)
|
if (PyObject_AsWriteBuffer(obj, &buffer, &buffer_len) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return Py_BuildValue("N" F_PY_SSIZE_T,
|
return Py_BuildValue("N" F_PY_SSIZE_T,
|
||||||
PyLong_FromVoidPtr(buffer), buffer_len);
|
PyLong_FromVoidPtr(buffer), buffer_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function table
|
* Function table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
{"address_of_buffer", multiprocessing_address_of_buffer, METH_O,
|
{"address_of_buffer", multiprocessing_address_of_buffer, METH_O,
|
||||||
"address_of_buffer(obj) -> int\n"
|
"address_of_buffer(obj) -> int\n"
|
||||||
"Return address of obj assuming obj supports buffer inteface"},
|
"Return address of obj assuming obj supports buffer inteface"},
|
||||||
#if HAVE_FD_TRANSFER
|
#if HAVE_FD_TRANSFER
|
||||||
{"sendfd", multiprocessing_sendfd, METH_VARARGS,
|
{"sendfd", multiprocessing_sendfd, METH_VARARGS,
|
||||||
"sendfd(sockfd, fd) -> None\n"
|
"sendfd(sockfd, fd) -> None\n"
|
||||||
"Send file descriptor given by fd over the unix domain socket\n"
|
"Send file descriptor given by fd over the unix domain socket\n"
|
||||||
"whose file decriptor is sockfd"},
|
"whose file decriptor is sockfd"},
|
||||||
{"recvfd", multiprocessing_recvfd, METH_VARARGS,
|
{"recvfd", multiprocessing_recvfd, METH_VARARGS,
|
||||||
"recvfd(sockfd) -> fd\n"
|
"recvfd(sockfd) -> fd\n"
|
||||||
"Receive a file descriptor over a unix domain socket\n"
|
"Receive a file descriptor over a unix domain socket\n"
|
||||||
"whose file decriptor is sockfd"},
|
"whose file decriptor is sockfd"},
|
||||||
#endif
|
#endif
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize
|
* Initialize
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct PyModuleDef multiprocessing_module = {
|
static struct PyModuleDef multiprocessing_module = {
|
||||||
PyModuleDef_HEAD_INIT,
|
PyModuleDef_HEAD_INIT,
|
||||||
"_multiprocessing",
|
"_multiprocessing",
|
||||||
NULL,
|
NULL,
|
||||||
-1,
|
-1,
|
||||||
module_methods,
|
module_methods,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
PyInit__multiprocessing(void)
|
PyInit__multiprocessing(void)
|
||||||
{
|
{
|
||||||
PyObject *module, *temp, *value;
|
PyObject *module, *temp, *value;
|
||||||
|
|
||||||
/* Initialize module */
|
/* Initialize module */
|
||||||
module = PyModule_Create(&multiprocessing_module);
|
module = PyModule_Create(&multiprocessing_module);
|
||||||
if (!module)
|
if (!module)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Get copy of objects from pickle */
|
/* Get copy of objects from pickle */
|
||||||
temp = PyImport_ImportModule(PICKLE_MODULE);
|
temp = PyImport_ImportModule(PICKLE_MODULE);
|
||||||
if (!temp)
|
if (!temp)
|
||||||
return NULL;
|
return NULL;
|
||||||
pickle_dumps = PyObject_GetAttrString(temp, "dumps");
|
pickle_dumps = PyObject_GetAttrString(temp, "dumps");
|
||||||
pickle_loads = PyObject_GetAttrString(temp, "loads");
|
pickle_loads = PyObject_GetAttrString(temp, "loads");
|
||||||
pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
|
pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
|
||||||
Py_XDECREF(temp);
|
Py_XDECREF(temp);
|
||||||
|
|
||||||
/* Get copy of BufferTooShort */
|
/* Get copy of BufferTooShort */
|
||||||
temp = PyImport_ImportModule("multiprocessing");
|
temp = PyImport_ImportModule("multiprocessing");
|
||||||
if (!temp)
|
if (!temp)
|
||||||
return NULL;
|
return NULL;
|
||||||
BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
|
BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
|
||||||
Py_XDECREF(temp);
|
Py_XDECREF(temp);
|
||||||
|
|
||||||
/* Add connection type to module */
|
/* Add connection type to module */
|
||||||
if (PyType_Ready(&ConnectionType) < 0)
|
if (PyType_Ready(&ConnectionType) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_INCREF(&ConnectionType);
|
Py_INCREF(&ConnectionType);
|
||||||
PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);
|
PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);
|
||||||
|
|
||||||
#if defined(MS_WINDOWS) || HAVE_SEM_OPEN
|
#if defined(MS_WINDOWS) || HAVE_SEM_OPEN
|
||||||
/* Add SemLock type to module */
|
/* Add SemLock type to module */
|
||||||
if (PyType_Ready(&SemLockType) < 0)
|
if (PyType_Ready(&SemLockType) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_INCREF(&SemLockType);
|
Py_INCREF(&SemLockType);
|
||||||
PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX",
|
PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX",
|
||||||
Py_BuildValue("i", SEM_VALUE_MAX));
|
Py_BuildValue("i", SEM_VALUE_MAX));
|
||||||
PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType);
|
PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
/* Add PipeConnection to module */
|
/* Add PipeConnection to module */
|
||||||
if (PyType_Ready(&PipeConnectionType) < 0)
|
if (PyType_Ready(&PipeConnectionType) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_INCREF(&PipeConnectionType);
|
Py_INCREF(&PipeConnectionType);
|
||||||
PyModule_AddObject(module, "PipeConnection",
|
PyModule_AddObject(module, "PipeConnection",
|
||||||
(PyObject*)&PipeConnectionType);
|
(PyObject*)&PipeConnectionType);
|
||||||
|
|
||||||
/* Initialize win32 class and add to multiprocessing */
|
/* Initialize win32 class and add to multiprocessing */
|
||||||
temp = create_win32_namespace();
|
temp = create_win32_namespace();
|
||||||
if (!temp)
|
if (!temp)
|
||||||
return NULL;
|
return NULL;
|
||||||
PyModule_AddObject(module, "win32", temp);
|
PyModule_AddObject(module, "win32", temp);
|
||||||
|
|
||||||
/* Initialize the event handle used to signal Ctrl-C */
|
/* Initialize the event handle used to signal Ctrl-C */
|
||||||
sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
if (!sigint_event) {
|
if (!sigint_event) {
|
||||||
PyErr_SetFromWindowsErr(0);
|
PyErr_SetFromWindowsErr(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
|
if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
|
||||||
PyErr_SetFromWindowsErr(0);
|
PyErr_SetFromWindowsErr(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Add configuration macros */
|
/* Add configuration macros */
|
||||||
temp = PyDict_New();
|
temp = PyDict_New();
|
||||||
if (!temp)
|
if (!temp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#define ADD_FLAG(name) \
|
#define ADD_FLAG(name) \
|
||||||
value = Py_BuildValue("i", name); \
|
value = Py_BuildValue("i", name); \
|
||||||
if (value == NULL) { Py_DECREF(temp); return NULL; } \
|
if (value == NULL) { Py_DECREF(temp); return NULL; } \
|
||||||
if (PyDict_SetItemString(temp, #name, value) < 0) { \
|
if (PyDict_SetItemString(temp, #name, value) < 0) { \
|
||||||
Py_DECREF(temp); Py_DECREF(value); return NULL; } \
|
Py_DECREF(temp); Py_DECREF(value); return NULL; } \
|
||||||
Py_DECREF(value)
|
Py_DECREF(value)
|
||||||
|
|
||||||
#ifdef HAVE_SEM_OPEN
|
#ifdef HAVE_SEM_OPEN
|
||||||
ADD_FLAG(HAVE_SEM_OPEN);
|
ADD_FLAG(HAVE_SEM_OPEN);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SEM_TIMEDWAIT
|
#ifdef HAVE_SEM_TIMEDWAIT
|
||||||
ADD_FLAG(HAVE_SEM_TIMEDWAIT);
|
ADD_FLAG(HAVE_SEM_TIMEDWAIT);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_FD_TRANSFER
|
#ifdef HAVE_FD_TRANSFER
|
||||||
ADD_FLAG(HAVE_FD_TRANSFER);
|
ADD_FLAG(HAVE_FD_TRANSFER);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_BROKEN_SEM_GETVALUE
|
#ifdef HAVE_BROKEN_SEM_GETVALUE
|
||||||
ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
|
ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_BROKEN_SEM_UNLINK
|
#ifdef HAVE_BROKEN_SEM_UNLINK
|
||||||
ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
|
ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (PyModule_AddObject(module, "flags", temp) < 0)
|
if (PyModule_AddObject(module, "flags", temp) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,163 +1,163 @@
|
||||||
#ifndef MULTIPROCESSING_H
|
#ifndef MULTIPROCESSING_H
|
||||||
#define MULTIPROCESSING_H
|
#define MULTIPROCESSING_H
|
||||||
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
#define PY_SSIZE_T_CLEAN
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Platform includes and definitions
|
* Platform includes and definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
# define WIN32_LEAN_AND_MEAN
|
# define WIN32_LEAN_AND_MEAN
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# include <process.h> /* getpid() */
|
# include <process.h> /* getpid() */
|
||||||
# define SEM_HANDLE HANDLE
|
# define SEM_HANDLE HANDLE
|
||||||
# define SEM_VALUE_MAX LONG_MAX
|
# define SEM_VALUE_MAX LONG_MAX
|
||||||
#else
|
#else
|
||||||
# include <fcntl.h> /* O_CREAT and O_EXCL */
|
# include <fcntl.h> /* O_CREAT and O_EXCL */
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
# include <arpa/inet.h> /* htonl() and ntohl() */
|
# include <arpa/inet.h> /* htonl() and ntohl() */
|
||||||
# if HAVE_SEM_OPEN
|
# if HAVE_SEM_OPEN
|
||||||
# include <semaphore.h>
|
# include <semaphore.h>
|
||||||
typedef sem_t *SEM_HANDLE;
|
typedef sem_t *SEM_HANDLE;
|
||||||
# endif
|
# endif
|
||||||
# define HANDLE int
|
# define HANDLE int
|
||||||
# define SOCKET int
|
# define SOCKET int
|
||||||
# define BOOL int
|
# define BOOL int
|
||||||
# define UINT32 uint32_t
|
# define UINT32 uint32_t
|
||||||
# define INT32 int32_t
|
# define INT32 int32_t
|
||||||
# define TRUE 1
|
# define TRUE 1
|
||||||
# define FALSE 0
|
# define FALSE 0
|
||||||
# define INVALID_HANDLE_VALUE (-1)
|
# define INVALID_HANDLE_VALUE (-1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure Py_ssize_t available
|
* Make sure Py_ssize_t available
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
|
#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
|
||||||
typedef int Py_ssize_t;
|
typedef int Py_ssize_t;
|
||||||
# define PY_SSIZE_T_MAX INT_MAX
|
# define PY_SSIZE_T_MAX INT_MAX
|
||||||
# define PY_SSIZE_T_MIN INT_MIN
|
# define PY_SSIZE_T_MIN INT_MIN
|
||||||
# define F_PY_SSIZE_T "i"
|
# define F_PY_SSIZE_T "i"
|
||||||
# define PY_FORMAT_SIZE_T ""
|
# define PY_FORMAT_SIZE_T ""
|
||||||
# define PyInt_FromSsize_t(n) PyInt_FromLong((long)n)
|
# define PyInt_FromSsize_t(n) PyInt_FromLong((long)n)
|
||||||
#else
|
#else
|
||||||
# define F_PY_SSIZE_T "n"
|
# define F_PY_SSIZE_T "n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format codes
|
* Format codes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if SIZEOF_VOID_P == SIZEOF_LONG
|
#if SIZEOF_VOID_P == SIZEOF_LONG
|
||||||
# define F_POINTER "k"
|
# define F_POINTER "k"
|
||||||
# define T_POINTER T_ULONG
|
# define T_POINTER T_ULONG
|
||||||
#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG)
|
#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG)
|
||||||
# define F_POINTER "K"
|
# define F_POINTER "K"
|
||||||
# define T_POINTER T_ULONGLONG
|
# define T_POINTER T_ULONGLONG
|
||||||
#else
|
#else
|
||||||
# error "can't find format code for unsigned integer of same size as void*"
|
# error "can't find format code for unsigned integer of same size as void*"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
# define F_HANDLE F_POINTER
|
# define F_HANDLE F_POINTER
|
||||||
# define T_HANDLE T_POINTER
|
# define T_HANDLE T_POINTER
|
||||||
# define F_SEM_HANDLE F_HANDLE
|
# define F_SEM_HANDLE F_HANDLE
|
||||||
# define T_SEM_HANDLE T_HANDLE
|
# define T_SEM_HANDLE T_HANDLE
|
||||||
# define F_DWORD "k"
|
# define F_DWORD "k"
|
||||||
# define T_DWORD T_ULONG
|
# define T_DWORD T_ULONG
|
||||||
#else
|
#else
|
||||||
# define F_HANDLE "i"
|
# define F_HANDLE "i"
|
||||||
# define T_HANDLE T_INT
|
# define T_HANDLE T_INT
|
||||||
# define F_SEM_HANDLE F_POINTER
|
# define F_SEM_HANDLE F_POINTER
|
||||||
# define T_SEM_HANDLE T_POINTER
|
# define T_SEM_HANDLE T_POINTER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PY_VERSION_HEX >= 0x03000000
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
# define F_RBUFFER "y"
|
# define F_RBUFFER "y"
|
||||||
#else
|
#else
|
||||||
# define F_RBUFFER "s"
|
# define F_RBUFFER "s"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Error codes which can be returned by functions called without GIL
|
* Error codes which can be returned by functions called without GIL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MP_SUCCESS (0)
|
#define MP_SUCCESS (0)
|
||||||
#define MP_STANDARD_ERROR (-1)
|
#define MP_STANDARD_ERROR (-1)
|
||||||
#define MP_MEMORY_ERROR (-1001)
|
#define MP_MEMORY_ERROR (-1001)
|
||||||
#define MP_END_OF_FILE (-1002)
|
#define MP_END_OF_FILE (-1002)
|
||||||
#define MP_EARLY_END_OF_FILE (-1003)
|
#define MP_EARLY_END_OF_FILE (-1003)
|
||||||
#define MP_BAD_MESSAGE_LENGTH (-1004)
|
#define MP_BAD_MESSAGE_LENGTH (-1004)
|
||||||
#define MP_SOCKET_ERROR (-1005)
|
#define MP_SOCKET_ERROR (-1005)
|
||||||
#define MP_EXCEPTION_HAS_BEEN_SET (-1006)
|
#define MP_EXCEPTION_HAS_BEEN_SET (-1006)
|
||||||
|
|
||||||
PyObject *mp_SetError(PyObject *Type, int num);
|
PyObject *mp_SetError(PyObject *Type, int num);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Externs - not all will really exist on all platforms
|
* Externs - not all will really exist on all platforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern PyObject *pickle_dumps;
|
extern PyObject *pickle_dumps;
|
||||||
extern PyObject *pickle_loads;
|
extern PyObject *pickle_loads;
|
||||||
extern PyObject *pickle_protocol;
|
extern PyObject *pickle_protocol;
|
||||||
extern PyObject *BufferTooShort;
|
extern PyObject *BufferTooShort;
|
||||||
extern PyTypeObject SemLockType;
|
extern PyTypeObject SemLockType;
|
||||||
extern PyTypeObject ConnectionType;
|
extern PyTypeObject ConnectionType;
|
||||||
extern PyTypeObject PipeConnectionType;
|
extern PyTypeObject PipeConnectionType;
|
||||||
extern HANDLE sigint_event;
|
extern HANDLE sigint_event;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Py3k compatibility
|
* Py3k compatibility
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if PY_VERSION_HEX >= 0x03000000
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
# define PICKLE_MODULE "pickle"
|
# define PICKLE_MODULE "pickle"
|
||||||
# define FROM_FORMAT PyUnicode_FromFormat
|
# define FROM_FORMAT PyUnicode_FromFormat
|
||||||
# define PyInt_FromLong PyLong_FromLong
|
# define PyInt_FromLong PyLong_FromLong
|
||||||
# define PyInt_FromSsize_t PyLong_FromSsize_t
|
# define PyInt_FromSsize_t PyLong_FromSsize_t
|
||||||
#else
|
#else
|
||||||
# define PICKLE_MODULE "cPickle"
|
# define PICKLE_MODULE "cPickle"
|
||||||
# define FROM_FORMAT PyString_FromFormat
|
# define FROM_FORMAT PyString_FromFormat
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PyVarObject_HEAD_INIT
|
#ifndef PyVarObject_HEAD_INIT
|
||||||
# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
|
# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef Py_TPFLAGS_HAVE_WEAKREFS
|
#ifndef Py_TPFLAGS_HAVE_WEAKREFS
|
||||||
# define Py_TPFLAGS_HAVE_WEAKREFS 0
|
# define Py_TPFLAGS_HAVE_WEAKREFS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Connection definition
|
* Connection definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CONNECTION_BUFFER_SIZE 1024
|
#define CONNECTION_BUFFER_SIZE 1024
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
int flags;
|
int flags;
|
||||||
PyObject *weakreflist;
|
PyObject *weakreflist;
|
||||||
char buffer[CONNECTION_BUFFER_SIZE];
|
char buffer[CONNECTION_BUFFER_SIZE];
|
||||||
} ConnectionObject;
|
} ConnectionObject;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Miscellaneous
|
* Miscellaneous
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_MESSAGE_LENGTH 0x7fffffff
|
#define MAX_MESSAGE_LENGTH 0x7fffffff
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
# define MIN(x, y) ((x) < (y) ? x : y)
|
# define MIN(x, y) ((x) < (y) ? x : y)
|
||||||
# define MAX(x, y) ((x) > (y) ? x : y)
|
# define MAX(x, y) ((x) > (y) ? x : y)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* MULTIPROCESSING_H */
|
#endif /* MULTIPROCESSING_H */
|
||||||
|
|
|
@ -1,136 +1,136 @@
|
||||||
/*
|
/*
|
||||||
* A type which wraps a pipe handle in message oriented mode
|
* A type which wraps a pipe handle in message oriented mode
|
||||||
*
|
*
|
||||||
* pipe_connection.c
|
* pipe_connection.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
|
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "multiprocessing.h"
|
#include "multiprocessing.h"
|
||||||
|
|
||||||
#define CLOSE(h) CloseHandle(h)
|
#define CLOSE(h) CloseHandle(h)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send string to the pipe; assumes in message oriented mode
|
* Send string to the pipe; assumes in message oriented mode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Py_ssize_t
|
static Py_ssize_t
|
||||||
conn_send_string(ConnectionObject *conn, char *string, size_t length)
|
conn_send_string(ConnectionObject *conn, char *string, size_t length)
|
||||||
{
|
{
|
||||||
DWORD amount_written;
|
DWORD amount_written;
|
||||||
|
|
||||||
return WriteFile(conn->handle, string, length, &amount_written, NULL)
|
return WriteFile(conn->handle, string, length, &amount_written, NULL)
|
||||||
? MP_SUCCESS : MP_STANDARD_ERROR;
|
? MP_SUCCESS : MP_STANDARD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempts to read into buffer, or if buffer too small into *newbuffer.
|
* Attempts to read into buffer, or if buffer too small into *newbuffer.
|
||||||
*
|
*
|
||||||
* Returns number of bytes read. Assumes in message oriented mode.
|
* Returns number of bytes read. Assumes in message oriented mode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Py_ssize_t
|
static Py_ssize_t
|
||||||
conn_recv_string(ConnectionObject *conn, char *buffer,
|
conn_recv_string(ConnectionObject *conn, char *buffer,
|
||||||
size_t buflength, char **newbuffer, size_t maxlength)
|
size_t buflength, char **newbuffer, size_t maxlength)
|
||||||
{
|
{
|
||||||
DWORD left, length, full_length, err;
|
DWORD left, length, full_length, err;
|
||||||
|
|
||||||
*newbuffer = NULL;
|
*newbuffer = NULL;
|
||||||
|
|
||||||
if (ReadFile(conn->handle, buffer, MIN(buflength, maxlength),
|
if (ReadFile(conn->handle, buffer, MIN(buflength, maxlength),
|
||||||
&length, NULL))
|
&length, NULL))
|
||||||
return length;
|
return length;
|
||||||
|
|
||||||
err = GetLastError();
|
err = GetLastError();
|
||||||
if (err != ERROR_MORE_DATA) {
|
if (err != ERROR_MORE_DATA) {
|
||||||
if (err == ERROR_BROKEN_PIPE)
|
if (err == ERROR_BROKEN_PIPE)
|
||||||
return MP_END_OF_FILE;
|
return MP_END_OF_FILE;
|
||||||
return MP_STANDARD_ERROR;
|
return MP_STANDARD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, NULL, &left))
|
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, NULL, &left))
|
||||||
return MP_STANDARD_ERROR;
|
return MP_STANDARD_ERROR;
|
||||||
|
|
||||||
full_length = length + left;
|
full_length = length + left;
|
||||||
if (full_length > maxlength)
|
if (full_length > maxlength)
|
||||||
return MP_BAD_MESSAGE_LENGTH;
|
return MP_BAD_MESSAGE_LENGTH;
|
||||||
|
|
||||||
*newbuffer = PyMem_Malloc(full_length);
|
*newbuffer = PyMem_Malloc(full_length);
|
||||||
if (*newbuffer == NULL)
|
if (*newbuffer == NULL)
|
||||||
return MP_MEMORY_ERROR;
|
return MP_MEMORY_ERROR;
|
||||||
|
|
||||||
memcpy(*newbuffer, buffer, length);
|
memcpy(*newbuffer, buffer, length);
|
||||||
|
|
||||||
if (ReadFile(conn->handle, *newbuffer+length, left, &length, NULL)) {
|
if (ReadFile(conn->handle, *newbuffer+length, left, &length, NULL)) {
|
||||||
assert(length == left);
|
assert(length == left);
|
||||||
return full_length;
|
return full_length;
|
||||||
} else {
|
} else {
|
||||||
PyMem_Free(*newbuffer);
|
PyMem_Free(*newbuffer);
|
||||||
return MP_STANDARD_ERROR;
|
return MP_STANDARD_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether any data is available for reading
|
* Check whether any data is available for reading
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define conn_poll(conn, timeout) conn_poll_save(conn, timeout, _save)
|
#define conn_poll(conn, timeout) conn_poll_save(conn, timeout, _save)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
conn_poll_save(ConnectionObject *conn, double timeout, PyThreadState *_save)
|
conn_poll_save(ConnectionObject *conn, double timeout, PyThreadState *_save)
|
||||||
{
|
{
|
||||||
DWORD bytes, deadline, delay;
|
DWORD bytes, deadline, delay;
|
||||||
int difference, res;
|
int difference, res;
|
||||||
BOOL block = FALSE;
|
BOOL block = FALSE;
|
||||||
|
|
||||||
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
|
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
|
||||||
return MP_STANDARD_ERROR;
|
return MP_STANDARD_ERROR;
|
||||||
|
|
||||||
if (timeout == 0.0)
|
if (timeout == 0.0)
|
||||||
return bytes > 0;
|
return bytes > 0;
|
||||||
|
|
||||||
if (timeout < 0.0)
|
if (timeout < 0.0)
|
||||||
block = TRUE;
|
block = TRUE;
|
||||||
else
|
else
|
||||||
/* XXX does not check for overflow */
|
/* XXX does not check for overflow */
|
||||||
deadline = GetTickCount() + (DWORD)(1000 * timeout + 0.5);
|
deadline = GetTickCount() + (DWORD)(1000 * timeout + 0.5);
|
||||||
|
|
||||||
Sleep(0);
|
Sleep(0);
|
||||||
|
|
||||||
for (delay = 1 ; ; delay += 1) {
|
for (delay = 1 ; ; delay += 1) {
|
||||||
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
|
if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
|
||||||
return MP_STANDARD_ERROR;
|
return MP_STANDARD_ERROR;
|
||||||
else if (bytes > 0)
|
else if (bytes > 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (!block) {
|
if (!block) {
|
||||||
difference = deadline - GetTickCount();
|
difference = deadline - GetTickCount();
|
||||||
if (difference < 0)
|
if (difference < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ((int)delay > difference)
|
if ((int)delay > difference)
|
||||||
delay = difference;
|
delay = difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delay > 20)
|
if (delay > 20)
|
||||||
delay = 20;
|
delay = 20;
|
||||||
|
|
||||||
Sleep(delay);
|
Sleep(delay);
|
||||||
|
|
||||||
/* check for signals */
|
/* check for signals */
|
||||||
Py_BLOCK_THREADS
|
Py_BLOCK_THREADS
|
||||||
res = PyErr_CheckSignals();
|
res = PyErr_CheckSignals();
|
||||||
Py_UNBLOCK_THREADS
|
Py_UNBLOCK_THREADS
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
return MP_EXCEPTION_HAS_BEEN_SET;
|
return MP_EXCEPTION_HAS_BEEN_SET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "connection.h" defines the PipeConnection type using the definitions above
|
* "connection.h" defines the PipeConnection type using the definitions above
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CONNECTION_NAME "PipeConnection"
|
#define CONNECTION_NAME "PipeConnection"
|
||||||
#define CONNECTION_TYPE PipeConnectionType
|
#define CONNECTION_TYPE PipeConnectionType
|
||||||
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
|
|
@ -1,260 +1,260 @@
|
||||||
/*
|
/*
|
||||||
* Win32 functions used by multiprocessing package
|
* Win32 functions used by multiprocessing package
|
||||||
*
|
*
|
||||||
* win32_functions.c
|
* win32_functions.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
|
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "multiprocessing.h"
|
#include "multiprocessing.h"
|
||||||
|
|
||||||
|
|
||||||
#define WIN32_FUNCTION(func) \
|
#define WIN32_FUNCTION(func) \
|
||||||
{#func, (PyCFunction)win32_ ## func, METH_VARARGS | METH_STATIC, ""}
|
{#func, (PyCFunction)win32_ ## func, METH_VARARGS | METH_STATIC, ""}
|
||||||
|
|
||||||
#define WIN32_CONSTANT(fmt, con) \
|
#define WIN32_CONSTANT(fmt, con) \
|
||||||
PyDict_SetItemString(Win32Type.tp_dict, #con, Py_BuildValue(fmt, con))
|
PyDict_SetItemString(Win32Type.tp_dict, #con, Py_BuildValue(fmt, con))
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_CloseHandle(PyObject *self, PyObject *args)
|
win32_CloseHandle(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
HANDLE hObject;
|
HANDLE hObject;
|
||||||
BOOL success;
|
BOOL success;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, F_HANDLE, &hObject))
|
if (!PyArg_ParseTuple(args, F_HANDLE, &hObject))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
success = CloseHandle(hObject);
|
success = CloseHandle(hObject);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
return PyErr_SetFromWindowsErr(0);
|
return PyErr_SetFromWindowsErr(0);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_ConnectNamedPipe(PyObject *self, PyObject *args)
|
win32_ConnectNamedPipe(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
HANDLE hNamedPipe;
|
HANDLE hNamedPipe;
|
||||||
LPOVERLAPPED lpOverlapped;
|
LPOVERLAPPED lpOverlapped;
|
||||||
BOOL success;
|
BOOL success;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, F_HANDLE F_POINTER,
|
if (!PyArg_ParseTuple(args, F_HANDLE F_POINTER,
|
||||||
&hNamedPipe, &lpOverlapped))
|
&hNamedPipe, &lpOverlapped))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
success = ConnectNamedPipe(hNamedPipe, lpOverlapped);
|
success = ConnectNamedPipe(hNamedPipe, lpOverlapped);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
return PyErr_SetFromWindowsErr(0);
|
return PyErr_SetFromWindowsErr(0);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_CreateFile(PyObject *self, PyObject *args)
|
win32_CreateFile(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
LPCTSTR lpFileName;
|
LPCTSTR lpFileName;
|
||||||
DWORD dwDesiredAccess;
|
DWORD dwDesiredAccess;
|
||||||
DWORD dwShareMode;
|
DWORD dwShareMode;
|
||||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes;
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes;
|
||||||
DWORD dwCreationDisposition;
|
DWORD dwCreationDisposition;
|
||||||
DWORD dwFlagsAndAttributes;
|
DWORD dwFlagsAndAttributes;
|
||||||
HANDLE hTemplateFile;
|
HANDLE hTemplateFile;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_POINTER
|
if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_POINTER
|
||||||
F_DWORD F_DWORD F_HANDLE,
|
F_DWORD F_DWORD F_HANDLE,
|
||||||
&lpFileName, &dwDesiredAccess, &dwShareMode,
|
&lpFileName, &dwDesiredAccess, &dwShareMode,
|
||||||
&lpSecurityAttributes, &dwCreationDisposition,
|
&lpSecurityAttributes, &dwCreationDisposition,
|
||||||
&dwFlagsAndAttributes, &hTemplateFile))
|
&dwFlagsAndAttributes, &hTemplateFile))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
handle = CreateFile(lpFileName, dwDesiredAccess,
|
handle = CreateFile(lpFileName, dwDesiredAccess,
|
||||||
dwShareMode, lpSecurityAttributes,
|
dwShareMode, lpSecurityAttributes,
|
||||||
dwCreationDisposition,
|
dwCreationDisposition,
|
||||||
dwFlagsAndAttributes, hTemplateFile);
|
dwFlagsAndAttributes, hTemplateFile);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
return PyErr_SetFromWindowsErr(0);
|
return PyErr_SetFromWindowsErr(0);
|
||||||
|
|
||||||
return Py_BuildValue(F_HANDLE, handle);
|
return Py_BuildValue(F_HANDLE, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_CreateNamedPipe(PyObject *self, PyObject *args)
|
win32_CreateNamedPipe(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
LPCTSTR lpName;
|
LPCTSTR lpName;
|
||||||
DWORD dwOpenMode;
|
DWORD dwOpenMode;
|
||||||
DWORD dwPipeMode;
|
DWORD dwPipeMode;
|
||||||
DWORD nMaxInstances;
|
DWORD nMaxInstances;
|
||||||
DWORD nOutBufferSize;
|
DWORD nOutBufferSize;
|
||||||
DWORD nInBufferSize;
|
DWORD nInBufferSize;
|
||||||
DWORD nDefaultTimeOut;
|
DWORD nDefaultTimeOut;
|
||||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes;
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_DWORD
|
if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_DWORD
|
||||||
F_DWORD F_DWORD F_DWORD F_POINTER,
|
F_DWORD F_DWORD F_DWORD F_POINTER,
|
||||||
&lpName, &dwOpenMode, &dwPipeMode,
|
&lpName, &dwOpenMode, &dwPipeMode,
|
||||||
&nMaxInstances, &nOutBufferSize,
|
&nMaxInstances, &nOutBufferSize,
|
||||||
&nInBufferSize, &nDefaultTimeOut,
|
&nInBufferSize, &nDefaultTimeOut,
|
||||||
&lpSecurityAttributes))
|
&lpSecurityAttributes))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
handle = CreateNamedPipe(lpName, dwOpenMode, dwPipeMode,
|
handle = CreateNamedPipe(lpName, dwOpenMode, dwPipeMode,
|
||||||
nMaxInstances, nOutBufferSize,
|
nMaxInstances, nOutBufferSize,
|
||||||
nInBufferSize, nDefaultTimeOut,
|
nInBufferSize, nDefaultTimeOut,
|
||||||
lpSecurityAttributes);
|
lpSecurityAttributes);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
return PyErr_SetFromWindowsErr(0);
|
return PyErr_SetFromWindowsErr(0);
|
||||||
|
|
||||||
return Py_BuildValue(F_HANDLE, handle);
|
return Py_BuildValue(F_HANDLE, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_ExitProcess(PyObject *self, PyObject *args)
|
win32_ExitProcess(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
UINT uExitCode;
|
UINT uExitCode;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "I", &uExitCode))
|
if (!PyArg_ParseTuple(args, "I", &uExitCode))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ExitProcess(uExitCode);
|
ExitProcess(uExitCode);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_GetLastError(PyObject *self, PyObject *args)
|
win32_GetLastError(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
return Py_BuildValue(F_DWORD, GetLastError());
|
return Py_BuildValue(F_DWORD, GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_OpenProcess(PyObject *self, PyObject *args)
|
win32_OpenProcess(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
DWORD dwDesiredAccess;
|
DWORD dwDesiredAccess;
|
||||||
BOOL bInheritHandle;
|
BOOL bInheritHandle;
|
||||||
DWORD dwProcessId;
|
DWORD dwProcessId;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, F_DWORD "i" F_DWORD,
|
if (!PyArg_ParseTuple(args, F_DWORD "i" F_DWORD,
|
||||||
&dwDesiredAccess, &bInheritHandle, &dwProcessId))
|
&dwDesiredAccess, &bInheritHandle, &dwProcessId))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
|
handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
|
||||||
if (handle == NULL)
|
if (handle == NULL)
|
||||||
return PyErr_SetFromWindowsErr(0);
|
return PyErr_SetFromWindowsErr(0);
|
||||||
|
|
||||||
return Py_BuildValue(F_HANDLE, handle);
|
return Py_BuildValue(F_HANDLE, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_SetNamedPipeHandleState(PyObject *self, PyObject *args)
|
win32_SetNamedPipeHandleState(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
HANDLE hNamedPipe;
|
HANDLE hNamedPipe;
|
||||||
PyObject *oArgs[3];
|
PyObject *oArgs[3];
|
||||||
DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
|
DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, F_HANDLE "OOO",
|
if (!PyArg_ParseTuple(args, F_HANDLE "OOO",
|
||||||
&hNamedPipe, &oArgs[0], &oArgs[1], &oArgs[2]))
|
&hNamedPipe, &oArgs[0], &oArgs[1], &oArgs[2]))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
|
||||||
for (i = 0 ; i < 3 ; i++) {
|
for (i = 0 ; i < 3 ; i++) {
|
||||||
if (oArgs[i] != Py_None) {
|
if (oArgs[i] != Py_None) {
|
||||||
dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]);
|
dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]);
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
pArgs[i] = &dwArgs[i];
|
pArgs[i] = &dwArgs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetNamedPipeHandleState(hNamedPipe, pArgs[0], pArgs[1], pArgs[2]))
|
if (!SetNamedPipeHandleState(hNamedPipe, pArgs[0], pArgs[1], pArgs[2]))
|
||||||
return PyErr_SetFromWindowsErr(0);
|
return PyErr_SetFromWindowsErr(0);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
win32_WaitNamedPipe(PyObject *self, PyObject *args)
|
win32_WaitNamedPipe(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
LPCTSTR lpNamedPipeName;
|
LPCTSTR lpNamedPipeName;
|
||||||
DWORD nTimeOut;
|
DWORD nTimeOut;
|
||||||
BOOL success;
|
BOOL success;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s" F_DWORD, &lpNamedPipeName, &nTimeOut))
|
if (!PyArg_ParseTuple(args, "s" F_DWORD, &lpNamedPipeName, &nTimeOut))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
success = WaitNamedPipe(lpNamedPipeName, nTimeOut);
|
success = WaitNamedPipe(lpNamedPipeName, nTimeOut);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
return PyErr_SetFromWindowsErr(0);
|
return PyErr_SetFromWindowsErr(0);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef win32_methods[] = {
|
static PyMethodDef win32_methods[] = {
|
||||||
WIN32_FUNCTION(CloseHandle),
|
WIN32_FUNCTION(CloseHandle),
|
||||||
WIN32_FUNCTION(GetLastError),
|
WIN32_FUNCTION(GetLastError),
|
||||||
WIN32_FUNCTION(OpenProcess),
|
WIN32_FUNCTION(OpenProcess),
|
||||||
WIN32_FUNCTION(ExitProcess),
|
WIN32_FUNCTION(ExitProcess),
|
||||||
WIN32_FUNCTION(ConnectNamedPipe),
|
WIN32_FUNCTION(ConnectNamedPipe),
|
||||||
WIN32_FUNCTION(CreateFile),
|
WIN32_FUNCTION(CreateFile),
|
||||||
WIN32_FUNCTION(CreateNamedPipe),
|
WIN32_FUNCTION(CreateNamedPipe),
|
||||||
WIN32_FUNCTION(SetNamedPipeHandleState),
|
WIN32_FUNCTION(SetNamedPipeHandleState),
|
||||||
WIN32_FUNCTION(WaitNamedPipe),
|
WIN32_FUNCTION(WaitNamedPipe),
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
PyTypeObject Win32Type = {
|
PyTypeObject Win32Type = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
create_win32_namespace(void)
|
create_win32_namespace(void)
|
||||||
{
|
{
|
||||||
Win32Type.tp_name = "_multiprocessing.win32";
|
Win32Type.tp_name = "_multiprocessing.win32";
|
||||||
Win32Type.tp_methods = win32_methods;
|
Win32Type.tp_methods = win32_methods;
|
||||||
if (PyType_Ready(&Win32Type) < 0)
|
if (PyType_Ready(&Win32Type) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_INCREF(&Win32Type);
|
Py_INCREF(&Win32Type);
|
||||||
|
|
||||||
WIN32_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
|
WIN32_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
|
||||||
WIN32_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
|
WIN32_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
|
||||||
WIN32_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
|
WIN32_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
|
||||||
WIN32_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
|
WIN32_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
|
||||||
WIN32_CONSTANT(F_DWORD, GENERIC_READ);
|
WIN32_CONSTANT(F_DWORD, GENERIC_READ);
|
||||||
WIN32_CONSTANT(F_DWORD, GENERIC_WRITE);
|
WIN32_CONSTANT(F_DWORD, GENERIC_WRITE);
|
||||||
WIN32_CONSTANT(F_DWORD, INFINITE);
|
WIN32_CONSTANT(F_DWORD, INFINITE);
|
||||||
WIN32_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
|
WIN32_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
|
||||||
WIN32_CONSTANT(F_DWORD, OPEN_EXISTING);
|
WIN32_CONSTANT(F_DWORD, OPEN_EXISTING);
|
||||||
WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
|
WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
|
||||||
WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
|
WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
|
||||||
WIN32_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
|
WIN32_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
|
||||||
WIN32_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
|
WIN32_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
|
||||||
WIN32_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
|
WIN32_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
|
||||||
WIN32_CONSTANT(F_DWORD, PIPE_WAIT);
|
WIN32_CONSTANT(F_DWORD, PIPE_WAIT);
|
||||||
WIN32_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
|
WIN32_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
|
||||||
|
|
||||||
WIN32_CONSTANT("i", NULL);
|
WIN32_CONSTANT("i", NULL);
|
||||||
|
|
||||||
return (PyObject*)&Win32Type;
|
return (PyObject*)&Win32Type;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue