[AGENT++] Asynchronous interface in SNMP++

Marek Malowidzki malowidz at wil.waw.pl
Tue Feb 17 12:48:55 CET 2004


Hi,

I have had a hard time trying to understand how the async interface is
designed in SNMP++ ;-). What I have observed is the following:
- Probably, as the console example suggests, SNMP++ can only listen on a
single port for traps (CNotifyEventQueue::set_listen_port(trap_port)). Thus,
it is impossible to listen on multiple ports (e.g., 162, 500 and 1200)?
- Any thread can be used to execute callbacks, including the synchronous
ones, which wait for responses  (the callbacks get processed in
EventListHolder::SNMPProcessPendingEvents(), which in turn calls
m_eventList.HandleEvents()). This may be a bit surprising for a programmer.
I do not have an example of a program in which this behavior would cause
bugs but I would expect that synchronous operations will be "atomic" and no
other code will get executed in the meantime. Additionally, since the
callbacks could in turn call subsequent methods on an Snmp object, it (and
the subobjects it uses) must be reentrant (it must be safe for the same
thread to enter a function multiple times). Fortunately, it seems to be ok.
- There is also a puzzle - how exactly the following function is intended to
work?

int CEventList::HandleEvents(const int maxfds, const fd_set &readfds, const
fd_set &writefds, const fd_set &exceptfds) {

 lock();
 CEventListElt *msgEltPtr = m_head.GetNext();
 int status = SNMP_CLASS_SUCCESS;
 while (msgEltPtr){
  if (msgEltPtr->GetEvents()->GetCount()) {
   unlock();
   status = msgEltPtr->GetEvents()->HandleEvents(maxfds, readfds, writefds,
exceptfds);
   lock();
  }
  msgEltPtr = msgEltPtr->GetNext();
 }
 unlock();
 return status;
}

It looks that the check in while() is just some kind of optimization and
that msgEltPtr->GetEvents()->HandleEvents() must be MT-safe in itself. Could
it happen that it will be CNotifyEventQueue::HandleEvents()? This one does
not seem to be locked. Or maybe, it has not been tested in a truly MT
environment?

Summarizing: I think that the synchronous threads should not execute
callbacks. Callbacks should be executed by threads that explicitly enter
event processing loop, e.g. calling something like
snmp.eventListHolder->SNMPProcessEvents().

Of course, I realize that this may be impossible - after all, the library
has a long history... I simply add some opinions and would be grateful for
comments. I think that for SNMP++.NET, the only reasonably choice would be
to execute callbacks using threads from the system thread pool (to
immediately "exit" the callback and not allow the stack to accumulate).

Marek




More information about the AGENTPP mailing list