zoukankan      html  css  js  c++  java
  • live555 中的socket的任务调度分析

    1.添加一个socket任务

    envir().taskScheduler().setBackgroundHandling(socketNum, SOCKET_WRITABLE|SOCKET_EXCEPTION,
    (TaskScheduler::BackgroundHandlerProc*)&connectionHandler, this);

    2.接下来就会把相关参数设置进socket任务集合中去,接下来就是等待任务调度。

     fHandlers->assignHandler(socketNum, conditionSet, handlerProc, clientData)
    class HandlerSet是一个链表类,里面存在一个成员变量fHandlers,是这个链表的头结点。
    assignHandler函数会将socket相关的一些参数,函数指针等封装成一个新节点,插入链表。

    3.doEventLoop 是事件循环函数,用于调度事件。

    void BasicTaskScheduler0::doEventLoop(char* watchVariable) {
    // Repeatedly loop, handling readble sockets and timed events:
    while (1) {
    if (watchVariable != NULL && *watchVariable != 0) break;
    SingleStep();
    }
    }

    4.在SingleStep函数中使用select来监听socket的任务的发生

    int selectResult = select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay); 

    在SingleStep中使用了一个参数 fLastHandledSocketNum 记录了上次任务发生时该任务在链表中的位置。

    a.检测是否上次的任务在任务链表中的某一个位置,如果在就从这个位置开始查找是否发生socket任务。

    复制代码
      if (fLastHandledSocketNum >= 0) {
        while ((handler = iter.next()) != NULL) {
          if (handler->socketNum == fLastHandledSocketNum) break;
        }
        if (handler == NULL) {
          fLastHandledSocketNum = -1;
          iter.reset(); // start from the beginning instead
        }
      }
      while ((handler = iter.next()) != NULL) {
        int sock = handler->socketNum; // alias
        int resultConditionSet = 0;
        if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
        if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
        if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
        if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
          fLastHandledSocketNum = sock;
              // Note: we set "fLastHandledSocketNum" before calling the handler,
              // in case the handler calls "doEventLoop()" reentrantly.
          (*handler->handlerProc)(handler->clientData, resultConditionSet);
          break;
        }
      }
    复制代码

    b. 如果没有任何soket任务发生,于是认为有可能在fLastHandledSocketNum 任务链表位置前面的某一个地方发生了socket任务。接下来就

    从链表头开始遍历,查找socket任务的发生。

    if (handler == NULL && fLastHandledSocketNum >= 0) {
        // We didn't call a handler, but we didn't get to check all of them,
        // so try again from the beginning:
        iter.reset();
        while ((handler = iter.next()) != NULL) {
          int sock = handler->socketNum; // alias
          int resultConditionSet = 0;
          if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
          if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
          if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
          if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
        fLastHandledSocketNum = sock;
            // Note: we set "fLastHandledSocketNum" before calling the handler,
                // in case the handler calls "doEventLoop()" reentrantly.
        (*handler->handlerProc)(handler->clientData, resultConditionSet);
        break;
          }
        }
        if (handler == NULL) fLastHandledSocketNum = -1;//because we didn't call a handler
      }

    5.查找到socket任务的socket时,调度相关的函数指针,执行相关函数。同时 fLastHandledSocketNum = sock

           fLastHandledSocketNum = sock;
           (*handler->handlerProc)(handler->clientData, resultConditionSet);

    原文链接:https://www.cnblogs.com/superPerfect/p/3611625.html

  • 相关阅读:
    jQuery小案例
    update-alternatives
    计算机网络备忘
    报文交换 (转自百度百科,方便以后复习)
    erlang supervisor simple_one_for_one实例
    erlang supervisor中启动普通的进程
    erlang四大behaviour之一gen_server(转载)
    用Doxygen+Graphviz生成函数调用流程图(转)
    selenium模块
    request模块
  • 原文地址:https://www.cnblogs.com/ranson7zop/p/7904988.html
Copyright © 2011-2022 走看看