//-------------------------------------------------------- Tango::DevShort *BaseDevice::get_dynShortArrayAttr_data_ptr(string &name) { map<string,Tango::DevShort *>::iterator ite; if ((ite=dynShortArrayAttr_data.find(name))==dynShortArrayAttr_data.end()) { TangoSys_OMemStream tms; tms << "Dynamic attribute " << name << " has not been created"; Tango::Except::throw_exception( (const char *)"ATTRIBUTE_NOT_FOUND", tms.str().c_str(), (const char *)"BaseDevice::get_dynShortArrayAttr_data_ptr()"); } return ite->second; }
void ZmqEventSupplier::init_event_cptr(string &event_name) { map<string,unsigned int>::iterator pos; pos = event_cptr.find(event_name); if (pos == event_cptr.end()) { if (event_cptr.insert(make_pair(event_name,0)).second == false) { TangoSys_OMemStream o; o << "Can't insert event counter for event "; o << event_name << " in EventSupplier instance" << ends; Except::throw_exception((const char *)"DServer_Events", o.str(), (const char *)"ZmqEventSupplier::init_event_cptr"); } } }
void ZmqEventSupplier::push_heartbeat_event() { time_t delta_time; time_t now_time; // // Heartbeat - check wether a heartbeat event has been sent recently // if not then send it. A heartbeat contains no data, it is used by the // consumer to know that the supplier is still alive. // Tango::Util *tg = Tango::Util::instance(); DServer *adm_dev = tg->get_dserver_device(); now_time = time(NULL); delta_time = now_time - adm_dev->last_heartbeat_zmq; cout3 << "ZmqEventSupplier::push_heartbeat_event(): delta time since last heartbeat " << delta_time << endl; if (heartbeat_name_init == false) { // // Build heartbeat name // This is something like // tango://host:port/dserver/exec_name/inst_name.heartbeat when using DB // tango://host:port/dserver/exec_name/inst_name#dbase=no.heartbeat when using file as database // heartbeat_event_name = heartbeat_event_name + adm_dev->get_full_name(); if (Util::_FileDb == true) heartbeat_event_name = heartbeat_event_name + MODIFIER_DBASE_NO; heartbeat_event_name = heartbeat_event_name + ".heartbeat"; heartbeat_name_init = true; } // // We here compare delta_time to 8 and not to 10. // This is necessary because, sometimes the polling thread is some // milli second in advance. The computation here is done in seconds // So, if the polling thread is in advance, delta_time computed in // seconds will be 9 even if in reality it is 9,9 // if (delta_time >= 8) { int nb_event = 1; cout3 << "ZmqEventSupplier::push_heartbeat_event(): detected heartbeat event for " << heartbeat_event_name << endl; cout3 << "ZmqEventSupplier::push_heartbeat_event(): delta _time " << delta_time << endl; if (double_send_heartbeat == true) { nb_event = 2; double_send_heartbeat = false; } while (nb_event != 0) { // // Create zmq message // zmq::message_t name_mess(heartbeat_event_name.size()); memcpy(name_mess.data(),(void *)heartbeat_event_name.data(),heartbeat_event_name.size()); bool endian_mess_sent = false; bool call_mess_sent = false; try { // // For debug and logging purposes // if (nb_event == 1) { if (omniORB::trace(20)) { omniORB::logger log; log << "ZMQ: Pushing some data" << '\n'; } if (omniORB::trace(30)) { { omniORB::logger log; log << "ZMQ: Event name" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)name_mess.data(),name_mess.size()); { omniORB::logger log; log << "ZMQ: Endianess" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)endian_mess.data(),endian_mess.size()); { omniORB::logger log; log << "ZMQ: Call info" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)heartbeat_call_mess.data(),heartbeat_call_mess.size()); } } // // Push the event // adm_dev->last_heartbeat_zmq = now_time; heartbeat_pub_sock->send(name_mess,ZMQ_SNDMORE); heartbeat_pub_sock->send(endian_mess,ZMQ_SNDMORE); endian_mess_sent = true; heartbeat_pub_sock->send(heartbeat_call_mess,0); call_mess_sent = true; // // For reference counting on zmq messages which do not have a local scope // endian_mess.copy(&endian_mess_2); heartbeat_call_mess.copy(&heartbeat_call_mess_2); nb_event--; } catch(...) { cout3 << "ZmqEventSupplier::push_heartbeat_event() failed !\n"; if (endian_mess_sent == true) endian_mess.copy(&endian_mess_2); if (call_mess_sent == true) heartbeat_call_mess.copy(&heartbeat_call_mess_2); TangoSys_OMemStream o; o << "Can't push ZMQ heartbeat event for event "; o << heartbeat_event_name; if (zmq_errno() != 0) o << "\nZmq error: " << zmq_strerror(zmq_errno()) << ends; else o << ends; Except::throw_exception((const char *)"DServer_Events", o.str(), (const char *)"ZmqEventSupplier::push_heartbeat_event"); } } } }
void ZmqEventSupplier::create_mcast_socket(string &mcast_data,int rate,McastSocketPub &ms) { // // Create the Publisher socket for real events and bind it // If the user has specified one IP address on the command line, // re-use it in the endpoint // ms.pub_socket = new zmq::socket_t(zmq_context,ZMQ_PUB); ms.endpoint = MCAST_PROT; if (ip_specified == true) { ms.endpoint = ms.endpoint + user_ip + ';'; } else { ApiUtil *au = ApiUtil::instance(); vector<string> adrs; au->get_ip_from_if(adrs); for (unsigned int i = 0;i < adrs.size();++i) { if (adrs[i].find("127.") == 0) continue; ms.endpoint = ms.endpoint + adrs[i] + ';'; break; } } ms.endpoint = ms.endpoint + mcast_data; int linger = 0; ms.pub_socket->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); // // Change multicast hops // Tango::Util *tg = Tango::Util::instance(); DServer *admin_dev = tg->get_dserver_device(); int nb_hops = admin_dev->mcast_hops; ms.pub_socket->setsockopt(ZMQ_MULTICAST_HOPS,&nb_hops,sizeof(nb_hops)); // // Change PGM rate to default value (80 Mbits/sec) or to user defined value // int local_rate = rate; ms.pub_socket->setsockopt(ZMQ_RATE,&local_rate,sizeof(local_rate)); // // Bind the publisher socket to the specified port // if (zmq_bind(*(ms.pub_socket),ms.endpoint.c_str()) != 0) { TangoSys_OMemStream o; o << "Can't bind ZMQ socket with endpoint "; o << ms.endpoint; o << "\nZmq error: " << zmq_strerror(zmq_errno()) << ends; Except::throw_exception((const char *)"DServer_Events", o.str(), (const char *)"ZmqEventSupplier::create_mcast_event_socket"); } // // The connection string returned to client does not need the host IP at all // ms.endpoint = MCAST_PROT + mcast_data; }
void ZmqEventSupplier::create_mcast_event_socket(string &mcast_data,string &ev_name,int rate,bool local_call) { map<string,McastSocketPub>::iterator ite; // // If the event is already in the mcast event map, check if it is // already used by local clients // if ((ite = event_mcast.find(ev_name)) != event_mcast.end()) { if (local_call == true) { if (ite->second.local_client == false) { create_event_socket(); ite->second.local_client = true; } } else { if (ite->second.local_client == true) { create_mcast_socket(mcast_data,rate,ite->second); } } } else { // // New mcast event // McastSocketPub ms; if (local_call == true) { create_event_socket(); ms.pub_socket = NULL; ms.local_client = true; } else { create_mcast_socket(mcast_data,rate,ms); ms.local_client = false; } // // Insert element in map // if (event_mcast.insert(make_pair(ev_name,ms)).second == false) { TangoSys_OMemStream o; o << "Can't insert multicast transport parameter for event "; o << ev_name << " in EventSupplier instance" << ends; Except::throw_exception((const char *)"DServer_Events", o.str(), (const char *)"ZmqEventSupplier::create_mcast_event_socket"); } } }