Blame Modules/_multiprocessing/multiprocessing.c

rpm-build 2bd099
/*
rpm-build 2bd099
 * Extension module used by multiprocessing package
rpm-build 2bd099
 *
rpm-build 2bd099
 * multiprocessing.c
rpm-build 2bd099
 *
rpm-build 2bd099
 * Copyright (c) 2006-2008, R Oudkerk
rpm-build 2bd099
 * Licensed to PSF under a Contributor Agreement.
rpm-build 2bd099
 */
rpm-build 2bd099
rpm-build 2bd099
#include "multiprocessing.h"
rpm-build 2bd099
rpm-build 2bd099
rpm-build 2bd099
/*
rpm-build 2bd099
 * Function which raises exceptions based on error codes
rpm-build 2bd099
 */
rpm-build 2bd099
rpm-build 2bd099
PyObject *
rpm-build 2bd099
_PyMp_SetError(PyObject *Type, int num)
rpm-build 2bd099
{
rpm-build 2bd099
    switch (num) {
rpm-build 2bd099
#ifdef MS_WINDOWS
rpm-build 2bd099
    case MP_STANDARD_ERROR:
rpm-build 2bd099
        if (Type == NULL)
rpm-build 2bd099
            Type = PyExc_OSError;
rpm-build 2bd099
        PyErr_SetExcFromWindowsErr(Type, 0);
rpm-build 2bd099
        break;
rpm-build 2bd099
    case MP_SOCKET_ERROR:
rpm-build 2bd099
        if (Type == NULL)
rpm-build 2bd099
            Type = PyExc_OSError;
rpm-build 2bd099
        PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
rpm-build 2bd099
        break;
rpm-build 2bd099
#else /* !MS_WINDOWS */
rpm-build 2bd099
    case MP_STANDARD_ERROR:
rpm-build 2bd099
    case MP_SOCKET_ERROR:
rpm-build 2bd099
        if (Type == NULL)
rpm-build 2bd099
            Type = PyExc_OSError;
rpm-build 2bd099
        PyErr_SetFromErrno(Type);
rpm-build 2bd099
        break;
rpm-build 2bd099
#endif /* !MS_WINDOWS */
rpm-build 2bd099
    case MP_MEMORY_ERROR:
rpm-build 2bd099
        PyErr_NoMemory();
rpm-build 2bd099
        break;
rpm-build 2bd099
    case MP_EXCEPTION_HAS_BEEN_SET:
rpm-build 2bd099
        break;
rpm-build 2bd099
    default:
rpm-build 2bd099
        PyErr_Format(PyExc_RuntimeError,
rpm-build 2bd099
                     "unknown error number %d", num);
rpm-build 2bd099
    }
rpm-build 2bd099
    return NULL;
rpm-build 2bd099
}
rpm-build 2bd099
rpm-build 2bd099
#ifdef MS_WINDOWS
rpm-build 2bd099
static PyObject *
rpm-build 2bd099
multiprocessing_closesocket(PyObject *self, PyObject *args)
rpm-build 2bd099
{
rpm-build 2bd099
    HANDLE handle;
rpm-build 2bd099
    int ret;
rpm-build 2bd099
rpm-build 2bd099
    if (!PyArg_ParseTuple(args, F_HANDLE ":closesocket" , &handle))
rpm-build 2bd099
        return NULL;
rpm-build 2bd099
rpm-build 2bd099
    Py_BEGIN_ALLOW_THREADS
rpm-build 2bd099
    ret = closesocket((SOCKET) handle);
rpm-build 2bd099
    Py_END_ALLOW_THREADS
rpm-build 2bd099
rpm-build 2bd099
    if (ret)
rpm-build 2bd099
        return PyErr_SetExcFromWindowsErr(PyExc_IOError, WSAGetLastError());
rpm-build 2bd099
    Py_RETURN_NONE;
rpm-build 2bd099
}
rpm-build 2bd099
rpm-build 2bd099
static PyObject *
rpm-build 2bd099
multiprocessing_recv(PyObject *self, PyObject *args)
rpm-build 2bd099
{
rpm-build 2bd099
    HANDLE handle;
rpm-build 2bd099
    int size, nread;
rpm-build 2bd099
    PyObject *buf;
rpm-build 2bd099
rpm-build 2bd099
    if (!PyArg_ParseTuple(args, F_HANDLE "i:recv" , &handle, &size))
rpm-build 2bd099
        return NULL;
rpm-build 2bd099
rpm-build 2bd099
    buf = PyBytes_FromStringAndSize(NULL, size);
rpm-build 2bd099
    if (!buf)
rpm-build 2bd099
        return NULL;
rpm-build 2bd099
rpm-build 2bd099
    Py_BEGIN_ALLOW_THREADS
rpm-build 2bd099
    nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0);
