]> granicus.if.org Git - icinga2/commitdiff
Fix deadlock in ApiClient::SendMessage
authorGunnar Beutner <gunnar.beutner@netways.de>
Mon, 30 Jun 2014 10:52:43 +0000 (12:52 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Mon, 30 Jun 2014 10:52:43 +0000 (12:52 +0200)
fixes #6368

lib/base/tlsstream.cpp
lib/base/tlsstream.hpp

index 4d8883a623eb07aad5e9671d196766fe5547a1fd..e8ec0e9d4d7bd39c472d08410c2b91aa44fa89b2 100644 (file)
@@ -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>
@@ -183,6 +184,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;
 
index 0d26656d034bd95f83a5413e8dec9a397e6b2db6..647e199b60a8fdbce2f8f8cfc0546ba10f969dbf 100644 (file)
@@ -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);
 };
 
 }