Nginx Source Learning Notes (21)--event module Two--event-driven core ngx_process_events_and_timers

Source: Internet
Author: User
Tags epoll
first of all continue to recall that, before the execution of the sub-thread has a content that is not involved ngx_process_events_and_timers, today we will study this function.

This post is from:http://blog.csdn.net/lengzijian/article/details/7601730

Let's take a look at section 19th:


Today's main explanation is the event-driven function, the red part of the diagram:

[CPP] View plaincopyprint?

  1. Src/event/ngx_event.c
  2. void
  3. Ngx_process_events_and_timers (ngx_cycle_t *cycle)
  4. {
  5. NGX_UINT_T flags;
  6. ngx_msec_t timer, Delta;
  7. if (ngx_timer_resolution) {
  8. timer = Ngx_timer_infinite;
  9. Flags = 0;
  10. } Else {
  11. Timer = Ngx_event_find_timer ();
  12. Flags = Ngx_update_time;
  13. }
  14. /*
  15. The Ngx_use_accept_mutex variable represents whether the accept mutex is used
  16. The default is to use, can pass Accept_mutex off;
  17. the role of the accept mutex is to avoid surprise groups while achieving load balancing
  18. */
  19. if (Ngx_use_accept_mutex) {
  20. /*
  21. The ngx_accept_disabled variable is calculated in the Ngx_event_accept function.
  22. if ngx_accept_disabled is greater than 0, it means that the process accepts more chains,
  23. so give up a chance to grab the mutex and reduce yourself by one.
  24. then, continue processing the events on the existing connection.
  25. Nginx uses this to implement the basic load balancing of the connection.
  26. */
  27. if (ngx_accept_disabled > 0) {
  28. ngx_accept_disabled--;
  29. } Else {
  30. /*
  31. attempting to lock the accept mutex, only the process that successfully acquires the lock will place the listen socket in Epoll.
  32. Therefore, this ensures that only one process has a listener interface, so all processes are blocked at epoll_wait,
  33. will not surprise the group phenomenon.
  34. */
  35. if (Ngx_trylock_accept_mutex (cycle) = = Ngx_error) {
  36. return ;
  37. }
  38. if (Ngx_accept_mutex_held) {
  39. /*
  40. If the process obtains a lock, a ngx_post_events flag is added.
  41. The function of this flag is to put all the resulting events into a queue , and so on after the release, slowly to handle the event.
  42. because processing times can be time-consuming, the process takes a long time to seize the lock without first casting the lock .
  43. causes other processes to fail to acquire locks, so that the efficiency of the accept is low.
  44. */
  45. Flags |= ngx_post_events;
  46. } Else {
  47. /*
  48. the process of not getting the proceeds, of course, does not require the NGX_POST_EVENTS flag.
  49. but you need to set the delay for how long, then to scramble for the lock.
  50. */
  51. if (Timer = = Ngx_timer_infinite
  52. || Timer > Ngx_accept_mutex_delay)
  53. {
  54. timer = Ngx_accept_mutex_delay;
  55. }
  56. }
  57. }
  58. }
  59. Delta = ngx_current_msec;
  60. / * Next, Epoll to start the wait event,
  61. the specific implementation of ngx_process_events is the ngx_epoll_process_events function corresponding to the Epoll module.
  62. This will be explained in detail later.
  63. */
  64. (void) ngx_process_events (cycle, timer, flags);
  65. //Statistics The time-consuming of this wait event
  66. Delta = Ngx_current_msec-delta;
  67. NGX_LOG_DEBUG1 (ngx_log_debug_event, Cycle->log, 0,
  68. "Timer Delta:%M" , Delta);
  69. /*
  70. Ngx_posted_accept_events is an event queue that holds epoll from the listener interface wait to the accept event.
  71. once the ngx_post_events flag mentioned above is used, all of the accept events are staged to this queue
  72. */
  73. if (ngx_posted_accept_events) {
  74. Ngx_event_process_posted (cycle, &ngx_posted_accept_events);
  75. }
  76. //After all the accept events have been processed, if the lock is held, it will be released.
  77. if (Ngx_accept_mutex_held) {
  78. Ngx_shmtx_unlock (&ngx_accept_mutex);
  79. }
  80. /*
  81. The delta is time-consuming and time-consuming, with milliseconds to check the timer at all times ,
  82. If timeout removes the expired timer from time Rbtree, the handler function that invokes the corresponding event is processed
  83. */
  84. if (Delta) {
  85. Ngx_event_expire_timers ();
  86. }
  87. NGX_LOG_DEBUG1 (ngx_log_debug_event, Cycle->log, 0,
  88. "posted Events%p" , ngx_posted_events);
  89. /*
  90. Handle Common events (read and write events obtained on the connection),
  91. because each event has its own handler method,
  92. */
  93. if (ngx_posted_events) {
  94. if (ngx_threaded) {
  95. Ngx_wakeup_worker_thread (cycle);
  96. } Else {
  97. Ngx_event_process_posted (cycle, &ngx_posted_events);
  98. }
  99. }
  100. }


