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

    1.添加一个socket任务

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

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

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

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

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

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

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

    在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任务的发生。

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

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

    1       fLastHandledSocketNum = sock;
    2       (*handler->handlerProc)(handler->clientData, resultConditionSet);
  • 相关阅读:
    项目结队开发---NABC分析(成员)
    梦断代码读后感(二)
    梦断代码读后感(一)
    首尾相连的循环数组求其子数组最大值
    子数组求和之大数溢出
    梦断代码读后感——终结
    软件工程结对开发——一维最大子数组求和溢出问题
    结对开发——求环形一维数组最大子数组的和
    结对开发——电梯调度问题需求分析
    软件工程——求二维数组所有子矩阵的和的最大值
  • 原文地址:https://www.cnblogs.com/superPerfect/p/3611625.html
Copyright © 2011-2022 走看看