summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortommi@webrtc.org <tommi@webrtc.org>2014-11-04 12:08:48 +0000
committertommi@webrtc.org <tommi@webrtc.org>2014-11-04 12:08:48 +0000
commit2efcfc489c7171daba0801546ea1fd8f006b0cd6 (patch)
treee02f05a12c815596fd9359eaa92e9a693aa085c1
parent42536c6027e2446aced33365a6719169e97876dc (diff)
downloadtalk-2efcfc489c7171daba0801546ea1fd8f006b0cd6.tar.gz
Change the PeerConnection proxy templates to use blocking method calls instead of using Thread::Send.
The problem with Thread::Send is that it processes incoming pending messages and for the proxies, this can mean that multiple incoming calls can concurrently run on the same thread, resulting in unexpected behavior. See e.g. crbug.com/429740 (and more) R=perkj@webrtc.org Review URL: https://webrtc-codereview.appspot.com/28939004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7607 4adac7df-926f-26a2-2b94-8c16560cd09d
-rw-r--r--app/webrtc/proxy.h43
1 files changed, 36 insertions, 7 deletions
diff --git a/app/webrtc/proxy.h b/app/webrtc/proxy.h
index 0c21ef9..134f580 100644
--- a/app/webrtc/proxy.h
+++ b/app/webrtc/proxy.h
@@ -55,6 +55,7 @@
#ifndef TALK_APP_WEBRTC_PROXY_H_
#define TALK_APP_WEBRTC_PROXY_H_
+#include "webrtc/base/event.h"
#include "webrtc/base/thread.h"
namespace webrtc {
@@ -92,6 +93,34 @@ class ReturnType<void> {
void value() {}
};
+namespace internal {
+
+class SynchronousMethodCall
+ : public rtc::MessageData,
+ public rtc::MessageHandler {
+ public:
+ SynchronousMethodCall(rtc::MessageHandler* proxy)
+ : e_(), proxy_(proxy) {}
+ ~SynchronousMethodCall() {}
+
+ void Invoke(rtc::Thread* t) {
+ if (t->IsCurrent()) {
+ proxy_->OnMessage(NULL);
+ } else {
+ e_.reset(new rtc::Event(false, false));
+ t->Post(this, 0);
+ e_->Wait(rtc::kForever);
+ }
+ }
+
+ private:
+ void OnMessage(rtc::Message*) { proxy_->OnMessage(NULL); e_->Set(); }
+ rtc::scoped_ptr<rtc::Event> e_;
+ rtc::MessageHandler* proxy_;
+};
+
+} // internal
+
template <typename C, typename R>
class MethodCall0 : public rtc::Message,
public rtc::MessageHandler {
@@ -100,12 +129,12 @@ class MethodCall0 : public rtc::Message,
MethodCall0(C* c, Method m) : c_(c), m_(m) {}
R Marshal(rtc::Thread* t) {
- t->Send(this, 0);
+ internal::SynchronousMethodCall(this).Invoke(t);
return r_.value();
}
private:
- void OnMessage(rtc::Message*) { r_.Invoke(c_, m_);}
+ void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
C* c_;
Method m_;
@@ -120,7 +149,7 @@ class ConstMethodCall0 : public rtc::Message,
ConstMethodCall0(C* c, Method m) : c_(c), m_(m) {}
R Marshal(rtc::Thread* t) {
- t->Send(this, 0);
+ internal::SynchronousMethodCall(this).Invoke(t);
return r_.value();
}
@@ -140,7 +169,7 @@ class MethodCall1 : public rtc::Message,
MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
R Marshal(rtc::Thread* t) {
- t->Send(this, 0);
+ internal::SynchronousMethodCall(this).Invoke(t);
return r_.value();
}
@@ -161,7 +190,7 @@ class ConstMethodCall1 : public rtc::Message,
ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
R Marshal(rtc::Thread* t) {
- t->Send(this, 0);
+ internal::SynchronousMethodCall(this).Invoke(t);
return r_.value();
}
@@ -182,7 +211,7 @@ class MethodCall2 : public rtc::Message,
MethodCall2(C* c, Method m, T1 a1, T2 a2) : c_(c), m_(m), a1_(a1), a2_(a2) {}
R Marshal(rtc::Thread* t) {
- t->Send(this, 0);
+ internal::SynchronousMethodCall(this).Invoke(t);
return r_.value();
}
@@ -205,7 +234,7 @@ class MethodCall3 : public rtc::Message,
: c_(c), m_(m), a1_(a1), a2_(a2), a3_(a3) {}
R Marshal(rtc::Thread* t) {
- t->Send(this, 0);
+ internal::SynchronousMethodCall(this).Invoke(t);
return r_.value();
}