Fix deadlock in ApiClient::SendMessage

fixes #6368
This commit is contained in:
Gunnar Beutner 2014-06-30 12:52:43 +02:00
parent 99b590ab95
commit 0ac6e97f32
2 changed files with 34 additions and 0 deletions

View File

@ -20,6 +20,7 @@
#include "base/tlsstream.hpp" #include "base/tlsstream.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include "base/exception.hpp" #include "base/exception.hpp"
#include "base/objectlock.hpp"
#include "base/logger_fwd.hpp" #include "base/logger_fwd.hpp"
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <iostream> #include <iostream>
@ -183,6 +184,32 @@ size_t TlsStream::Read(void *buffer, size_t count)
} }
void TlsStream::Write(const 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; size_t left = count;

View File

@ -23,6 +23,7 @@
#include "base/i2-base.hpp" #include "base/i2-base.hpp"
#include "base/socket.hpp" #include "base/socket.hpp"
#include "base/stream.hpp" #include "base/stream.hpp"
#include "base/fifo.hpp"
#include "base/tlsutility.hpp" #include "base/tlsutility.hpp"
namespace icinga namespace icinga
@ -49,6 +50,7 @@ public:
virtual size_t Read(void *buffer, size_t count); virtual size_t Read(void *buffer, size_t count);
virtual void Write(const 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; virtual bool IsEof(void) const;
@ -57,6 +59,9 @@ private:
shared_ptr<SSL> m_SSL; shared_ptr<SSL> m_SSL;
BIO *m_BIO; BIO *m_BIO;
boost::mutex m_WriteMutex;
FIFO m_SendQ;
Socket::Ptr m_Socket; Socket::Ptr m_Socket;
ConnectionRole m_Role; ConnectionRole m_Role;
@ -64,6 +69,8 @@ private:
static bool m_SSLIndexInitialized; static bool m_SSLIndexInitialized;
static void NullCertificateDeleter(X509 *certificate); static void NullCertificateDeleter(X509 *certificate);
void FinishAsyncWrite(void);
}; };
} }