/src/ngx_python_sleep.c

https://github.com/arut/nginx-python-module · C · 108 lines · 74 code · 31 blank · 3 comment · 9 complexity · 0e180ecd7be1791477723cb597ff8163 MD5 · raw file

  1. /*
  2. * Copyright (C) Roman Arutyunyan
  3. */
  4. #include <Python.h>
  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_event.h>
  8. #include "ngx_python.h"
  9. #if !(NGX_PYTHON_SYNC)
  10. static PyObject *ngx_python_sleep(PyObject *self, PyObject *args);
  11. static void ngx_python_sleep_handler(ngx_event_t *ev);
  12. static PyMethodDef ngx_python_sleep_function = {
  13. "sleep",
  14. (PyCFunction) ngx_python_sleep,
  15. METH_VARARGS,
  16. "non-blocking sleep"
  17. };
  18. static PyObject *
  19. ngx_python_sleep(PyObject *self, PyObject *args)
  20. {
  21. double secs;
  22. ngx_event_t event;
  23. ngx_connection_t c;
  24. ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
  25. "python time.sleep()");
  26. if (!PyArg_ParseTuple(args, "d:sleep", &secs)) {
  27. return NULL;
  28. }
  29. ngx_memzero(&c, sizeof(ngx_connection_t));
  30. c.data = ngx_python_get_ctx();
  31. ngx_memzero(&event, sizeof(ngx_event_t));
  32. event.data = &c;
  33. event.handler = ngx_python_sleep_handler;
  34. event.log = ngx_cycle->log;
  35. ngx_add_timer(&event, secs * 1000);
  36. do {
  37. if (ngx_python_yield() != NGX_OK) {
  38. ngx_del_timer(&event);
  39. return NULL;
  40. }
  41. } while (!event.timedout);
  42. Py_RETURN_NONE;
  43. }
  44. static void
  45. ngx_python_sleep_handler(ngx_event_t *ev)
  46. {
  47. ngx_connection_t *c;
  48. ngx_python_ctx_t *ctx;
  49. c = ev->data;
  50. ctx = c->data;
  51. ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
  52. "python time.sleep() event handler");
  53. ngx_python_wakeup(ctx);
  54. }
  55. ngx_int_t
  56. ngx_python_sleep_install(ngx_cycle_t *cycle)
  57. {
  58. PyObject *sleep, *tm;
  59. tm = PyImport_ImportModule("time");
  60. if (tm == NULL) {
  61. return NGX_ERROR;
  62. }
  63. sleep = PyCFunction_NewEx(&ngx_python_sleep_function, NULL, NULL);
  64. if (sleep == NULL) {
  65. Py_DECREF(tm);
  66. return NGX_ERROR;
  67. }
  68. if (PyObject_SetAttrString(tm, "sleep", sleep) < 0) {
  69. Py_DECREF(sleep);
  70. Py_DECREF(tm);
  71. return NGX_ERROR;
  72. }
  73. Py_DECREF(sleep);
  74. Py_DECREF(tm);
  75. return NGX_OK;
  76. }
  77. #endif