/Modules/_multiprocessing/win32_functions.c

http://unladen-swallow.googlecode.com/ · C · 266 lines · 204 code · 55 blank · 7 comment · 23 complexity · 1acff7e6b36507484ae16f12782ec6b3 MD5 · raw file

  1. /*
  2. * Win32 functions used by multiprocessing package
  3. *
  4. * win32_functions.c
  5. *
  6. * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
  7. */
  8. #include "multiprocessing.h"
  9. #define WIN32_FUNCTION(func) \
  10. {#func, (PyCFunction)win32_ ## func, METH_VARARGS | METH_STATIC, ""}
  11. #define WIN32_CONSTANT(fmt, con) \
  12. PyDict_SetItemString(Win32Type.tp_dict, #con, Py_BuildValue(fmt, con))
  13. static PyObject *
  14. win32_CloseHandle(PyObject *self, PyObject *args)
  15. {
  16. HANDLE hObject;
  17. BOOL success;
  18. if (!PyArg_ParseTuple(args, F_HANDLE, &hObject))
  19. return NULL;
  20. Py_BEGIN_ALLOW_THREADS
  21. success = CloseHandle(hObject);
  22. Py_END_ALLOW_THREADS
  23. if (!success)
  24. return PyErr_SetFromWindowsErr(0);
  25. Py_RETURN_NONE;
  26. }
  27. static PyObject *
  28. win32_ConnectNamedPipe(PyObject *self, PyObject *args)
  29. {
  30. HANDLE hNamedPipe;
  31. LPOVERLAPPED lpOverlapped;
  32. BOOL success;
  33. if (!PyArg_ParseTuple(args, F_HANDLE F_POINTER,
  34. &hNamedPipe, &lpOverlapped))
  35. return NULL;
  36. Py_BEGIN_ALLOW_THREADS
  37. success = ConnectNamedPipe(hNamedPipe, lpOverlapped);
  38. Py_END_ALLOW_THREADS
  39. if (!success)
  40. return PyErr_SetFromWindowsErr(0);
  41. Py_RETURN_NONE;
  42. }
  43. static PyObject *
  44. win32_CreateFile(PyObject *self, PyObject *args)
  45. {
  46. LPCTSTR lpFileName;
  47. DWORD dwDesiredAccess;
  48. DWORD dwShareMode;
  49. LPSECURITY_ATTRIBUTES lpSecurityAttributes;
  50. DWORD dwCreationDisposition;
  51. DWORD dwFlagsAndAttributes;
  52. HANDLE hTemplateFile;
  53. HANDLE handle;
  54. if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_POINTER
  55. F_DWORD F_DWORD F_HANDLE,
  56. &lpFileName, &dwDesiredAccess, &dwShareMode,
  57. &lpSecurityAttributes, &dwCreationDisposition,
  58. &dwFlagsAndAttributes, &hTemplateFile))
  59. return NULL;
  60. Py_BEGIN_ALLOW_THREADS
  61. handle = CreateFile(lpFileName, dwDesiredAccess,
  62. dwShareMode, lpSecurityAttributes,
  63. dwCreationDisposition,
  64. dwFlagsAndAttributes, hTemplateFile);
  65. Py_END_ALLOW_THREADS
  66. if (handle == INVALID_HANDLE_VALUE)
  67. return PyErr_SetFromWindowsErr(0);
  68. return Py_BuildValue(F_HANDLE, handle);
  69. }
  70. static PyObject *
  71. win32_CreateNamedPipe(PyObject *self, PyObject *args)
  72. {
  73. LPCTSTR lpName;
  74. DWORD dwOpenMode;
  75. DWORD dwPipeMode;
  76. DWORD nMaxInstances;
  77. DWORD nOutBufferSize;
  78. DWORD nInBufferSize;
  79. DWORD nDefaultTimeOut;
  80. LPSECURITY_ATTRIBUTES lpSecurityAttributes;
  81. HANDLE handle;
  82. if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_DWORD
  83. F_DWORD F_DWORD F_DWORD F_POINTER,
  84. &lpName, &dwOpenMode, &dwPipeMode,
  85. &nMaxInstances, &nOutBufferSize,
  86. &nInBufferSize, &nDefaultTimeOut,
  87. &lpSecurityAttributes))
  88. return NULL;
  89. Py_BEGIN_ALLOW_THREADS
  90. handle = CreateNamedPipe(lpName, dwOpenMode, dwPipeMode,
  91. nMaxInstances, nOutBufferSize,
  92. nInBufferSize, nDefaultTimeOut,
  93. lpSecurityAttributes);
  94. Py_END_ALLOW_THREADS
  95. if (handle == INVALID_HANDLE_VALUE)
  96. return PyErr_SetFromWindowsErr(0);
  97. return Py_BuildValue(F_HANDLE, handle);
  98. }
  99. static PyObject *
  100. win32_ExitProcess(PyObject *self, PyObject *args)
  101. {
  102. UINT uExitCode;
  103. if (!PyArg_ParseTuple(args, "I", &uExitCode))
  104. return NULL;
  105. #if defined(Py_DEBUG)
  106. SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
  107. _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
  108. #endif
  109. ExitProcess(uExitCode);
  110. return NULL;
  111. }
  112. static PyObject *
  113. win32_GetLastError(PyObject *self, PyObject *args)
  114. {
  115. return Py_BuildValue(F_DWORD, GetLastError());
  116. }
  117. static PyObject *
  118. win32_OpenProcess(PyObject *self, PyObject *args)
  119. {
  120. DWORD dwDesiredAccess;
  121. BOOL bInheritHandle;
  122. DWORD dwProcessId;
  123. HANDLE handle;
  124. if (!PyArg_ParseTuple(args, F_DWORD "i" F_DWORD,
  125. &dwDesiredAccess, &bInheritHandle, &dwProcessId))
  126. return NULL;
  127. handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
  128. if (handle == NULL)
  129. return PyErr_SetFromWindowsErr(0);
  130. return Py_BuildValue(F_HANDLE, handle);
  131. }
  132. static PyObject *
  133. win32_SetNamedPipeHandleState(PyObject *self, PyObject *args)
  134. {
  135. HANDLE hNamedPipe;
  136. PyObject *oArgs[3];
  137. DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
  138. int i;
  139. if (!PyArg_ParseTuple(args, F_HANDLE "OOO",
  140. &hNamedPipe, &oArgs[0], &oArgs[1], &oArgs[2]))
  141. return NULL;
  142. PyErr_Clear();
  143. for (i = 0 ; i < 3 ; i++) {
  144. if (oArgs[i] != Py_None) {
  145. dwArgs[i] = PyInt_AsUnsignedLongMask(oArgs[i]);
  146. if (PyErr_Occurred())
  147. return NULL;
  148. pArgs[i] = &dwArgs[i];
  149. }
  150. }
  151. if (!SetNamedPipeHandleState(hNamedPipe, pArgs[0], pArgs[1], pArgs[2]))
  152. return PyErr_SetFromWindowsErr(0);
  153. Py_RETURN_NONE;
  154. }
  155. static PyObject *
  156. win32_WaitNamedPipe(PyObject *self, PyObject *args)
  157. {
  158. LPCTSTR lpNamedPipeName;
  159. DWORD nTimeOut;
  160. BOOL success;
  161. if (!PyArg_ParseTuple(args, "s" F_DWORD, &lpNamedPipeName, &nTimeOut))
  162. return NULL;
  163. Py_BEGIN_ALLOW_THREADS
  164. success = WaitNamedPipe(lpNamedPipeName, nTimeOut);
  165. Py_END_ALLOW_THREADS
  166. if (!success)
  167. return PyErr_SetFromWindowsErr(0);
  168. Py_RETURN_NONE;
  169. }
  170. static PyMethodDef win32_methods[] = {
  171. WIN32_FUNCTION(CloseHandle),
  172. WIN32_FUNCTION(GetLastError),
  173. WIN32_FUNCTION(OpenProcess),
  174. WIN32_FUNCTION(ExitProcess),
  175. WIN32_FUNCTION(ConnectNamedPipe),
  176. WIN32_FUNCTION(CreateFile),
  177. WIN32_FUNCTION(CreateNamedPipe),
  178. WIN32_FUNCTION(SetNamedPipeHandleState),
  179. WIN32_FUNCTION(WaitNamedPipe),
  180. {NULL}
  181. };
  182. PyTypeObject Win32Type = {
  183. PyVarObject_HEAD_INIT(NULL, 0)
  184. };
  185. PyObject *
  186. create_win32_namespace(void)
  187. {
  188. Win32Type.tp_name = "_multiprocessing.win32";
  189. Win32Type.tp_methods = win32_methods;
  190. if (PyType_Ready(&Win32Type) < 0)
  191. return NULL;
  192. Py_INCREF(&Win32Type);
  193. WIN32_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
  194. WIN32_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
  195. WIN32_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
  196. WIN32_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
  197. WIN32_CONSTANT(F_DWORD, GENERIC_READ);
  198. WIN32_CONSTANT(F_DWORD, GENERIC_WRITE);
  199. WIN32_CONSTANT(F_DWORD, INFINITE);
  200. WIN32_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
  201. WIN32_CONSTANT(F_DWORD, OPEN_EXISTING);
  202. WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
  203. WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
  204. WIN32_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
  205. WIN32_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
  206. WIN32_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
  207. WIN32_CONSTANT(F_DWORD, PIPE_WAIT);
  208. WIN32_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
  209. WIN32_CONSTANT("i", NULL);
  210. return (PyObject*)&Win32Type;
  211. }