Improved Event::Post performance.

This commit is contained in:
Gunnar Beutner 2012-07-13 23:33:30 +02:00
parent a73f41fb6c
commit b176963c93
10 changed files with 47 additions and 66 deletions

View File

@ -99,14 +99,7 @@ void Application::RunEventLoop(void)
if (m_ShuttingDown)
break;
vector<Event::Ptr> events;
Event::Wait(&events, boost::get_system_time() + boost::posix_time::seconds(sleep));
for (vector<Event::Ptr>::iterator it = events.begin(); it != events.end(); it++) {
Event::Ptr ev = *it;
ev->OnEventDelivered();
}
Event::ProcessEvents(boost::get_system_time() + boost::posix_time::seconds(sleep));
}
}

View File

@ -53,18 +53,10 @@ protected:
void Finish(void)
{
Event::Ptr ev = boost::make_shared<Event>();
ev->OnEventDelivered.connect(boost::bind(&T::FinishForwarder, static_cast<shared_ptr<T> >(GetSelf())));
Event::Post(ev);
Event::Post(boost::bind(boost::cref(OnTaskCompleted), static_cast<shared_ptr<T> >(GetSelf())));
}
bool m_Finished;
private:
static void FinishForwarder(const shared_ptr<T>& task)
{
task->OnTaskCompleted(task);
}
};
}

View File

@ -21,33 +21,43 @@
using namespace icinga;
deque<Event::Ptr> Event::m_Events;
vector<Event> Event::m_Events;
condition_variable Event::m_EventAvailable;
mutex Event::m_Mutex;
bool Event::Wait(vector<Event::Ptr> *events, const system_time& wait_until)
Event::Event(const function<void ()>& callback)
: m_Callback(callback)
{ }
void Event::ProcessEvents(const system_time& wait_until)
{
vector<Event> events;
{
mutex::scoped_lock lock(m_Mutex);
while (m_Events.empty()) {
if (!m_EventAvailable.timed_wait(lock, wait_until))
return false;
}
vector<Event::Ptr> result;
std::copy(m_Events.begin(), m_Events.end(), back_inserter(*events));
m_Events.clear();
return true;
}
void Event::Post(const Event::Ptr& ev)
{
if (Application::IsMainThread()) {
ev->OnEventDelivered();
return;
}
events.swap(m_Events);
}
vector<Event>::iterator it;
for (it = events.begin(); it != events.end(); it++)
it->m_Callback();
}
void Event::Post(const function<void ()>& callback)
{
if (Application::IsMainThread()) {
callback();
return;
}
Event ev(callback);
{
mutex::scoped_lock lock(m_Mutex);
m_Events.push_back(ev);

View File

@ -23,19 +23,18 @@
namespace icinga
{
class I2_BASE_API Event : public Object
class I2_BASE_API Event
{
public:
typedef shared_ptr<Event> Ptr;
typedef weak_ptr<Event> WeakPtr;
static bool Wait(vector<Event::Ptr> *events, const system_time& wait_until);
static void Post(const Event::Ptr& ev);
boost::signal<void ()> OnEventDelivered;
static void ProcessEvents(const system_time& wait_until);
static void Post(const function<void ()>& callback);
private:
static deque<Event::Ptr> m_Events;
Event(const function<void ()>& callback);
function<void ()> m_Callback;
static vector<Event> m_Events;
static condition_variable m_EventAvailable;
static mutex m_Mutex;
};

View File

@ -49,9 +49,7 @@ void Logger::Write(LogSeverity severity, const string& facility,
entry.Facility = facility;
entry.Message = message;
Event::Ptr ev = boost::make_shared<Event>();
ev->OnEventDelivered.connect(boost::bind(&Logger::ForwardLogEntry, entry));
Event::Post(ev);
Event::Post(boost::bind(&Logger::ForwardLogEntry, entry));
}
/**

View File

@ -111,11 +111,8 @@ void Socket::CloseInternal(bool from_dtor)
/* nobody can possibly have a valid event subscription when the
destructor has been called */
if (!from_dtor) {
Event::Ptr ev = boost::make_shared<Event>();
ev->OnEventDelivered.connect(boost::bind(boost::ref(OnClosed), GetSelf()));
Event::Post(ev);
}
if (!from_dtor)
Event::Post(boost::bind(boost::ref(OnClosed), GetSelf()));
}
/**
@ -159,9 +156,7 @@ int Socket::GetLastSocketError(void)
void Socket::HandleSocketError(const exception& ex)
{
if (!OnError.empty()) {
Event::Ptr ev = boost::make_shared<Event>();
ev->OnEventDelivered.connect(boost::bind(boost::ref(OnError), GetSelf(), runtime_error(ex.what())));
Event::Post(ev);
Event::Post(boost::bind(boost::ref(OnError), GetSelf(), runtime_error(ex.what())));
CloseInternal(false);
} else {

View File

@ -159,9 +159,7 @@ void TcpClient::HandleReadable(void)
m_RecvQueue->Write(NULL, rc);
}
Event::Ptr ev = boost::make_shared<Event>();
ev->OnEventDelivered.connect(boost::bind(boost::ref(OnDataAvailable), GetSelf()));
Event::Post(ev);
Event::Post(boost::bind(boost::ref(OnDataAvailable), GetSelf()));
}
/**

View File

@ -91,7 +91,5 @@ void TcpServer::HandleReadable(void)
TcpClient::Ptr client = m_ClientFactory(fd);
Event::Ptr ev = boost::make_shared<Event>();
ev->OnEventDelivered.connect(boost::bind(boost::ref(OnNewClient), GetSelf(), client));
Event::Post(ev);
Event::Post(boost::bind(boost::ref(OnNewClient), GetSelf(), client));
}

View File

@ -142,9 +142,7 @@ void TlsClient::HandleReadable(void)
}
post_event:
Event::Ptr ev = boost::make_shared<Event>();
ev->OnEventDelivered.connect(boost::bind(boost::ref(OnDataAvailable), GetSelf()));
Event::Post(ev);
Event::Post(boost::bind(boost::ref(OnDataAvailable), GetSelf()));
}
/**
@ -257,11 +255,8 @@ int TlsClient::ValidateCertificateInternal(int ok, X509_STORE_CTX *x509Context)
shared_ptr<X509> x509Certificate = shared_ptr<X509>(x509Context->cert, &TlsClient::NullCertificateDeleter);
bool valid = ValidateCertificate((ok != 0), x509Context, x509Certificate);
if (valid) {
Event::Ptr ev = boost::make_shared<Event>();
ev->OnEventDelivered.connect(boost::bind(boost::ref(OnCertificateValidated), GetSelf()));
Event::Post(ev);
}
if (valid)
Event::Post(boost::bind(boost::ref(OnCertificateValidated), GetSelf()));
return valid ? 1 : 0;
}

View File

@ -46,6 +46,10 @@ void NagiosCheckTask::Run(void)
void NagiosCheckTask::ProcessFinishedHandler(void)
{
time_t now;
time(&now);
GetResult().SetExecutionEnd(now);
string output = m_Process->GetOutput();
boost::algorithm::trim(output);
ProcessCheckOutput(output);
@ -71,9 +75,8 @@ void NagiosCheckTask::ProcessFinishedHandler(void)
GetResult().SetState(state);
time_t now;
time(&now);
GetResult().SetExecutionEnd(now);
GetResult().SetScheduleEnd(now);
Finish();
}