[AGENT++] New Releases of AGENT++, AgentX++ and Tool Suite
Claus Klein
claus.klein at arcormail.de
Mon Feb 19 08:30:56 CET 2018
Hi Frank,
I have checked the new version with xcode on my macbook.
I’m Sorry to say, but there are still problems:
First of all, it does not compile on mac OSX!
Darwin Kernel Version 15.6.0: Tue Jan 9 20:12:05 PST 2018; root:xnu-3248.73.5~1/RELEASE_X86_64
The pthread_mutex_timedlock() is still not availble on OSX.
2.) the Synchronized::trylock() return the wrong result
The pthread_mutex_trylock() return:
[EBUSY] if Mutex is already locked!
3.) the QueuedThreadPool does execute the tasks in random order
NOTE: This should not defined AGENTPP_QUEUED_THREAD_POOL_USE_ASSIGN; see below
4.) there are still race conditions at code
void TaskManager::run()
{
lock();
while (go) {
if (task) {
task->run();
delete task;
task = 0;
unlock(); <<<<<<<<<<<<<<<<<<<
threadPool->idle_notification();
lock(); <<<<<<<<<<<<<<<<<<<
} else {
wait();
}
}
if (task) {
delete task;
task = 0;
}
unlock();
}
5.) The code is still not exception save at all!
With regards
Claus Klein
P.S. this patch fix some of the problems, but not all; please check:
diff --git a/include/agent_pp/threads.h b/include/agent_pp/threads.h
index e722a89..9e088b0 100644
--- a/include/agent_pp/threads.h
+++ b/include/agent_pp/threads.h
@@ -19,8 +19,8 @@
_##########################################################################*/
-#ifndef multi_h_
-#define multi_h_
+#ifndef agent_pp_threads_h_
+#define agent_pp_threads_h_
#include <agent_pp/agent++.h>
@@ -552,7 +552,7 @@ public:
* TRUE if non of the threads in the pool is currently
* executing any task.
*/
- bool is_idle();
+ virtual bool is_idle();
/**
* Check whether the ThreadPool is busy (i.e., all threads are
@@ -562,7 +562,7 @@ public:
* TRUE if non of the threads in the pool is currently
* idle (not executing any task).
*/
- bool is_busy();
+ virtual bool is_busy();
/**
* Get the size of the thread pool.
@@ -655,13 +655,31 @@ public:
*/
void execute(Runnable*);
+ /**
+ * Check whether the ThreadPool is idle or not.
+ *
+ * @return
+ * TRUE if non of the threads in the pool is currently
+ * executing any task and the queue is empty.
+ */
+ virtual bool is_idle();
+
+ /**
+ * Check whether the ThreadPool is busy (i.e., all threads are
+ * running a task) or not.
+ *
+ * @return
+ * TRUE if the queue is not empty or the pool is_busy()
+ */
+ virtual bool is_busy();
+
/**
* Gets the current number of queued tasks.
*
* @return
* the number of tasks that are currently queued.
*/
- unsigned int queue_length() { return queue.size(); }
+ unsigned int queue_length(); // FIXME: not thread save! { return queue.size(); }
/**
diff --git a/src/threads.cpp b/src/threads.cpp
index 3942a7e..26b02a6 100644
--- a/src/threads.cpp
+++ b/src/threads.cpp
@@ -1148,7 +1148,21 @@ void QueuedThreadPool::assign(Runnable* t)
void QueuedThreadPool::execute(Runnable* t)
{
Thread::lock();
- assign(t);
+
+#ifdef AGENTPP_QUEUED_THREAD_POOL_USE_ASSIGN
+ if (queue.empty()) {
+ assign(t);
+ } else
+#endif
+
+ {
+ LOG_BEGIN(loggerModuleName, DEBUG_LOG | 1);
+ LOG("queue.push");
+ LOG_END;
+ queue.add(t);
+ Thread::notify();
+ }
+
Thread::unlock();
}
@@ -1169,14 +1183,47 @@ void QueuedThreadPool::run()
Thread::unlock();
}
+unsigned int QueuedThreadPool::queue_length()
+{
+ Thread::lock();
+ unsigned len = queue.size();
+ Thread::unlock();
+
+ return len;
+}
+
void QueuedThreadPool::idle_notification()
{
+ LOG_BEGIN(loggerModuleName, DEBUG_LOG | 1);
+ LOG("idle_notification");
+ LOG_END;
+
Thread::lock();
Thread::notify();
Thread::unlock();
+
ThreadPool::idle_notification();
}
+bool QueuedThreadPool::is_idle()
+{
+ Thread::lock();
+ bool result = is_alive() && queue.empty() && ThreadPool::is_idle();
+ Thread::unlock();
+
+ return result;
+}
+
+bool QueuedThreadPool::is_busy()
+{
+ Thread::lock();
+ bool result = !queue.empty() || ThreadPool::is_busy();
+ Thread::unlock();
+
+ return result;
+}
+
+/*--------------------- class LockRequest --------------------------*/
void MibTask::run() { (task->called_class->*task->method)(task->req); }
> Am 23.01.2018 um 23:28 schrieb Frank Fock <fock at agentpp.com>:
>
> AGENT++ 4.1.0: (SNMP++ 3.3.10 or later)
>
> * Changed: CAUTION: Thread policy changed from RECURSIVE to ERRORCHECK in
> this release. You should carefully test your instrumentation code locking
> (start_synch()) before using this release with your instrumentation
> in production!
> * Improved: Incoming Request objects are now always locked using a LockQueue
> for SNMP requests, in order to allow several threads to work with those
> request objects during different phase of the request (i.e. SET request
> phase or GETBULK processing in conjunction with proxies or subagents).
> * Fixed [APP-48]: ThreadPool may not execute a task if one of its threads
> is not properly started.
More information about the AGENTPP
mailing list