nginx笔记

Posted on 2011-09-30 09:45 冷锋 阅读(390) 评论(0)  编辑 收藏 引用 所属分类: linux

ngx_connection_t,抽象的连接,在core模块的ngx_event_process_init 函数中预先分配好。ngx_event_process_init预分配connects,read\write 事件的数组,

并依次初始化,并依次初始化各连接的链表关系,也就是在data上存下一个connection的指针 
 cycle
->connections =
        ngx_alloc(
sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
    
if (cycle->connections == NULL) {
        
return NGX_ERROR;
    }
.

 c 
= cycle->connections;
.
    
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];
#if (NGX_THREADS)
        c[i].
lock = 0;
#endif
    } 
while (i);
    cycle
->free_connections = next;
    cycle
->free_connection_n = cycle->connection_n;

//初始化linsten socket,并设置listen的处理函数为 rev->handler = ngx_event_acceptex;
Rev->accept=1;
 
for (i = 0; i < cycle->listening.nelts; i++) {

        c 
= ngx_get_connection(ls[i].fd, cycle->log);

        
if (c == NULL) {
            
return NGX_ERROR;
        }
}(结构体部分成员)
struct ngx_connection_s {
    
void               *data;
    ngx_event_t        
*read;//读事件处理
    ngx_event_t        *write;//写事件处理
    ngx_socket_t        fd;//连接对应的socket
    ngx_listening_t    *listening;/

    ngx_log_t          
*log;

    ngx_pool_t         
*pool;

         
//平台相关的读写,对应socket的send,recv
        ngx_recv_pt         recv;
    ngx_send_pt         send;

    
struct sockaddr    *sockaddr;//地址
    socklen_t           socklen;
    ngx_str_t           addr_text;
}

ngx_get_connection:freeconnect队头取出一个connection,并将socket绑定此connection

在上层应用(比如HTTP),使用ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)加入读事件。

 

在ngx_epoll_process_events函数中,
 
if (flags & NGX_POST_EVENTS) {
                ngx_locked_post_event(wev, 
&ngx_posted_events);

            } 
else {
                wev
->handler(wev);
            }

如果带有NGX_POST_EVENTS标记,就把事件投递到队列中不立即处理。
在ngx_process_events_and_timers 中,会在每个循环调用ngx_event_process_posted(cycle, 
&ngx_posted_events);不断取出事件队列进行处理。
 NGX_POST_EVENTS是为了进行耗时操作前先释放进程锁,放入队列稍后再处理(用进程锁应该是避免N个进程accept导致的惊群,新版linux已经不会出现这个问题)。
  
if (ngx_posted_events) {
        
if (ngx_threaded) {
            ngx_wakeup_worker_thread(cycle);

        } 
else {
            ngx_event_process_posted(cycle, 
&ngx_posted_events);
        }
    }

 


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


posts - 15, comments - 18, trackbacks - 0, articles - 0

Copyright © 冷锋