Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Modules/_multiprocessing/multiprocessing.c

    r10 r391  
    99#include "multiprocessing.h"
    1010
     11#if (defined(CMSG_LEN) && defined(SCM_RIGHTS))
     12    #define HAVE_FD_TRANSFER 1
     13#else
     14    #define HAVE_FD_TRANSFER 0
     15#endif
     16
    1117PyObject *create_win32_namespace(void);
    1218
     
    2127mp_SetError(PyObject *Type, int num)
    2228{
    23         switch (num) {
     29    switch (num) {
    2430#ifdef MS_WINDOWS
    25         case MP_STANDARD_ERROR:
    26                 if (Type == NULL)
    27                         Type = PyExc_WindowsError;
    28                 PyErr_SetExcFromWindowsErr(Type, 0);
    29                 break;
    30         case MP_SOCKET_ERROR:
    31                 if (Type == NULL)
    32                         Type = PyExc_WindowsError;
    33                 PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
    34                 break;
     31    case MP_STANDARD_ERROR:
     32        if (Type == NULL)
     33            Type = PyExc_WindowsError;
     34        PyErr_SetExcFromWindowsErr(Type, 0);
     35        break;
     36    case MP_SOCKET_ERROR:
     37        if (Type == NULL)
     38            Type = PyExc_WindowsError;
     39        PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
     40        break;
    3541#else /* !MS_WINDOWS */
    36         case MP_STANDARD_ERROR:
    37         case MP_SOCKET_ERROR:
    38                 if (Type == NULL)
    39                         Type = PyExc_OSError;
    40                 PyErr_SetFromErrno(Type);
    41                 break;
     42    case MP_STANDARD_ERROR:
     43    case MP_SOCKET_ERROR:
     44        if (Type == NULL)
     45            Type = PyExc_OSError;
     46        PyErr_SetFromErrno(Type);
     47        break;
    4248#endif /* !MS_WINDOWS */
    43         case MP_MEMORY_ERROR:
    44                 PyErr_NoMemory();
    45                 break;
    46         case MP_END_OF_FILE:
    47                 PyErr_SetNone(PyExc_EOFError);
    48                 break;
    49         case MP_EARLY_END_OF_FILE:
    50                 PyErr_SetString(PyExc_IOError,
    51                                 "got end of file during message");
    52                 break;
    53         case MP_BAD_MESSAGE_LENGTH:
    54                 PyErr_SetString(PyExc_IOError, "bad message length");
    55                 break;
    56         case MP_EXCEPTION_HAS_BEEN_SET:
    57                 break;
    58         default:
    59                 PyErr_Format(PyExc_RuntimeError,
    60                              "unkown error number %d", num);
    61         }
    62         return NULL;
     49    case MP_MEMORY_ERROR:
     50        PyErr_NoMemory();
     51        break;
     52    case MP_END_OF_FILE:
     53        PyErr_SetNone(PyExc_EOFError);
     54        break;
     55    case MP_EARLY_END_OF_FILE:
     56        PyErr_SetString(PyExc_IOError,
     57                        "got end of file during message");
     58        break;
     59    case MP_BAD_MESSAGE_LENGTH:
     60        PyErr_SetString(PyExc_IOError, "bad message length");
     61        break;
     62    case MP_EXCEPTION_HAS_BEEN_SET:
     63        break;
     64    default:
     65        PyErr_Format(PyExc_RuntimeError,
     66                     "unknown error number %d", num);
     67    }
     68    return NULL;
    6369}
    6470
     
    7783ProcessingCtrlHandler(DWORD dwCtrlType)
    7884{
    79         SetEvent(sigint_event);
    80         return FALSE;
     85    SetEvent(sigint_event);
     86    return FALSE;
    8187}
    8288
     
    9298   Reimplements some of the functionality of the fdcred
    9399   module at http://www.mca-ltd.com/resources/fdcred_1.tgz. */
     100/* Based in http://resin.csoft.net/cgi-bin/man.cgi?section=3&topic=CMSG_DATA */
    94101
    95102static PyObject *
    96103multiprocessing_sendfd(PyObject *self, PyObject *args)
    97104{
    98         int conn, fd, res;
    99         char dummy_char;
    100         char buf[CMSG_SPACE(sizeof(int))];
    101         struct msghdr msg = {0};
    102         struct iovec dummy_iov;
    103         struct cmsghdr *cmsg;
    104 
    105         if (!PyArg_ParseTuple(args, "ii", &conn, &fd))
    106                 return NULL;
    107 
    108         dummy_iov.iov_base = &dummy_char;
    109         dummy_iov.iov_len = 1;
    110         msg.msg_control = buf;
    111         msg.msg_controllen = sizeof(buf);
    112         msg.msg_iov = &dummy_iov;
    113         msg.msg_iovlen = 1;
    114         cmsg = CMSG_FIRSTHDR(&msg);
    115         cmsg->cmsg_level = SOL_SOCKET;
    116         cmsg->cmsg_type = SCM_RIGHTS;
    117         cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    118         msg.msg_controllen = cmsg->cmsg_len;
    119         *(int*)CMSG_DATA(cmsg) = fd;
    120 
    121         Py_BEGIN_ALLOW_THREADS
    122         res = sendmsg(conn, &msg, 0);
    123         Py_END_ALLOW_THREADS
    124 
    125         if (res < 0)
    126                 return PyErr_SetFromErrno(PyExc_OSError);
    127         Py_RETURN_NONE;
     105    int conn, fd, res;
     106    struct iovec dummy_iov;
     107    char dummy_char;
     108    struct msghdr msg;
     109    struct cmsghdr *cmsg;
     110    union {
     111        struct cmsghdr hdr;
     112        unsigned char buf[CMSG_SPACE(sizeof(int))];
     113    } cmsgbuf;
     114
     115    if (!PyArg_ParseTuple(args, "ii", &conn, &fd))
     116        return NULL;
     117
     118    dummy_iov.iov_base = &dummy_char;
     119    dummy_iov.iov_len = 1;
     120
     121    memset(&msg, 0, sizeof(msg));
     122    msg.msg_control = &cmsgbuf.buf;
     123    msg.msg_controllen = sizeof(cmsgbuf.buf);
     124    msg.msg_iov = &dummy_iov;
     125    msg.msg_iovlen = 1;
     126
     127    cmsg = CMSG_FIRSTHDR(&msg);
     128    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
     129    cmsg->cmsg_level = SOL_SOCKET;
     130    cmsg->cmsg_type = SCM_RIGHTS;
     131    * (int *) CMSG_DATA(cmsg) = fd;
     132
     133    Py_BEGIN_ALLOW_THREADS
     134    res = sendmsg(conn, &msg, 0);
     135    Py_END_ALLOW_THREADS
     136
     137    if (res < 0)
     138        return PyErr_SetFromErrno(PyExc_OSError);
     139    Py_RETURN_NONE;
    128140}
    129141
     
    131143multiprocessing_recvfd(PyObject *self, PyObject *args)
    132144{
    133         int conn, fd, res;
    134         char dummy_char;
    135         char buf[CMSG_SPACE(sizeof(int))];
    136         struct msghdr msg = {0};
    137         struct iovec dummy_iov;
    138         struct cmsghdr *cmsg;
    139 
    140         if (!PyArg_ParseTuple(args, "i", &conn))
    141                 return NULL;
    142 
    143         dummy_iov.iov_base = &dummy_char;
    144         dummy_iov.iov_len = 1;
    145         msg.msg_control = buf;
    146         msg.msg_controllen = sizeof(buf);
    147         msg.msg_iov = &dummy_iov;
    148         msg.msg_iovlen = 1;
    149         cmsg = CMSG_FIRSTHDR(&msg);
    150         cmsg->cmsg_level = SOL_SOCKET;
    151         cmsg->cmsg_type = SCM_RIGHTS;
    152         cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    153         msg.msg_controllen = cmsg->cmsg_len;
    154 
    155         Py_BEGIN_ALLOW_THREADS
    156         res = recvmsg(conn, &msg, 0);
    157         Py_END_ALLOW_THREADS
    158 
    159         if (res < 0)
    160                 return PyErr_SetFromErrno(PyExc_OSError);
    161 
    162         fd = *(int*)CMSG_DATA(cmsg);
    163         return Py_BuildValue("i", fd);
     145    int conn, fd, res;
     146    char dummy_char;
     147    struct iovec dummy_iov;
     148    struct msghdr msg = {0};
     149    struct cmsghdr *cmsg;
     150    union {
     151        struct cmsghdr hdr;
     152        unsigned char buf[CMSG_SPACE(sizeof(int))];
     153    } cmsgbuf;
     154
     155    if (!PyArg_ParseTuple(args, "i", &conn))
     156        return NULL;
     157
     158    dummy_iov.iov_base = &dummy_char;
     159    dummy_iov.iov_len = 1;
     160
     161    memset(&msg, 0, sizeof(msg));
     162    msg.msg_control = &cmsgbuf.buf;
     163    msg.msg_controllen = sizeof(cmsgbuf.buf);
     164    msg.msg_iov = &dummy_iov;
     165    msg.msg_iovlen = 1;
     166
     167    cmsg = CMSG_FIRSTHDR(&msg);
     168    cmsg->cmsg_level = SOL_SOCKET;
     169    cmsg->cmsg_type = SCM_RIGHTS;
     170    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
     171    msg.msg_controllen = cmsg->cmsg_len;
     172
     173    Py_BEGIN_ALLOW_THREADS
     174    res = recvmsg(conn, &msg, 0);
     175    Py_END_ALLOW_THREADS
     176
     177    if (res < 0)
     178        return PyErr_SetFromErrno(PyExc_OSError);
     179
     180    if (msg.msg_controllen < CMSG_LEN(sizeof(int)) ||
     181        (cmsg = CMSG_FIRSTHDR(&msg)) == NULL ||
     182        cmsg->cmsg_level != SOL_SOCKET ||
     183        cmsg->cmsg_type != SCM_RIGHTS ||
     184        cmsg->cmsg_len < CMSG_LEN(sizeof(int))) {
     185        /* If at least one control message is present, there should be
     186           no room for any further data in the buffer. */
     187        PyErr_SetString(PyExc_RuntimeError, "No file descriptor received");
     188        return NULL;
     189    }
     190
     191    fd = * (int *) CMSG_DATA(cmsg);
     192    return Py_BuildValue("i", fd);
    164193}
    165194
     
    176205multiprocessing_address_of_buffer(PyObject *self, PyObject *obj)
    177206{
    178         void *buffer;
    179         Py_ssize_t buffer_len;
    180 
    181         if (PyObject_AsWriteBuffer(obj, &buffer, &buffer_len) < 0)
    182                 return NULL;
    183 
    184         return Py_BuildValue("N" F_PY_SSIZE_T,
    185                              PyLong_FromVoidPtr(buffer), buffer_len);
     207    void *buffer;
     208    Py_ssize_t buffer_len;
     209
     210    if (PyObject_AsWriteBuffer(obj, &buffer, &buffer_len) < 0)
     211        return NULL;
     212
     213    return Py_BuildValue("N" F_PY_SSIZE_T,
     214                         PyLong_FromVoidPtr(buffer), buffer_len);
    186215}
    187216
     
    192221
    193222static PyMethodDef module_methods[] = {
    194         {"address_of_buffer", multiprocessing_address_of_buffer, METH_O,
    195          "address_of_buffer(obj) -> int\n"
    196         "Return address of obj assuming obj supports buffer inteface"},
     223    {"address_of_buffer", multiprocessing_address_of_buffer, METH_O,
     224     "address_of_buffer(obj) -> int\n"
     225    "Return address of obj assuming obj supports buffer inteface"},
    197226#if HAVE_FD_TRANSFER
    198         {"sendfd", multiprocessing_sendfd, METH_VARARGS,
    199         "sendfd(sockfd, fd) -> None\n"
    200         "Send file descriptor given by fd over the unix domain socket\n"
    201         "whose file decriptor is sockfd"},
    202         {"recvfd", multiprocessing_recvfd, METH_VARARGS,
    203         "recvfd(sockfd) -> fd\n"
    204         "Receive a file descriptor over a unix domain socket\n"
    205         "whose file decriptor is sockfd"},
    206 #endif
    207         {NULL}
     227    {"sendfd", multiprocessing_sendfd, METH_VARARGS,
     228    "sendfd(sockfd, fd) -> None\n"
     229    "Send file descriptor given by fd over the unix domain socket\n"
     230    "whose file decriptor is sockfd"},
     231    {"recvfd", multiprocessing_recvfd, METH_VARARGS,
     232    "recvfd(sockfd) -> fd\n"
     233    "Receive a file descriptor over a unix domain socket\n"
     234    "whose file decriptor is sockfd"},
     235#endif
     236    {NULL}
    208237};
    209238
     
    216245init_multiprocessing(void)
    217246{
    218         PyObject *module, *temp, *value;
    219 
    220         /* Initialize module */
    221         module = Py_InitModule("_multiprocessing", module_methods);
    222         if (!module)
    223                 return;
    224 
    225         /* Get copy of objects from pickle */
    226         temp = PyImport_ImportModule(PICKLE_MODULE);
    227         if (!temp)
    228                 return;
    229         pickle_dumps = PyObject_GetAttrString(temp, "dumps");
    230         pickle_loads = PyObject_GetAttrString(temp, "loads");
    231         pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
    232         Py_XDECREF(temp);
    233 
    234         /* Get copy of BufferTooShort */
    235         temp = PyImport_ImportModule("multiprocessing");
    236         if (!temp)
    237                 return;
    238         BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
    239         Py_XDECREF(temp);
    240 
    241         /* Add connection type to module */
    242         if (PyType_Ready(&ConnectionType) < 0)
    243                 return;
    244         Py_INCREF(&ConnectionType);     
    245         PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);
    246 
    247 #if defined(MS_WINDOWS) || HAVE_SEM_OPEN
    248         /* Add SemLock type to module */
    249         if (PyType_Ready(&SemLockType) < 0)
    250                 return;
    251         Py_INCREF(&SemLockType);
    252         PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX",
    253                              Py_BuildValue("i", SEM_VALUE_MAX));
    254         PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType);   
     247    PyObject *module, *temp, *value;
     248
     249    /* Initialize module */
     250    module = Py_InitModule("_multiprocessing", module_methods);
     251    if (!module)
     252        return;
     253
     254    /* Get copy of objects from pickle */
     255    temp = PyImport_ImportModule(PICKLE_MODULE);
     256    if (!temp)
     257        return;
     258    pickle_dumps = PyObject_GetAttrString(temp, "dumps");
     259    pickle_loads = PyObject_GetAttrString(temp, "loads");
     260    pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
     261    Py_XDECREF(temp);
     262
     263    /* Get copy of BufferTooShort */
     264    temp = PyImport_ImportModule("multiprocessing");
     265    if (!temp)
     266        return;
     267    BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
     268    Py_XDECREF(temp);
     269
     270    /* Add connection type to module */
     271    if (PyType_Ready(&ConnectionType) < 0)
     272        return;
     273    Py_INCREF(&ConnectionType);
     274    PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);
     275
     276#if defined(MS_WINDOWS) ||                                              \
     277  (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED))
     278    /* Add SemLock type to module */
     279    if (PyType_Ready(&SemLockType) < 0)
     280        return;
     281    Py_INCREF(&SemLockType);
     282    {
     283        PyObject *py_sem_value_max;
     284        /* Some systems define SEM_VALUE_MAX as an unsigned value that
     285         * causes it to be negative when used as an int (NetBSD). */
     286        if ((int)(SEM_VALUE_MAX) < 0)
     287            py_sem_value_max = PyLong_FromLong(INT_MAX);
     288        else
     289            py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);
     290        if (py_sem_value_max == NULL)
     291            return;
     292        PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX",
     293                             py_sem_value_max);
     294    }
     295    PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType);
    255296#endif
    256297
    257298#ifdef MS_WINDOWS
    258         /* Add PipeConnection to module */
    259         if (PyType_Ready(&PipeConnectionType) < 0)
    260                 return;
    261         Py_INCREF(&PipeConnectionType);
    262         PyModule_AddObject(module, "PipeConnection",
    263                            (PyObject*)&PipeConnectionType);
    264 
    265         /* Initialize win32 class and add to multiprocessing */
    266         temp = create_win32_namespace();
    267         if (!temp)
    268                 return;
    269         PyModule_AddObject(module, "win32", temp);
    270 
    271         /* Initialize the event handle used to signal Ctrl-C */
    272         sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
    273         if (!sigint_event) {
    274                 PyErr_SetFromWindowsErr(0);
    275                 return;
    276         }
    277         if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
    278                 PyErr_SetFromWindowsErr(0);
    279                 return;
    280         }
    281 #endif
    282 
    283         /* Add configuration macros */
    284         temp = PyDict_New();
    285         if (!temp)
    286                 return;
    287 #define ADD_FLAG(name)                                            \
    288         value = Py_BuildValue("i", name);                         \
    289         if (value == NULL) { Py_DECREF(temp); return; }           \
    290         if (PyDict_SetItemString(temp, #name, value) < 0) {       \
    291                 Py_DECREF(temp); Py_DECREF(value); return; }      \
    292         Py_DECREF(value)
    293        
    294 #ifdef HAVE_SEM_OPEN
    295         ADD_FLAG(HAVE_SEM_OPEN);
     299    /* Add PipeConnection to module */
     300    if (PyType_Ready(&PipeConnectionType) < 0)
     301        return;
     302    Py_INCREF(&PipeConnectionType);
     303    PyModule_AddObject(module, "PipeConnection",
     304                       (PyObject*)&PipeConnectionType);
     305
     306    /* Initialize win32 class and add to multiprocessing */
     307    temp = create_win32_namespace();
     308    if (!temp)
     309        return;
     310    PyModule_AddObject(module, "win32", temp);
     311
     312    /* Initialize the event handle used to signal Ctrl-C */
     313    sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
     314    if (!sigint_event) {
     315        PyErr_SetFromWindowsErr(0);
     316        return;
     317    }
     318    if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
     319        PyErr_SetFromWindowsErr(0);
     320        return;
     321    }
     322#endif
     323
     324    /* Add configuration macros */
     325    temp = PyDict_New();
     326    if (!temp)
     327        return;
     328#define ADD_FLAG(name)                                            \
     329    value = Py_BuildValue("i", name);                             \
     330    if (value == NULL) { Py_DECREF(temp); return; }               \
     331    if (PyDict_SetItemString(temp, #name, value) < 0) {           \
     332        Py_DECREF(temp); Py_DECREF(value); return; }              \
     333    Py_DECREF(value)
     334
     335#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
     336    ADD_FLAG(HAVE_SEM_OPEN);
    296337#endif
    297338#ifdef HAVE_SEM_TIMEDWAIT
    298         ADD_FLAG(HAVE_SEM_TIMEDWAIT);
     339    ADD_FLAG(HAVE_SEM_TIMEDWAIT);
    299340#endif
    300341#ifdef HAVE_FD_TRANSFER
    301         ADD_FLAG(HAVE_FD_TRANSFER);
     342    ADD_FLAG(HAVE_FD_TRANSFER);
    302343#endif
    303344#ifdef HAVE_BROKEN_SEM_GETVALUE
    304         ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
     345    ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
    305346#endif
    306347#ifdef HAVE_BROKEN_SEM_UNLINK
    307         ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
    308 #endif
    309         if (PyModule_AddObject(module, "flags", temp) < 0)
    310                 return;
    311 }
     348    ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
     349#endif
     350    if (PyModule_AddObject(module, "flags", temp) < 0)
     351        return;
     352}
Note: See TracChangeset for help on using the changeset viewer.