Beispiel #1
0
STDMETHODIMP LightOPCGroup::Write(DWORD dwCount, OPCHANDLE *phServer, VARIANT *pItemValues,
		                  DWORD dwTransactionID, DWORD *pdwCancelID, HRESULT **ppErrors)
{
 HRESULT hr = S_FALSE;
 HRESULT *errs = 0;
 loRequest *rq = 0;
 unsigned items_ok = 0;

 LO_CHECK_STATEz1("AsyncIO2:Write", ppErrors);

 UL_TRACE((LOG_GRH("AsyncIO2:Write(%u)..."), dwCount));

 if (!phServer || !dwCount || !pdwCancelID || !pItemValues)
   { hr = E_INVALIDARG; goto Return; }
 *pdwCancelID = 0;
 if (owner->q_req.metric_overload) { hr = CONNECT_E_ADVISELIMIT; goto Return; }

 errs = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT));
 rq = lo_req_alloc(dwCount, loUPL_AsyncWrite);
 if (!rq || !errs) { hr = E_OUTOFMEMORY; goto Return; }
 loTagPair_init(rq->upl.tagpair, dwCount);
 rq->operation = loRQ_OP_WRITE | loRQ_CONN_DATABACK | loRQ_DEVICE;
 rq->group_key = ServerHandle;
 rq->serv_key = owner->serv_key;
 rq->upl.transaction_id = dwTransactionID;
 rq->upl.rctx = owner->ctxt;

 lock_read();
 rq->upl.rctx.cta.vc_lcid = grLCID;

 if (owner->access_mode & loAM_RDONLY_OP)
   {
    unsigned ii;
    for(ii = 0; ii < dwCount; ii++) errs[ii] = OPC_E_BADRIGHTS;
    goto Unlock;
   }

 if (0 == (advise_present & loRQ_CONN_DATABACK)/*conn_databack*/)
   hr = CONNECT_E_NOCONNECTION;
 else
   {
    unsigned ii;
    loTagPair *tpl = rq->upl.tagpair;
//    HRESULT *errors = rq->upl.errors;
    LightOPCItem *it;
    loTagEntry *tags = owner->se->tags;

    for(ii = 0; ii < dwCount; ii++, pItemValues++)
      if (!(it = by_index(phServer[ii]))) errs[ii] = OPC_E_INVALIDHANDLE;
      else
        {
         loTagEntry *te = &tags[it->tid];

#if 0 != LO_CHECK_RIGHTS
         if (!(OPC_WRITEABLE & te->attr.taRights)) errs[ii] = OPC_E_BADRIGHTS;
         else
#endif
              if (VT_EMPTY == V_VT(pItemValues) || /*) *errors = OPC_E_BADTYPE;
         else if (*/S_OK == (errs[ii] =
                       VariantCopy(&rq->upl.variant[ii], pItemValues)))
           {
            tpl->tpTi = te->attr.taTi;
            tpl->tpRt = te->attr.taRt;
            tpl->tpAP = it->AcPath;
            tpl++;
            rq->upl.opchandle[items_ok++] = it->hClient;
            errs[ii] = S_OK;
           }
        }/* end of for */
   }
Unlock:
 unlock();

 if (items_ok)
   {
    rq->upl.used = items_ok;
    rq->upl.master_err = hr = items_ok == dwCount? S_OK: S_FALSE;
    if (0 == (*pdwCancelID = lo_req_put_async(&owner->q_req, rq)))
      hr = CONNECT_E_ADVISELIMIT;
    rq = 0;
   }

