Hello.

I've written a multi-threaded puller for getting a lot of SNMP data. When the application do pulling I see the messages:

_callback_lock already locket in snmp_call_callbacks
netsnmp_assert 1==_locks[major][minor] failed callback.c:126
_callback_lock()

Looking at callback.c I've found a function _callback_lock() very primitive. It does not wait if a lock exists, just returns with the messages above. (Pleas, note a type: locket -> locked).

I've add a simple waiting loop and messages gone. A patch in an attachment. I do no magic with autoconf and includes is not enveloped with #if. May be somebody can do this work?

And I should note, operations with locks as integer array is not atomic at all! So some problems with multi-threads may rise anyway.

--
Sem.
--- snmplib/callback.c.orig     2007-02-05 14:01:43.000000000 +0300
+++ snmplib/callback.c  2008-01-18 19:08:17.000000000 +0300
@@ -38,6 +38,9 @@
 #include <dmalloc.h>
 #endif
 
+#include <sys/socket.h>
+#include <sys/time.h>
+
 #include <net-snmp/types.h>
 #include <net-snmp/output_api.h>
 #include <net-snmp/utilities.h>
@@ -107,6 +110,9 @@
 NETSNMP_STATIC_INLINE int
 _callback_lock(int major, int minor, const char* warn, int assert)
 {
+    int n=0;
+    struct timeval lock_time = { 0, 1000 };
+
 #ifdef NETSNMP_PARANOID_LEVEL_HIGH
     if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
         netsnmp_assert("bad callback id");
@@ -119,18 +125,23 @@
                 types[major], (SNMP_CALLBACK_LIBRARY == major) ?
                 SNMP_STRORNULL(lib[minor]) : "null"));
 #endif
-    if (CALLBACK_LOCK(major,minor) > 1)
+    while (CALLBACK_LOCK_COUNT(major,minor) >= 1 && ++n < 100)
+       select(0, NULL, NULL, NULL, &lock_time);
+
+    if(n >= 100)
         {
         if (NULL != warn)
             snmp_log(LOG_WARNING,
-                     "_callback_lock already locket in %s\n", warn);
-        if (assert)
-            netsnmp_assert(1==CALLBACK_LOCK_COUNT(major,minor));
+                     "lock in _callback_lock sleeps more than 100 microseconds 
in %s\n", warn);
+/*        if (assert)
+            netsnmp_assert(1==CALLBACK_LOCK_COUNT(major,minor));*/
         
         return 1;
     }
-    else
+    else {
+       CALLBACK_LOCK(major,minor);
         return 0;
+    }
     
 }
 
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to