summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/sync/notifier/base/signal_thread_task.h3
-rw-r--r--chrome/browser/sync/notifier/listener/mediator_thread_impl.cc2
-rw-r--r--third_party/libjingle/README.chromium2
-rw-r--r--third_party/libjingle/files/talk/base/asynchttprequest.h3
-rw-r--r--third_party/libjingle/files/talk/base/autodetectproxy.cc2
-rw-r--r--third_party/libjingle/files/talk/base/autodetectproxy.h2
-rw-r--r--third_party/libjingle/files/talk/base/messagequeue.cc8
-rw-r--r--third_party/libjingle/files/talk/base/messagequeue.h9
-rw-r--r--third_party/libjingle/files/talk/base/signalthread.cc64
-rw-r--r--third_party/libjingle/files/talk/base/signalthread.h59
-rw-r--r--third_party/libjingle/files/talk/base/thread.cc9
-rw-r--r--third_party/libjingle/mods-since-v0_4_0.diff505
12 files changed, 590 insertions, 78 deletions
diff --git a/chrome/browser/sync/notifier/base/signal_thread_task.h b/chrome/browser/sync/notifier/base/signal_thread_task.h
index ebee005..82853a3 100644
--- a/chrome/browser/sync/notifier/base/signal_thread_task.h
+++ b/chrome/browser/sync/notifier/base/signal_thread_task.h
@@ -77,7 +77,8 @@ class SignalThreadTask : public talk_base::Task,
void ClearSignalThread() {
if (signal_thread_) {
- signal_thread_->Destroy();
+ // Don't wait on the thread destruction, or we may deadlock.
+ signal_thread_->Destroy(false);
signal_thread_ = NULL;
}
}
diff --git a/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc b/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc
index 62d44c0..d688b7e 100644
--- a/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc
+++ b/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc
@@ -68,7 +68,7 @@ void MediatorThreadImpl::Run() {
pump_->WakeTasks();
}
MessageLoop::current()->RunAllPending();
- } while (!IsStopping());
+ } while (!IsQuitting());
#if defined(OS_WIN)
set_socketserver(old_socket_server);
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium
index 3259d69..a4d124e 100644
--- a/third_party/libjingle/README.chromium
+++ b/third_party/libjingle/README.chromium
@@ -38,3 +38,5 @@ Local Modifications:
* Added a #define guard to libjingle's base/logging.h to prevent the
LOG() macros from being redefined when included by users of the
library. The #define guard is SAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS.
+ * Updated signalthread.* and dependencies to add threadcounting and
+ improve multithread safety.
diff --git a/third_party/libjingle/files/talk/base/asynchttprequest.h b/third_party/libjingle/files/talk/base/asynchttprequest.h
index 65bfa26..7f2f348 100644
--- a/third_party/libjingle/files/talk/base/asynchttprequest.h
+++ b/third_party/libjingle/files/talk/base/asynchttprequest.h
@@ -20,8 +20,7 @@ class FirewallManager;
class MemoryStream;
class AsyncHttpRequest:
- public SignalThread,
- public sigslot::has_slots<> {
+ public SignalThread {
public:
AsyncHttpRequest(const std::string &user_agent);
diff --git a/third_party/libjingle/files/talk/base/autodetectproxy.cc b/third_party/libjingle/files/talk/base/autodetectproxy.cc
index 917c548..cda405f 100644
--- a/third_party/libjingle/files/talk/base/autodetectproxy.cc
+++ b/third_party/libjingle/files/talk/base/autodetectproxy.cc
@@ -111,7 +111,7 @@ void AutoDetectProxy::Complete(talk_base::ProxyType type) {
LOG_V(sev) << "AutoDetectProxy detected " << proxy_.address.ToString()
<< " as type " << proxy_.type;
- Thread::Current()->MessageQueue::Stop();
+ Thread::Current()->Quit();
}
void AutoDetectProxy::OnConnectEvent(talk_base::AsyncSocket * socket) {
diff --git a/third_party/libjingle/files/talk/base/autodetectproxy.h b/third_party/libjingle/files/talk/base/autodetectproxy.h
index 9633d31..43d765e 100644
--- a/third_party/libjingle/files/talk/base/autodetectproxy.h
+++ b/third_party/libjingle/files/talk/base/autodetectproxy.h
@@ -19,7 +19,7 @@ namespace talk_base {
class AsyncSocket;
-class AutoDetectProxy : public SignalThread, public sigslot::has_slots<> {
+class AutoDetectProxy : public SignalThread {
public:
AutoDetectProxy(const std::string& user_agent);
diff --git a/third_party/libjingle/files/talk/base/messagequeue.cc b/third_party/libjingle/files/talk/base/messagequeue.cc
index 48a372b..171f324 100644
--- a/third_party/libjingle/files/talk/base/messagequeue.cc
+++ b/third_party/libjingle/files/talk/base/messagequeue.cc
@@ -101,6 +101,10 @@ MessageQueue::MessageQueue(SocketServer* ss)
}
MessageQueue::~MessageQueue() {
+ // The signal is done from here to ensure
+ // that it always gets called when the queue
+ // is going away.
+ SignalQueueDestroyed();
if (active_) {
MessageQueueManager::Instance()->Remove(this);
Clear(NULL);
@@ -111,12 +115,12 @@ void MessageQueue::set_socketserver(SocketServer* ss) {
ss_ = ss;
}
-void MessageQueue::Stop() {
+void MessageQueue::Quit() {
fStop_ = true;
ss_->WakeUp();
}
-bool MessageQueue::IsStopping() {
+bool MessageQueue::IsQuitting() {
return fStop_;
}
diff --git a/third_party/libjingle/files/talk/base/messagequeue.h b/third_party/libjingle/files/talk/base/messagequeue.h
index 5ef976d..d39aab8 100644
--- a/third_party/libjingle/files/talk/base/messagequeue.h
+++ b/third_party/libjingle/files/talk/base/messagequeue.h
@@ -160,9 +160,8 @@ public:
// Get (or Peek) returns false. By guaranteeing delivery of those messages,
// we eliminate the race condition when an MessageHandler and MessageQueue
// may be destroyed independently of each other.
-
- virtual void Stop();
- virtual bool IsStopping();
+ virtual void Quit();
+ virtual bool IsQuitting();
virtual void Restart();
// Get() will process I/O until:
@@ -187,6 +186,10 @@ public:
}
}
+ // When this signal is sent out, any references to this queue should
+ // no longer be used.
+ sigslot::signal0<> SignalQueueDestroyed;
+
protected:
void EnsureActive();
diff --git a/third_party/libjingle/files/talk/base/signalthread.cc b/third_party/libjingle/files/talk/base/signalthread.cc
index 0b5154d6..c9ac86a 100644
--- a/third_party/libjingle/files/talk/base/signalthread.cc
+++ b/third_party/libjingle/files/talk/base/signalthread.cc
@@ -10,22 +10,31 @@ using namespace talk_base;
SignalThread::SignalThread()
: main_(Thread::Current()), state_(kInit)
{
- worker_.SetParent(this);
+ main_->SignalQueueDestroyed.connect(this,
+ &SignalThread::OnMainThreadDestroyed);
+ refcount_ = 1;
+ worker_.parent_ = this;
+}
+
+void SignalThread::OnMainThreadDestroyed() {
+ EnterExit ee(this);
+ main_ = NULL;
}
SignalThread::~SignalThread() {
- worker_.SetParent(NULL);
}
void SignalThread::SetPriority(ThreadPriority priority) {
+ EnterExit ee(this);
ASSERT(main_->IsCurrent());
ASSERT(kInit == state_);
worker_.SetPriority(priority);
}
void SignalThread::Start() {
+ EnterExit ee(this);
ASSERT(main_->IsCurrent());
- if (kInit == state_) {
+ if (kInit == state_ || kComplete == state_) {
state_ = kRunning;
OnWorkStart();
worker_.Start();
@@ -34,18 +43,24 @@ void SignalThread::Start() {
}
}
-void SignalThread::Destroy() {
+void SignalThread::Destroy(bool wait) {
+ EnterExit ee(this);
ASSERT(main_->IsCurrent());
if ((kInit == state_) || (kComplete == state_)) {
- delete this;
- } else if (kRunning == state_) {
+ refcount_--;
+ } else if (kRunning == state_ || kReleasing == state_) {
state_ = kStopping;
- // A couple tricky issues here:
- // 1) Thread::Stop() calls Join(), which we don't want... we just want
- // to stop the MessageQueue, which causes ContinueWork() to return false.
- // 2) OnWorkStop() must follow Stop(), so that when the thread wakes up
- // due to OWS(), ContinueWork() will return false.
- worker_.MessageQueue::Stop();
+ // OnWorkStop() must follow Quit(), so that when the thread wakes up due to
+ // OWS(), ContinueWork() will return false.
+ if (wait) {
+ // Release the thread's lock so that it can return from ::Run.
+ cs_.Leave();
+ worker_.Stop();
+ cs_.Enter();
+ refcount_--;
+ } else {
+ worker_.Quit();
+ }
OnWorkStop();
} else {
ASSERT(false);
@@ -53,9 +68,10 @@ void SignalThread::Destroy() {
}
void SignalThread::Release() {
+ EnterExit ee(this);
ASSERT(main_->IsCurrent());
if (kComplete == state_) {
- delete this;
+ refcount_--;
} else if (kRunning == state_) {
state_ = kReleasing;
} else {
@@ -65,11 +81,13 @@ void SignalThread::Release() {
}
bool SignalThread::ContinueWork() {
+ EnterExit ee(this);
ASSERT(worker_.IsCurrent());
return worker_.ProcessMessages(0);
}
void SignalThread::OnMessage(Message *msg) {
+ EnterExit ee(this);
if (ST_MSG_WORKER_DONE == msg->message_id) {
ASSERT(main_->IsCurrent());
OnWorkDone();
@@ -80,15 +98,31 @@ void SignalThread::OnMessage(Message *msg) {
do_delete = true;
}
if (kStopping != state_) {
+ // Before signaling that the work is done, make sure that the worker
+ // thread actually is done. We got here because DoWork() finished and
+ // Run() posted the ST_MSG_WORKER_DONE message. This means the worker
+ // thread is about to go away anyway, but sometimes it doesn't actually
+ // finish before SignalWorkDone is processed, and for a reusable
+ // SignalThread this makes an assert in thread.cc fire.
+ //
+ // Calling Stop() on the worker ensures that the OS thread that underlies
+ // the worker will finish, and will be set to NULL, enabling us to call
+ // Start() again.
+ worker_.Stop();
SignalWorkDone(this);
}
if (do_delete) {
- delete this;
+ refcount_--;
}
}
}
void SignalThread::Run() {
DoWork();
- main_->Post(this, ST_MSG_WORKER_DONE);
+ {
+ EnterExit ee(this);
+ if (main_) {
+ main_->Post(this, ST_MSG_WORKER_DONE);
+ }
+ }
}
diff --git a/third_party/libjingle/files/talk/base/signalthread.h b/third_party/libjingle/files/talk/base/signalthread.h
index ccba912..ad6b46a 100644
--- a/third_party/libjingle/files/talk/base/signalthread.h
+++ b/third_party/libjingle/files/talk/base/signalthread.h
@@ -13,13 +13,17 @@ namespace talk_base {
// Cancellation: Call Release(true), to abort the worker thread.
// Fire-and-forget: Call Release(false), which allows the thread to run to
// completion, and then self-destruct without further notification.
+// Periodic tasks: Wait for SignalWorkDone, then eventually call Start()
+// again to repeat the task. When the instance isn't needed anymore,
+// call Release. DoWork, OnWorkStart and OnWorkStop are called again,
+// on a new thread.
// The subclass should override DoWork() to perform the background task. By
// periodically calling ContinueWork(), it can check for cancellation.
// OnWorkStart and OnWorkDone can be overridden to do pre- or post-work
// tasks in the context of the main thread.
///////////////////////////////////////////////////////////////////////////////
-class SignalThread : protected MessageHandler {
+class SignalThread : public sigslot::has_slots<>, protected MessageHandler {
public:
SignalThread();
@@ -32,8 +36,9 @@ public:
// Context: Main Thread. If the worker thread is not running, deletes the
// object immediately. Otherwise, asks the worker thread to abort processing,
// and schedules the object to be deleted once the worker exits.
- // SignalWorkDone will not be signalled.
- void Destroy();
+ // SignalWorkDone will not be signalled. If wait is true, does not return
+ // until the thread is deleted.
+ void Destroy(bool wait);
// Context: Main Thread. If the worker thread is complete, deletes the
// object immediately. Otherwise, schedules the object to be deleted once
@@ -50,11 +55,11 @@ protected:
// Context: Main Thread. Subclass should override to do pre-work setup.
virtual void OnWorkStart() { }
-
+
// Context: Worker Thread. Subclass should override to do work.
virtual void DoWork() = 0;
- // Context: Worker Thread. Subclass should call periodically to
+ // Context: Worker Thread. Subclass should call periodically to
// dispatch messages and determine if the thread should terminate.
bool ContinueWork();
@@ -64,7 +69,7 @@ protected:
// Context: Main Thread. Subclass should override to do post-work cleanup.
virtual void OnWorkDone() { }
-
+
// Context: Any Thread. If subclass overrides, be sure to call the base
// implementation. Do not use (message_id < ST_MSG_FIRST_AVAILABLE)
virtual void OnMessage(Message *msg);
@@ -73,26 +78,44 @@ private:
friend class Worker;
class Worker : public Thread {
public:
- virtual void Run() {
- CritScope cs(&parent_crit_);
- if (parent_)
- parent_->Run();
+ SignalThread* parent_;
+ virtual void Run() { parent_->Run(); }
+ };
+
+ class EnterExit {
+ friend class SignalThread;
+
+ SignalThread * t_;
+
+ EnterExit(SignalThread * t) : t_(t) {
+ t_->cs_.Enter();
+ t_->refcount_ += 1;
}
- void SetParent(SignalThread* parent) {
- CritScope cs(&parent_crit_);
- parent_ = parent;
+ ~EnterExit() {
+ bool d = (0 == (--(t_->refcount_)));
+ t_->cs_.Leave();
+ if (d)
+ delete t_;
}
-
- private:
- SignalThread* parent_;
- CriticalSection parent_crit_;
};
+ friend class EnterExit;
+
+ CriticalSection cs_;
+ int refcount_;
+
void Run();
+ void OnMainThreadDestroyed();
Thread* main_;
Worker worker_;
- enum State { kInit, kRunning, kComplete, kStopping, kReleasing } state_;
+ enum State {
+ kInit, // Initialized, but not started
+ kRunning, // Started and doing work
+ kReleasing, // Same as running, but to be deleted when work is done
+ kComplete, // Work is done
+ kStopping, // Work is being interrupted
+ } state_;
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/libjingle/files/talk/base/thread.cc b/third_party/libjingle/files/talk/base/thread.cc
index 99fa701..fa2d23c 100644
--- a/third_party/libjingle/files/talk/base/thread.cc
+++ b/third_party/libjingle/files/talk/base/thread.cc
@@ -131,8 +131,8 @@ void Thread::Start() {
// Make sure Join() hasn't been called yet.
if (stopped_)
return;
- pthread_create(&thread_, &attr, PreRun, this);
- started_ = true;
+ if (pthread_create(&thread_, &attr, PreRun, this) == 0)
+ started_ = true;
}
void Thread::Join() {
@@ -141,6 +141,7 @@ void Thread::Join() {
if (started_) {
void *pv;
pthread_join(thread_, &pv);
+ started_ = false;
}
}
#endif
@@ -225,7 +226,7 @@ void Thread::Run() {
}
void Thread::Stop() {
- MessageQueue::Stop();
+ MessageQueue::Quit();
Join();
}
@@ -347,7 +348,7 @@ bool Thread::ProcessMessages(int cmsLoop) {
while (true) {
Message msg;
if (!Get(&msg, cmsNext))
- return false;
+ return !IsQuitting();
Dispatch(&msg);
if (cmsLoop != kForever) {
diff --git a/third_party/libjingle/mods-since-v0_4_0.diff b/third_party/libjingle/mods-since-v0_4_0.diff
index 6c63ac6..b36cf65 100644
--- a/third_party/libjingle/mods-since-v0_4_0.diff
+++ b/third_party/libjingle/mods-since-v0_4_0.diff
@@ -1,5 +1,5 @@
-Only in libjingle/files/: .svn
-Only in libjingle-0.4.0/: Makefile.in
+Only in libjingle/files: .svn
+Only in libjingle-0.4.0: Makefile.in
diff -r libjingle-0.4.0/README libjingle/files/README
1,39c1,39
< Libjingle
@@ -168,8 +168,8 @@ diff -r libjingle-0.4.0/README.win libjingle/files/README.win
>
> 9. Build the solution
>
-Only in libjingle-0.4.0/: aclocal.m4
-Only in libjingle-0.4.0/: config.guess
+Only in libjingle-0.4.0: aclocal.m4
+Only in libjingle-0.4.0: config.guess
diff -r libjingle-0.4.0/config.h libjingle/files/config.h
14c14
< #define HAVE_ALSA_ASOUNDLIB_H 1
@@ -199,17 +199,41 @@ diff -r libjingle-0.4.0/config.h libjingle/files/config.h
< #define __ALSA_ENABLED__ 1
---
> /* #undef __ALSA_ENABLED__ */
-Only in libjingle-0.4.0/: config.h.in
-Only in libjingle-0.4.0/: config.sub
-Only in libjingle-0.4.0/: configure
-Only in libjingle-0.4.0/: depcomp
-Only in libjingle-0.4.0/: install-sh
-Only in libjingle-0.4.0/: ltmain.sh
-Only in libjingle-0.4.0/: missing
+Only in libjingle-0.4.0: config.h.in
+Only in libjingle-0.4.0: config.sub
+Only in libjingle-0.4.0: configure
+Only in libjingle-0.4.0: depcomp
+Only in libjingle-0.4.0: install-sh
+Only in libjingle-0.4.0: ltmain.sh
+Only in libjingle-0.4.0: missing
Only in libjingle/files/talk: .svn
Only in libjingle-0.4.0/talk: Makefile.in
Only in libjingle/files/talk/base: .svn
Only in libjingle-0.4.0/talk/base: Makefile.in
+diff -r libjingle-0.4.0/talk/base/asynchttprequest.h libjingle/files/talk/base/asynchttprequest.h
+23,24c23
+< public SignalThread,
+< public sigslot::has_slots<> {
+---
+> public SignalThread {
+diff -r libjingle-0.4.0/talk/base/asynctcpsocket.cc libjingle/files/talk/base/asynctcpsocket.cc
+31a32,33
+> #include <cstring>
+>
+diff -r libjingle-0.4.0/talk/base/autodetectproxy.cc libjingle/files/talk/base/autodetectproxy.cc
+29c29
+< #include "talk/base/httpcommon.h"
+---
+> #include "talk/base/httpcommon-inl.h"
+114c114
+< Thread::Current()->MessageQueue::Stop();
+---
+> Thread::Current()->Quit();
+diff -r libjingle-0.4.0/talk/base/autodetectproxy.h libjingle/files/talk/base/autodetectproxy.h
+22c22
+< class AutoDetectProxy : public SignalThread, public sigslot::has_slots<> {
+---
+> class AutoDetectProxy : public SignalThread {
diff -r libjingle-0.4.0/talk/base/base64.h libjingle/files/talk/base/base64.h
26,27c26,27
< static const std::string Base64::Base64Table;
@@ -229,6 +253,36 @@ diff -r libjingle-0.4.0/talk/base/common.h libjingle/files/talk/base/common.h
< TypeName(const TypeName&); \
< void operator=(const TypeName&)
<
+diff -r libjingle-0.4.0/talk/base/criticalsection.h libjingle/files/talk/base/criticalsection.h
+83c83
+< public:
+---
+> public:
+85a86
+> pthread_mutexattr_init(&mutex_attribute);
+87a89,90
+> pthread_mutexattr_destroy(&mutex_attribute);
+> TRACK_OWNER(thread_ = 0);
+93a97
+> TRACK_OWNER(thread_ = pthread_self());
+95a100
+> TRACK_OWNER(thread_ = 0);
+98c103,110
+< private:
+---
+>
+> #if CS_TRACK_OWNER
+> bool CurrentThreadIsOwner() const {
+> return pthread_equal(thread_, pthread_self());
+> }
+> #endif // CS_TRACK_OWNER
+>
+> private:
+99a112
+> TRACK_OWNER(pthread_t thread_);
+diff -r libjingle-0.4.0/talk/base/cryptstring.h libjingle/files/talk/base/cryptstring.h
+30a31
+> #include <string.h>
diff -r libjingle-0.4.0/talk/base/diskcache_win32.cc libjingle/files/talk/base/diskcache_win32.cc
38c38
< entry->streams = max(entry->streams, index + 1);
@@ -237,6 +291,9 @@ diff -r libjingle-0.4.0/talk/base/diskcache_win32.cc libjingle/files/talk/base/d
diff -r libjingle-0.4.0/talk/base/helpers.cc libjingle/files/talk/base/helpers.cc
38a39
> #include <wincrypt.h>
+diff -r libjingle-0.4.0/talk/base/host.cc libjingle/files/talk/base/host.cc
+30a31
+> #include <cstdlib>
diff -r libjingle-0.4.0/talk/base/httpclient.cc libjingle/files/talk/base/httpclient.cc
670a671
> HttpAuthContext *context = context_.get();
@@ -245,6 +302,19 @@ diff -r libjingle-0.4.0/talk/base/httpclient.cc libjingle/files/talk/base/httpcl
---
> context, response, auth_method);
> context_.reset(context);
+diff -r libjingle-0.4.0/talk/base/logging.cc libjingle/files/talk/base/logging.cc
+27a28
+> #include <stdio.h>
+diff -r libjingle-0.4.0/talk/base/logging.h libjingle/files/talk/base/logging.h
+67a68,69
+>
+> #if defined(SAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS)
+70a73
+> #endif // defined(SAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS)
+195a199
+> #if defined(SAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS)
+290a295
+> #endif // defined(SAFE_TO_DEFINE_TALK_BASE_LOGGING_MACROS)
diff -r libjingle-0.4.0/talk/base/messagequeue.cc libjingle/files/talk/base/messagequeue.cc
98,99c98,99
< new_ss = true;
@@ -252,19 +322,78 @@ diff -r libjingle-0.4.0/talk/base/messagequeue.cc libjingle/files/talk/base/mess
---
> default_ss_.reset(new PhysicalSocketServer());
> ss_ = default_ss_.get();
-108,109d107
+103a104,107
+> // The signal is done from here to ensure
+> // that it always gets called when the queue
+> // is going away.
+> SignalQueueDestroyed();
+108,109d111
< if (new_ss)
< delete ss_;
-113,115d110
+113,115d114
< if (new_ss)
< delete ss_;
< new_ss = false;
+119c118
+< void MessageQueue::Stop() {
+---
+> void MessageQueue::Quit() {
+124c123
+< bool MessageQueue::IsStopping() {
+---
+> bool MessageQueue::IsQuitting() {
diff -r libjingle-0.4.0/talk/base/messagequeue.h libjingle/files/talk/base/messagequeue.h
35a36
> #include "talk/base/scoped_ptr.h"
-192a194,195
+162,164c163,164
+<
+< virtual void Stop();
+< virtual bool IsStopping();
+---
+> virtual void Quit();
+> virtual bool IsQuitting();
+188a189,192
+> // When this signal is sent out, any references to this queue should
+> // no longer be used.
+> sigslot::signal0<> SignalQueueDestroyed;
+>
+192a197,198
> // If a server isn't supplied in the constructor, use this one.
> scoped_ptr<SocketServer> default_ss_;
+diff -r libjingle-0.4.0/talk/base/natserver.cc libjingle/files/talk/base/natserver.cc
+28a29
+> #include <cstring>
+diff -r libjingle-0.4.0/talk/base/natsocketfactory.cc libjingle/files/talk/base/natsocketfactory.cc
+29a30
+> #include <cstring>
+diff -r libjingle-0.4.0/talk/base/physicalsocketserver.cc libjingle/files/talk/base/physicalsocketserver.cc
+61a62
+> #include "talk/base/winsock_initializer.h"
+67,86d67
+< #ifdef WIN32
+< class WinsockInitializer {
+< public:
+< WinsockInitializer() {
+< WSADATA wsaData;
+< WORD wVersionRequested = MAKEWORD(1, 0);
+< err_ = WSAStartup(wVersionRequested, &wsaData);
+< }
+< ~WinsockInitializer() {
+< WSACleanup();
+< }
+< int error() {
+< return err_;
+< }
+< private:
+< int err_;
+< };
+< WinsockInitializer g_winsockinit;
+< #endif
+<
+124a106,108
+> #ifdef WIN32
+> EnsureWinsockInit();
+> #endif
diff -r libjingle-0.4.0/talk/base/proxydetect.cc libjingle/files/talk/base/proxydetect.cc
205,206c205,206
< const char* list = slist.c_str();
@@ -525,15 +654,188 @@ diff -r libjingle-0.4.0/talk/base/scoped_ptr.h libjingle/files/talk/base/scoped_
< using talk_base::scoped_ptr;
---
> #include "base/scoped_ptr.h"
+diff -r libjingle-0.4.0/talk/base/signalthread.cc libjingle/files/talk/base/signalthread.cc
+12a13,15
+> main_->SignalQueueDestroyed.connect(this,
+> &SignalThread::OnMainThreadDestroyed);
+> refcount_ = 1;
+15a19,23
+> void SignalThread::OnMainThreadDestroyed() {
+> EnterExit ee(this);
+> main_ = NULL;
+> }
+>
+19a28
+> EnterExit ee(this);
+25a35
+> EnterExit ee(this);
+27c37
+< if (kInit == state_) {
+---
+> if (kInit == state_ || kComplete == state_) {
+36c46,47
+< void SignalThread::Destroy() {
+---
+> void SignalThread::Destroy(bool wait) {
+> EnterExit ee(this);
+39,40c50,51
+< delete this;
+< } else if (kRunning == state_) {
+---
+> refcount_--;
+> } else if (kRunning == state_ || kReleasing == state_) {
+42,47c53,63
+< // A couple tricky issues here:
+< // 1) Thread::Stop() calls Join(), which we don't want... we just want
+< // to stop the MessageQueue, which causes ContinueWork() to return false.
+< // 2) OnWorkStop() must follow Stop(), so that when the thread wakes up
+< // due to OWS(), ContinueWork() will return false.
+< worker_.MessageQueue::Stop();
+---
+> // OnWorkStop() must follow Quit(), so that when the thread wakes up due to
+> // OWS(), ContinueWork() will return false.
+> if (wait) {
+> // Release the thread's lock so that it can return from ::Run.
+> cs_.Leave();
+> worker_.Stop();
+> cs_.Enter();
+> refcount_--;
+> } else {
+> worker_.Quit();
+> }
+54a71
+> EnterExit ee(this);
+57c74
+< delete this;
+---
+> refcount_--;
+66a84
+> EnterExit ee(this);
+71a90
+> EnterExit ee(this);
+81a101,111
+> // Before signaling that the work is done, make sure that the worker
+> // thread actually is done. We got here because DoWork() finished and
+> // Run() posted the ST_MSG_WORKER_DONE message. This means the worker
+> // thread is about to go away anyway, but sometimes it doesn't actually
+> // finish before SignalWorkDone is processed, and for a reusable
+> // SignalThread this makes an assert in thread.cc fire.
+> //
+> // Calling Stop() on the worker ensures that the OS thread that underlies
+> // the worker will finish, and will be set to NULL, enabling us to call
+> // Start() again.
+> worker_.Stop();
+85c115
+< delete this;
+---
+> refcount_--;
+92c122,127
+< main_->Post(this, ST_MSG_WORKER_DONE);
+---
+> {
+> EnterExit ee(this);
+> if (main_) {
+> main_->Post(this, ST_MSG_WORKER_DONE);
+> }
+> }
+diff -r libjingle-0.4.0/talk/base/signalthread.h libjingle/files/talk/base/signalthread.h
+15a16,19
+> // Periodic tasks: Wait for SignalWorkDone, then eventually call Start()
+> // again to repeat the task. When the instance isn't needed anymore,
+> // call Release. DoWork, OnWorkStart and OnWorkStop are called again,
+> // on a new thread.
+22c26
+< class SignalThread : protected MessageHandler {
+---
+> class SignalThread : public sigslot::has_slots<>, protected MessageHandler {
+35,36c39,41
+< // SignalWorkDone will not be signalled.
+< void Destroy();
+---
+> // SignalWorkDone will not be signalled. If wait is true, does not return
+> // until the thread is deleted.
+> void Destroy(bool wait);
+53c58
+<
+---
+>
+57c62
+< // Context: Worker Thread. Subclass should call periodically to
+---
+> // Context: Worker Thread. Subclass should call periodically to
+67c72
+<
+---
+>
+79a85,106
+> class EnterExit {
+> friend class SignalThread;
+>
+> SignalThread * t_;
+>
+> EnterExit(SignalThread * t) : t_(t) {
+> t_->cs_.Enter();
+> t_->refcount_ += 1;
+> }
+> ~EnterExit() {
+> bool d = (0 == (--(t_->refcount_)));
+> t_->cs_.Leave();
+> if (d)
+> delete t_;
+> }
+> };
+>
+> friend class EnterExit;
+>
+> CriticalSection cs_;
+> int refcount_;
+>
+80a108
+> void OnMainThreadDestroyed();
+84c112,118
+< enum State { kInit, kRunning, kComplete, kStopping, kReleasing } state_;
+---
+> enum State {
+> kInit, // Initialized, but not started
+> kRunning, // Started and doing work
+> kReleasing, // Same as running, but to be deleted when work is done
+> kComplete, // Work is done
+> kStopping, // Work is being interrupted
+> } state_;
+Only in libjingle/files/talk/base: signalthread_unittest.cc
diff -r libjingle-0.4.0/talk/base/socket.h libjingle/files/talk/base/socket.h
77a78
> #undef ETIMEDOUT // remove pthread.h's definition
+diff -r libjingle-0.4.0/talk/base/socketadapters.cc libjingle/files/talk/base/socketadapters.cc
+43a44,45
+> #include <cstring>
+>
+diff -r libjingle-0.4.0/talk/base/ssladapter.cc libjingle/files/talk/base/ssladapter.cc
+34c34,35
+< #define SSL_USE_OPENSSL 1
+---
+> // Turn off OpenSSL
+> //#define SSL_USE_OPENSSL 1
+84a86
+> #if SSL_USE_OPENSSL || SSL_USE_SCHANNEL
+85a88,90
+> #else
+> return NULL;
+> #endif
+diff -r libjingle-0.4.0/talk/base/stream.cc libjingle/files/talk/base/stream.cc
+27a28
+> #include <stdio.h>
+diff -r libjingle-0.4.0/talk/base/stringencode.cc libjingle/files/talk/base/stringencode.cc
+34a35
+> #include <stdlib.h>
diff -r libjingle-0.4.0/talk/base/stringutils.h libjingle/files/talk/base/stringutils.h
-87a88
+33a34
+> #include <string.h>
+87a89
> #if 0
-93a95
+93a96
> #endif
-272c274
+272c275
< inline static const char* Traits<char>::empty_str() { return ""; }
---
> inline static const char* empty_str() { return ""; }
@@ -572,6 +874,74 @@ diff -r libjingle-0.4.0/talk/base/task.cc libjingle/files/talk/base/task.cc
< Wake(); // to self-delete
---
> GetRunner()->WakeTasks();
+diff -r libjingle-0.4.0/talk/base/taskrunner.h libjingle/files/talk/base/taskrunner.h
+63a64,68
+> bool HasPendingTimeoutTask() {
+> return next_timeout_task_ != NULL &&
+> next_timeout_task_->TimedOut();
+> }
+>
+diff -r libjingle-0.4.0/talk/base/testclient.cc libjingle/files/talk/base/testclient.cc
+29a30
+> #include <cstring>
+diff -r libjingle-0.4.0/talk/base/thread.cc libjingle/files/talk/base/thread.cc
+100a101,105
+> bool ThreadManager::ThreadActive(Thread *thread) {
+> CritScope cs(&crit_);
+> return(std::find(threads_.begin(), threads_.end(), thread) != threads_.end());
+> }
+>
+103a109
+> stopped_ = false;
+124,125c130,135
+< pthread_create(&thread_, &attr, PreRun, this);
+< started_ = true;
+---
+> CritScope cs(&started_crit_);
+> // Make sure Join() hasn't been called yet.
+> if (stopped_)
+> return;
+> if (pthread_create(&thread_, &attr, PreRun, this) == 0)
+> started_ = true;
+128a139,140
+> CritScope cs(&started_crit_);
+> stopped_ = true;
+168a181,184
+> CritScope cs(&started_crit_);
+> // Make sure Join() hasn't been called yet.
+> if (stopped_)
+> return;
+181a198,199
+> CritScope cs(&started_crit_);
+> stopped_ = true;
+191a210,212
+> // Make sure the thread hasn't been deleted.
+> if (!g_thmgr.ThreadActive(thread))
+> return NULL;
+207c228
+< MessageQueue::Stop();
+---
+> MessageQueue::Quit();
+329c350
+< return false;
+---
+> return !IsQuitting();
+diff -r libjingle-0.4.0/talk/base/thread.h libjingle/files/talk/base/thread.h
+57a58
+> bool ThreadActive(Thread *thread);
+134a136
+> CriticalSection started_crit_;
+135a138
+> bool stopped_;
+diff -r libjingle-0.4.0/talk/base/urlencode.cc libjingle/files/talk/base/urlencode.cc
+0a1,2
+> #include <stdlib.h>
+> #include <string.h>
+diff -r libjingle-0.4.0/talk/base/win32socketserver.cc libjingle/files/talk/base/win32socketserver.cc
+31a32
+> #include "talk/base/winsock_initializer.h"
+269a271
+> talk_base::EnsureWinsockInit();
diff -r libjingle-0.4.0/talk/base/winping.cc libjingle/files/talk/base/winping.cc
133c133
< return sizeof(ICMP_ECHO_REPLY) + max(8UL, data_size);
@@ -582,6 +952,8 @@ diff -r libjingle-0.4.0/talk/base/winping.cc libjingle/files/talk/base/winping.c
\ No newline at end of file
---
> } // namespace talk_base
+Only in libjingle/files/talk/base: winsock_initializer.cc
+Only in libjingle/files/talk/base: winsock_initializer.h
Only in libjingle-0.4.0/talk: examples
Only in libjingle-0.4.0/talk: libjingle.sln
Only in libjingle-0.4.0/talk: libjingle.vcproj
@@ -589,16 +961,54 @@ Only in libjingle/files/talk/p2p: .svn
Only in libjingle-0.4.0/talk/p2p: Makefile.in
Only in libjingle/files/talk/p2p/base: .svn
Only in libjingle-0.4.0/talk/p2p/base: Makefile.in
+diff -r libjingle-0.4.0/talk/p2p/base/p2ptransport.cc libjingle/files/talk/p2p/base/p2ptransport.cc
+37c37
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
diff -r libjingle-0.4.0/talk/p2p/base/port.cc libjingle/files/talk/p2p/base/port.cc
-270c270
+34a35
+> #include <cstring>
+270c271
< talk_base::scoped_ptr<StunMessage> stun_msg(new StunMessage());
---
> scoped_ptr<StunMessage> stun_msg(new StunMessage());
+diff -r libjingle-0.4.0/talk/p2p/base/rawtransport.cc libjingle/files/talk/p2p/base/rawtransport.cc
+35c35
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
+diff -r libjingle-0.4.0/talk/p2p/base/rawtransportchannel.cc libjingle/files/talk/p2p/base/rawtransportchannel.cc
+39c39
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
+diff -r libjingle-0.4.0/talk/p2p/base/relayport.cc libjingle/files/talk/p2p/base/relayport.cc
+36a37
+> #include <cstring>
+diff -r libjingle-0.4.0/talk/p2p/base/session.cc libjingle/files/talk/p2p/base/session.cc
+32c32
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
+diff -r libjingle-0.4.0/talk/p2p/base/sessionmanager.cc libjingle/files/talk/p2p/base/sessionmanager.cc
+32c32
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
diff -r libjingle-0.4.0/talk/p2p/base/sessionmanager.h libjingle/files/talk/p2p/base/sessionmanager.h
159c159
< buzz::XmlElement* SessionManager::CreateErrorMessage(
---
> buzz::XmlElement* CreateErrorMessage(
+diff -r libjingle-0.4.0/talk/p2p/base/stun.cc libjingle/files/talk/p2p/base/stun.cc
+31a32
+> #include <cstring>
+diff -r libjingle-0.4.0/talk/p2p/base/transport.cc libjingle/files/talk/p2p/base/transport.cc
+34c34
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
Only in libjingle/files/talk/p2p/client: .svn
Only in libjingle-0.4.0/talk/p2p/client: Makefile.in
diff -r libjingle-0.4.0/talk/p2p/client/httpportallocator.cc libjingle/files/talk/p2p/client/httpportallocator.cc
@@ -762,19 +1172,18 @@ diff -r libjingle-0.4.0/talk/xmllite/xmlprinter.cc libjingle/files/talk/xmllite/
> }
Only in libjingle/files/talk/xmpp: .svn
Only in libjingle-0.4.0/talk/xmpp: Makefile.in
-diff -r libjingle-0.4.0/talk/xmpp/constants.cc libjingle/files/talk/xmpp/constants.cc
-206a207,209
-> const std::string NS_GOOGLE_AUTH_PROTOCOL("http://www.google.com/talk/protocol/auth");
-> const QName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT(true, NS_GOOGLE_AUTH_PROTOCOL, "client-uses-full-bind-result");
->
-208a212
-> const QName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN(true, NS_GOOGLE_AUTH_PROTOCOL, "allow-non-google-login");
-diff -r libjingle-0.4.0/talk/xmpp/constants.h libjingle/files/talk/xmpp/constants.h
-175a176,178
-> extern const std::string NS_GOOGLE_AUTH_PROTOCOL;
-> extern const QName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT;
-> extern const QName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN;
+Only in libjingle-0.4.0/talk/xmpp: constants.cc
+Only in libjingle-0.4.0/talk/xmpp: constants.h
+diff -r libjingle-0.4.0/talk/xmpp/jid.cc libjingle/files/talk/xmpp/jid.cc
+33c33
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
diff -r libjingle-0.4.0/talk/xmpp/saslcookiemechanism.h libjingle/files/talk/xmpp/saslcookiemechanism.h
+33c33
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
40,41c40,55
< SaslCookieMechanism(const std::string & mechanism, const std::string & username, const std::string & cookie) :
< mechanism_(mechanism), username_(username), cookie_(cookie) {}
@@ -806,6 +1215,16 @@ diff -r libjingle-0.4.0/talk/xmpp/saslcookiemechanism.h libjingle/files/talk/xmp
diff -r libjingle-0.4.0/talk/xmpp/saslhandler.h libjingle/files/talk/xmpp/saslhandler.h
31a32
> #include <vector>
+diff -r libjingle-0.4.0/talk/xmpp/saslmechanism.cc libjingle/files/talk/xmpp/saslmechanism.cc
+30c30
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
+diff -r libjingle-0.4.0/talk/xmpp/xmppclient.cc libjingle/files/talk/xmpp/xmppclient.cc
+30c30
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
diff -r libjingle-0.4.0/talk/xmpp/xmppclient.h libjingle/files/talk/xmpp/xmppclient.h
141c141
< std::string XmppClient::GetStateName(int state) const {
@@ -820,8 +1239,34 @@ diff -r libjingle-0.4.0/talk/xmpp/xmppclientsettings.h libjingle/files/talk/xmpp
> const std::string & token_service() const { return token_service_; }
93a98
> std::string token_service_;
+Only in libjingle/files/talk/xmpp: xmppconstants.cc
+Only in libjingle/files/talk/xmpp: xmppconstants.h
+diff -r libjingle-0.4.0/talk/xmpp/xmppengineimpl.cc libjingle/files/talk/xmpp/xmppengineimpl.cc
+37c37
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
+diff -r libjingle-0.4.0/talk/xmpp/xmppengineimpl_iq.cc libjingle/files/talk/xmpp/xmppengineimpl_iq.cc
+32c32
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
diff -r libjingle-0.4.0/talk/xmpp/xmpplogintask.cc libjingle/files/talk/xmpp/xmpplogintask.cc
+34c34
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
218a219,221
> auth->SetAttr(QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN, "true");
> auth->SetAttr(QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT, "true");
>
+diff -r libjingle-0.4.0/talk/xmpp/xmppstanzaparser.cc libjingle/files/talk/xmpp/xmppstanzaparser.cc
+32c32
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"
+diff -r libjingle-0.4.0/talk/xmpp/xmpptask.cc libjingle/files/talk/xmpp/xmpptask.cc
+31c31
+< #include "talk/xmpp/constants.h"
+---
+> #include "talk/xmpp/xmppconstants.h"