[asterisk-scf-commits] asterisk-scf/integration/util-cpp.git branch "master" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Fri Jan 21 17:00:49 CST 2011
branch "master" has been updated
via 127ae4a06949d2bba30c7948ad499f9296272ef6 (commit)
from 5aba658323238ead764a0e999c56aa027147d405 (commit)
Summary of changes:
CMakeLists.txt | 2 +-
Threading/CMakeLists.txt | 19 ++-
Threading/CMakeLists.txt~ | 32 ++++
.../AsteriskSCF/Threading/SimpleWorkQueue.h | 34 +++--
.../include/AsteriskSCF/Threading/WorkQueue.h | 32 ++---
Threading/src/SimpleWorkQueue.cpp | 169 ++++++++++----------
.../{SimpleWorkQueue.cpp => SimpleWorkQueue.cpp~} | 80 +++++-----
7 files changed, 199 insertions(+), 169 deletions(-)
create mode 100644 Threading/CMakeLists.txt~
copy Threading/src/{SimpleWorkQueue.cpp => SimpleWorkQueue.cpp~} (81%)
- Log -----------------------------------------------------------------
commit 127ae4a06949d2bba30c7948ad499f9296272ef6
Author: Ken Hunt <ken.hunt at digium.com>
Date: Fri Jan 21 17:00:48 2011 -0600
Incorporating more review feedback.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2a28ed3..4bfc63e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,4 +3,4 @@ if (integrated_build STREQUAL "true")
set(util_cpp_bindir ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
endif()
-add_subdirectory(WorkQueue)
+add_subdirectory(Threading)
diff --git a/Threading/CMakeLists.txt b/Threading/CMakeLists.txt
index d4f5412..6275408 100644
--- a/Threading/CMakeLists.txt
+++ b/Threading/CMakeLists.txt
@@ -6,15 +6,16 @@
# All rights reserved.
#
-asterisk_scf_component_init(WorkQueue CXX)
+asterisk_scf_component_init(Threading CXX)
include_directories(include)
-asterisk_scf_component_add_slice(WorkQueue LoggerIf)
-asterisk_scf_component_add_file(WorkQueue include/AsteriskSCF/WorkQueue/WorkQueue.h)
-asterisk_scf_component_add_file(WorkQueue include/AsteriskSCF/WorkQueue/SimpleWorkQueue.h)
-asterisk_scf_component_add_file(WorkQueue src/SimpleWorkQueue.cpp)
-asterisk_scf_component_add_boost_libraries(WorkQueue core thread)
+asterisk_scf_component_add_slice(Threading LoggerIf)
+asterisk_scf_component_add_file(Threading include/AsteriskSCF/Threading/WorkQueue.h)
+asterisk_scf_component_add_file(Threading include/AsteriskSCF/Threading/SimpleWorkQueue.h)
+asterisk_scf_component_add_file(Threading include/AsteriskSCF/Threading/PausibleWorkQueue.h)
+asterisk_scf_component_add_file(Threading src/SimpleWorkQueue.cpp)
+asterisk_scf_component_add_boost_libraries(Threading core thread)
if(NOT logger_dir)
message(FATAL_ERROR "The logger directory could not be found ${logger_dir}")
@@ -23,9 +24,9 @@ endif()
include_directories(${logger_dir}/common)
include_directories(${logger_dir}/client/src)
-asterisk_scf_component_build_library(WorkQueue)
+asterisk_scf_component_build_library(Threading)
-target_link_libraries(WorkQueue logging-client)
+target_link_libraries(Threading logging-client)
-asterisk_scf_component_install(WorkQueue LIBRARY lib "Work Queue" WorkQueue ARCHIVE DESTINATION lib)
+asterisk_scf_component_install(Threading LIBRARY lib "Threading" Threading ARCHIVE DESTINATION lib)
diff --git a/Threading/CMakeLists.txt~ b/Threading/CMakeLists.txt~
new file mode 100644
index 0000000..61c91ab
--- /dev/null
+++ b/Threading/CMakeLists.txt~
@@ -0,0 +1,32 @@
+#
+# Asterisk Scalable Communications Framework
+#
+# Copyright (C) 2010, 2011 -- Digium, Inc.
+#
+# All rights reserved.
+#
+
+asterisk_scf_component_init(Threading CXX)
+
+include_directories(include)
+
+asterisk_scf_component_add_slice(Threading LoggerIf)
+asterisk_scf_component_add_file(Threading include/AsteriskSCF/Threading/Threading.h)
+asterisk_scf_component_add_file(Threading include/AsteriskSCF/Threading/SimpleThreading.h)
+asterisk_scf_component_add_file(Threading include/AsteriskSCF/Threading/PausibleThreading.h)
+asterisk_scf_component_add_file(Threading src/SimpleThreading.cpp)
+asterisk_scf_component_add_boost_libraries(Threading core thread)
+
+if(NOT logger_dir)
+ message(FATAL_ERROR "The logger directory could not be found ${logger_dir}")
+endif()
+
+include_directories(${logger_dir}/common)
+include_directories(${logger_dir}/client/src)
+
+asterisk_scf_component_build_library(Threading)
+
+target_link_libraries(Threading logging-client)
+
+asterisk_scf_component_install(Threading LIBRARY lib "Threading" Threading ARCHIVE DESTINATION lib)
+
diff --git a/Threading/include/AsteriskSCF/Threading/SimpleWorkQueue.h b/Threading/include/AsteriskSCF/Threading/SimpleWorkQueue.h
index d597271..61ace49 100644
--- a/Threading/include/AsteriskSCF/Threading/SimpleWorkQueue.h
+++ b/Threading/include/AsteriskSCF/Threading/SimpleWorkQueue.h
@@ -1,7 +1,7 @@
/*
* Asterisk SCF -- An open-source communications framework.
*
- * Copyright (C) 2010, Digium, Inc.
+ * Copyright (C) 2010-2011, Digium, Inc.
*
* See http://www.asterisk.org for more information about
* the Asterisk SCF project. Please do not directly contact
@@ -15,42 +15,48 @@
*/
#pragma once
-#include <list>
#include <string>
#include <boost/thread.hpp>
#include <boost/thread/condition.hpp>
#include <boost/shared_ptr.hpp>
#include "WorkQueue.h"
+#include "PausibleWorkQueue.h"
#include "logger.h"
namespace AsteriskSCF
{
+namespace Threading
+{
+
/**
* A simple Work Queue implementation.
* See WorkQueue for more information.
*/
class SimpleWorkQueuePriv;
-class ASTERISK_SCF_ICEBOX_EXPORT SimpleWorkQueue : public WorkQueue, boost::noncopyable
+class ASTERISK_SCF_ICEBOX_EXPORT SimpleWorkQueue : public WorkQueue, public PausibleWorkQueue, boost::noncopyable
{
public:
SimpleWorkQueue(const std::string& id, const AsteriskSCF::System::Logging::Logger& logger);
~SimpleWorkQueue();
- virtual WorkQueue::PoolId enqueue(const WorkPtr& w);
- virtual void terminate();
- virtual void join();
+ // Overrides for the WorkQueue interface.
+ virtual boost::shared_ptr<WorkQueue::PoolId> enqueue(const WorkPtr& w);
+ virtual void enqueue(const WorkPtr& w, PoolId)
+ {
+ enqueue(w);
+ }
- // This implementation adds the concept of Pausing to the generic WorkQueue.
- bool isRunning();
- bool workPending();
- void pause();
- void resume();
+ // Overrides for the PausibleWorkQueue mixin interface.
+ virtual bool isRunning();
+ virtual bool workPending();
+ virtual void pause();
+ virtual void resume();
-private:
- boost::shared_ptr<SimpleWorkQueuePriv> mImpl;
+private: boost::shared_ptr<SimpleWorkQueuePriv> mImpl;
};
-};
+} // end namespace Threading
+} // end namespace AsteriskSCF
diff --git a/Threading/include/AsteriskSCF/Threading/WorkQueue.h b/Threading/include/AsteriskSCF/Threading/WorkQueue.h
index 5b306cc..65c7f88 100644
--- a/Threading/include/AsteriskSCF/Threading/WorkQueue.h
+++ b/Threading/include/AsteriskSCF/Threading/WorkQueue.h
@@ -1,7 +1,7 @@
/*
* Asterisk SCF -- An open-source communications framework.
*
- * Copyright (C) 2010, Digium, Inc.
+ * Copyright (C) 2010-2011, Digium, Inc.
*
* See http://www.asterisk.org for more information about
* the Asterisk SCF project. Please do not directly contact
@@ -19,6 +19,9 @@
namespace AsteriskSCF
{
+namespace Threading
+{
+
/**
* This class defines an interface to a work queue. A work queue manages one or
* more processing threads, and allows work to be enqueued.
@@ -52,35 +55,22 @@ public:
/**
* Enqueue work to be peformed.
*/
- virtual PoolId enqueue(const WorkPtr& w) = 0;
+ virtual boost::shared_ptr<PoolId> enqueue(const WorkPtr& w) = 0;
/**
* Enqueue work to be performed, and specify a particular thread
- * of a Thread Pool to do the work.
- * Note: Implementations of Thread Pools are expected to override this
- * default implementation.
- */
- virtual void enqueue(const WorkPtr& w, PoolId)
- {
- enqueue(w);
- }
-
- /**
- * Terminate the work queue.
+ * of a Thread Pool to do the work. Note: For single threaded work queues,
+ * the PoolId can be ignored.
*/
- virtual void terminate() = 0;
-
- /**
- * Block until processing on all worker threads completes.
- */
- virtual void join() = 0;
+ virtual void enqueue(const WorkPtr& w, PoolId) = 0;
virtual ~WorkQueue() {};
protected:
- WorkQueue() {}; // Hide the constructor since this is an interface.
+ WorkQueue() {}; // Hide the constructor since this is an interface.
};
typedef WorkQueue::WorkPtr WorkPtr;
-};
+} // end namespace WorkQueue
+} // end namespace AsteriskSCF
diff --git a/Threading/src/SimpleWorkQueue.cpp b/Threading/src/SimpleWorkQueue.cpp
index 963d747..85766bf 100644
--- a/Threading/src/SimpleWorkQueue.cpp
+++ b/Threading/src/SimpleWorkQueue.cpp
@@ -27,39 +27,42 @@
#include "logger.h"
-#include "AsteriskSCF/WorkQueue/SimpleWorkQueue.h"
+#include "AsteriskSCF/Threading/SimpleWorkQueue.h"
+using namespace boost;
using namespace AsteriskSCF;
+using namespace AsteriskSCF::Threading;
using namespace AsteriskSCF::System::Logging;
-using namespace boost;
-namespace // annonymous namespace has file-only visibility.
+namespace
{
- /**
- * This is a private no-op implementation of a work item. Returned from WaitAndDequeue
- * if the program is Terminated while waiting on the EmptyQueueCondition.
- */
- class HiddenNoWorkClass : public WorkQueue::Work
- {
- public:
- HiddenNoWorkClass() {};
- void doWork() {} // Do nothing
- };
+ /**
+ * This is a private no-op implementation of a work item. Returned from WaitAndDequeue
+ * if the program is Terminated while waiting on the EmptyQueueCondition.
+ */
+ class HiddenNoWorkClass : public AsteriskSCF::Threading::WorkQueue::Work
+ {
+ public:
+ HiddenNoWorkClass() {};
+ void doWork() {} // Do nothing
+ };
}
namespace AsteriskSCF
{
+namespace Threading
+{
+
class SimpleWorkQueuePriv
{
public:
SimpleWorkQueuePriv(const std::string& id, const Logger& logger)
: mLogger(logger),
mQid(id),
- mInitialized(false),
mFinished(false),
mPaused(false), // runs by default.
+ mNoOpPoolIdPtr (new WorkQueue::PoolId),
mThread(boost::bind(&SimpleWorkQueuePriv::execute, this))
-
{
mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": called. Queue ID:" << mQid;
}
@@ -69,6 +72,33 @@ public:
mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": called. Queue ID:" << mQid;
}
+ /**
+ * Stops this thread from executing.
+ */
+ void terminate()
+ {
+ mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": called for queue " << mQid ;
+
+ mFinished = true;
+ resume();
+
+ { // scope for the lock.
+ boost::lock_guard<boost::mutex> lock(mQueueMutex);
+ mEmptyQueueCondition.notify_all(); // In case the thread was waiting on an EmptyQueueCondition
+ }
+ }
+
+
+ /**
+ * Allows other thread to join to this thread. The caller needs to
+ * call this object's Terminate method, or the join will block
+ * indefinitely.
+ */
+ void join()
+ {
+ mThread.join();
+ }
+
WorkPtr dequeue();
WorkPtr waitAndDequeue();
void execute();
@@ -76,7 +106,6 @@ public:
const Logger& mLogger;
std::string mQid;
- bool mInitialized;
bool mFinished;
bool mPaused;
std::list<WorkPtr> mQueue;
@@ -84,28 +113,29 @@ public:
boost::condition mEmptyQueueCondition;
boost::mutex mPauseMutex;
boost::condition mPauseCondition;
+ boost::shared_ptr<WorkQueue::PoolId> mNoOpPoolIdPtr;
+
boost::thread mThread; // This variable is last so that the class is fully initialized before the thread executes.
};
-}
+
SimpleWorkQueue::SimpleWorkQueue(const std::string& qid, const Logger& logger) : mImpl(new SimpleWorkQueuePriv(qid, logger))
{
mImpl->mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": called. Queue ID:" << mImpl->mQid;
- mImpl->mInitialized = true;
}
SimpleWorkQueue::~SimpleWorkQueue()
{
mImpl->mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": called. Queue ID:" << mImpl->mQid;
- terminate();
+ mImpl->terminate();
// Wait for worker thread to shut down.
- join();
+ mImpl->join();
}
bool SimpleWorkQueue::isRunning()
{
- return (mImpl->mInitialized && !mImpl->mPaused && !mImpl->mFinished);
+ return (!mImpl->mPaused && !mImpl->mFinished);
}
/**
@@ -113,7 +143,7 @@ bool SimpleWorkQueue::isRunning()
*/
void SimpleWorkQueue::pause()
{
- mImpl->mLogger(Info) << BOOST_CURRENT_FUNCTION << ": called for queue " << mImpl->mQid;
+ mImpl->mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": called for queue " << mImpl->mQid;
boost::lock_guard<boost::mutex> lock(mImpl->mPauseMutex);
mImpl->mPaused = true;
@@ -124,34 +154,13 @@ void SimpleWorkQueue::pause()
*/
void SimpleWorkQueue::resume()
{
- mImpl->mLogger(Info) << BOOST_CURRENT_FUNCTION << ": called for queue " << mImpl->mQid;
+ mImpl->mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": called for queue " << mImpl->mQid;
boost::lock_guard<boost::mutex> lock(mImpl->mPauseMutex);
mImpl->mPaused = false;
mImpl->mPauseCondition.notify_all();
}
-/**
- * Stops this thread from executing.
- */
-void SimpleWorkQueue::terminate()
-{
- mImpl->mLogger(Info) << BOOST_CURRENT_FUNCTION << ": called for queue " << mImpl->mQid ;
-
- mImpl->mFinished = true;
- mImpl->mPaused = false;
-
- {
- boost::lock_guard<boost::mutex> lock(mImpl->mPauseMutex);
- mImpl->mPauseCondition.notify_all(); // In case the thread was waiting on the PauseCondition.
- }
-
- {
- boost::lock_guard<boost::mutex> lock(mImpl->mQueueMutex);
- mImpl->mEmptyQueueCondition.notify_all(); // In case the thread was waiting on an EmptyQueueCondition
- }
-}
-
/**
* A convenience method to determine if there is any pending work on the queue.
*/
@@ -161,36 +170,22 @@ bool SimpleWorkQueue::workPending()
}
/**
- * Allows other thread to join to this thread. The caller needs to
- * call this object's Terminate method, or the join will block
- * indefinitely.
- */
-void SimpleWorkQueue::join()
-{
- mImpl->mThread.join();
-}
-
-static WorkQueue::PoolId noOpPoolId;
-
-/**
* Enqueue an item of work for processing on this queue's thread.
*/
-WorkQueue::PoolId SimpleWorkQueue::enqueue(const WorkPtr& w)
+boost::shared_ptr<WorkQueue::PoolId> SimpleWorkQueue::enqueue(const WorkPtr& w)
{
- bool wasEmpty(false);
-
{ // scope for the mutex.
boost::lock_guard<boost::mutex> lock(mImpl->mQueueMutex);
- wasEmpty = mImpl->mQueue.empty();
+ bool wasEmpty = mImpl->mQueue.empty();
mImpl->mQueue.push_back(w);
- if (wasEmpty)
- {
- mImpl->mEmptyQueueCondition.notify_all();
- }
- }
+ if (wasEmpty)
+ {
+ mImpl->mEmptyQueueCondition.notify_all();
+ }
+ }
- return noOpPoolId;
+ return mImpl->mNoOpPoolIdPtr;
}
static shared_ptr<WorkQueue::Work> HiddenNoWorkPtr(new HiddenNoWorkClass());
@@ -209,7 +204,7 @@ WorkPtr SimpleWorkQueuePriv::waitAndDequeue()
if (mFinished)
{
- mLogger(Info) << BOOST_CURRENT_FUNCTION << ": Returning the NO_WORK token. Queue ID:" << mQid;
+ mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Returning the NO_WORK token. Queue ID:" << mQid;
return HiddenNoWorkPtr;
}
@@ -235,8 +230,8 @@ bool SimpleWorkQueuePriv::isPaused()
*/
void SimpleWorkQueuePriv::execute()
{
- while (!mFinished)
- {
+ while (!mFinished)
+ {
{ // scope the lock
boost::unique_lock<boost::mutex> lock(mPauseMutex);
while(mPaused)
@@ -252,25 +247,31 @@ void SimpleWorkQueuePriv::execute()
}
} // end lock scope
- mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Pinging the work queue. Queue ID:" << mQid;
+ mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Pinging the work queue. Queue ID:" << mQid;
- WorkPtr work = waitAndDequeue();
+ WorkPtr work = waitAndDequeue();
+
+ mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Doing the work. Queue ID:" << mQid;
- mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Doing the work. Queue ID:" << mQid;
-
- try
- {
- work->doWork();
- }
- catch(const std::exception& e)
- {
- // Workers should be catching/managing their own exceptions!
- mLogger(Warning) << BOOST_CURRENT_FUNCTION << ": Work item threw exception for queue " << mQid;
- mLogger(Warning) << " Details: " << e.what();
- }
+ try
+ {
+ work->doWork();
+ }
+ catch(const std::exception& e)
+ {
+ // Workers should be catching/managing their own exceptions!
+ mLogger(Warning) << BOOST_CURRENT_FUNCTION << ": Work item threw exception for queue " << mQid;
+ mLogger(Warning) << " Details: " << e.what();
+ }
+ catch(...)
+ {
+ mLogger(Warning) << BOOST_CURRENT_FUNCTION << ": Work item threw non-standard exception. ";
+ }
} // while !mFinished
- mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Exiting the thread for good. Queue ID:" << mQid;
+ mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Exiting the thread for good. Queue ID:" << mQid;
}
+} // end namespace Threading
+} // end namespace AsteriskSCF
diff --git a/Threading/src/SimpleWorkQueue.cpp b/Threading/src/SimpleWorkQueue.cpp~
similarity index 81%
copy from Threading/src/SimpleWorkQueue.cpp
copy to Threading/src/SimpleWorkQueue.cpp~
index 963d747..943fcf2 100644
--- a/Threading/src/SimpleWorkQueue.cpp
+++ b/Threading/src/SimpleWorkQueue.cpp~
@@ -33,18 +33,18 @@ using namespace AsteriskSCF;
using namespace AsteriskSCF::System::Logging;
using namespace boost;
-namespace // annonymous namespace has file-only visibility.
+namespace
{
- /**
- * This is a private no-op implementation of a work item. Returned from WaitAndDequeue
- * if the program is Terminated while waiting on the EmptyQueueCondition.
- */
- class HiddenNoWorkClass : public WorkQueue::Work
- {
- public:
- HiddenNoWorkClass() {};
- void doWork() {} // Do nothing
- };
+ /**
+ * This is a private no-op implementation of a work item. Returned from WaitAndDequeue
+ * if the program is Terminated while waiting on the EmptyQueueCondition.
+ */
+ class HiddenNoWorkClass : public WorkQueue::Work
+ {
+ public:
+ HiddenNoWorkClass() {};
+ void doWork() {} // Do nothing
+ };
}
namespace AsteriskSCF
@@ -100,7 +100,7 @@ SimpleWorkQueue::~SimpleWorkQueue()
terminate();
// Wait for worker thread to shut down.
- join();
+ join();
}
bool SimpleWorkQueue::isRunning()
@@ -141,15 +141,15 @@ void SimpleWorkQueue::terminate()
mImpl->mFinished = true;
mImpl->mPaused = false;
- {
- boost::lock_guard<boost::mutex> lock(mImpl->mPauseMutex);
+ { // scope for the lock.
+ boost::lock_guard<boost::mutex> lock(mImpl->mPauseMutex);
mImpl->mPauseCondition.notify_all(); // In case the thread was waiting on the PauseCondition.
- }
+ }
- {
- boost::lock_guard<boost::mutex> lock(mImpl->mQueueMutex);
+ { // scope for the lock.
+ boost::lock_guard<boost::mutex> lock(mImpl->mQueueMutex);
mImpl->mEmptyQueueCondition.notify_all(); // In case the thread was waiting on an EmptyQueueCondition
- }
+ }
}
/**
@@ -184,11 +184,11 @@ WorkQueue::PoolId SimpleWorkQueue::enqueue(const WorkPtr& w)
wasEmpty = mImpl->mQueue.empty();
mImpl->mQueue.push_back(w);
- if (wasEmpty)
- {
- mImpl->mEmptyQueueCondition.notify_all();
- }
- }
+ if (wasEmpty)
+ {
+ mImpl->mEmptyQueueCondition.notify_all();
+ }
+ }
return noOpPoolId;
}
@@ -235,8 +235,8 @@ bool SimpleWorkQueuePriv::isPaused()
*/
void SimpleWorkQueuePriv::execute()
{
- while (!mFinished)
- {
+ while (!mFinished)
+ {
{ // scope the lock
boost::unique_lock<boost::mutex> lock(mPauseMutex);
while(mPaused)
@@ -252,25 +252,25 @@ void SimpleWorkQueuePriv::execute()
}
} // end lock scope
- mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Pinging the work queue. Queue ID:" << mQid;
-
- WorkPtr work = waitAndDequeue();
+ mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Pinging the work queue. Queue ID:" << mQid;
- mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Doing the work. Queue ID:" << mQid;
+ WorkPtr work = waitAndDequeue();
+
+ mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Doing the work. Queue ID:" << mQid;
- try
- {
- work->doWork();
- }
- catch(const std::exception& e)
- {
- // Workers should be catching/managing their own exceptions!
- mLogger(Warning) << BOOST_CURRENT_FUNCTION << ": Work item threw exception for queue " << mQid;
- mLogger(Warning) << " Details: " << e.what();
- }
+ try
+ {
+ work->doWork();
+ }
+ catch(const std::exception& e)
+ {
+ // Workers should be catching/managing their own exceptions!
+ mLogger(Warning) << BOOST_CURRENT_FUNCTION << ": Work item threw exception for queue " << mQid;
+ mLogger(Warning) << " Details: " << e.what();
+ }
} // while !mFinished
- mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Exiting the thread for good. Queue ID:" << mQid;
+ mLogger(Debug) << BOOST_CURRENT_FUNCTION << ": Exiting the thread for good. Queue ID:" << mQid;
}
-----------------------------------------------------------------------
--
asterisk-scf/integration/util-cpp.git
More information about the asterisk-scf-commits
mailing list