LCOV - code coverage report
Current view: top level - home/build/openresty-1.13.6.1/build/ngx_lua-0.10.11/src - ngx_http_lua_sleep.c (source / functions) Hit Total Coverage
Test: coverage ngix Lines: 4 79 5.1 %
Date: 2020-03-03 04:25:50 Functions: 1 5 20.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright (C) Xiaozhe Wang (chaoslawful)
       4             :  * Copyright (C) Yichun Zhang (agentzh)
       5             :  */
       6             : 
       7             : 
       8             : #ifndef DDEBUG
       9             : #define DDEBUG 0
      10             : #endif
      11             : #include "ddebug.h"
      12             : 
      13             : 
      14             : #include "ngx_http_lua_util.h"
      15             : #include "ngx_http_lua_sleep.h"
      16             : #include "ngx_http_lua_contentby.h"
      17             : 
      18             : 
      19             : static int ngx_http_lua_ngx_sleep(lua_State *L);
      20             : static void ngx_http_lua_sleep_handler(ngx_event_t *ev);
      21             : static void ngx_http_lua_sleep_cleanup(void *data);
      22             : static ngx_int_t ngx_http_lua_sleep_resume(ngx_http_request_t *r);
      23             : 
      24             : 
      25             : static int
      26           0 : ngx_http_lua_ngx_sleep(lua_State *L)
      27             : {
      28             :     int                          n;
      29             :     ngx_int_t                    delay; /* in msec */
      30             :     ngx_http_request_t          *r;
      31             :     ngx_http_lua_ctx_t          *ctx;
      32             :     ngx_http_lua_co_ctx_t       *coctx;
      33             : 
      34           0 :     n = lua_gettop(L);
      35           0 :     if (n != 1) {
      36           0 :         return luaL_error(L, "attempt to pass %d arguments, but accepted 1", n);
      37             :     }
      38             : 
      39           0 :     r = ngx_http_lua_get_req(L);
      40           0 :     if (r == NULL) {
      41           0 :         return luaL_error(L, "no request found");
      42             :     }
      43             : 
      44           0 :     delay = (ngx_int_t) (luaL_checknumber(L, 1) * 1000);
      45             : 
      46           0 :     if (delay < 0) {
      47           0 :         return luaL_error(L, "invalid sleep duration \"%d\"", delay);
      48             :     }
      49             : 
      50           0 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
      51           0 :     if (ctx == NULL) {
      52           0 :         return luaL_error(L, "no request ctx found");
      53             :     }
      54             : 
      55           0 :     ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
      56             :                                | NGX_HTTP_LUA_CONTEXT_ACCESS
      57             :                                | NGX_HTTP_LUA_CONTEXT_CONTENT
      58             :                                | NGX_HTTP_LUA_CONTEXT_TIMER
      59             :                                | NGX_HTTP_LUA_CONTEXT_SSL_CERT
      60             :                                | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH);
      61             : 
      62           0 :     coctx = ctx->cur_co_ctx;
      63           0 :     if (coctx == NULL) {
      64           0 :         return luaL_error(L, "no co ctx found");
      65             :     }
      66             : 
      67           0 :     ngx_http_lua_cleanup_pending_operation(coctx);
      68           0 :     coctx->cleanup = ngx_http_lua_sleep_cleanup;
      69           0 :     coctx->data = r;
      70             : 
      71           0 :     coctx->sleep.handler = ngx_http_lua_sleep_handler;
      72           0 :     coctx->sleep.data = coctx;
      73           0 :     coctx->sleep.log = r->connection->log;
      74             : 
      75           0 :     if (delay == 0) {
      76             : #ifdef HAVE_POSTED_DELAYED_EVENTS_PATCH
      77             :         dd("posting 0 sec sleep event to head of delayed queue");
      78             : 
      79           0 :         coctx->sleep.delayed = 1;
      80           0 :         ngx_post_event(&coctx->sleep, &ngx_posted_delayed_events);
      81             : #else
      82             :         ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "ngx.sleep(0)"
      83             :                       " called without delayed events patch, this will"
      84             :                       " hurt performance");
      85             :         ngx_add_timer(&coctx->sleep, (ngx_msec_t) delay);
      86             : #endif
      87             : 
      88             :     } else {
      89             :         dd("adding timer with delay %lu ms, r:%.*s", (unsigned long) delay,
      90             :            (int) r->uri.len, r->uri.data);
      91             : 
      92           0 :         ngx_add_timer(&coctx->sleep, (ngx_msec_t) delay);
      93             :     }
      94             : 
      95           0 :     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
      96             :                    "lua ready to sleep for %d ms", delay);
      97             : 
      98           0 :     return lua_yield(L, 0);
      99             : }
     100             : 
     101             : 
     102             : void
     103           0 : ngx_http_lua_sleep_handler(ngx_event_t *ev)
     104             : {
     105             :     ngx_connection_t        *c;
     106             :     ngx_http_request_t      *r;
     107             :     ngx_http_lua_ctx_t      *ctx;
     108             :     ngx_http_log_ctx_t      *log_ctx;
     109             :     ngx_http_lua_co_ctx_t   *coctx;
     110             : 
     111           0 :     coctx = ev->data;
     112             : 
     113           0 :     r = coctx->data;
     114           0 :     c = r->connection;
     115             : 
     116           0 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
     117             : 
     118           0 :     if (ctx == NULL) {
     119           0 :         return;
     120             :     }
     121             : 
     122           0 :     if (c->fd != (ngx_socket_t) -1) {  /* not a fake connection */
     123           0 :         log_ctx = c->log->data;
     124           0 :         log_ctx->current_request = r;
     125             :     }
     126             : 
     127           0 :     coctx->cleanup = NULL;
     128             : 
     129           0 :     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
     130             :                    "lua sleep timer expired: \"%V?%V\"", &r->uri, &r->args);
     131             : 
     132           0 :     ctx->cur_co_ctx = coctx;
     133             : 
     134           0 :     if (ctx->entered_content_phase) {
     135           0 :         (void) ngx_http_lua_sleep_resume(r);
     136             : 
     137             :     } else {
     138           0 :         ctx->resume_handler = ngx_http_lua_sleep_resume;
     139           0 :         ngx_http_core_run_phases(r);
     140             :     }
     141             : 
     142           0 :     ngx_http_run_posted_requests(c);
     143             : }
     144             : 
     145             : 
     146             : void
     147          18 : ngx_http_lua_inject_sleep_api(lua_State *L)
     148             : {
     149          18 :     lua_pushcfunction(L, ngx_http_lua_ngx_sleep);
     150          18 :     lua_setfield(L, -2, "sleep");
     151          18 : }
     152             : 
     153             : 
     154             : static void
     155           0 : ngx_http_lua_sleep_cleanup(void *data)
     156             : {
     157           0 :     ngx_http_lua_co_ctx_t          *coctx = data;
     158             : 
     159           0 :     if (coctx->sleep.timer_set) {
     160           0 :         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
     161             :                        "lua clean up the timer for pending ngx.sleep");
     162             : 
     163           0 :         ngx_del_timer(&coctx->sleep);
     164             :     }
     165             : 
     166             : #ifdef HAVE_POSTED_DELAYED_EVENTS_PATCH
     167           0 :     if (coctx->sleep.posted) {
     168           0 :         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
     169             :                        "lua clean up the posted event for pending ngx.sleep");
     170             : 
     171           0 :         ngx_delete_posted_event(&coctx->sleep);
     172             :     }
     173             : #endif
     174           0 : }
     175             : 
     176             : 
     177             : static ngx_int_t
     178           0 : ngx_http_lua_sleep_resume(ngx_http_request_t *r)
     179             : {
     180             :     lua_State                   *vm;
     181             :     ngx_connection_t            *c;
     182             :     ngx_int_t                    rc;
     183             :     ngx_uint_t                   nreqs;
     184             :     ngx_http_lua_ctx_t          *ctx;
     185             : 
     186           0 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
     187           0 :     if (ctx == NULL) {
     188           0 :         return NGX_ERROR;
     189             :     }
     190             : 
     191           0 :     ctx->resume_handler = ngx_http_lua_wev_handler;
     192             : 
     193           0 :     c = r->connection;
     194           0 :     vm = ngx_http_lua_get_lua_vm(r, ctx);
     195           0 :     nreqs = c->requests;
     196             : 
     197           0 :     rc = ngx_http_lua_run_thread(vm, r, ctx, 0);
     198             : 
     199           0 :     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
     200             :                    "lua run thread returned %d", rc);
     201             : 
     202           0 :     if (rc == NGX_AGAIN) {
     203           0 :         return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
     204             :     }
     205             : 
     206           0 :     if (rc == NGX_DONE) {
     207           0 :         ngx_http_lua_finalize_request(r, NGX_DONE);
     208           0 :         return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
     209             :     }
     210             : 
     211           0 :     if (ctx->entered_content_phase) {
     212           0 :         ngx_http_lua_finalize_request(r, rc);
     213           0 :         return NGX_DONE;
     214             :     }
     215             : 
     216           0 :     return rc;
     217             : }
     218             : 
     219             : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */

Generated by: LCOV version 1.13