rpm-build 2bd099
    Py_END_ALLOW_THREADS
rpm-build 2bd099
rpm-build 2bd099
    if (nread < 0) {
rpm-build 2bd099
        Py_DECREF(buf);
rpm-build 2bd099
        return PyErr_SetExcFromWindowsErr(PyExc_IOError, WSAGetLastError());
rpm-build 2bd099
    }
rpm-build 2bd099
    _PyBytes_Resize(&buf, nread);
rpm-build 2bd099
    return buf;
rpm-build 2bd099
}
rpm-build 2bd099
rpm-build 2bd099
static PyObject *
rpm-build 2bd099
multiprocessing_send(PyObject *self, PyObject *args)
rpm-build 2bd099
{
rpm-build 2bd099
    HANDLE handle;
rpm-build 2bd099
    Py_buffer buf;
rpm-build 2bd099
    int ret, length;
rpm-build 2bd099
rpm-build 2bd099
    if (!PyArg_ParseTuple(args, F_HANDLE "y*:send" , &handle, &buf))
rpm-build 2bd099
        return NULL;
rpm-build 2bd099
rpm-build 2bd099
    length = (int)Py_MIN(buf.len, INT_MAX);
rpm-build 2bd099
rpm-build 2bd099
    Py_BEGIN_ALLOW_THREADS
rpm-build 2bd099
    ret = send((SOCKET) handle, buf.buf, length, 0);
rpm-build 2bd099
    Py_END_ALLOW_THREADS
rpm-build 2bd099
rpm-build 2bd099
    PyBuffer_Release(&buf;;
rpm-build 2bd099
    if (ret < 0)
rpm-build 2bd099
        return PyErr_SetExcFromWindowsErr(PyExc_IOError, WSAGetLastError());
rpm-build 2bd099
    return PyLong_FromLong(ret);
rpm-build 2bd099
}
rpm-build 2bd099
rpm-build 2bd099
#endif
rpm-build 2bd099
rpm-build 2bd099
/*
rpm-build 2bd099
 * Function table
rpm-build 2bd099
 */
rpm-build 2bd099
rpm-build 2bd099
static PyMethodDef module_methods[] = {
rpm-build 2bd099
#ifdef MS_WINDOWS
rpm-build 2bd099
    {"closesocket", multiprocessing_closesocket, METH_VARARGS, ""},
rpm-build 2bd099
    {"recv", multiprocessing_recv, METH_VARARGS, ""},
rpm-build 2bd099
    {"send", multiprocessing_send, METH_VARARGS, ""},
rpm-build 2bd099
#endif
rpm-build 2bd099
#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)
rpm-build 2bd099
    {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""},
rpm-build 2bd099
#endif
rpm-build 2bd099
    {NULL}
rpm-build 2bd099
};
rpm-build 2bd099
rpm-build 2bd099
rpm-build 2bd099
/*
rpm-build 2bd099
 * Initialize
rpm-build 2bd099
 */
rpm-build 2bd099
rpm-build 2bd099
static struct PyModuleDef multiprocessing_module = {
rpm-build 2bd099
    PyModuleDef_HEAD_INIT,
rpm-build 2bd099
    "_multiprocessing",
rpm-build 2bd099
    NULL,
rpm-build 2bd099
    -1,
rpm-build 2bd099
    module_methods,
rpm-build 2bd099
    NULL,
rpm-build 2bd099
    NULL,
rpm-build 2bd099
    NULL,
rpm-build 2bd099
    NULL
rpm-build 2bd099
};
rpm-build 2bd099
rpm-build 2bd099
rpm-build 2bd099
PyMODINIT_FUNC
rpm-build 2bd099
PyInit__multiprocessing(void)
rpm-build 2bd099
{
rpm-build 2bd099
    PyObject *module, *temp, *value = NULL;
rpm-build 2bd099
rpm-build 2bd099
    /* Initialize module */
rpm-build 2bd099
    module = PyModule_Create(&multiprocessing_module);
rpm-build 2bd099
    if (!module)
rpm-build 2bd099
        return NULL;
rpm-build 2bd099
rpm-build 2bd099
#if defined(MS_WINDOWS) ||                                              \
rpm-build 2bd099
  (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED))
rpm-build 2bd099
    /* Add _PyMp_SemLock type to module */
rpm-build 2bd099
    if (PyType_Ready(&_PyMp_SemLockType) < 0)
rpm-build 2bd099
        return NULL;
rpm-build 2bd099
    Py_INCREF(&_PyMp_SemLockType);
rpm-build 2bd099
    {
rpm-build 2bd099
        PyObject *py_sem_value_max;
rpm-build 2bd099
        /* Some systems define SEM_VALUE_MAX as an unsigned value that
rpm-build 2bd099
         * causes it to be negative when used as an int (NetBSD). */
rpm-build 2bd099
        if ((int)(SEM_VALUE_MAX) < 0)
rpm-build 2bd099
            py_sem_value_max = PyLong_FromLong(INT_MAX);
rpm-build 2bd099
        else
rpm-build 2bd099
            py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);
rpm-build 2bd099
        if (py_sem_value_max == NULL)
rpm-build 2bd099
            return NULL;
rpm-build 2bd099
        PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX",
rpm-build 2bd099
                             py_sem_value_max);
