HRESULT LightOPCServer::internalRemoveGroup(unsigned groupHandleID, int bForce) { #if 1 HRESULT hr = loOPC_E_INVALIDHANDLE; #else HRESULT hr = loOPC_E_NOTFOUND; #endif unsigned ii; UL_DEBUG((LOG_SR("internalRemoveGroup(%u %s)"), groupHandleID, bForce? "FORCE": "")); WR_lock(&lk_remove); lock_write(); if (ii = by_handle(groupHandleID)) { hr = del(ii, bForce && !(/*se->driver.*/ldFlags & loDf_NOFORCE)) ? OPC_S_INUSE: S_OK; ostatus.dwGroupCount--; } unlock(); lw_rw_unlock(&lk_remove); UL_DEBUG((LOGID, "%!l internalRemoveGroup(%u %s) =", hr, groupHandleID, bForce? "FORCE": "")); return hr; }
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; }
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; }