diff --git a/src/Alarm.cpp b/src/Alarm.cpp index 93180ffeda02f9dc53728303a054fd222566d23f..48a1d4cee4a87166c54dd137108a699bfdaf14d6 100644 --- a/src/Alarm.cpp +++ b/src/Alarm.cpp @@ -607,29 +607,14 @@ void Alarm::init_device() { #if 1 try { - //add_event(i->second, al_ev_it->second); - //TODO:subscribe_event(i->second, ecb, al_ev_it->second); - for (vector<string>::iterator j = al_ev_it->second.begin(); j != al_ev_it->second.end(); j++) - { - vector<event>::iterator k = \ - find(events->v_event.begin(), events->v_event.end(), *j); - if (k == events->v_event.end()) //if not already present - { - string name=*j; - vector<string> context;//TODO - events->add(name, context); - } - } add_event(i->second, al_ev_it->second);//moved after events->add - for (vector<string>::iterator j = al_ev_it->second.begin(); j != al_ev_it->second.end(); j++) + if(i->second.to_be_evaluated) { - vector<event>::iterator k = \ - find(events->v_event.begin(), events->v_event.end(), *j); - if (k == events->v_event.end()) //if not already present - { - string name=*j; - events->start(name); - } + bei_t e; + e.ev_name = ALARM_THREAD_TO_BE_EVAL; + e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); + e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); + evlist.push_back(e); } } catch (string& err) { WARN_STREAM << "Alarm::init_device(): " << err << endl; @@ -667,39 +652,7 @@ void Alarm::init_device() #endif } } - -#if 0 - //now subscribe all events - for (vector<string>::iterator j = evn.begin(); j != evn.end(); j++) - { - vector<event>::iterator k = \ - find(events->v_event.begin(), events->v_event.end(), *j); - if (k != events->v_event.end()) - { - } - } -#endif - - - /* - * update event table with fresh-subscribed event[s] data - */ - - list<bei_t> el; - el = evlist.show(); - - try { - for (list<bei_t>::iterator j = el.begin(); j != el.end(); j++) - { - //cout << "name = " << j->name << "\ttype = " << j->type << endl; - events->update_events(*j); - } - } - catch (string& err) - { - WARN_STREAM << "init_device(): error updating events = " << err << endl; - } set_change_event("alarm",true,false); /* * create alarm processing thread @@ -1165,7 +1118,6 @@ void Alarm::read_AlarmState(Tango::Attribute &attr) { if(it->second.attr_name == attr.get_name()) { - break; } } @@ -1458,35 +1410,16 @@ void Alarm::load(Tango::DevString argin) - +#ifndef _RW_LOCK + alarms.lock(); +#else + alarms.vlock->readerIn(); +#endif alarm_container_t::iterator i = alarms.v_alarm.find(alm.name); if(i != alarms.v_alarm.end()) { try { - //add_event(i->second, al_ev_it->second); - - for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++) - { - vector<event>::iterator k = \ - find(events->v_event.begin(), events->v_event.end(), *j); - if (k == events->v_event.end()) //if not already present - { - string name=*j; - vector<string> context;//TODO - events->add(name, context, UPDATE_PROP, false);//throws exception if already present - } - } add_event(i->second, evn);//moved after events->add - for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++) - { - vector<event>::iterator k = \ - find(events->v_event.begin(), events->v_event.end(), *j); - if (k != events->v_event.end()) //if already present - { - string name=*j; - events->start(name);//throws exception if not found - } - } } catch (string& err) { WARN_STREAM << "Alarm::"<<__func__<<": string exception=" << err << endl; //TODO: handle error @@ -1513,55 +1446,9 @@ void Alarm::load(Tango::DevString argin) catch (Tango::DevFailed &e) { WARN_STREAM << "Alarm::"<<__func__<<": Tango exception=" << e.errors[0].desc << endl; } - } - - - - - - - -#if 0//TODO - try { - //TODO:subscribe_event(alm, ecb, evn); - vector<string> contexts;//TODO - events->add(alm.name, contexts, UPDATE_PROP, false); - } catch (string& err) { - WARN_STREAM << "Alarm::load(): " << err << endl; -#ifndef _RW_LOCK - alarms.lock(); -#else - alarms.vlock->writerIn(); -#endif - alarm_container_t::iterator i = alarms.v_alarm.find(alm.name); //look for alarm just added - if (i != alarms.v_alarm.end()) - alarms.erase(i); //and remove from alarm_table -#ifndef _RW_LOCK - alarms.unlock(); -#else - alarms.vlock->writerOut(); -#endif - alarms.log_alarm_db(TYPE_LOG_DESC_REM, ts, alm.name, "", "", //remove alarm just added - "", 0, "", "", "", "", -1); - Tango::Except::throw_exception( \ - (const char*)"Alarm::load()", \ - (const char*)err.c_str(), \ - (const char*)"Alarm::load()", Tango::ERR); - } - -#endif - - if(alm.cmd_name_a.length() > 0) - { -#ifndef _RW_LOCK - alarms.lock(); -#else - alarms.vlock->readerIn(); -#endif - alarm_container_t::iterator i = alarms.v_alarm.find(alm.name); //look for alarm just added - if (i != alarms.v_alarm.end()) + if(i->second.cmd_name_a.length() > 0) { try { i->second.dp_a = new Tango::DeviceProxy(i->second.cmd_dp_a); @@ -1588,23 +1475,10 @@ void Alarm::load(Tango::DevString argin) err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_a << ", err=" << e.errors[0].desc << ends; WARN_STREAM << "Alarm::load(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); - } + } } -#ifndef _RW_LOCK - alarms.unlock(); -#else - alarms.vlock->readerOut(); -#endif - } - if(alm.cmd_name_n.length() > 0) - { -#ifndef _RW_LOCK - alarms.lock(); -#else - alarms.vlock->readerIn(); -#endif - alarm_container_t::iterator i = alarms.v_alarm.find(alm.name); //look for alarm just added - if (i != alarms.v_alarm.end()) + + if(i->second.cmd_name_n.length() > 0) { try { i->second.dp_n = new Tango::DeviceProxy(i->second.cmd_dp_n); @@ -1633,45 +1507,27 @@ void Alarm::load(Tango::DevString argin) set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } } + DEBUG_STREAM << "Alarm::"<<__func__<<": created command proxy, to_be_evaluated=" << (int)alm.to_be_evaluated << endl; + //TODO: to be moved in subscribe thread after subscription + //if at least one event was already existing, evaluate formula of just added alarm + if(i->second.to_be_evaluated) //TODO: remove this evaluation of the formula that is not necessary + { + DEBUG_STREAM << "Alarm::"<<__func__<<": to_be_evaluated!!" << endl; + bei_t e; + e.ev_name = ALARM_THREAD_TO_BE_EVAL; + e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); + e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); + evlist.push_back(e); + } + } #ifndef _RW_LOCK alarms.unlock(); #else alarms.vlock->readerOut(); #endif - } - - //if at least one event was already existing, evaluate formula of just added alarm - if(alm.to_be_evaluated) //TODO: remove this evaluation of the formula that is not necessary - { - DEBUG_STREAM << "Alarm::load(): Evaluating formula=" << alm.formula << endl; - try { - struct formula_res_t res; - string attr_values; - res = eval_formula(alm.formula_tree, attr_values); - DEBUG_STREAM << "Parsing succeeded of "<< alm.formula << "; result=" << res.value << " quality=" << res.quality << endl; - alarms.update(alm.name, gettime(), res, attr_values, alm.grp2str(), alm.msg, alm.formula); //pass "now" as timestamp in this case - } catch(std::out_of_range& e) - { - ostringstream o; - o << alm.name << ": in formula array index out of range!" << ends; - WARN_STREAM << "Alarm::load(): " << o.str() << endl; - set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); - } catch(string & e) - { - ostringstream o; - o << alm.name << ": in formula err=" << e << ends; - WARN_STREAM << "Alarm::load(): " << o.str() << endl; - set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); - } catch(Tango::DevFailed& e) - { - ostringstream o; - o << alm.name << "error=" << e.errors[0].desc << ends; - WARN_STREAM << "Alarm::load(): " << o.str() << endl; - set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); - } - } +#if 0//TODO prepare_alarm_attr(); try { @@ -1691,6 +1547,7 @@ void Alarm::load(Tango::DevString argin) err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } +#endif /*----- PROTECTED REGION END -----*/ // Alarm::load } @@ -2354,9 +2211,9 @@ void Alarm::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn) alarm_parse al_gr(alm); // Construct Spirit grammar alm.name.clear(); alm.attr_name.clear(); - alm.quality = Tango::ATTR_VALID; - alm.ex_reason.clear(); - alm.ex_desc.clear(); + alm.quality = Tango::ATTR_INVALID; + alm.ex_reason=string("NOT_SUBSCRIBED"); + alm.ex_desc=string("One or more events not subscribed"); alm.ex_origin.clear(); alm.formula.clear(); alm.msg.clear(); @@ -2572,6 +2429,20 @@ void Alarm::add_event(alarm_t& a, vector<string> &evn) throw(string&) /* * get the list of all the events in the formula */ + + + for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++) + { + vector<event>::iterator k = \ + find(events->v_event.begin(), events->v_event.end(), *j); + if (k == events->v_event.end()) //if not already present + { + string name=*j; + vector<string> context;//TODO + events->add(name, context, UPDATE_PROP, false);//throws exception if already present + } + } + for (vector<string>::iterator j = evn.begin(); j != evn.end(); j++) { vector<event>::iterator k = \ find(events->v_event.begin(), events->v_event.end(), *j); @@ -2684,48 +2555,19 @@ void Alarm::add_event(alarm_t& a, vector<string> &evn) throw(string&) } } } //for (vector<string>::iterator j = evn.begin(); ... -} -#if 0 -void Alarm::subscribe_event(alarm_t& a, EventCallBack& ecb, vector<string> &evn) throw(string&) -{ - //now subscribe all events - for (vector<string>::iterator j = evn.begin(); j != evn.end(); j++) - { + + for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++) + { vector<event>::iterator k = \ find(events->v_event.begin(), events->v_event.end(), *j); - if (k != events->v_event.end()) + if (k != events->v_event.end()) //if already present { - if(k->eid == 0) //not subscribed yet - { - try { -#if TANGO_VER < 611 - k->eid = k->dp->subscribe_event(k->attribute, \ - Tango::CHANGE_EVENT, \ - &ecb, k->filter); -#else - k->eid = k->dp->subscribe_event(k->attribute, \ - Tango::CHANGE_EVENT, \ - &ecb, k->filter,true); //stateless subscription (doesn't fail if server not running) -#endif - DEBUG_STREAM << "Alarm::add_event(): subscribed event for '" \ - << k->attribute << "' attribute" << endl; - } catch (...) { - ostringstream o; - o << "Alarm::add_event(): subscribe_event() failed for '" \ - << *j << "'" << ends; - WARN_STREAM << o.str() << endl; - k->pop_alarm(a.name); //remove alarm/formula just added to event - //events->v_event.pop_back(); - events->v_event.erase(k); //remove event just added to event_table - delete k->dp; - k->dp = NULL; - throw o.str(); - } - } - } // if (k != events->v_event.end())/ - } // for + string name=*j; + events->start(name);//throws exception if not found + } + } } -#endif + /* * because called asynchronously by alarm evaluating thread * will use an alarm to report errors @@ -2895,135 +2737,68 @@ void Alarm::do_alarm(bei_t& e) found->err_counter = 0; vector<string>::iterator j = found->m_alarm.begin(); while (j != found->m_alarm.end()) - { - //alarm_container_t::iterator it = alarms.v_alarm.find(j->first); -#ifndef _RW_LOCK - alarms.lock(); -#else - alarms.vlock->readerIn(); -#endif - alarm_container_t::iterator it = alarms.v_alarm.find(*j); - if(it != alarms.v_alarm.end()) - { - string tmpname=it->first; - try { - string attr_values; - res = eval_formula(it->second.formula_tree, attr_values); - DEBUG_STREAM << "Alarm::"<<__func__<<": Evaluation of " << it->second.formula << "; result=" << res.value << " quality=" << res.quality << endl; -#ifndef _RW_LOCK - alarms.unlock(); -#else - alarms.vlock->readerOut(); -#endif - changed = alarms.update(tmpname, found->ts, res, attr_values, it->second.grp2str(), it->second.msg, it->second.formula); //update internal structure and log to db - if(changed) - num_changed++; - Tango::DevBoolean *attr_value = get_AlarmState_data_ptr(it->second.attr_name); - *attr_value = (it->second.stat == S_ALARM); - try - { //DevFailed for push events - if(it->second.ex_reason.length() == 0) - { - timeval now; - gettimeofday(&now, NULL); - push_change_event(it->second.attr_name,(Tango::DevBoolean *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false); - push_archive_event(it->second.attr_name,(Tango::DevBoolean *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false); - } - else - { - Tango::DevErrorList errors(1); - errors.length(1); - errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str()); - errors[0].severity = Tango::ERR; - errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str()); - errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str()); - Tango::DevFailed except(errors); - push_change_event(it->second.attr_name, &except); - push_archive_event(it->second.attr_name, &except); - } - } catch(Tango::DevFailed & ex) - { - WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; - } - } catch(std::out_of_range& ex) - { + { + DEBUG_STREAM << "Alarm::"<<__func__<<": before do_alarm_eval name=" << *j << " ev=" << e.ev_name << endl; + changed = do_alarm_eval(*j, e.ev_name, found->ts); + if(changed) + num_changed++; + j++; + } + + prepare_alarm_attr(); + if(num_changed==0) + return; + if(ds_num == 0) + { + //attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false); + struct timeval now; + gettimeofday(&now,NULL); + push_change_event("alarm",(char**)ds,now,Tango::ATTR_WARNING, ds_num, 0, false); + } + else + //attr.set_value(ds, ds_num, 0, false); + push_change_event("alarm",ds, ds_num, 0, false); + + } +} /* do_alarm() */ + +bool Alarm::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ts) +{ + bool changed = true; + bool eval_err = false; + formula_res_t res; + //alarm_container_t::iterator it = alarms.v_alarm.find(j->first); + DEBUG_STREAM << "Alarm::"<<__func__<<": before lock name=" << alm_name<< " ev=" << ev_name << endl; #ifndef _RW_LOCK - alarms.unlock(); + alarms.lock(); #else - alarms.vlock->readerOut(); + alarms.vlock->readerIn(); #endif - ostringstream o; - o << tmpname << ": in formula array index out of range!" << ends; - WARN_STREAM << "Alarm::"<<__func__<<": " << o.str() << endl; - set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); - try - { //DevFailed for push events - Tango::DevErrorList errors(1); - errors.length(1); - it->second.ex_reason = string("OUT_OF_RANGE"); - it->second.ex_desc = e.ev_name + ": " + o.str(); - it->second.ex_origin = e.ev_name; - errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str()); - errors[0].severity = Tango::ERR; - errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str()); - errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str()); - Tango::DevFailed except(errors); - push_change_event(it->second.attr_name, &except); - push_archive_event(it->second.attr_name, &except); - } catch(Tango::DevFailed & ex) - { - WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; - } - } catch(string & ex) + DEBUG_STREAM << "Alarm::"<<__func__<<": after lock name=" << alm_name<< " ev=" << ev_name << endl; + alarm_container_t::iterator it = alarms.v_alarm.find(alm_name); + if(it != alarms.v_alarm.end()) + { + string tmpname=it->first; + try { + string attr_values; + res = eval_formula(it->second.formula_tree, attr_values); + DEBUG_STREAM << "Alarm::"<<__func__<<": Evaluation of " << it->second.formula << "; result=" << res.value << " quality=" << res.quality << endl; + changed = alarms.update(tmpname, ts, res, attr_values, it->second.grp2str(), it->second.msg, it->second.formula); //update internal structure and log to db + Tango::DevBoolean *attr_value = get_AlarmState_data_ptr(it->second.attr_name); + *attr_value = (it->second.stat == S_ALARM); + try + { //DevFailed for push events + if(it->second.ex_reason.length() == 0) { -#ifndef _RW_LOCK - alarms.unlock(); -#else - alarms.vlock->readerOut(); -#endif - ostringstream o; - o << tmpname << ": in formula err=" << ex << ends; - WARN_STREAM << "Alarm::"<<__func__<<": " << o.str() << endl; - set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); - try - { //DevFailed for push events - Tango::DevErrorList errors(1); - errors.length(1); - it->second.ex_reason = string("FORMULA_ERROR"); - it->second.ex_desc = e.ev_name + ": " + o.str(); - it->second.ex_origin = e.ev_name; - errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str()); - errors[0].severity = Tango::ERR; - errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str()); - errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str()); - Tango::DevFailed except(errors); - push_change_event(it->second.attr_name, &except); - push_archive_event(it->second.attr_name, &except); - } catch(Tango::DevFailed & ex) - { - WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; - } + timeval now; + gettimeofday(&now, NULL); + push_change_event(it->second.attr_name,(Tango::DevBoolean *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false); + push_archive_event(it->second.attr_name,(Tango::DevBoolean *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false); } - } - else - { -#ifndef _RW_LOCK - alarms.unlock(); -#else - alarms.vlock->readerOut(); -#endif - ostringstream o; - //o << j->first << ": not found formula in alarm table" << ends; - o << (*j) << ": not found formula in alarm table" << ends; - WARN_STREAM << "Alarm::"<<__func__<<": " << o.str() << endl; - set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); - try - { //DevFailed for push events + else + { Tango::DevErrorList errors(1); errors.length(1); - it->second.ex_reason = string("NOT_FOUND"); - it->second.ex_desc = e.ev_name + ": " + o.str(); - it->second.ex_origin = e.ev_name; errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str()); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str()); @@ -3031,30 +2806,98 @@ void Alarm::do_alarm(bei_t& e) Tango::DevFailed except(errors); push_change_event(it->second.attr_name, &except); push_archive_event(it->second.attr_name, &except); - } catch(Tango::DevFailed & ex) - { - WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } + } catch(Tango::DevFailed & ex) + { + WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; + } + } catch(std::out_of_range& ex) + { + eval_err = true; + ostringstream o; + o << tmpname << ": in formula array index out of range!" << ends; + WARN_STREAM << "Alarm::"<<__func__<<": " << o.str() << endl; + set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); + try + { //DevFailed for push events + Tango::DevErrorList errors(1); + errors.length(1); + it->second.ex_reason = string("OUT_OF_RANGE"); + it->second.ex_desc = ev_name + ": " + o.str(); + it->second.ex_origin = ev_name; + errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str()); + errors[0].severity = Tango::ERR; + errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str()); + errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str()); + Tango::DevFailed except(errors); + push_change_event(it->second.attr_name, &except); + push_archive_event(it->second.attr_name, &except); + } catch(Tango::DevFailed & ex) + { + WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; + } + } catch(string & ex) + { + eval_err = true; + ostringstream o; + o << tmpname << ": in formula err=" << ex << ends; + WARN_STREAM << "Alarm::"<<__func__<<": " << o.str() << endl; + set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); + try + { //DevFailed for push events + Tango::DevErrorList errors(1); + errors.length(1); + it->second.ex_reason = string("FORMULA_ERROR"); + it->second.ex_desc = ev_name + ": " + o.str(); + it->second.ex_origin = ev_name; + errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str()); + errors[0].severity = Tango::ERR; + errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str()); + errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str()); + Tango::DevFailed except(errors); + push_change_event(it->second.attr_name, &except); + push_archive_event(it->second.attr_name, &except); + } catch(Tango::DevFailed & ex) + { + WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } - j++; } - - prepare_alarm_attr(); - if(num_changed==0) - return; - if(ds_num == 0) + if(!eval_err) + it->second.to_be_evaluated = false; + } + else + { + ostringstream o; + //o << j->first << ": not found formula in alarm table" << ends; + o << (alm_name) << ": not found formula in alarm table" << ends; + WARN_STREAM << "Alarm::"<<__func__<<": " << o.str() << endl; + set_internal_alarm(INTERNAL_ERROR, gettime(), o.str()); + try + { //DevFailed for push events + Tango::DevErrorList errors(1); + errors.length(1); + it->second.ex_reason = string("NOT_FOUND"); + it->second.ex_desc = ev_name + ": " + o.str(); + it->second.ex_origin = ev_name; + errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str()); + errors[0].severity = Tango::ERR; + errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str()); + errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str()); + Tango::DevFailed except(errors); + push_change_event(it->second.attr_name, &except); + push_archive_event(it->second.attr_name, &except); + } catch(Tango::DevFailed & ex) { - //attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false); - struct timeval now; - gettimeofday(&now,NULL); - push_change_event("alarm",(char**)ds,now,Tango::ATTR_WARNING, ds_num, 0, false); + WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } - else - //attr.set_value(ds, ds_num, 0, false); - push_change_event("alarm",ds, ds_num, 0, false); - } -} /* do_alarm() */ +#ifndef _RW_LOCK + alarms.unlock(); +#else + alarms.vlock->readerOut(); +#endif + return changed; +} void Alarm::timer_update() { diff --git a/src/Alarm.h b/src/Alarm.h index 29ec800c722397de3558004d15ebf5fb8960f58f..9bd4f81cbc3e61d71dc00c6af86f058465e1e599 100644 --- a/src/Alarm.h +++ b/src/Alarm.h @@ -301,11 +301,12 @@ friend class alarm_thread; friend class SubscribeThread; friend class event_table; + alarm_table alarms; + protected : - + private: vector<alarm_t> stored; /* property stored alarms (on exit) */ - alarm_table alarms; event_table* events; // event_list evlist; /* producer/consumer events list */ //gcc 4 problem?? // EventCallBack ecb; /* callback handles */ @@ -354,6 +355,7 @@ private: public: void put_signal_property(); void do_alarm(bei_t& e); //public instead of protected for gcc 4 problem?? + bool do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ts); void timer_update(); //public instead of protected for gcc 4 problem?? event_list evlist; /* producer/consumer events list */ //public instead of protected for gcc 4 problem?? bool abortflag; diff --git a/src/alarm-thread.cpp b/src/alarm-thread.cpp index 57d523bb248754008b4b99c96752ef03ca112742..9e00ec3cdbb383161f0bd641ee52e364df90535d 100644 --- a/src/alarm-thread.cpp +++ b/src/alarm-thread.cpp @@ -52,18 +52,69 @@ alarm_thread::~alarm_thread() */ void alarm_thread::run(void *) { + size_t to_be_evaluated = 0; + //int period = 5; //seconds + int awaken = 0; + vector<string> alm_to_be_eval; while (true) { /* * pop_front() will wait() on condition variable */ try { - bei_t e = p_Alarm->evlist.pop_front(); - //DEBUG_STREAM << "alarm_thread::run(): woken up!!!! " << e.name << endl; - if ((e.ev_name == ALARM_THREAD_EXIT) && \ - (e.value[0] == ALARM_THREAD_EXIT_VALUE)) - break; - p_Alarm->do_alarm(e); + if(to_be_evaluated > 0) + { + bool changed = true; + int num_changed = 0; + if(alm_to_be_eval.size() > 0) + { + for(vector<string>::iterator i = alm_to_be_eval.begin(); i != alm_to_be_eval.end(); i++) + { + changed = p_Alarm->do_alarm_eval(*i, "FORCED_EVAL", gettime()); + if(changed) + num_changed++; + } +#if 0 //TODO + prepare_alarm_attr(); + if(num_changed==0) + return; + if(ds_num == 0) + { + //attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false); + struct timeval now; + gettimeofday(&now,NULL); + push_change_event("alarm",(char**)ds,now,Tango::ATTR_WARNING, ds_num, 0, false); + } + else + //attr.set_value(ds, ds_num, 0, false); + push_change_event("alarm",ds, ds_num, 0, false); +#endif + } +#if 0 + alm_to_be_eval = p_Alarm->alarms.to_be_evaluated_list(); + to_be_evaluated = alm_to_be_eval.size(); +#else + to_be_evaluated = 0; +#endif + } + bei_t e; + { + e = p_Alarm->evlist.pop_front(); + //DEBUG_STREAM << "alarm_thread::run(): woken up!!!! " << e.name << endl; + if ((e.ev_name == ALARM_THREAD_EXIT) && \ + (e.value[0] == ALARM_THREAD_EXIT_VALUE)) + { + break; + } + else if ((e.ev_name == ALARM_THREAD_TO_BE_EVAL) && \ + (e.value[0] == ALARM_THREAD_TO_BE_EVAL_VALUE)) + { + alm_to_be_eval = p_Alarm->alarms.to_be_evaluated_list(); + to_be_evaluated = alm_to_be_eval.size(); + continue; + } + p_Alarm->do_alarm(e); + } } catch(omni_thread_fatal& ex) { diff --git a/src/alarm-thread.h b/src/alarm-thread.h index 221cdabff7c97b90cd3dfd2ea615ebd21ec4f6ae..58d40e735d03ffca27f178e634fe0182eb601cf0 100644 --- a/src/alarm-thread.h +++ b/src/alarm-thread.h @@ -25,11 +25,14 @@ #define ALARM_THREAD_EXIT "alarm_thread_exit" #define ALARM_THREAD_EXIT_VALUE -100 +#define ALARM_THREAD_TO_BE_EVAL "to_be_evaluated" +#define ALARM_THREAD_TO_BE_EVAL_VALUE -200 class alarm_thread : public omni_thread { public: alarm_thread(Alarm_ns::Alarm *p); ~alarm_thread(); + //int period; protected: void run(void *); private: diff --git a/src/alarm_table.cpp b/src/alarm_table.cpp index 5c4f47e1be21ccdefddb3fdd79e51b58f274fa29..ba6287f5c4a07b0c8c2fa2543bd6827912606190 100644 --- a/src/alarm_table.cpp +++ b/src/alarm_table.cpp @@ -679,6 +679,50 @@ bool alarm_table::exist(string& s) return false; } +unsigned int alarm_table::to_be_evaluated_num() +{ + unsigned int ret=0; +#ifndef _RW_LOCK + this->lock(); +#else + vlock->readerIn(); +#endif + for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++) + { + if(i->second.to_be_evaluated == true) + ret++; + } + +#ifndef _RW_LOCK + this->unlock(); +#else + vlock->readerOut(); +#endif + return ret; +} + +vector<string> alarm_table::to_be_evaluated_list() +{ + vector<string> ret; +#ifndef _RW_LOCK + this->lock(); +#else + vlock->readerIn(); +#endif + for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++) + { + if(i->second.to_be_evaluated == true) + ret.push_back(i->first); + } + +#ifndef _RW_LOCK + this->unlock(); +#else + vlock->readerOut(); +#endif + return ret; +} + #ifdef _RW_LOCK void alarm_table::new_rwlock() { diff --git a/src/alarm_table.h b/src/alarm_table.h index 818a7e400dad9166334df8e67f431f41e0930d3e..1d96b664712fd13cf9e389959c88eedbe3f94aed 100644 --- a/src/alarm_table.h +++ b/src/alarm_table.h @@ -350,6 +350,8 @@ class alarm_table { bool timer_update(); void erase(alarm_container_t::iterator i); bool exist(string& s); + unsigned int to_be_evaluated_num(); + vector<string> to_be_evaluated_list(); //vector<alarm_t> v_alarm; alarm_container_t v_alarm; #ifdef _RW_LOCK diff --git a/src/event_table.cpp b/src/event_table.cpp index 40a3b63ee58c72aa428ebcc2577b115a2a110089..18b9b6e1e68df9ee129ad575443adfa649caca1b 100644 --- a/src/event_table.cpp +++ b/src/event_table.cpp @@ -176,12 +176,10 @@ event::event(string& s) : name(s) void event::push_alarm(string& n) { m_alarm.push_back(n); - cout << "event::"<<__func__<< ": event="<<name<<" alm="<< n << " size="<< m_alarm.size() << endl; } void event::pop_alarm(string& n) { - cout << "event::"<<__func__<< ": event="<<name<<" alm="<< n << " size="<< m_alarm.size() << endl; vector<string>::iterator it = find(m_alarm.begin(), m_alarm.end(), n); if(it != m_alarm.end()) m_alarm.erase(it); @@ -685,6 +683,7 @@ void event_table::unsubscribe_events() //============================================================================= void event_table::add(string &signame, vector<string> contexts) { + DEBUG_STREAM << "event_table::"<<__func__<< " entering signame=" << signame << endl; add(signame, contexts, NOTHING, false); } //============================================================================= @@ -770,18 +769,7 @@ void event_table::add(string &signame, vector<string> contexts, int to_do, bool if(found && start) { - try - { - Tango::AttributeInfo info; - if(signal->attr) - { - info = signal->attr->get_config(); - } - } - catch (Tango::DevFailed &e) - { - INFO_STREAM <<"event_table::"<<__func__<< " ERROR for " << signame << " in get_config err=" << e.errors[0].desc << endl; - } + } //DEBUG_STREAM <<"event_table::"<< __func__<< " created proxy to " << signame << endl; @@ -849,29 +837,6 @@ void event_table::subscribe_events() } } sig->event_cb = new EventCallBack(static_cast<Alarm_ns::Alarm *>(mydev)); - Tango::AttributeInfo info; - try - { - sig->siglock->writerOut(); - sig->siglock->readerIn(); - info = sig->attr->get_config(); - sig->siglock->readerOut(); - sig->siglock->writerIn(); - } - catch (Tango::DevFailed &e) - { - Tango::Except::print_exception(e); - //sig->siglock->writerOut(); - sig->siglock->readerOut(); - sig->siglock->writerIn(); - sig->event_id = SUB_ERR; - delete sig->event_cb; - sig->ex_reason = e.errors[0].reason; - sig->ex_desc = e.errors[0].desc; - sig->ex_origin = e.errors[0].origin; - sig->siglock->writerOut(); - continue; - } sig->first = true; sig->first_err = true; DEBUG_STREAM << "event_table::"<<__func__<<":Subscribing for " << sig->name << " " << (sig->first ? "FIRST" : "NOT FIRST") << endl; @@ -931,6 +896,7 @@ void event_table::subscribe_events() void event_table::start(string &signame) { + DEBUG_STREAM << "event_table::"<<__func__<< " entering signame=" << signame << endl; ReaderLock lock(veclock); vector<string> contexts; for (unsigned int i=0 ; i<v_event.size() ; i++) @@ -1057,60 +1023,6 @@ void event_table::start_all() } -void event_table::update_events(bei_t &e) throw(string&) -{ - //LOG_STREAM << "event_table::update_events(bei_t &e): Entering..." << endl ; - vector<event>::iterator found = \ - find(v_event.begin(), v_event.end(), e.ev_name); - - if (found == v_event.end()) - { - //try to remove network domain and FQDN - string ev_name_str(e.ev_name); - string::size_type pos_slash = ev_name_str.find("tango://"); - if (pos_slash != string::npos) //FQDN!! - { - //first remove network domain if any - string::size_type pos_dot = ev_name_str.find(".",8); //look for first . after tango:// - string::size_type pos_colon = ev_name_str.find(":",8); //look for first : after tango:// - pos_slash = ev_name_str.find('/',8); //look for first / after tango:// - if(pos_dot < pos_slash && pos_dot != string::npos && pos_colon != string::npos && pos_slash != string::npos) //dot is in the TANGO_HOST part - { - string ev_name_str_no_domain = ev_name_str.substr(0,pos_dot) + ev_name_str.substr(pos_colon); - //LOG_STREAM << __FUNCTION__ << " event "<< e.ev_name << " not found, trying without domain: " << ev_name_str_no_domain << endl; - found = \ - find(v_event.begin(), v_event.end(), ev_name_str_no_domain); - } - if (found == v_event.end() && pos_slash != string::npos) - { - ev_name_str = ev_name_str.substr(pos_slash + 1);//remove FQDN - //LOG_STREAM << __FUNCTION__ << " event "<< e.ev_name << " not found, trying without fqdn: " << ev_name_str << endl; - found = \ - find(v_event.begin(), v_event.end(), ev_name_str); - } - } - if (found == v_event.end()) - { - /* - * shouldn't happen!!! - */ - ostringstream o; - o << "event_table::update_events(): event '" \ - << e.ev_name << "' not found! error=" << e.msg << ends; - ERROR_STREAM << o.str() << endl; - //cerr << o.str() << endl; - throw o.str(); - } - } - - if (found != v_event.end()) - { - found->value = e.value; - found->ts = e.ts; - found->type = e.type; - } -} - //============================================================================= //============================================================================= bool event_table::get_if_stop() diff --git a/src/event_table.h b/src/event_table.h index 6d995f95e595d4a3ef2eefe272e81e0e924d9723..d9beb8e4ae3b247e0938c801c713ba3c43c5a6e1 100644 --- a/src/event_table.h +++ b/src/event_table.h @@ -118,7 +118,7 @@ typedef struct basic_event_info_s { */ class event_list : public omni_mutex { public: - event_list(void): full(this), empty(this) {} + event_list(void): empty(this) {} ~event_list(void) {} void push_back(bei_t& e); const bei_t pop_front(void); @@ -127,8 +127,7 @@ class event_list : public omni_mutex { protected: list<bei_t> l_event; private: - omni_condition full, - empty; + omni_condition empty; }; /* @@ -159,7 +158,6 @@ class event_table : public Tango::TangoMonitor, public Tango::LogAdapter { void unsubscribe_events(); void start(string &signame); void start_all(); - void update_events(bei_t& e) throw(string&); void update_property(); /** * return number of signals to be subscribed