[icinga-checkins] icinga.org: icinga2/master: Implement AsyncTask::Wait() and make completion callbacks optional.

git at icinga.org git at icinga.org
Wed Feb 6 10:54:58 CET 2013


Module: icinga2
Branch: master
Commit: 1da5035e553021fe4fbd080b01c4e38108acfee5
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=1da5035e553021fe4fbd080b01c4e38108acfee5

Author: Gunnar Beutner <gunnar.beutner at netways.de>
Date:   Wed Feb  6 10:53:28 2013 +0100

Implement AsyncTask::Wait() and make completion callbacks optional.

---

 lib/base/application.cpp |   33 +++++++++++++++++++++++----------
 lib/base/application.h   |    4 +++-
 lib/base/asynctask.h     |   19 +++++++++++++++----
 lib/base/utility.cpp     |   12 ++++++++++++
 lib/base/utility.h       |    2 ++
 5 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/lib/base/application.cpp b/lib/base/application.cpp
index cd7c2ca..31d87ab 100644
--- a/lib/base/application.cpp
+++ b/lib/base/application.cpp
@@ -90,10 +90,31 @@ Application::Ptr Application::GetInstance(void)
 }
 
 /**
+ * Runs one iteration of the event loop.
+ *
+ * @returns false if we're shutting down, true otherwise.
+ */
+bool Application::ProcessEvents(void) const
+{
+	Object::ClearHeldObjects();
+
+	double sleep = Timer::ProcessTimers();
+
+	if (m_ShuttingDown)
+		return false;
+
+	Event::ProcessEvents(boost::posix_time::milliseconds(sleep * 1000));
+
+	DynamicObject::FlushTx();
+
+	return true;
+}
+
+/**
  * Processes events for registered sockets and timers and calls whatever
  * handlers have been set up for these events.
  */
-void Application::RunEventLoop(void)
+void Application::RunEventLoop(void) const
 {
 #ifdef _DEBUG
 	double nextProfile = 0;
@@ -104,17 +125,9 @@ void Application::RunEventLoop(void)
 	t.detach();
 
 	while (!m_ShuttingDown) {
-		Object::ClearHeldObjects();
-
-		double sleep = Timer::ProcessTimers();
-
-		if (m_ShuttingDown)
+		if (!ProcessEvents())
 			break;
 
-		Event::ProcessEvents(boost::posix_time::milliseconds(sleep * 1000));
-
-		DynamicObject::FlushTx();
-
 #ifdef _DEBUG
 		if (nextProfile < Utility::GetTime()) {
 			stringstream msgbuf;
diff --git a/lib/base/application.h b/lib/base/application.h
index b75ce64..3ba1af3 100644
--- a/lib/base/application.h
+++ b/lib/base/application.h
@@ -76,8 +76,10 @@ public:
 	static String GetPkgDataDir(void);
 	static void SetPkgDataDir(const String& path);
 
+	bool ProcessEvents(void) const;
+
 protected:
-	void RunEventLoop(void);
+	void RunEventLoop(void) const;
 
 private:
 	static Application *m_Instance; /**< The application instance. */
diff --git a/lib/base/asynctask.h b/lib/base/asynctask.h
index f195a18..efb49a2 100644
--- a/lib/base/asynctask.h
+++ b/lib/base/asynctask.h
@@ -128,6 +128,14 @@ public:
 		FinishInternal();
 	}
 
+	/**
+	 * Blocks until the task is completed.
+	 */
+	void Wait(void)
+	{
+		Utility::WaitUntil(boost::bind(&AsyncTask<TClass, TResult>::IsFinished, this));
+	}
+
 protected:
 	/**
 	 * Begins executing the task. The Run method must ensure
@@ -146,11 +154,14 @@ private:
 		assert(!m_Finished);
 
 		m_Finished = true;
-		m_CompletionCallback(GetSelf());
 
-		/* Clear callback because the bound function might hold a
-		 * reference to this task. */
-		m_CompletionCallback = CompletionCallback();
+		if (!m_CompletionCallback.empty()) {
+			m_CompletionCallback(GetSelf());
+
+			/* Clear callback because the bound function might hold a
+			 * reference to this task. */
+			m_CompletionCallback = CompletionCallback();
+		}
 	}
 
 	CompletionCallback m_CompletionCallback; /**< The completion callback. */
diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp
index 29ef516..bee1105 100644
--- a/lib/base/utility.cpp
+++ b/lib/base/utility.cpp
@@ -499,3 +499,15 @@ bool Utility::Glob(const String& pathSpec, const function<void (const String&)>&
 	return true;
 #endif /* _WIN32 */
 }
+
+/**
+ * Waits until the given predicate is true. Executes events while waiting.
+ *
+ * @param predicate The predicate.
+ */
+void Utility::WaitUntil(const function<bool (void)>& predicate)
+{
+	while (!predicate)
+		Application::GetInstance()->ProcessEvents();
+}
+
diff --git a/lib/base/utility.h b/lib/base/utility.h
index bbccaa4..3638d12 100644
--- a/lib/base/utility.h
+++ b/lib/base/utility.h
@@ -58,6 +58,8 @@ public:
 
 	static bool Glob(const String& pathSpec, const function<void (const String&)>& callback);
 
+	static void WaitUntil(const function<bool (void)>& predicate);
+
 	static
 #ifdef _WIN32
 	HMODULE





More information about the icinga-checkins mailing list