Previously said that the accept event, in fact, he is the listener socket interface on whether there is a new event, the following introduction of the next Accept time handler method:

Ngx_event_accept:

[CPP] View plaincopyprint?

  1. Src/event/ngx_event_accept.c
  2. void
  3. Ngx_event_accept (ngx_event_t *ev)
  4. {
  5. Socklen_t Socklen;
  6. ngx_err_t err;
  7. ngx_log_t *log;
  8. ngx_socket_t s;
  9. ngx_event_t *rev, *wev;
  10. ngx_listening_t *ls;
  11. Ngx_connection_t *c, *LC;
  12. ngx_event_conf_t *ECF;
  13. U_char Sa[ngx_sockaddrlen];
  14. //Omit part of the code
  15. LC = ev->data;
  16. ls = lc->listening;
  17. Ev->ready = 0;
  18. Ngx_log_debug2 (ngx_log_debug_event, Ev->log, 0,
  19. "Accept on%V, ready:%d" , &ls->addr_text, ev->available);
  20. Do {
  21. Socklen = Ngx_sockaddrlen;
  22. //accept a new connection
  23. s = Accept (LC->FD, (struct sockaddr *) SA, &socklen);
  24. //Omit part of the code
  25. /*
  26. after the accept to a new connection, the value of the ngx_accept_disabled is recalculated,
  27. It is mainly used to do load balancing, previously mentioned.
  28. Here we can see his just the way
  29. "one-eighth of total connections-number of remaining connections"
  30. Total connections are the maximum number of connections per process set, which can be specified in the configuration file.
  31. so after each process to 7/8 of the total number of connections, ngx_accept_disabled is more than 0, the connection is overloaded
  32. */
  33. ngx_accept_disabled = NGX_CYCLE->CONNECTION_N/8
  34. -ngx_cycle->free_connection_n;
  35. //Get a connection
  36. c = ngx_get_connection (S, ev->log);
  37. //Create a memory pool for the new link
  38. //When the connection is closed, the pool is released
  39. C->pool = Ngx_create_pool (ls->pool_size, Ev->log);
  40. if (C->pool = = NULL) {
  41. Ngx_close_accepted_connection (c);
  42. return ;
  43. }
  44. C->SOCKADDR = Ngx_palloc (C->pool, Socklen);
  45. if (c->sockaddr = = NULL) {
  46. Ngx_close_accepted_connection (c);
  47. return ;
  48. }
  49. ngx_memcpy (c->sockaddr, SA, Socklen);
  50. Log = Ngx_palloc (C->pool, sizeof(ngx_log_t));
  51. if (log = = NULL) {
  52. Ngx_close_accepted_connection (c);
  53. return ;
  54. }
  55. / * Set a blocking mode for AIO and non-blocking mode for others * /
  56. if (ngx_inherited_nonblocking) {
  57. if (Ngx_event_flags & ngx_use_aio_event) {
  58. if (ngx_blocking (s) = =-1) {
  59. Ngx_log_error (Ngx_log_alert, Ev->log, Ngx_socket_errno,
  60. Ngx_blocking_n "failed");
  61. Ngx_close_accepted_connection (c);
  62. return ;
  63. }
  64. }
  65. } Else {
  66. //We use the Epoll model, here we set the connection as nonblocking
  67. if (!( Ngx_event_flags & (ngx_use_aio_event| Ngx_use_rtsig_event )) {
  68. if (ngx_nonblocking (s) = =-1) {
  69. Ngx_log_error (Ngx_log_alert, Ev->log, Ngx_socket_errno,
  70. Ngx_nonblocking_n "failed");
  71. Ngx_close_accepted_connection (c);
  72. return ;
  73. }
  74. }
  75. }
  76. *log = ls->log;
  77. //Initialize a new connection
  78. C->RECV = NGX_RECV;
  79. C->send = Ngx_send;
  80. C->recv_chain = Ngx_recv_chain;
  81. C->send_chain = Ngx_send_chain;
  82. C->log = log;
  83. C->pool->log = log;
  84. C->socklen = Socklen;
  85. c->listening = ls;
  86. C->LOCAL_SOCKADDR = ls->sockaddr;
  87. c->unexpected_eof = 1;
  88. #if (Ngx_have_unix_domain)
  89. if (c->sockaddr->sa_family = = Af_unix) {
  90. C->tcp_nopush = ngx_tcp_nopush_disabled;
  91. C->tcp_nodelay = ngx_tcp_nodelay_disabled;
  92. #if (Ngx_solaris)
  93. /* Solaris ' s Sendfilev () supports Af_nca, af_inet, and Af_inet6 */
  94. C->sendfile = 0;
  95. #endif
  96. }
  97. #endif
  98. Rev = c->read;
  99. Wev = c->write;
  100. Wev->ready = 1;
  101. if (Ngx_event_flags & (ngx_use_aio_event| ngx_use_rtsig_event)) {
  102. / * Rtsig, AIO, IOCP * /
  103. Rev->ready = 1;
  104. }
  105. if (ev->deferred_accept) {
  106. Rev->ready = 1;
  107. #if (ngx_have_kqueue)
  108. rev->available = 1;
  109. #endif
  110. }
  111. Rev->log = log;
  112. Wev->log = log;
  113. /*
  114. * TODO:MT:-Ngx_atomic_fetch_add ()
  115. * or protection by critical sections or light mutexes
  116. *
  117. * TODO:MP:-Allocated in a shared memory
  118. *-Ngx_atomic_fetch_add ()
  119. * or protection by critical sections or light mutexes
  120. */
  121. C->number = Ngx_atomic_fetch_add (Ngx_connection_counter, 1);
  122. if (Ngx_add_conn && (ngx_event_flags & ngx_use_epoll_event) = = 0) {
  123. if (Ngx_add_conn (c) = = Ngx_error) {
  124. Ngx_close_accepted_connection (c);
  125. return ;
  126. }
  127. }
  128. Log->data = NULL;
  129. Log->handler = NULL;
  130. /*
  131. Here Listen handler is important, it will complete the final initialization of the new connection,
  132. at the same time, the new connection to the accept is put into epoll, and the function hanging on this handler,
  133. is ngx_http_init_connection in the following HTTP module in detail
  134. */
  135. Ls->handler (c);
  136. if (Ngx_event_flags & ngx_use_kqueue_event) {
  137. ev->available--;
  138. }
  139. } while (ev->available);
  140. }


So is the handler method of the Accpt event. Then is the read-write event of each connection handler method, this part will directly introduce us to the HTTP module, we are not urgent, but also learn the Nginx Classic module epoll.

The above describes the Nginx source learning notes (21)--event module Two--event-driven core ngx_process_events_and_timers, including the content of the queue, I hope to be interested in PHP tutorial friends helpful.

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.