posixshmem.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. posixshmem - A Python extension that provides shm_open() and shm_unlink()
  3. */
  4. #define PY_SSIZE_T_CLEAN
  5. #include <Python.h>
  6. // for shm_open() and shm_unlink()
  7. #ifdef HAVE_SYS_MMAN_H
  8. #include <sys/mman.h>
  9. #endif
  10. /*[clinic input]
  11. module _posixshmem
  12. [clinic start generated code]*/
  13. /*[clinic end generated code: output=da39a3ee5e6b4b0d input=a416734e49164bf8]*/
  14. /*
  15. *
  16. * Module-level functions & meta stuff
  17. *
  18. */
  19. #ifdef HAVE_SHM_OPEN
  20. /*[clinic input]
  21. _posixshmem.shm_open -> int
  22. path: unicode
  23. flags: int
  24. mode: int = 0o777
  25. # "shm_open(path, flags, mode=0o777)\n\n\
  26. Open a shared memory object. Returns a file descriptor (integer).
  27. [clinic start generated code]*/
  28. static int
  29. _posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags,
  30. int mode)
  31. /*[clinic end generated code: output=8d110171a4fa20df input=e83b58fa802fac25]*/
  32. {
  33. int fd;
  34. int async_err = 0;
  35. const char *name = PyUnicode_AsUTF8(path);
  36. if (name == NULL) {
  37. return -1;
  38. }
  39. do {
  40. Py_BEGIN_ALLOW_THREADS
  41. fd = shm_open(name, flags, mode);
  42. Py_END_ALLOW_THREADS
  43. } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  44. if (fd < 0) {
  45. if (!async_err)
  46. PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
  47. return -1;
  48. }
  49. return fd;
  50. }
  51. #endif /* HAVE_SHM_OPEN */
  52. #ifdef HAVE_SHM_UNLINK
  53. /*[clinic input]
  54. _posixshmem.shm_unlink
  55. path: unicode
  56. Remove a shared memory object (similar to unlink()).
  57. Remove a shared memory object name, and, once all processes have unmapped
  58. the object, de-allocates and destroys the contents of the associated memory
  59. region.
  60. [clinic start generated code]*/
  61. static PyObject *
  62. _posixshmem_shm_unlink_impl(PyObject *module, PyObject *path)
  63. /*[clinic end generated code: output=42f8b23d134b9ff5 input=8dc0f87143e3b300]*/
  64. {
  65. int rv;
  66. int async_err = 0;
  67. const char *name = PyUnicode_AsUTF8(path);
  68. if (name == NULL) {
  69. return NULL;
  70. }
  71. do {
  72. Py_BEGIN_ALLOW_THREADS
  73. rv = shm_unlink(name);
  74. Py_END_ALLOW_THREADS
  75. } while (rv < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  76. if (rv < 0) {
  77. if (!async_err)
  78. PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
  79. return NULL;
  80. }
  81. Py_RETURN_NONE;
  82. }
  83. #endif /* HAVE_SHM_UNLINK */
  84. #include "clinic/posixshmem.c.h"
  85. static PyMethodDef module_methods[ ] = {
  86. _POSIXSHMEM_SHM_OPEN_METHODDEF
  87. _POSIXSHMEM_SHM_UNLINK_METHODDEF
  88. {NULL} /* Sentinel */
  89. };
  90. static PyModuleDef_Slot module_slots[] = {
  91. {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
  92. {0, NULL}
  93. };
  94. static struct PyModuleDef _posixshmemmodule = {
  95. PyModuleDef_HEAD_INIT,
  96. .m_name = "_posixshmem",
  97. .m_doc = "POSIX shared memory module",
  98. .m_size = 0,
  99. .m_methods = module_methods,
  100. .m_slots = module_slots,
  101. };
  102. /* Module init function */
  103. PyMODINIT_FUNC
  104. PyInit__posixshmem(void)
  105. {
  106. return PyModuleDef_Init(&_posixshmemmodule);
  107. }