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