Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}