rpm-build 2bd099
    }
rpm-build 2bd099
    PyModule_AddObject(module, "SemLock", (PyObject*)&_PyMp_SemLockType);
rpm-build 2bd099
#endif
rpm-build 2bd099
rpm-build 2bd099
    /* Add configuration macros */
rpm-build 2bd099
    temp = PyDict_New();
rpm-build 2bd099
    if (!temp)
rpm-build 2bd099
        return NULL;
rpm-build 2bd099
rpm-build 2bd099
#define ADD_FLAG(name)                                            \
rpm-build 2bd099
    value = Py_BuildValue("i", name);                             \
rpm-build 2bd099
    if (value == NULL) { Py_DECREF(temp); return NULL; }          \
rpm-build 2bd099
    if (PyDict_SetItemString(temp, #name, value) < 0) {           \
rpm-build 2bd099
        Py_DECREF(temp); Py_DECREF(value); return NULL; }         \
rpm-build 2bd099
    Py_DECREF(value)
rpm-build 2bd099
rpm-build 2bd099
#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
rpm-build 2bd099
    ADD_FLAG(HAVE_SEM_OPEN);
rpm-build 2bd099
#endif
rpm-build 2bd099
#ifdef HAVE_SEM_TIMEDWAIT
rpm-build 2bd099
    ADD_FLAG(HAVE_SEM_TIMEDWAIT);
rpm-build 2bd099
#endif
rpm-build 2bd099
#ifdef HAVE_BROKEN_SEM_GETVALUE
rpm-build 2bd099
    ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
rpm-build 2bd099
#endif
rpm-build 2bd099
#ifdef HAVE_BROKEN_SEM_UNLINK
rpm-build 2bd099
    ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
rpm-build 2bd099
#endif
rpm-build 2bd099
rpm-build 2bd099
    if (PyModule_AddObject(module, "flags", temp) < 0)
rpm-build 2bd099
        return NULL;
rpm-build 2bd099
rpm-build 2bd099
    return module;
rpm-build 2bd099
}