Return:
 if (rq) lo_req_free(rq);

 if (SUCCEEDED(hr))
   {
    if (ppErrors) *ppErrors = errs, errs = 0;
    UL_NOTICE((LOG_GRH("AsyncIO2:Write(%u) = %u -> %x Ok"),
                       dwCount, items_ok, *pdwCancelID));
   }
 else
   {
    UL_INFO((LOG_GRH("AsyncIO2:Write(%u) = %u /%s"),
               dwCount, items_ok, loStrError(hr)));
   }
 if (errs) loComFree(errs);

 LO_FINISH();
 return hr;
}
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 #3
0
STDMETHODIMP LightOPCGroup::Write(DWORD dwCount,
                                  OPCHANDLE  *phServer,
                                  VARIANT *pItemValues,
                                  HRESULT **ppErrors)
{
 HRESULT hr = S_OK;
 HRESULT *err = 0;
 unsigned items_ok = 0;
 loRequest *rq;

 LO_CHECK_STATEz1("SyncIO:Write", ppErrors);
 UL_TRACE((LOG_GRH("SyncIO:Write(%u)..."), dwCount));

 if (!phServer || !pItemValues || !dwCount)
   { hr = E_INVALIDARG; goto Return; }

 err = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT));
 rq = lo_req_alloc(dwCount, loUPL_variant /*| loUPL_errors*/ | loUPL_tagpair);
 if (!rq || !err) { hr = E_OUTOFMEMORY; goto Return; }
 rq->operation = loRQ_OP_WRITE | loRQ_SYNC | loRQ_DEVICE;
 rq->group_key = ServerHandle;
 rq->serv_key = owner->serv_key;
 rq->com_allocated = rq->upl.errors = err;
 loTagPair_init(rq->upl.tagpair, dwCount);
 rq->upl.rctx = owner->ctxt;

 lock_read();
 rq->upl.rctx.cta.vc_lcid = grLCID;

 if (owner->access_mode & loAM_RDONLY_OP)
   {
    unsigned ii;
    for(ii = 0; ii < dwCount; ii++) err[ii] = OPC_E_BADRIGHTS;
   }
 else
   {
    loService *se = owner->se;
    loTagEntry *tags = se->tags;
    loTagPair *tpl = rq->upl.tagpair;
//    HRESULT *errors = rq->upl.errors;
    VARIANT *variant = rq->upl.variant;
    LightOPCItem *it;
    unsigned ii;

    for(ii = 0; ii < dwCount; ii++, tpl++, pItemValues++)
      if (!(it = by_index(phServer[ii]))) err[ii] = OPC_E_INVALIDHANDLE;
      else
        {
         loTagEntry *te = &tags[it->tid];

#if 0 != LO_CHECK_RIGHTS
         if (!(OPC_WRITEABLE & te->attr.taRights)) err[ii] = OPC_E_BADRIGHTS;
         else
#endif
              if (VT_EMPTY == V_VT(pItemValues) ||/*) *errors = OPC_E_BADTYPE;
         else if (*/ S_OK == (err[ii] =
                       VariantCopy(&variant[ii], pItemValues)))
           {
            err[ii] = S_OK;
            tpl->tpTi = te->attr.taTi;
            tpl->tpRt = te->attr.taRt;
            tpl->tpAP = it->AcPath;
            items_ok++;
           }
         else UL_TRACE((LOG_GRH("SyncIO:Write(%u) [ %x / %x ] %s"),
               ii, V_VT(pItemValues), taVTYPE(&te->attr), loStrError(err[ii])));
       }
    rq->upl.used = dwCount;
   }
 unlock();
// rq->upl.used = dwCount;

 if (0 == items_ok)
   {
//    memcpy(err, rq->upl.errors, dwCount * sizeof(*err));
    rq->com_allocated = 0;
    lo_req_free(rq);
    hr = S_FALSE;
   }
 else
   {
    rq->upl.master_err = items_ok == dwCount? S_OK: S_FALSE;
    err = 0;
    if (rq = lo_req_put_sync(&owner->q_req, &owner->q_ret, rq))
      {
       hr = rq->upl.master_err;
//       memcpy(err, rq->upl.errors, dwCount * sizeof(*err));
       err = rq->upl.errors;
       rq->com_allocated = 0;
       lo_req_free(rq);
      }
    else hr = LO_E_SHUTDOWN;
   }

Return:
  if (SUCCEEDED(hr))
   {
    if (ppErrors) *ppErrors = err, err = 0;
//    if (items_ok != dwCount && hr == S_OK) hr = S_FALSE;
    UL_NOTICE((LOG_GRH("SyncIO:Write(%u) = %u Ok"), dwCount, items_ok));
   }
 else
   {
    UL_INFO((LOG_GRH("SyncIO:Write(%u) = %u /%s"),
               dwCount, items_ok, loStrError(hr)));
   }
 if (err) loComFree(err);
 LO_FINISH();
 return hr;
}