nginx源代码分析 - 收到请求(一) accept处理事件

收到客户端请求
epoll_wait返回events = 1,
ngx_connection_t  *c = event_list[i].data.ptr;

static struct epoll_event  *event_list;

typedef union epoll_data {
    void         *ptr;
    int           fd;
    uint32_t      u32;
    uint64_t      u64;
} epoll_data_t;

struct epoll_event {
    uint32_t      events;
    epoll_data_t  data;
};

events = epoll_wait(ep, event_list, (int) nevents, timer);

ngx_event_process_init
ngx_event_t         *rev, *wev;
rev = cycle->read_events; 分配内存,初始化
wev = cycle->write_events;

cycle->connection_n 最大连接数,即配置文件中指定的1024
do {
    i--;

    c[i].data = next;
    c[i].read = &cycle->read_events[i];
    c[i].write = &cycle->write_events[i];
    c[i].fd = (ngx_socket_t) -1;

    next = &c[i];
} while (i);
这些链接倒序形成链表,data字段指向上一个连接
cycle->free_connections = next; 指向最后一个连接
cycle->free_connection_n = cycle->connection_n;空闲连接数1024

c代表连接
rev = c->read;
wev = c->write;
c->fd = s;
rev->data = c;
wev->data = c;
c->type = ls[i].type; 1

c->listening = &ls[i];
ls[i].connection = c;

rev->accept = 1;
rev->handler = ngx_event_accept;

ngx_add_event(rev, NGX_READ_EVENT, 0)
ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
如果event是读,则临时变量ngx_event_t *e = c->write,prev = EPOLLOUT;
如果event是写,e = c->read; prev = EPOLLIN|EPOLLRDHUP;

如果e->active,则op = EPOLL_CTL_MOD;否则op = EPOLL_CTL_ADD;意思是上个事件还在激活状态,则只是修改

struct epoll_event   ee;
ee.events = events | (uint32_t) flags; 读事件
ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
data指针指向连接c,ev->instance = 0
ev->active = 1;

c = event_list[i].data.ptr;
instance = (uintptr_t) c & 1; 0
c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1); 取得连接

instance据网上资料是讲为了不处理一些已经关闭的连接的事件

rev->available = 1;
rev->ready = 1;
rev->handler(rev);


即ngx_event_accept
ngx_connection_t  *c, *lc;
lc = ev->data 取得accept连接

s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK);调用accept


调用栈是

Breakpoint 13, ngx_event_accept (ev=0x799e40) at src/event/ngx_event_accept.c:24
24    {
(gdb) bt
#0  ngx_event_accept (ev=0x799e40) at src/event/ngx_event_accept.c:24
#1  0x0000000000452d23 in ngx_epoll_process_events (cycle=0x72d530, timer=18446744073709551615, flags=1)
    at src/event/modules/ngx_epoll_module.c:907
#2  0x00000000004414c8 in ngx_process_events_and_timers (cycle=0x72d530) at src/event/ngx_event.c:242
#3  0x00000000004504a5 in ngx_worker_process_cycle (cycle=0x72d530, data=0x0) at src/os/unix/ngx_process_cycle.c:753
#4  0x000000000044cca6 in ngx_spawn_process (cycle=0x72d530, proc=0x4503b0 <ngx_worker_process_cycle>, data=0x0,
    name=0x4dcfcb "worker process", respawn=-3) at src/os/unix/ngx_process.c:198
#5  0x000000000044f2e1 in ngx_start_worker_processes (cycle=0x72d530, n=2, type=-3) at src/os/unix/ngx_process_cycle.c:358
#6  0x000000000044e894 in ngx_master_process_cycle (cycle=0x72d530) at src/os/unix/ngx_process_cycle.c:130
#7  0x000000000040ba95 in main (argc=5, argv=0x7fffffffe6c8) at src/core/nginx.c:367


如果设置了ngx_use_accept_mutex,flags = 3
(gdb) bt
#0  ngx_epoll_process_events (cycle=0x72d530, timer=18446744073709551615, flags=3) at src/event/modules/ngx_epoll_module.c:901
#1  0x00000000004414c8 in ngx_process_events_and_timers (cycle=0x72d530) at src/event/ngx_event.c:242
#2  0x00000000004504a5 in ngx_worker_process_cycle (cycle=0x72d530, data=0x0) at src/os/unix/ngx_process_cycle.c:753
#3  0x000000000044cca6 in ngx_spawn_process (cycle=0x72d530, proc=0x4503b0 <ngx_worker_process_cycle>, data=0x0,
    name=0x4dcfcb "worker process", respawn=-3) at src/os/unix/ngx_process.c:198
#4  0x000000000044f2e1 in ngx_start_worker_processes (cycle=0x72d530, n=2, type=-3) at src/os/unix/ngx_process_cycle.c:358
#5  0x000000000044e894 in ngx_master_process_cycle (cycle=0x72d530) at src/os/unix/ngx_process_cycle.c:130
#6  0x000000000040ba95 in main (argc=5, argv=0x7fffffffe6c8) at src/core/nginx.c:367

flags & NGX_POST_EVENTS = true, queue = ngx_posted_accept_events
放到队列中
ngx_post_event(rev, queue)


在ngx_event_process_posted(cycle, &ngx_posted_accept_events);中调用ngx_event_accept,栈是
(gdb) bt
#0  ngx_event_accept (ev=0x799e40) at src/event/ngx_event_accept.c:24
#1  0x0000000000443d67 in ngx_event_process_posted (cycle=0x72d530, posted=0x71da30 <ngx_posted_accept_events>)
    at src/event/ngx_event_posted.c:33
#2  0x0000000000441528 in ngx_process_events_and_timers (cycle=0x72d530) at src/event/ngx_event.c:249
#3  0x00000000004504a5 in ngx_worker_process_cycle (cycle=0x72d530, data=0x0) at src/os/unix/ngx_process_cycle.c:753
#4  0x000000000044cca6 in ngx_spawn_process (cycle=0x72d530, proc=0x4503b0 <ngx_worker_process_cycle>, data=0x0,
    name=0x4dcfcb "worker process", respawn=-3) at src/os/unix/ngx_process.c:198
#5  0x000000000044f2e1 in ngx_start_worker_processes (cycle=0x72d530, n=2, type=-3) at src/os/unix/ngx_process_cycle.c:358
#6  0x000000000044e894 in ngx_master_process_cycle (cycle=0x72d530) at src/os/unix/ngx_process_cycle.c:130
#7  0x000000000040ba95 in main (argc=5, argv=0x7fffffffe6c8) at src/core/nginx.c:367


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值