webrtc中的MethodCall0代码功能分析
MethodCall0实现了这样一个功能:
将一个类对象的成员函数(无参数)放在某个线程上下文执行,无返回(void)。
涉及到webRTC的类有:
Message, MessageHandler, Thread, ReturnType
调用例子:下例是将proxy对象的Release_s方法放在work_thread执行上下文执行。
VideoSourceProxy *proxy;
talk_base::Thread* work_thread;
...
MethodCall0<VideoSourceProxy, void> call(proxy, &VideoSourceProxy::Release_s); //声明一个MethodCall0对象call
call.Marshal(work_thread); // 将VideoSourceProxy的成员Release_s放在线程thread的上下文执行,无返回结果(void)
MethodCall0的实现如下:
template <typename R>
class ReturnType {
public:
template<typename C, typename M>
void Invoke(C* c, M m) { r_ = (c->*m)(); }
template<typename C, typename M, typename T1>
void Invoke(C* c, M m, T1 a1) { r_ = (c->*m)(a1); }
template<typename C, typename M, typename T1, typename T2>
void Invoke(C* c, M m, T1 a1, T2 a2) { r_ = (c->*m)(a1, a2); }
template<typename C, typename M, typename T1, typename T2, typename T3>
void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) { r_ = (c->*m)(a1, a2, a3); }
R value() { return r_; }
private:
R r_;
};
template <typename C, typename R>
class MethodCall0 : public talk_base::Message,
public talk_base::MessageHandler {
public:
typedef R (C::*Method)();
MethodCall0(C* c, Method m) : c_(c), m_(m) {}
R Marshal(talk_base::Thread* t) {
t->Send(this, 0);
return r_.value();
}
private:
void OnMessage(talk_base::Message*) { r_.Invoke(c_, m_);}
C* c_;
Method m_;
ReturnType<R> r_;
};
struct Message {
Message() {
memset(this, 0, sizeof(*this));
}
inline bool Match(MessageHandler* handler, uint32 id) const {
return (handler == NULL || handler == phandler)
&& (id == MQID_ANY || id == message_id);
}
MessageHandler *phandler;
uint32 message_id;
MessageData *pdata;
uint32 ts_sensitive;
};
// Messages get dispatched to a MessageHandler
class MessageHandler {
public:
virtual void OnMessage(Message* msg) = 0;
protected:
MessageHandler() {}
virtual ~MessageHandler();
private:
DISALLOW_COPY_AND_ASSIGN(MessageHandler);
};
从源码中可以看出,MethodCall0 最终调用了webrtc中Thread的send()方法来执行指定的函数,send()方法是指让函数在Thread线程中同步执行,webrtc中大量使用次方法来保证线程安全。