From 65e69fcd37086cad856194d4e274bad72e459199 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 1 Jul 2014 09:38:22 +0200 Subject: [PATCH] Another attempt at fixing the API deadlock fixes #6617 --- lib/remote/apiclient.cpp | 11 +++++++++++ lib/remote/apiclient.hpp | 4 ++++ lib/remote/apilistener.cpp | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/lib/remote/apiclient.cpp b/lib/remote/apiclient.cpp index 9203094f1..e7a2c5cb0 100644 --- a/lib/remote/apiclient.cpp +++ b/lib/remote/apiclient.cpp @@ -65,6 +65,17 @@ ConnectionRole ApiClient::GetRole(void) const } void ApiClient::SendMessage(const Dictionary::Ptr& message) +{ + if (m_WriteQueue.GetLength() > 5000) { + Log(LogWarning, "remote", "Closing connection for API identity '" + m_Identity + "': Too many queued messages."); + Disconnect(); + return; + } + + m_WriteQueue.Enqueue(boost::bind(&ApiClient::SendMessageSync, this, message)); +} + +void ApiClient::SendMessageSync(const Dictionary::Ptr& message) { try { ObjectLock olock(m_Stream); diff --git a/lib/remote/apiclient.hpp b/lib/remote/apiclient.hpp index b491708c0..b6d87e068 100644 --- a/lib/remote/apiclient.hpp +++ b/lib/remote/apiclient.hpp @@ -23,6 +23,7 @@ #include "remote/endpoint.hpp" #include "base/stream.hpp" #include "base/timer.hpp" +#include "base/workqueue.hpp" #include "remote/i2-remote.hpp" namespace icinga @@ -64,8 +65,11 @@ private: ConnectionRole m_Role; double m_Seen; + WorkQueue m_WriteQueue; + bool ProcessMessage(void); void MessageThreadProc(void); + void SendMessageSync(const Dictionary::Ptr& request); }; } diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index c666a701b..5f981bd60 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -364,6 +364,10 @@ void ApiListener::ApiTimerHandler(void) if (endpoint->GetHost().IsEmpty() || endpoint->GetPort().IsEmpty()) continue; + /* don't try to connect if there's already a connection attempt */ + if (endpoint->GetConnecting()) + continue; + Utility::QueueAsyncCallback(boost::bind(&ApiListener::AddConnection, this, endpoint)); } }