loTrid loTridLast(loService *se) /* get the last id of primary cache update. */ { loTrid trid; if (!loSERVICE_OK(se)) return 0; lw_rw_rdlock(&se->lkPrim); trid = se->update_pipe.tstate < 0? 0: se->prim_trid; lw_rw_unlock(&se->lkPrim); return trid; }
static void rio_cache_read(loService *se, loUpdList *upl) { HRESULT mastererr = upl->master_err; HRESULT masterqual = upl->master_qual; HRESULT *errors = upl->errors; WORD *quality = upl->quality; VARIANT *variant = upl->variant; VARTYPE *vartype = upl->vartype; FILETIME *timestamp = upl->timestamp; loTagPair *tpl = upl->tagpair; loTagEntry *tags = se->tags; unsigned ii; unsigned localize_max = 0; unsigned localize_min = 0; lw_rw_rdlock(&se->lkPrim); for(ii = upl->used; ii--; errors++, quality++, variant++, vartype++, timestamp++, tpl++) { if (tpl->tpTi) { HRESULT hr; loTagEntry *te = &tags[tpl->tpTi]; #if 1 == LO_EV_TIMESTAMP if (!IsFILETIME(te->prim.tsTime)) *timestamp = loFT_SUBST(te->prim.tsTime, se->ts_prim); else #endif *timestamp = te->prim.tsTime; *errors = te->prim.tsError; #ifdef VAR_CHANGETYPE *quality = te->prim.tsQuality; hr = VAR_CHANGETYPE(variant, &te->primValue, *vartype); #else loCONV convtype = (loCONV)*quality; *quality = te->prim.tsQuality; switch(convtype/*lo_check_conversion(&te->attr, *vartype)*/) { case loCONV_CHANGE: hr = VARIANTCHANGEt(variant, &te->primValue, upl->rctx.cta, *vartype); break; case loCONV_COPY: hr = VariantCopy(variant, &te->primValue); break; case loCONV_ASSIGN: *variant = te->primValue; #if 1 loTagPair_init(tpl, 1); goto Cont; #else hr = S_OK; break; #endif case loCONV_CONVERT: if (S_OK == (hr = VariantCopy(variant, &te->primValue))) { if (!localize_max) localize_min = quality - upl->quality; localize_max = quality - upl->quality + 1; goto PreserveTP; } break; } loTagPair_init(tpl, 1); PreserveTP: #endif if (S_OK != hr) { LO_E_BADTYPE_QUAL(hr, *errors, *quality); masterqual = S_FALSE; mastererr = S_FALSE; continue; } Cont:; } if (OPC_QUALITY_GOOD != (OPC_QUALITY_MASK & *quality)) masterqual = S_FALSE; if (S_OK != *errors) mastererr = S_FALSE; } #if 2 == LO_EV_TIMESTAMP if (IsFILETIME(*se->ts_prim)) lo_check_ev_timestamp(upl->used, upl->timestamp, se->ts_prim); #endif lw_rw_unlock(&se->lkPrim); if (localize_max) se->driver.ldConvertTags(&upl->rctx.cactx, localize_max - localize_min, upl->tagpair + localize_min, upl->variant + localize_min, upl->quality + localize_min, upl->errors + localize_min, &mastererr, &masterqual, upl->variant + localize_min, upl->vartype + localize_min, upl->rctx.cta.vc_lcid); upl->master_qual = masterqual; /*if (upl->master_err == S_OK)*/ upl->master_err = mastererr; }
HRESULT LightOPCGroup::internalValidateItems(DWORD dwCount, OPCITEMDEF *pItemDefs, loTagId *tid, void **acpath, OPCITEMRESULT **ppResults, HRESULT **ppErrors) { HRESULT hr = S_OK; HRESULT *err = 0; OPCITEMRESULT *ir = 0; DWORD ii; loService *se; loTagEntry *tags; int free_tid = 0, inc_ap = 0, ai_goal = loDAIG_ADDITEM, am_mask; loCallerx cctx; loAA_DECLARE(sizeof(loTagId)); if (!tid) { free_tid = 1; ai_goal = loDAIG_VALIDATE; tid = (loTagId*)loAA_ALLOC(dwCount * sizeof(loTagId)); } if (acpath) inc_ap = 1; UL_TRACE((LOG_GRH("loGroup::intValidateItems(%lu, %p %p %p)"), dwCount, pItemDefs, ppResults, ppErrors)); if (ppResults) *ppResults = 0; if (ppErrors) *ppErrors = 0; if (!dwCount || !pItemDefs || !ppResults) { hr = E_INVALIDARG; goto Return; } cctx = owner->ctxt; se = owner->se; tags = se->tags; err = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT)); ir = (OPCITEMRESULT*)loComAlloc(dwCount * sizeof(OPCITEMRESULT)); if (!err || !ir || !tid) { hr = E_OUTOFMEMORY; goto Return; } memset(ir, 0, dwCount * sizeof(OPCITEMRESULT)); am_mask = owner->access_mode & loAM_RDONLY_ADD? (loOPC_RIGHTS & ~OPC_WRITEABLE): loOPC_RIGHTS; lw_rw_rdlock(&se->lkMgmt); for(ii = 0; ii < dwCount; ii++, acpath += inc_ap) if (tid[ii] = loFindItemID(se, &owner->ctxt.cactx, 1, pItemDefs[ii].szItemID, pItemDefs[ii].szAccessPath, pItemDefs[ii].vtRequestedDataType, ai_goal, acpath, &err[ii])) { loTagAttrib *ta = &tags[tid[ii]].attr; ir[ii].dwAccessRights = am_mask/*loOPC_RIGHTS*/ & ta->taRights; ir[ii].vtCanonicalDataType = taVTYPE(ta); } else hr = S_FALSE; lw_rw_unlock(&se->lkMgmt); lock_read(); cctx.cta.vc_lcid = grLCID; unlock(); for(ii = 0; ii < dwCount; ii++) if (S_OK == err[ii]) { loTagAttrib *ta = &tags[tid[ii]].attr; if (loTF_EMPTY & ta->taFlags) { err[ii] = OPC_E_INVALIDITEMID; tid[ii] = 0; hr = S_FALSE; goto LogErr; } else if ( /*VT_EMPTY != pItemDefs[ii].vtRequestedDataType &&*/ S_OK != (err[ii] = lo_checktype(&cctx, ta, pItemDefs[ii].vtRequestedDataType))) { /*err[ii] = OPC_E_BADTYPE */; tid[ii] = 0; hr = S_FALSE; goto LogErr; } else UL_TRACE((LOG_GR("intValidateItem(%ls)(%ls) = %u"), loWnul(pItemDefs[ii].szItemID), loWnul(pItemDefs[ii].szAccessPath), tid[ii])); } else { LogErr: UL_NOTICE((LOG_GR("intValidateItem(%ls)(%ls) = %s"), loWnul(pItemDefs[ii].szItemID), loWnul(pItemDefs[ii].szAccessPath), loStrError(err[ii]))); } Return: if (free_tid) { loAA_FREE(tid); } if (FAILED(hr)) { UL_TRACE((LOG_GRH("intValidateItems(%lu) = %s"), dwCount, loStrError(hr))); } else { *ppResults = ir, ir = 0; if (ppErrors) *ppErrors = err, err = 0; UL_TRACE((LOG_GRH("intValidateItems(%lu) = %s"), dwCount, loStrError(hr))); } if (ir) loComFree(ir); if (err) loComFree(err); return hr; }