If there is a queued update on a particular object's attribute, also queue further 'sync' updates so we don't end up with an inconsistent value. --- src/amf/amfd/imm.cc | 35 +++++++++++++++++++++++++++++------ src/amf/amfd/imm.h | 9 ++++++--- 2 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/src/amf/amfd/imm.cc b/src/amf/amfd/imm.cc index ac7a3cbae..82d2b1329 100644 --- a/src/amf/amfd/imm.cc +++ b/src/amf/amfd/imm.cc @@ -26,6 +26,7 @@ #include <errno.h> #include <cstring> #include <sys/stat.h> +#include <typeinfo> #include <unistd.h> #include <saImmOm.h> @@ -393,7 +394,7 @@ Job *Fifo::peek() { } // -void Fifo::queue(Job *job) { job_.push(job); } +void Fifo::queue(Job *job) { job_.push_back(job); } // Job *Fifo::dequeue() { @@ -403,7 +404,7 @@ Job *Fifo::dequeue() { tmp = 0; } else { tmp = job_.front(); - job_.pop(); + job_.pop_front(); } return tmp; @@ -550,8 +551,27 @@ void Fifo::trim_to_size(const uint32_t size) { TRACE_LEAVE(); } +bool Fifo::pendingImmUpdateOp(const std::string& dn, + const std::string& attribute) { + TRACE_ENTER(); + + for (auto job : job_) { + if (job->getJobType() == JOB_TYPE_IMM && + typeid(*job) == typeid(ImmObjUpdate)) { + ImmObjUpdate *update_job = dynamic_cast<ImmObjUpdate*>(job); + if (update_job->dn == dn && + update_job->attributeName_ == attribute) { + TRACE("Found an existing update on '%s'", dn.c_str()); + return true; + } + } + } + + return false; +} + // -std::queue<Job *> Fifo::job_; +std::deque<Job *> Fifo::job_; // extern struct ImmutilWrapperProfile immutilWrapperProfile; @@ -1756,7 +1776,7 @@ SaAisErrorT avd_saImmOiRtObjectUpdate_sync( const std::string &dn, SaImmAttrNameT attributeName, SaImmValueTypeT attrValueType, void *value, SaImmAttrModificationTypeT modifyType) { - SaAisErrorT rc = SA_AIS_OK; + SaAisErrorT rc = SA_AIS_ERR_TRY_AGAIN; SaImmAttrModificationT_2 attrMod; const SaImmAttrModificationT_2 *attrMods[] = {&attrMod, nullptr}; SaImmAttrValueT attrValues[] = {value}; @@ -1764,7 +1784,10 @@ SaAisErrorT avd_saImmOiRtObjectUpdate_sync( bool isImmReady = isImmServiceReady(avd_cb); TRACE_ENTER2("'%s' %s", dn.c_str(), attributeName); - if (isImmReady == true) { + // Only perform the update if there isn't a pending IMM update involving + // the attribute. Else queue it so the attribute's value remains consistent. + if (isImmReady == true && + Fifo::pendingImmUpdateOp(dn, attribute_name) == false) { attrMod.modType = modifyType; attrMod.modAttr.attrName = attributeName; attrMod.modAttr.attrValuesNumber = 1; @@ -1777,7 +1800,7 @@ SaAisErrorT avd_saImmOiRtObjectUpdate_sync( attributeName, rc); } - if (rc != SA_AIS_OK || isImmReady == false) { + if (rc != SA_AIS_OK) { // Now it will be updated through job queue. avd_saImmOiRtObjectUpdate(dn, attribute_name, attrValueType, value); } diff --git a/src/amf/amfd/imm.h b/src/amf/amfd/imm.h index 1778d27ee..3cfc207cf 100644 --- a/src/amf/amfd/imm.h +++ b/src/amf/amfd/imm.h @@ -26,10 +26,10 @@ #ifndef AMF_AMFD_IMM_H_ #define AMF_AMFD_IMM_H_ +#include <deque> +#include <string> #include "amf/amfd/cb.h" #include "osaf/immutil/immutil.h" -#include <queue> -#include <string> typedef void (*AvdImmOiCcbApplyCallbackT)(CcbUtilOperationData_t *opdata); typedef SaAisErrorT (*AvdImmOiCcbCompletedCallbackT)( @@ -177,8 +177,11 @@ class Fifo { static void trim_to_size(const uint32_t size); + static bool pendingImmUpdateOp(const std::string& dn, + const std::string& attribute); + private: - static std::queue<Job *> job_; + static std::deque<Job *> job_; }; // -- 2.17.1 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel