[PATCH] SELECT1: Do not block in EventListHolder::SNMPProcessEvents()
Dominik Vogt
dvogt at ffm.tc.iot.dtag.de
Wed Jul 28 12:51:14 CEST 2010
Other threads blocked until the loop in EventListHolder::SNMPProcessEvents()
finished. Now they return immediately.
---
include/snmp_pp/eventlistholder.h | 2 +
src/eventlistholder.cpp | 52 +++++++++++++++++++++++++++++++++---
2 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/include/snmp_pp/eventlistholder.h b/include/snmp_pp/eventlistholder.h
index f007573..adc24d9 100644
--- a/include/snmp_pp/eventlistholder.h
+++ b/include/snmp_pp/eventlistholder.h
@@ -109,6 +109,8 @@ class DLLOPT EventListHolder
CEventList m_eventList; // contains all expected events
SnmpSynchronized pevents_mutex;
+ bool m_is_processing_events;
+ bool m_is_processing_events_restart_necessary;
};
#ifdef SNMP_PP_NAMESPACE
diff --git a/src/eventlistholder.cpp b/src/eventlistholder.cpp
index 547a84e..3185b27 100644
--- a/src/eventlistholder.cpp
+++ b/src/eventlistholder.cpp
@@ -49,6 +49,8 @@ EventListHolder::EventListHolder(Snmp *snmp_session)
// Automatically add the SNMP notification queue
m_notifyEventQueue = new CNotifyEventQueue(this, snmp_session);
m_eventList.AddEntry(m_notifyEventQueue);
+ m_is_processing_events = false;
+ m_is_processing_events_restart_necessary = false;
}
//---------[ Block For Response ]-----------------------------------
@@ -96,7 +98,17 @@ int EventListHolder::SNMPProcessPendingEvents()
int status;
pevents_mutex.lock();
+ if (m_is_processing_events)
+ {
+ m_is_processing_events_restart_necessary = true;
+ pevents_mutex.unlock();
+ return status;
+ }
+ m_is_processing_events = true;
+restart_loop:
+ m_is_processing_events_restart_necessary = false;
+ pevents_mutex.unlock();
do
{
do
@@ -119,14 +131,25 @@ int EventListHolder::SNMPProcessPendingEvents()
}
} while (nfound > 0);
+ if (pollfds)
+ {
+ delete [] pollfds;
+ pollfds = 0;
+ }
+
// go through the message queue and resend any messages
// which are past the timeout.
status = m_eventList.DoRetries(now);
+ pevents_mutex.lock();
+ if (m_is_processing_events_restart_necessary)
+ {
+ /* another thread tried to start the loop; rerun it to make sure that no
+ * events have been missed. */
+ goto restart_loop;
+ }
pevents_mutex.unlock();
- if (pollfds) delete [] pollfds;
-
return status;
}
@@ -189,10 +212,20 @@ int EventListHolder::SNMPProcessPendingEvents()
int nfound = 0;
struct timeval fd_timeout;
msec now(0, 0);
- int status;
+ int status = 0;
pevents_mutex.lock();
+ if (m_is_processing_events)
+ {
+ m_is_processing_events_restart_necessary = true;
+ pevents_mutex.unlock();
+ return status;
+ }
+ m_is_processing_events = true;
+restart_loop:
+ m_is_processing_events_restart_necessary = false;
+ pevents_mutex.unlock();
do {
fd_timeout.tv_sec = 0;
fd_timeout.tv_usec = 0;
@@ -209,12 +242,21 @@ int EventListHolder::SNMPProcessPendingEvents()
status = m_eventList.HandleEvents(maxfds, readfds, writefds, exceptfds);
// TM should we do anything with bad status?
}
- } while (nfound > 0);
+ } while (nfound > 0 && !m_eventList.Done());
+ pevents_mutex.lock();
+ if (m_is_processing_events_restart_necessary)
+ {
+ /* another thread tried to start the loop; rerun it to make sure that no
+ * events have been missed. */
+ goto restart_loop;
+ }
+ pevents_mutex.unlock();
// go through the message queue and resend any messages
// which are past the timeout.
status = m_eventList.DoRetries(now);
-
+ pevents_mutex.lock();
+ m_is_processing_events = false;
pevents_mutex.unlock();
return status;
--
1.5.5.6
--azLHFNyN32YCQGCU
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: attachment;
filename="0004-SELECT1-Break-out-of-processPendingEvents.patch"
More information about the AGENTPP
mailing list