您的位置:首页 > 其它

【Darwin学习笔记】之EventThread

2015-01-27 16:48 288 查看
【转载请注明出处】:http://blog.csdn.net/longlong530

EventThread负责侦听Darwin系统的Socket事件,包括以下两类, 对于两类事件是分别如何处理的,我们从头开始分析。

a) 建立新的RTSP连接请求事件

b) 已有RTSP连接上的RTSP请求消息事件



一. EventThread 的创建

RunServer.cpp 中StartServer函数初始化调用了 Socket::Initialize(),在该函数内即创建了EventThread,但是这里仅为创建,并未启动,所以还没有进入到线程的Entry()函数

二. EventThread 的启动

RunServer.cpp 中StartServer函数初始化调用了Socket::StartThread(),启动了在上一步创建的sEventThread类所对应的线程。

三. EventThread 的运行

EventThread 线程启动后进入,EventThread::Entry()函数中开始调用select_waitevent函数监听所有的Socket端口,直到有事件发生为止

当有事件发生时:

//通过事件中的标识找到相应的对象参考指针
            StrPtrLen idStr((char*)&theCurrentEvent.er_data, sizeof(theCurrentEvent.er_data));
			//fRefTable中的对象参考指针RTSPListenerSocket
            OSRef* ref = fRefTable.Resolve(&idStr);
            if (ref != NULL)
            {
				//通过参考指针得到EventContext对象
                EventContext* theContext = (EventContext*)ref->GetObject();

找到对应的对象后,开始调用其处理方法,这里要着重关注ProcessEvent()方法:

ProcessEvent作为虚函数有两个实现,在这里RTSP连接和RTSP连接内的消息请求会有不同的调用分支;

EventContext类中实现了ProcessEvent方法;

EventContext的派生类TCPListenerSocket中实现了ProcessEvent方法。

a). 建立新的RTSP连接请求事件

fRefTable表插入时间:
QTSServer::StartTasks()中的 fListeners[x]->RequestEvent(EV_RE);,存入的对象为RTSPListenerSocket

调用方法: TCPListenerSocket::ProcessEvent

方法描述: 此方法调用RTSPListenerSocket的GetSessionTask方法建立一个RTSPSession,并把相应的套接口加入侦听队列,等待RTSP请求。

然后还需调用this->RequestEvent(EV_RE)把建立RTSP连接的请求加入到侦听队列。

b). 已有RTSP连接上的RTSP请求消息事件

fRefTable表插入时间:
上一步的this->RequestEvent(EV_RE)

调用方法: EventContext::ProcessEvent

方法描述: 通过Task的Signal把对应的RTSPSession类型的Task加入到TaskThread::fTaskQueue中等待TaskThread处理。

//处理RTSP连接请求或者RTSP连接上的消息请求事件
theContext->ProcessEvent(theCurrentEvent.er_eventbits);
fRefTable.Release(ref);//减少引用计数


另外介绍下TCPListenerSocket::ProcessEvent方法,RTSPSession就这这里的GetSessionTask中被创建。摘取片段进行备注说明
//获取RTSPSession的fSocket参数,然后将当前接收数据的socket赋值给该参数;
    theTask = this->GetSessionTask(&theSocket);
    if (theTask == NULL)
    {    //this should be a disconnect. do an ioctl call?
        close(osSocket);
        if (theSocket)
            theSocket->fState &= ~kConnected; // turn off connected state
    }
    else//创建成功,接着创建Socket对象;
    {      
        /*此处省略部分代码*/
        //把刚刚建立好的RTSP连接加入到侦听队列,等待RTSP请求的到来;
        theSocket->Set(osSocket, &addr);
        theSocket->InitNonBlocking(osSocket);//初始化;
	//将新建的RTSPSession保存到EventContext对应的fTask属性,当该socket连接后面的消息事件到来时即将该RTSPSession任务加入到task线程中;
        theSocket->SetTask(theTask);
        theSocket->RequestEvent(EV_RE);//新对象监听读事件;(EventContext开始监听该socket连接之上发送的消息)
        
	//theTask就是新建的RTSPSession;
        theTask->SetThreadPicker(Task::GetBlockingTaskThreadPicker()); //The RTSP Task processing threads


【转载请注明出处】:http://blog.csdn.net/longlong530
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: