2.live555源码分析----服务端doEventLoop()函数分析
来源:互联网 发布:linux关闭selinux命令 编辑:程序博客网 时间:2024/05/16 18:32
上一篇博客说道,live555服务端main函数做的最后一件事就是调用如下代码陷入死循环:
env->taskScheduler().doEventLoop(); // does not return
那么这个doEventLoop是什么样的呢?如下:
void BasicTaskScheduler0::doEventLoop(char* watchVariable) { // Repeatedly loop, handling readble sockets and timed events: while (1) { if (watchVariable != NULL && *watchVariable != 0) break; SingleStep(); }}
就是不停地调用SingleStep()这个函数,SingleStep函数中代码比较多,我下面仅截取关键代码,首先是使用selet陷入阻塞,等待事件发生:
int selectResult = select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay);
返回值后之后会对所有的socket进行遍历,找到是哪个socket发生了事件:
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 >= 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 }
当找到相应的的socket的时候,调用的是(*handler->handlerProc)这个函数,这个函数是什么呢?在上一篇博客里讲过,其实这个函数就是我们用turnOnBackgroundReadHandling()和相应socket绑定的函数,那么相对于一个server socket,绑定的就是incomingConnectionHandlerRTSP,主要功能是接受连接,创建新会话。如果是一个处理单个客户端的socket,那它绑定的就是incomingRequestHandler(),也就是负责从socket里读出数据,然后使用函数handleRequstBytes()对数据进行处理。
handler类型是HandlerDescriptor,这个类的定义是:
class HandlerDescriptor { HandlerDescriptor(HandlerDescriptor* nextHandler); virtual ~HandlerDescriptor();public: int socketNum; int conditionSet; TaskScheduler::BackgroundHandlerProc* handlerProc; void* clientData;private: // Descriptors are linked together in a doubly-linked list: friend class HandlerSet; friend class HandlerIterator; HandlerDescriptor* fNextHandler; HandlerDescriptor* fPrevHandler;};
这个类存储了select监控的socket的状况和相关参数。其中:
TaskScheduler::BackgroundHandlerProc* handlerProc;
就是当这个socket发生事件时所需要调用的函数。
阅读全文
0 0
- 2.live555源码分析----服务端doEventLoop()函数分析
- live555 服务端源码分析一
- live555 (doEventLoop)
- live555 源码分析
- live555 源码架构分析
- Live555源码分析:generateSDPDescription
- live555 源码分析:简介
- live555 源码分析:基础设施
- live555 源码分析:MediaSever
- live555 源码分析:RTSPServer
- live555 源码分析:ServerMediaSession
- Live555源码分析
- live555 源码分析:简介
- live555源码分析-live555大致流程
- live555源码分析-live555大致流程
- Live555源码分析之1
- live555 源码分析:播放启动
- hbase服务端源码分析
- JAVA异常之异常处理
- SQL语句查询最近几天,几个小时的数据的写法
- testng源码阅读之二
- List / Map / Collections方法
- oracle创建用户、表空间、授权
- 2.live555源码分析----服务端doEventLoop()函数分析
- 如何清除页面的图片缓存
- java缓存技术
- git-note
- Retrofit 网络请求
- error installing apk
- 作业3
- ubuntu16 安装RPM软件包
- 微服务构建