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);
  • 相关阅读:
    (网页)中的简单的遮罩层
    (后端)shiro:Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.
    (网页)jQuery的时间datetime控件在AngularJs中使用实例
    Maven Myeclipse 搭建项目
    MyBatis 环境搭建 (一)
    java 常用方法
    XML 基础
    JS BOM
    js 事件
    js 的使用原则
  • 原文地址:https://www.cnblogs.com/superPerfect/p/3611625.html
Copyright © 2011-2022 走看看