step1:在ngx_process_events_and_timers函数中,主线程抢到accept锁,
ngx_accept_mutex_held被置为1,此时,flags |= NGX_POST_EVENTS。然后进入
ngx_process_events(epoll下为ngx_epoll_process_events函数)函数,收到的所有非accept
epoll事件,会添加到队列ngx_posted_events中;
step2:在工作进程的主线程处理函数ngx_worker_process_cycle中,通知所有等待处理事件的工作线程处理
ngx_posted_events中的事件。
step3:主线程再次进入事件循环,尝试抢accept锁,没有抢到,ngx_accept_mutex_held被置为0,此时,flags =
0。然后进入ngx_process_events,收到的所有非accept epoll事件,由于flags不为NGX_POST_EVENTS,
因此,会直接调用事件的处理函数对事件进行处理。
问题就出在这里:
假如step2中的一个工作线程正在处理一个connection的事件ev1(c->read或c->write),而在step3中,这个
connection又产生了一个相同的事件ev1(c->read或c->write),就出现了主线程和工作线程处理同一事件的冲突。