[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