diff --git a/lib/base/tlsstream.cpp b/lib/base/tlsstream.cpp index 4d8883a62..e8ec0e9d4 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 #include @@ -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; diff --git a/lib/base/tlsstream.hpp b/lib/base/tlsstream.hpp index 0d26656d0..647e199b6 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 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); }; }