Net-Snmp and Multithreading

Net-Snmp and Multithreading

I am writing a C++ SNMP server using a NET-SNMP library. I read the documentation and still got one question. Can multiple threads sharing single snmp session and using it in procedures like snmp_sess_synch_response() simultaneously, or I must init and open new session in each thread?

1 Answer

Well, when I am trying to snmp_sess_synch_response() from two different threads using the same opaque session pointer simultaneously, one of three errors always occures. The first is memory access violation, the second is endless WaitForSingleObject() in both threads and the third is heap allocation error.

I suppose I can treat this as an answer, thus sharing single session between multiple threads is unsafe, because using it in procedures like snmp_sess_synch_response() simultaneously will cause an errors.

P.S. Here is the piece of code of described before:

void* _opaqueSession;
boost::mutex _sessionMtx;

std::shared_ptr<netsnmp_pdu> ReadObjectValue(Oid& objectID)
{
    netsnmp_pdu*    requestPdu = snmp_pdu_create(SNMP_MSG_GET);
    netsnmp_pdu*    response = 0;
    snmp_add_null_var(requestPdu, objectID.GetObjId(), objectID.GetLen());

    void* opaqueSessionCopy;
    {
        //Locks the _opaqueSession, wherever it appears
        boost::mutex::scoped_lock lock(_sessionMtx);
        opaqueSessionCopy = _opaqueSession;
    }

    //Errors here!
    snmp_sess_synch_response(opaqueSessionCopy, requestPdu, &response);

    std::shared_ptr<netsnmp_pdu> result(response);
    return result;
}

void ExecuteThread1()
{
    Oid sysName(".1.3.6.1.2.1.1.5.0");
    try
    {
        while(true)
        {
            boost::thread::interruption_pont();
            ReadObjectValue(sysName);
        }
    }
    catch(...)
    {}
}

void ExecuteThread2()
{
    Oid sysServices(".1.3.6.1.2.1.1.7.0");
    try
    {
        while(true)
        {
            boost::thread::interruption_pont();
            ReadObjectValue(sysServices);
        }
    }
    catch(...)
    {}
}

int main()
{
    std::string community = "public";
    std::string ipAddress = "127.0.0.1";
    snmp_session    session;
    {
        SNMP::snmp_sess_init(&session);

        session.timeout = 500000;
        session.retries = 0;

        session.version = SNMP_VERSION_2c;
        session.remote_port = 161;

        session.peername = (char*)ipAddress.c_str();

        session.community = (u_char*)community.c_str();
        session.community_len = community.size();
    }

    _opaqueSession = snmp_sess_open(&session);

    boost::thread thread1 = boost::thread(&ExecuteThread1);
    boost::thread thread2 = boost::thread(&ExecuteThread2);

    boost::this_thread::sleep(boost::posix_time::seconds::seconds(30));

    thread1.interrupt();
    thread1.join();

    thread2.interrupt();
    thread2.join();

    return 0;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

David Miller
Author

David Miller

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.