Commit fa268032 authored by Benjamin Peterson's avatar Benjamin Peterson

fix multiprocessing line endings in py3k

parent 53a5b0d3
This diff is collapsed.
#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 */
/* /*
* 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"
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment