/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2003 * *This library is free software; you can redistribute it and/or *modify it under the terms of the GNU Lesser General Public *License as published by the Free Software Foundation; either *version 2.1 of the License, or (at your option) any later version. * *This library is distributed in the hope that it will be useful, *but WITHOUT ANY WARRANTY; without even the implied warranty of *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *Lesser General Public License for more details. * *You should have received a copy of the GNU Lesser General Public *License along with this library; if not, write to the Free Software *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "baciPcommonImpl_T.h" #include #include template void baci::CheckDevIOValue::checkValue(T value){} template baci::PcommonImpl::PcommonImpl(const ACE_CString& name, BACIComponent* component_p, DevIO* devIO, bool flagdeldevIO) : CharacteristicModelImpl(name, component_p->getCharacteristicModel()), checkDevIOValue_m(name), property_mp(0), devIO_mp(0), initialization_m(1), destroyed_m(false), reference_mp(CORBA::Object::_nil()), historyStart_m(-1), historyTurnaround_m(false) { ACS_TRACE("baci::PcommonImpl<>::PcommonImpl"); // read static data if (readCharacteristics()==false) { std::string procName="PcommonImpl::PcommonImpl("; procName+=name.c_str(); procName+=",...)"; ACS_LOG(LM_RUNTIME_CONTEXT, "baci::PcommonImpl<>::PcommonImpl", (LM_ERROR, "Failed to read static data for '%s'", name.c_str())); baciErrTypeProperty::PropertyStaticDataExImpl ex(__FILE__,__LINE__,procName.c_str()); ex.addData("Property",name.c_str()); throw ex; } // create BACI property instance (calling default_value() and id() do not work properly!!!) property_mp = new BACIProperty(name.c_str(), this, this, BACIValue(defaultValue_m), component_p); if (property_mp==0) { std::string procName="PcommonImpl::PcommonImpl("; procName+=name.c_str(); procName+=",...)"; baciErrTypeProperty::PropertyCreationExImpl ex(__FILE__,__LINE__,procName.c_str()); ex.addData("Property",name.c_str()); throw ex; } reference_mp = BACI_CORBA::ActivateCORBAObject(this, name.c_str()); if (CORBA::is_nil(reference_mp)==true) { std::string procName="PcommonImpl::PcommonImpl("; procName+=name.c_str(); procName+=",...)"; ACS_LOG(LM_RUNTIME_CONTEXT, "baci::PcommonImpl<>::PcommonImpl", (LM_ERROR, "Failed to activate CORBA object '%s'", name.c_str())); delete property_mp; baciErrTypeProperty::PropertyActivationExImpl ex(__FILE__,__LINE__,procName.c_str()); ex.addData("Property",name.c_str()); throw ex; } ACE_CString_Vector recoveryMonitorsNames = BACIRecoveryManager::getInstance()->getObjectsStartingWith(name.c_str()); if (recoveryMonitorsNames.size()>0) { for (ACE_CString_Vector::iterator i = recoveryMonitorsNames.begin(); i != recoveryMonitorsNames.end(); i++) { //ACS_DEBUG_PARAM("baci::template PcommonImpl<>::template PcommonImpl<>", "Recovering monitor: '%s'.", i->c_str()); new TMonitorImpl (i->c_str(), min_timer_trigger(), BACIValue(0.0/*min_delta_trigger()*/), property_mp); } } if (devIO!=0) { devIO_mp = devIO; deldevIO_m = flagdeldevIO; devIO_mp->m_initialize = initializeDevIO_m; } else { deldevIO_m = true; // value_m = defaultValue_m; devIO_mp = new DevIOMem(value_m); ACS_DEBUG("baci::PcommonImpl<>::PcommonImpl", "No DevIO provided - created DevIOMem."); } } template baci::PcommonImpl::~PcommonImpl() { ACS_TRACE("baci::PcommonImpl<>::~PcommonImpl"); if (deldevIO_m==true) { delete devIO_mp; } // destroy BACI property if (property_mp!=0) { delete property_mp; property_mp = 0; } } template void baci::PcommonImpl::destroy() { ACS_TRACE("baci::PcommonImpl<>::destroy"); if (destroyed_m==true) return; destroyed_m = true; if (CORBA::is_nil(reference_mp)==false) { // this calls delete on this object, so DO NOT use any of its variables anymore if (BACI_CORBA::DestroyCORBAObject(reference_mp)==false) { ACS_LOG(LM_RUNTIME_CONTEXT, "baci::PcommonImpl<>::~PcommonImpl", (LM_ERROR, "Failed to destroy CORBA object '%s'", property_mp->getName())); } else { CORBA::release(reference_mp); _remove_ref(); } } } template void baci::PcommonImpl::publish_now () { publishNow(); } template void baci::PcommonImpl::publishNow() { BACIValue value; CompletionImpl co; ACS::CBDescOut descOut; BACIMonitor* mon_p=0; ACS::TimeInterval time = getTimeStamp(); value.reset(); getValue((BACIProperty *)property_mp, (BACIValue *)&value, co, descOut); property_mp->setLastValue(value); for (int n=0; ngetMonitorCount(); n++) { mon_p = property_mp->getMonitorAt(n); if (mon_p==0 || mon_p->isInDestructionState()==true) continue; bool ok; if(co.isErrorFree()) { co.timeStamp = time; co.type = ACSErr::ACSErrTypeMonitor; co.code = ACSErrTypeMonitor::ACSErrMonitorOnPush; ok = property_mp->getComponent()->dispatchCallback(mon_p->getCallbackID(), value, descOut, co); } else { baciErrTypeProperty::CanNotGetValueCompletion ec(co, __FILE__, __LINE__, "baci::PcommonImpl<>::publishNow"); ACSErrTypeMonitor::ACSErrMonitorErrorCompletion c(ec, __FILE__, __LINE__, "baci::PcommonImpl<>::publishNow"); ok = property_mp->getComponent()->dispatchCallback(mon_p->getCallbackID(), value, descOut, c); } if(ok == false) { ACS_LOG(LM_RUNTIME_CONTEXT, "baci::PcommonImpl<>::publishNow", (LM_ERROR, "Failed to execute monitor callback for property '%s'", property_mp->getName())); } } } /* --------------- [ Action implementator interface ] -------------- */ template baci::ActionRequest baci::PcommonImpl::invokeAction(int function, BACIComponent* component_p, const int &callbackID, const CBDescIn& descIn, BACIValue* value, Completion& completion, CBDescOut& descOut) { ACE_UNUSED_ARG(function); CompletionImpl c; // only one action ActionRequest req = getValueAction(component_p, callbackID, descIn, value, c, descOut); if (c.isErrorFree()) { completion = c; } else { completion = baciErrTypeProperty::InvokeActionErrorCompletion(c, __FILE__, __LINE__, "baci::PcommonImpl<>::invokeAction"); }//if-else return req; }//invokeAction /* -------------- [ Property implementator interface ] -------------- */ template void baci::PcommonImpl::getValue(BACIProperty* property, BACIValue* value, Completion &completion, CBDescOut& descOut) { ACE_UNUSED_ARG(property); ACE_UNUSED_ARG(descOut); TM nval; ACS::Time ts = getTimeStamp(); try { nval = devIO_mp->read(ts); checkDevIOValue_m.checkValue(nval); } catch (ACSErr::ACSbaseExImpl& ex) { completion = baciErrTypeDevIO::ReadErrorCompletion (ex, __FILE__, __LINE__,"PcommonImpl::getValue(...)"); return; } value->setValue( nval ); // if there is no error add value to history // !!! to be done in a loop addValueToHistory(ts, nval); completion = ACSErrTypeOK::ACSErrOKCompletion(); completion.timeStamp = ts; }//getValue /* --------------- [ History support ] --------------- */ template void baci::PcommonImpl::addValueToHistory(ACS::Time time, TM &value) { if ((historyTurnaround_m == false)&& (historyStart_m==(HISTORY_SIZE-1))) historyTurnaround_m = true; historyStart_m = ++historyStart_m % HISTORY_SIZE; historyTime_m[historyStart_m] = time; historyValue_m[historyStart_m] = value; // check memory management } /* -------------- [ Other interfaces ] -------------- */ /// async. get value action implementation template baci::ActionRequest baci::PcommonImpl::getValueAction(BACIComponent* component_p, int callbackID, const CBDescIn& descIn, BACIValue* value, Completion& completion, CBDescOut& descOut) { ACE_UNUSED_ARG(component_p); ACE_UNUSED_ARG(callbackID); ACE_UNUSED_ARG(descIn); CompletionImpl co; getValue(property_mp, value, co, descOut); if (co.isErrorFree()) { completion = co; } else { baciErrTypeProperty::CanNotGetValueCompletion errComp (co, __FILE__, __LINE__, "baci::PcommonImpl<>::getValueAction"); errComp.setProperty((property_mp->getName())); completion = errComp; }//if-else // complete action requesting done invokation, // otherwise return reqInvokeWorking and set descOut.estimated_timeout return reqInvokeDone; }//getValueAction /* ---------------------- [ CORBA interface ] ---------------------- */ template bool baci::PcommonImpl::readCharacteristics() { cdb::DAONode* dao = this->getDAONode(); if (!dao) return false; try { CORBA::String_var str; str = dao->get_string("description"); description_m = str.in(); str = dao->get_string("format"); format_m = str.in(); str = dao->get_string("units"); units_m = str.in(); resolution_m = dao->get_long("resolution"); CORBA::Double dbl; dbl = dao->get_double("default_timer_trig"); dbl = dbl * static_cast(10000000.0); defaultTimerTrig_m = static_cast(dbl); dbl = dao->get_double("min_timer_trig"); dbl = dbl * static_cast(10000000.0); minTimerTrig_m = static_cast(dbl); // NOTE: default_value is always a scalar value str = dao->get_string("default_value"); CDBconverter::convertValue(str.in(), defaultValue_m); str = dao->get_string("initialize_devio"); if(strcmp(str.in(),"false") == 0 || strcmp(str.in(),"0")==0) initializeDevIO_m = false; else initializeDevIO_m = true; return true; } catch (ACSErr::ACSbaseExImpl& ex) { ex.log(); return false; } catch (...) { return false; } } /* ---------------------- [ CORBA interface ] ---------------------- */ template char* baci::PcommonImpl::characteristic_component_name () { return CORBA::string_dup (property_mp->getComponent()->getName()); } template char* baci::PcommonImpl::name () { return CORBA::string_dup (property_mp->getName()); } template CORBA::Boolean baci::PcommonImpl::initialize_devio () { return CORBA::Boolean(initializeDevIO_m); } template char* baci::PcommonImpl::description () { return CORBA::string_dup (description_m.c_str()); } template char* baci::PcommonImpl::format () { return CORBA::string_dup (format_m.c_str()); } template char* baci::PcommonImpl::units () { return CORBA::string_dup (units_m.c_str()); } template ACS::pattern baci::PcommonImpl::resolution () { return resolution_m; } template T baci::PcommonImpl::get_sync (ACSErr::Completion_out c ) { CompletionImpl co; ACS::CBDescOut descOut; BACIValue value(0.0); this->getValue(property_mp, &value, co, descOut); if (co.isErrorFree()) { c = co.returnCompletion(false); } else { baciErrTypeProperty::CanNotGetValueCompletion completion(co, __FILE__, __LINE__, "baci::PcommonImpl<>::get_sync"); completion.setProperty((property_mp->getName())); c = completion.returnCompletion(false); }//if-else // .... or replace with call BACIValue::retn() TM t = value.getValue(static_cast(0)); return CORBAMem::retn(t); }//get_sync template void baci::PcommonImpl::get_async (TCB *cb, const ACS::CBDescIn & desc ) { property_mp->getComponent()->registerAction(BACIValue::mapType(static_cast(0)), cb, desc, this, 0); } template CORBA::Long baci::PcommonImpl::get_history (CORBA::Long n_last_values, TSeq_out vs, ACS::TimeSeq_out ts) { // thread lock needed if (n_last_values < 0) throw CORBA::BAD_PARAM(); CORBA::Long length, first; if (historyTurnaround_m==true) { length = HISTORY_SIZE; first = historyStart_m+1; } else { length = historyStart_m+1; first = 0; } // last n values if (n_last_values > length) n_last_values = length; first = (first+length-n_last_values)%HISTORY_SIZE; if (n_last_values < length) length = n_last_values; vs = new TSeq(length); vs->length(length); ts = new ACS::TimeSeq(length); ts->length(length); for (int i = 0; i < length; i++) { (*vs)[i] = CORBAMem::addToArry(historyValue_m[(first+i)%HISTORY_SIZE]); (*ts)[i] = historyTime_m[(first+i)%HISTORY_SIZE]; } return length; } template TMonitor *baci::PcommonImpl::create_monitor (TCB *cb, const ACS::CBDescIn & desc) { TMonitorImpl* monitor_p = new TMonitorImpl(ACE_CString(property_mp->getName())+"_monitor", cb, desc, default_timer_trigger(), BACIValue::NullValue, min_timer_trigger(), BACIValue(0/*min_delta_trigger()*/), property_mp); if (monitor_p==0) throw CORBA::NO_RESOURCES(); else if (monitor_p->initialization()) { monitor_p->destroy(); throw CORBA::NO_RESOURCES(); } TMonitor* mon_p = TMonitor::_narrow(monitor_p->getCORBAReference()); return mon_p; } template TMonitor* baci::PcommonImpl::create_postponed_monitor (ACS::Time start_time, TCB *cb, const ACS::CBDescIn & desc) { TMonitorImpl* monitor = new TMonitorImpl(ACE_CString(property_mp->getName())+"_monitor", cb, desc, default_timer_trigger(), BACIValue::NullValue, min_timer_trigger(), BACIValue(0/*min_delta_trigger()*/), property_mp, start_time); if (!monitor) throw CORBA::NO_RESOURCES(); else if (monitor->initialization()) { monitor->destroy(); throw CORBA::NO_RESOURCES(); } TMonitor *mon = TMonitor::_narrow(monitor->getCORBAReference()); return mon; } template ACS::TimeInterval baci::PcommonImpl::default_timer_trigger () { return defaultTimerTrig_m; } template ACS::TimeInterval baci::PcommonImpl::min_timer_trigger () { return minTimerTrig_m; } template TS baci::PcommonImpl::default_value () { return CORBAMem::retn(defaultValue_m); } /*___oOo___*/