lw_thrrettype loUpdatePipe(void *vse) { loService *se = (loService *)vse; if (!loIS_VALID(se)) { UL_ERROR((LOGID, "loUpdatePipe() prematurely terminated")); lw_RETURN; } UL_TRACE((LOGID, "loUpdatePipe() started...")); loThrControl_accept(&se->update_pipe); lw_mutex_lock(&se->update_pipe.lk); for(;; lw_conds_wait(&se->update_pipe.cond, &se->update_pipe.lk)) if (0 != se->update_pipe.tstate) { if (0 > se->update_pipe.tstate) break; /* terminate thread */ lw_mutex_unlock(&se->update_pipe.lk); lw_rw_wrlock(&se->lkPrim); lw_mutex_lock(&se->update_pipe.lk); if (0 > se->update_pipe.tstate) { lw_rw_unlock(&se->lkPrim); break; }/* terminate thread */ { /* do actual update here */ unsigned ii = se->lastused; loTagEntry *te = se->tags; loTagValue *ts = se->secondary; loTrid prim_changed = se->sec_trid; while(ii--) { te++; ts++; if (ts->tvTi) { if (ts->tvTi == loCH_TIMESTAMP) te->prim.tsTime = ts->tvState.tsTime; else { te->primChanged = prim_changed; te->prim = ts->tvState; #if LO_KEEP_OLD_CACHE { HRESULT hr; if (S_OK != (hr = VariantCopy(&te->primValue, &ts->tvValue))) { LO_E_BADTYPE_QUAL(hr, te->prim.tsError, te->prim.tsQuality); UL_WARNING((LOGID, "%!l loUpdatePipe(VariantCopy())", hr)); } } #else VariantClear(&te->primValue); te->primValue = ts->tvValue; VARIANTINIT(&ts->tvValue); #endif } ts->tvTi = 0; } } } se->prim_trid = se->sec_trid; #if 0 != LO_EV_TIMESTAMP if (se->ts_prim != se->ts_sec) { freeX(se->ts_prim); se->ts_prim = se->ts_sec; } memcpy(se->ts_prim, se->ts_prim + se->ts_size, se->ts_size * sizeof(FILETIME)); #endif lw_rw_unlock(&se->lkPrim); se->update_pipe.tstate = 0; lw_condb_broadcast(&se->lkTridWait); } loThrControl_finish(&se->update_pipe); lw_mutex_unlock(&se->update_pipe.lk); UL_NOTICE((LOGID, "loUpdatePipe() finished")); lw_RETURN; }
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; }
loTrid loCacheUpdate(loService *se, unsigned count, loTagValue taglist[], FILETIME *timestamp) { unsigned ii; loTagValue *ts; #if 0 != LO_FILL_TIMESTAMP FILETIME ft; #endif // UL_DEBUG((LOGID, "loCacheUpdate(%p %u %p)", se, count, taglist)); if (!loSERVICE_OK(se)) return 0;//EBADF; /*ERROR:EARG*/ if (!timestamp && (0 >= count || !taglist)) return 0; #if 0 != LO_FILL_TIMESTAMP #if 1 == LO_FILL_TIMESTAMP se->driver.ldCurrentTime(&se->cactx, &ft); #else if (timestamp) ft = *timestamp; else memset(&ft, 0, sizeof(ft)); #endif #endif if (!(ts = loCacheLock(se))) { UL_INFO((LOGID, "loCacheUpdate() lock failed")); return 0;//-1; /*ERROR:out-of-service*/ } for(ii = 0; ii < count; ii++, taglist++) { loTagId ti; if (0 == (ti = taglist->tvTi)) continue; else if (ti < 1 || ti > se->lastused/*tag_count*/) { /*rv = -1;*//*ERROR:BAD ti*/ UL_INFO((LOGID, "loCacheUpdate(BAD ti:%u)", ii)); continue; } else { HRESULT hr; loTagValue *tv = &ts[ti]; tv->tvState = taglist->tvState; #if 0 != LO_FILL_TIMESTAMP if (!IsFILETIME(tv->tvState.tsTime)) tv->tvState.tsTime = ft; #endif /* hr = (V_ISBYREF(&taglist->tvValue)? VariantCopyInd(&tv->tvValue, &taglist->tvValue): VariantCopy(&tv->tvValue, &taglist->tvValue)); */ hr = VariantCopy(&tv->tvValue, &taglist->tvValue); if (S_OK != hr) { LO_E_BADTYPE_QUAL(hr, tv->tvState.tsError, tv->tvState.tsQuality); /*rv = -1;*//*ERROR:BAD VALUE*/ UL_WARNING((LOGID, "%!l loCacheUpdate(VariantCopy())", hr)); } tv->tvTi = ti; } } return loCacheUnlock(se, timestamp); /* return rv; */ }