How to run c++ net-snmp code asynchronous?

930 Views Asked by At

I need to send snmp requests to many objects asynhronous. My sipmlified c++ code:

struct measure
{
   int ac;
   float dc;
}

class Sensor()
{
private:
   char *object;
   char *ip;
   mutex *mut;
   vector <measure> mqueue;
public:
   Sensor(char *object, char *ip, std::mutex& mut)   
   {
      this->object=object;
      this->ip=ip;
      this->mut=&mut;
   }


   measure getSnmp()
   {
      measure results;

      struct snmp_session session;
      struct snmp_session *sess_handle;
      struct snmp_pdu *pdu;
      struct snmp_pdu *response;

      oid id_oid[MAX_OID_LEN];
      oid serial_oid[MAX_OID_LEN];

      size_t id_len = MAX_OID_LEN;
      size_t serial_len = MAX_OID_LEN;

      struct variable_list *vars;

      int status=1;

      snmp_sess_init(&session);
      session.peername=this->ip;
      session.version=SNMP_VERSION_1;

      session.community="public";
      session.community_len=strlen((char*)session.community);

      sess_handle=snmp_open(&session);      

      pdu=snmp_pdu_create(SNMP_MSG_GET);

      read_objid(OID1, id_oid, &id_len);
      snmp_add_null_var(pdu, id_oid, id_len);       
      read_objid(OID2, id_oid, &id_len);
      snmp_add_null_var(pdu, id_oid, id_len);
      status=snmp_synch_response(sess_handle, pdu, &response);
      if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)      
      {
         vars = response->variables;
         results.ac=(int)boost::lexical_cast<float>(vars->val.string);
         vars = vars->next_variable;
         results.dc=boost::lexical_cast<float>(vars->val.string);
      }
      else
      {
         results.ac=-1.0;
         results.dc=-1.0;
      }
      if(response)
         snmp_free_pdu(response);
      snmp_close(sess_handle);
      return results;
   }

   void addMeasure(measure results)
   {
      this->mqueue.push_back(results);
      while(this->mqueue.size()>720)
      {
         this->mqueue.erase(this->mqueue.begin());
      }   
   } 


   void operate()
   {
      measure results;
      while(true)
      {
         this->mut->lock();
         results=this->getSnmp();
         this->mut->unlock();
      }
      this->addMeasure(results);
      std::this_thread::sleep_for(std::chrono::seconds(60));
   }

}

int main()
{
   mutex mmm;
   std::vector<Sensor> sensors;  

   /* fill vector sensors from db */

   for(int i=0; i<sensors.size(); i++)
   {
      t[i]=std::thread(&Sensor::operate, &sensors[i]);
      t[i].detach();
   }

   /* http-server thread join */

   return 0;

}

I used mutex to run net-snmp part in getSnmp function synchronously. Without mutex program fails with "Segmentation fault" if vector sensors has more than one element. I understand that this way is absolutly not asynchronous. How to run it without mutex?

0

There are 0 best solutions below