| /* | 
 |  * 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 *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_EXCEPTION_HAS_BEEN_SET: | 
 |         break; | 
 |     default: | 
 |         PyErr_Format(PyExc_RuntimeError, | 
 |                      "unkown error number %d", num); | 
 |     } | 
 |     return NULL; | 
 | } | 
 |  | 
 |  | 
 | 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("Nn", | 
 |                          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"}, | 
 |     {NULL} | 
 | }; | 
 |  | 
 |  | 
 | /* | 
 |  * Initialize | 
 |  */ | 
 |  | 
 | static struct PyModuleDef multiprocessing_module = { | 
 |     PyModuleDef_HEAD_INIT, | 
 |     "_multiprocessing", | 
 |     NULL, | 
 |     -1, | 
 |     module_methods, | 
 |     NULL, | 
 |     NULL, | 
 |     NULL, | 
 |     NULL | 
 | }; | 
 |  | 
 |  | 
 | PyMODINIT_FUNC | 
 | PyInit__multiprocessing(void) | 
 | { | 
 |     PyObject *module, *temp, *value = NULL; | 
 |  | 
 |     /* Initialize module */ | 
 |     module = PyModule_Create(&multiprocessing_module); | 
 |     if (!module) | 
 |         return NULL; | 
 |  | 
 |     /* Get copy of BufferTooShort */ | 
 |     temp = PyImport_ImportModule("multiprocessing"); | 
 |     if (!temp) | 
 |         return NULL; | 
 |     BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort"); | 
 |     Py_XDECREF(temp); | 
 |  | 
 | #if defined(MS_WINDOWS) ||                                              \ | 
 |   (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) | 
 |     /* Add SemLock type to module */ | 
 |     if (PyType_Ready(&SemLockType) < 0) | 
 |         return NULL; | 
 |     Py_INCREF(&SemLockType); | 
 |     { | 
 |         PyObject *py_sem_value_max; | 
 |         /* Some systems define SEM_VALUE_MAX as an unsigned value that | 
 |          * causes it to be negative when used as an int (NetBSD). */ | 
 |         if ((int)(SEM_VALUE_MAX) < 0) | 
 |             py_sem_value_max = PyLong_FromLong(INT_MAX); | 
 |         else | 
 |             py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); | 
 |         if (py_sem_value_max == NULL) | 
 |             return NULL; | 
 |         PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX", | 
 |                              py_sem_value_max); | 
 |     } | 
 |     PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType); | 
 | #endif | 
 |  | 
 | #ifdef MS_WINDOWS | 
 |     /* Initialize win32 class and add to multiprocessing */ | 
 |     temp = create_win32_namespace(); | 
 |     if (!temp) | 
 |         return NULL; | 
 |     PyModule_AddObject(module, "win32", temp); | 
 | #endif | 
 |  | 
 |     /* Add configuration macros */ | 
 |     temp = PyDict_New(); | 
 |     if (!temp) | 
 |         return NULL; | 
 |  | 
 | #define ADD_FLAG(name)                                            \ | 
 |     value = Py_BuildValue("i", name);                             \ | 
 |     if (value == NULL) { Py_DECREF(temp); return NULL; }          \ | 
 |     if (PyDict_SetItemString(temp, #name, value) < 0) {           \ | 
 |         Py_DECREF(temp); Py_DECREF(value); return NULL; }                 \ | 
 |     Py_DECREF(value) | 
 |  | 
 | #if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) | 
 |     ADD_FLAG(HAVE_SEM_OPEN); | 
 | #endif | 
 | #ifdef HAVE_SEM_TIMEDWAIT | 
 |     ADD_FLAG(HAVE_SEM_TIMEDWAIT); | 
 | #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 NULL; | 
 |  | 
 |     return module; | 
 | } |