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/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;

View 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);
};
}