static ngx_int_t
ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
    ngx_connection_t              *c;
    ngx_http_postponed_request_t  *pr;

    c = r->connection;

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);

	//当前请求对象并不是最前面的,因此不能向out chain链写入(如果有)数据,
	//取而代之的是通过函数ngx_http_postpone_filter_add将其加入到当前请求的postponed链内。
    if (r != c->data)
	{
        if (in)
		{
            ngx_http_postpone_filter_add(r, in);
            return NGX_OK;
        }

#if 0
        /* TODO: SSI may pass NULL */
        ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http postpone filter NULL inactive request");
#endif

        return NGX_OK;
    }

	//如果r->postponed为空,则说明是最后一个sub request,也就是最新的那个,因此需要将它先发送出去。  
    /* 到这里,表示当前请求可以往out chain发送数据,如果它的postponed链表中没有子请求,也没有数据,
       则直接发送当前产生的数据in或者继续发送out chain中之前没有发送完成的数据 */
    if (r->postponed == NULL) 
	{

        if (in || c->buffered) 
		{
            return ngx_http_next_body_filter(r->main, in);
        }
		//当前请求没有需要发送的数据
        return NGX_OK;
    }
	
	//当前请求是否有新数据产生,如果有的话需加到最后
	 /* 当前请求的postponed链表中之前就存在需要处理的节点,则新建一个节点,保存当前产生的数据in,
	   并将它插入到postponed队尾 */
    if (in) 
	{
        ngx_http_postpone_filter_add(r, in);
    }

	/* 处理postponed链表中的节点 */
    do 
	{
        pr = r->postponed;

	/* 如果该节点保存的是一个子请求,则将它加到主请求的posted_requests链表中,
           以便下次调用ngx_http_run_posted_requests函数,处理该子节点 */
        if (pr->request)
		{

            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http postpone filter wake \"%V?%V\"", &pr->request->uri, &pr->request->args);

            r->postponed = pr->next;

			/* 按照后序遍历产生的序列,因为当前请求(节点)有未处理的子请求(节点),
               必须先处理完改子请求,才能继续处理后面的子节点。
               这里将该子请求设置为可以往out chain发送数据的请求。  */
            c->data = pr->request;

            return ngx_http_post_request(pr->request, NULL);
        }
		  /* 如果该节点保存的是数据,可以直接处理该节点,将它发送到out chain */
        if (pr->out == NULL)
		{
            ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http postpone filter NULL output");
        } 
		else 
		{
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http postpone filter output \"%V?%V\"", &r->uri, &r->args);

            if (ngx_http_next_body_filter(r->main, pr->out) == NGX_ERROR) 
			{
                return NGX_ERROR;
            }
        }

        r->postponed = pr->next;

    } 
	while (r->postponed);

    return NGX_OK;
}
static ngx_int_t
ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
    ngx_connection_t              *c;
    ngx_http_postponed_request_t  *pr;

    c = r->connection;

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);

    if (r != c->data) {

        if (in) {
            ngx_http_postpone_filter_add(r, in);
            return NGX_OK;
        }

#if 0
        /* TODO: SSI may pass NULL */
        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                      "http postpone filter NULL inactive request",
                      &r->uri, &r->args);
#endif

        return NGX_OK;
    }

    if (r->postponed == NULL) {

        if (in || c->buffered) {
            return ngx_http_next_body_filter(r->main, in);
        }

        return NGX_OK;
    }

    if (in) {
        ngx_http_postpone_filter_add(r, in);
    }

    do {
        pr = r->postponed;

        if (pr->request) {

            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                           "http postpone filter wake \"%V?%V\"",
                           &pr->request->uri, &pr->request->args);

            r->postponed = pr->next;

            c->data = pr->request;

            return ngx_http_post_request(pr->request, NULL);
        }

        if (pr->out == NULL) {
            ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                          "http postpone filter NULL output",
                          &r->uri, &r->args);

        } else {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                           "http postpone filter output \"%V?%V\"",
                           &r->uri, &r->args);

            if (ngx_http_next_body_filter(r->main, pr->out) == NGX_ERROR) {
                return NGX_ERROR;
            }
        }

        r->postponed = pr->next;

    } while (r->postponed);

    return NGX_OK;
}
static ngx_int_t
ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
    ngx_connection_t              *c;
    ngx_http_postponed_request_t  *pr;

    c = r->connection;							//[p]获取当前的连接对象

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);

    if (r != c->data) {							//[p]r不是当前正在处理的请求

        if (in) {
            ngx_http_postpone_filter_add(r, in);//[p]数据加入到父请求链表末尾
            return NGX_OK;						//[p]直接结束过滤链表
        }

#if 0
        /* TODO: SSI may pass NULL */
        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                      "http postpone filter NULL inactive request",
                      &r->uri, &r->args);
#endif

        return NGX_OK;
    }

    if (r->postponed == NULL) {				//[p]没有需要延后发送的数据

        if (in || c->buffered) {			//[p]使用主请求发送数据
            return ngx_http_next_filter(r->main, in);
        }

        return NGX_OK;
    }

    if (in) {								//[p]有需要延后发送的数据
        ngx_http_postpone_filter_add(r, in);//[p]将数据加入到父请求链表末尾
    }

    do {									//[p]循环处理现有的待发数据
        pr = r->postponed;					//[p]获取头结点

        if (pr->request) {					//[p]节点是子请求

            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                           "http postpone filter wake \"%V?%V\"",
                           &pr->request->uri, &pr->request->args);

            r->postponed = pr->next;		//[p]移除头结点

            c->data = pr->request;			//[p]置为连接处理的当前请求

            return ngx_http_post_request(pr->request, NULL);//[p]加入待处理请求链表
        }

        if (pr->out == NULL) {
            ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                          "http postpone filter NULL output",
                          &r->uri, &r->args);

        } else {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                           "http postpone filter output \"%V?%V\"",
                           &r->uri, &r->args);

            if (ngx_http_next_filter(r->main, pr->out) == NGX_ERROR) {
                return NGX_ERROR;
            }
        }

        r->postponed = pr->next;	//[p]处理下一个节点

    } while (r->postponed);			//[p]直到所有数据节点处理完毕

    return NGX_OK;
}