现在的位置: 首页 > 综合 > 正文

Nginx的connection定义

2014年07月04日 ⁄ 综合 ⁄ 共 2224字 ⁄ 字号 评论关闭

在讲Nginx的事件驱动之前,得先弄明白ngx_connection_t这个结构。(定义在Ngx_connection.h)他是nginx事件驱动的基础,每一个监听在worker进程中都会为其分配一个connection,每一个监听接收到的连接,worker进程也会用connection来维护它,直到连接的终止,该connection才被回收。

额,由于它的定义实在太长了,所以这里就不列出来了,说几个比较重要的域吧:

    void               *data;    //貌似是用来构成cycle中freeconnections链表用的
    ngx_event_t        *read;  //读事件
    ngx_event_t        *write;  //写事件

    ngx_socket_t        fd;   //socket描述符

    ngx_recv_pt         recv;
    ngx_send_pt         send;
    ngx_recv_chain_pt   recv_chain;   //chain结构,貌似是用来爆粗接收到的数据
    ngx_send_chain_pt   send_chain;

    ngx_listening_t    *listening;   // 监听头结构

    off_t               sent;

    ngx_log_t          *log;

    ngx_pool_t         *pool;     //内存池

data域用来构成链表,这个待会说。raad指的是该连接的读事件,write是写事件,fd则对应当前连接的socket描述符,chain用来保存接受数据,如果这个连接是与监听绑定在一起的,那么listening域将于相应的监听端口绑定。pool则是这个连接的内存池,用来为当前连接分配内存,知道连接中断以后该内存池才会销毁。

在ngx_event_process_init函数中有connection数组的初始化代码:

	/*创建一个connection数组,维护所有的connection; 
	   本过程已经是在worker进程中了,所以是每个worker都有自己的 
	   connection数组。 
	   同样每一个worker进程也有自己的cycle
	   */  
    cycle->connections =
        ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
    if (cycle->connections == NULL) {
        return NGX_ERROR;
    }

    c = cycle->connections;  //指向当前worker进程的cycle的connection数组
//创建读事件数组
    cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                                   cycle->log);
    if (cycle->read_events == NULL) {
        return NGX_ERROR;
    }

    rev = cycle->read_events;   //指向当前worker进程的cycle的读取事件数组
    for (i = 0; i < cycle->connection_n; i++) {
        rev[i].closed = 1;
        rev[i].instance = 1;
#if (NGX_THREADS)
        rev[i].lock = &c[i].lock;
        rev[i].own_lock = &c[i].lock;
#endif
    }
//创建写事件的数组
    cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                                    cycle->log);
    if (cycle->write_events == NULL) {
        return NGX_ERROR;
    }

    wev = cycle->write_events;  //同样是指向当前worker进程的cycle的写事件的数组
    for (i = 0; i < cycle->connection_n; i++) {
        wev[i].closed = 1;
#if (NGX_THREADS)
        wev[i].lock = &c[i].lock;
        wev[i].own_lock = &c[i].lock;
#endif
    }

    i = cycle->connection_n;
    next = NULL;

   
    /*初始化整个connection数组,connection数组使用得很是巧妙, 这里类似于一个链表的结构
    能够快速的获取释放一个连接结构。下一篇画个图来详细看看 
    这个connection。 
    */  
    do {
        i--;

        c[i].data = next;   //这里用于将connection串成一个链,好管理
        c[i].read = &cycle->read_events[i];   //为当前的connection赋读事件
        c[i].write = &cycle->write_events[i];  //为当前的connection赋写事件
        c[i].fd = (ngx_socket_t) -1;

        next = &c[i];

#if (NGX_THREADS)
        c[i].lock = 0;
#endif
    } while (i);

基本内容注释已经都说的比较清楚了,这里的connection门的组织是按照链表的形式的,并且有一个free域指向空闲connection的头。对于connection数组的重要操作有ngx_get_connection,为该函数传入一个socket描述符,然后函数从空闲connection中为该描述符分配一个connection,并初始化一些基本的信息,好像其他的函数也没什么意思了很简单。。。就不写了。

抱歉!评论已关闭.