In the case of work process is configured to support multi-threading in the following scene, there is an event at the same time will be handled by the main thread and worker thread.
step1: in ngx_process_events_and_timers function, the main thread get the accept lock and set the ngx_accept_mutex_held to 1, at this time, the flags | = NGX_POST_EVENTS. And then enter ngx_process_events (epoll, under for ngx_epoll_process_events function) function, all received non-accept epoll events will be added to the the queue ngx_posted_events;
step2: in the main thread of the work process handler function ngx_worker_process_cycle to, inform all the worker threads to process events
in the queue ngx_posted_events .
step3: the main thread to re-enter the event loop, try to grab the accept lock, no grab, ngx_accept_mutex_held be set to 0, then, the flags =
0. Then enter ngx_process_events, received all non-accept epoll events. The flag is not NGX_POST_EVENTS, Therefore, directly calling the event handler to handle the event.
The problem lies here:
If in step2 a worker thread is processing a connection event ev1 (c-> read or c-> write), while in step3 connection produced a similar event ev1 (c-> the read or c-> write), the main thread and worker thread handle the same event conflictly.