[icinga-checkins] icinga.org: icinga2/next: Fix deadlock in ApiClient::SendMessage

git at icinga.org git at icinga.org
Mon Jun 30 12:53:41 CEST 2014


Module: icinga2
Branch: next
Commit: 0ac6e97f329b551882f925a009e6efe498ec45c3
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=0ac6e97f329b551882f925a009e6efe498ec45c3

Author: Gunnar Beutner <gunnar.beutner at netways.de>
Date:   Mon Jun 30 12:52:43 2014 +0200

Fix deadlock in ApiClient::SendMessage

fixes #6368

---

 lib/base/tlsstream.cpp |   27 +++++++++++++++++++++++++++
 lib/base/tlsstream.hpp |    7 +++++++
 2 files changed, 34 insertions(+)

diff --git a/lib/base/tlsstream.cpp b/lib/base/tlsstream.cpp
index 4d8883a..e8ec0e9 100644
--- a/lib/base/tlsstream.cpp
+++ b/lib/base/tlsstream.cpp
@@ -20,6 +20,7 @@
 #include "base/tlsstream.hpp"
 #include "base/utility.hpp"
 #include "base/exception.hpp"
+#include "base/objectlock.hpp"
 #include "base/logger_fwd.hpp"
 #include <boost/bind.hpp>
 #include <iostream>
@@ -184,6 +185,32 @@ size_t TlsStream::Read(void *buffer, size_t count)
 
 void TlsStream::Write(const void *buffer, size_t count)
 {
+	{
+		ObjectLock olock(&m_SendQ);
+		m_SendQ.Write(buffer, count);
+	}
+
+	Utility::QueueAsyncCallback(boost::bind(&TlsStream::FinishAsyncWrite, this));
+}
+
+void TlsStream::FinishAsyncWrite(void)
+{
+	boost::mutex::scoped_lock lock(m_WriteMutex);
+	
+	for (;;) {
+		ObjectLock olock(&m_SendQ);
+		char buffer[1024];
+		size_t count = m_SendQ.Read(buffer, sizeof(buffer));
+		
+		if (count == 0)
+			break; /* No more data in the sendq */
+		
+		WriteSync(buffer, count);
+	}
+}
+
+void TlsStream::WriteSync(const void *buffer, size_t count)
+{
 	size_t left = count;
 
 	while (left > 0) {
diff --git a/lib/base/tlsstream.hpp b/lib/base/tlsstream.hpp
index 0d26656..647e199 100644
--- a/lib/base/tlsstream.hpp
+++ b/lib/base/tlsstream.hpp
@@ -23,6 +23,7 @@
 #include "base/i2-base.hpp"
 #include "base/socket.hpp"
 #include "base/stream.hpp"
+#include "base/fifo.hpp"
 #include "base/tlsutility.hpp"
 
 namespace icinga
@@ -49,6 +50,7 @@ public:
 
 	virtual size_t Read(void *buffer, size_t count);
 	virtual void Write(const void *buffer, size_t count);
+        void WriteSync(const void *buffer, size_t count);
 
 	virtual bool IsEof(void) const;
 
@@ -56,6 +58,9 @@ private:
 	boost::mutex m_SSLLock;
 	shared_ptr<SSL> m_SSL;
 	BIO *m_BIO;
+        
+        boost::mutex m_WriteMutex;
+        FIFO m_SendQ;
 
 	Socket::Ptr m_Socket;
 	ConnectionRole m_Role;
@@ -64,6 +69,8 @@ private:
 	static bool m_SSLIndexInitialized;
 
 	static void NullCertificateDeleter(X509 *certificate);
+        
+        void FinishAsyncWrite(void);
 };
 
 }



More information about the icinga-checkins mailing list