注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Koala++'s blog

计算广告学 RTB

 
 
 

日志

 
 

Larbin[5]fetchPipe源代码分析  

2010-04-19 17:10:40|  分类: Larbin |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

       main函数中的最后一个重要函数是checkAll函数,将checkAll分为两部分来看:

// read and write what can be

for (uint i = 0; i < global::nb_conn; i++) {

    Connexion *conn = global::connexions + i;

    switch (conn->state) {

    case connectingC:

    case writeC:

       if (global::ansPoll[conn->socket]) {

           // trying to finish the connection

           pipeWrite(conn);

       }

       break;

    case openC:

       if (global::ansPoll[conn->socket]) {

           // The socket is open, let's try to read it

           pipeRead(conn);

       }

       break;

    }

}

       这里如果是处理connectingCwriteC状态就去连接,或是将请求发出去,如果是读数据,就发出写请求。

       checkAll的后面一部分是:

// update fd_set for the next select

for (uint i = 0; i < global::nb_conn; i++) {

    int n = (global::connexions + i)->socket;

    switch ((global::connexions + i)->state) {

    case connectingC:

    case writeC:

       global::setPoll(n, POLLOUT);

       break;

    case openC:

       global::setPoll(n, POLLIN);

       break;

    }

}

       这里对要将读写设为非堵塞的设置,setPoll为:

/** set this fds for next poll */

#define setPoll(fds, event) \

  global::pollfds[global::posPoll].fd = fds; \

  global::pollfds[global::posPoll].events = event; \

  global::posPoll++

       看一下pipeWrite的代码:

/** The socket is finally open !

 * Make sure it's all right, and write the request

 */

static void pipeWrite(Connexion *conn) {

    int res = 0;

    int wrtn, len;

    socklen_t size = sizeof(int);

    switch (conn->state) {

    case connectingC:

       // not connected yet

       getsockopt(conn->socket, SOL_SOCKET, SO_ERROR, &res, &size);

       if (res) {

           // Unable to connect

           conn->err = noConnection;

           endOfFile(conn);

           return;

       }

       // Connection succesfull

       conn->state = writeC;

       // no break

    case writeC:

       // writing the first string

       len = strlen(conn->request.getString());

       wrtn = write(conn->socket, conn->request.getString()

+ conn->pos, len - conn->pos);

       if (wrtn >= 0) {

           addWrite(wrtn);

           conn->pos += wrtn;

           if (conn->pos < len) {

              // Some chars of this string are not written yet

              return;

           }

       } else {

          if (errno == EAGAIN || errno == EINTR || errno == ENOTCONN) {

              // little error, come back soon

              return;

           } else {

              // unrecoverable error, forget it

              conn->err = earlyStop;

              endOfFile(conn);

              return;

           }

       }

       // All the request has been written

       conn->state = openC;

    }

}

       如果是要连接,调用getsockopt,再把状态改为writeC。如果是writeC,调用write,将状态改为openC

/** Is there something to read on this socket

 * (which is open)

 */

static void pipeRead(Connexion *conn) {

    int p = conn->parser->pos;

    int size = read(conn->socket, conn->buffer + p, maxPageSize - p - 1);

    switch (size) {

    case 0:

       // End of file

       if (conn->parser->endInput())

           conn->err = (FetchError) errno;

       endOfFile(conn);

       break;

    case -1:

        // 省略

       break;

    default:

        // 省略

       break;

    }

}

       如果没有出错,读到了最后,调用endOfFile

static void endOfFile(Connexion *conn) {

    crash("End of file");

    conn->state = emptyC;

    close(conn->socket);

    if (conn->parser->isRobots) {

       // That was a robots.txt

       robots *r = ((robots *) conn->parser);

       r->parse(conn->err != success);

       r->server->robotsResult(conn->err);

       conn->recycle();

       global::freeConns->put(conn);

    } else {

       // that was an html page

       manageHtml();

    }

}

       conn的状态变为emptyC,也就是把这个conn资源释放,下面看这个是不是robots.txt,如果是就是前面connparser进行解析,如果是一个html页面,就用manageHtml

#ifdef THREAD_OUTPUT

#define manageHtml() global::userConns->put(conn)

#else // THREAD_OUTPUT

#define manageHtml() \

    endOfLoad((html *)conn->parser, conn->err); \

    conn->recycle(); \

    global::freeConns->put(conn)

#endif // THREAD_OUTPUT

       这里endOfLoad里将页面保存。

 

 

 

 

 

  评论这张
 
阅读(1950)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017