Пример #1
0
int loSetStateW(loService *se, loClient *cli, int oper, int state, const loWchar *reason)
{
    int rv = EBADF;

    if (oper & ~(loOP_OPERATE | loOP_STOP | loOP_DISCONNECT | loOP_SHUTDOWN | loOP_DESTROY))
        return EINVAL;
    if (loSERVICE_OK(se))
    {
        lw_mutex_lock(&se->lkList);
        if (!se->shutdown)
        {
            LightOPCServer *los;
            rv = ENOENT;
            for(los = (LightOPCServer*)se->servlist; los; los = los->serv_next)
                if (!cli || los == cli)
                {
                    los->set_state(oper, state, reason);
                    rv = 0;
                }
        }
        lw_mutex_unlock(&se->lkList);
    }

    return rv;
}
Пример #2
0
loTagValue *loCacheLock(loService *se)
{
 if (loSERVICE_OK(se))
   {
    lw_mutex_lock(&se->update_pipe.lk);
    if (se->update_pipe.tstate >= 0) return se->secondary;
    lw_mutex_unlock(&se->update_pipe.lk);
   }
 return 0;
}
Пример #3
0
loTrid loCacheUnlock(loService *se, FILETIME *timestamp)
{
 if (!loIS_VALID(se)) return 0;
 if (se->update_pipe.tstate >= 0) se->update_pipe.tstate = 1;
 if (se->sec_trid == se->prim_trid) ++se->sec_trid;
 if (loTRIDmin > se->sec_trid) se->sec_trid = loTRIDmin;
#if 0 != LO_EV_TIMESTAMP
 if (timestamp) se->ts_sec[se->ts_size] = *timestamp;
#endif
 lw_conds_signal(&se->update_pipe.cond);
 lw_mutex_unlock(&se->update_pipe.lk);
 return se->sec_trid;
}
Пример #4
0
int loGetBandwidth(loService *se, loClient *cli)
{
    int rv = -1;
    LightOPCServer *ls;
    loMilliSec bandw_time, curtime;

    if (!loSERVICE_OK(se)) return -1;
    curtime = lo_millisec();
    lw_mutex_lock(&se->lkList);
    ls = se->servlist;
    if (cli)
    {
        while(ls && ls != cli) ls = ls->serv_next;
        if (ls)
        {
            lw_mutex_lock(&ls->async.lk);
            rv = (int)ls->ostatus.dwBandWidth;
            bandw_time = ls->bandwidth_time;
            lw_mutex_unlock(&ls->async.lk);
            rv = (int)lo_adjust_bandwidth(rv, bandw_time, curtime);
        }
    }
    else
        while(ls)
        {
            int tv;
            lw_mutex_lock(&ls->async.lk);
            tv = (int)ls->ostatus.dwBandWidth;
            bandw_time = ls->bandwidth_time;
            lw_mutex_unlock(&ls->async.lk);
            tv = (int)lo_adjust_bandwidth(tv, bandw_time, curtime);
            if (tv > rv) rv = tv;
            ls = ls->serv_next;
        }
    lw_mutex_unlock(&se->lkList);
    return rv < 0? 0: rv;
}
Пример #5
0
int loServiceDestroy(loService *se)
{
    UL_TRACE((LOGID, "loServiceDestroy(%p)...", se));

    if (!loIS_VALID(se)) return EBADF;
    if ((se->initphase & (ifLKLIST|ifLKSEC)) == (ifLKLIST|ifLKSEC))
    {
        lw_mutex_lock(&se->lkList);
        if (se->shutdown)
        {
            lw_mutex_unlock(&se->lkList);
            UL_ERROR((LOGID, "loServiceDestroy(%p) shutdown started again", se));
            return EBADF;
        }
        if (se->servlist)
        {
            LightOPCServer *los = (LightOPCServer*)se->servlist;
            se->shutdown = 1;
            while(los)
            {
                los->set_state(loOP_SHUTDOWN|loOP_STOP|loOP_DISCONNECT, 0, 0);
                los = los->serv_next;
            }
            lw_mutex_unlock(&se->lkList);
            UL_NOTICE((LOGID, "loServiceDestroy(%p) shutdown started", se));
            return EBUSY;
        }
        se->shutdown = -1;
        lw_mutex_unlock(&se->lkList);
#if 0
        loThrControl_stop(&se->update_pipe);
#endif
        lw_condb_broadcast_continious(&se->lkTridWait, &se->update_pipe.lk);
    }
    return loInternalServiceDestroy(se);
}
Пример #6
0
int loTridWait(loService *se, loTrid trid) /* wait for data be moved to primary cache. */
{
 int rv = 0;
 if (!loSERVICE_OK(se)) return -1;
 if (!loIsTRID(trid)) return -1;
 lw_mutex_lock(&se->update_pipe.lk);
 for(;; lw_condb_wait(&se->lkTridWait, &se->update_pipe.lk))
   {
    unsigned trdif = se->prim_trid - trid;
#if 1
    if (trdif < ~trdif) { rv = 1; break; }
#elif 1
    if (trdif <= -trdif) { rv = 1; break; }
#else
    if ((int)trdif >= -(int)trdif) { rv = 1; break; }
#endif
    if (se->update_pipe.tstate < 0 || se->shutdown) break;
   }
 lw_mutex_unlock(&se->update_pipe.lk);
 return rv;
}
Пример #7
0
int lo_rio_requests(LightOPCServer *cli)
{
 loRequest *rq;
 loService *se = cli->se;

 while(rq = cli->q_req.req)
   {
    int operation = rq->operation;
    loTrid trid;

    if (loThrControl_outof01(&cli->async)) return -1;
    cli->q_req.req = rq->rq_next;
    if (operation & loRQ_OPER_IO)
      cli->q_req.metric_overload = 0;
    lw_mutex_unlock(&cli->async.lk);

    UL_TRACE((LOGID, "REQUEST Retreived %x / %x", operation, rq->upl.trqid));

    switch(operation & (loRQ_OPER_MASK | loRQ_DEVICE))
      {
#if LO_USE_BOTHMODEL
    case loRQ_OP_ADVISE:
      {
       void *aconn = 0;
       if (rq->conn_stream)
         {
          rq->upl.master_err = CoGetInterfaceAndReleaseStream(rq->conn_stream,
                                                             *rq->conn_iface,
                                                              &aconn);
          rq->conn_stream = 0;
         }
       else rq->upl.master_err = S_OK;
       if (SUCCEEDED(rq->upl.master_err))
         rq->upl.master_err = cli->sync_advise(operation, &aconn, rq->group_key);
       if (aconn) ((IUnknown*)aconn)->Release();
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else lo_req_free(rq);
      }
       break;

    case loRQ_OP_REMOVE_GROUP:
       rq->upl.master_err = cli->internalRemoveGroup(rq->group_key,
                                  operation & loRQ_OF_REMOVE_FORCE);
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else lo_req_free(rq);
       break;
#endif
/********************************************/

    case loRQ_OP_WRITE|loRQ_DEVICE:
       if (se->driver.ldWriteTags)
         {
          int rv;
          loLOCK_DRIVER(se);
          rv = se->driver.ldWriteTags(&rq->upl.rctx.cactx, rq->upl.used,
                                      rq->upl.tagpair, rq->upl.variant,
                                      rq->upl.errors, &rq->upl.master_err,
                                      rq->upl.rctx.cta.vc_lcid);
          loUNLOCK_DRIVER(se);
          if (rv == loDW_ALLDONE)
            {
             if (operation & loRQ_SYNC)
               lo_req_put_bcast(&cli->q_ret, rq);
             else
               {
                cli->send_callback(0, rq->group_key, &rq->upl, operation);
                lo_req_free(rq);
               }
             break;
            }
         }
// UL_ERROR((LOGID, "DEV WRITE failed"));
    case loRQ_OP_WRITE:
       rio_cache_write(se, &rq->upl);
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else
         {
          cli->send_callback(0, rq->group_key, &rq->upl, operation);
          lo_req_free(rq);
         }
       break;
/********************************************/

    case loRQ_OP_READ|loRQ_DEVICE:
       if (se->driver.ldReadTags /*&&
           !(cli->access_mode & (loAM_NOREAD_DEV |
                                 loAM_ERREAD_DEV))*/)
         {
          HRESULT m_err = rq->upl.master_err,
                  m_qual = rq->upl.master_qual;
          loLOCK_DRIVER(se);
          trid = se->driver.ldReadTags(&rq->upl.rctx.cactx, rq->upl.used,
                                       rq->upl.tagpair, rq->upl.variant, rq->upl.quality,
                                       rq->upl.timestamp, rq->upl.errors, &m_err, &m_qual,
                                       rq->upl.vartype, rq->upl.rctx.cta.vc_lcid);
          loUNLOCK_DRIVER(se);
          if (loDR_STORED == trid)
            {
             if (S_OK != m_err) rq->upl.master_err = S_FALSE;
             if (S_OK != m_qual) rq->upl.master_qual = S_FALSE;
             if (operation & loRQ_SYNC)
               lo_req_put_bcast(&cli->q_ret, rq);
             else
               {
                cli->send_callback(0, rq->group_key, &rq->upl, operation);
                lo_req_free(rq);
               }
             break;
            }
          else if (loDR_CACHED != trid) loTridWait(se, trid);
         }
    case loRQ_OP_READ:
       rio_cache_read(se, &rq->upl);
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else
         {
          cli->send_callback(0, rq->group_key, &rq->upl, operation);
          lo_req_free(rq);
         }
       break;
/********************************************/

    case loRQ_OP_REFRESH|loRQ_DEVICE:
       if (se->driver.ldReadTags /*&&
          !(cli->access_mode & (loAM_NOREAD_DEV |
                                loAM_ERREAD_DEV))*/)
         {
          loLOCK_DRIVER(se);
          trid = se->driver.ldReadTags(&rq->upl.rctx.cactx, 
                                       rq->upl.used, rq->upl.tagpair,
                                       0, 0, 0, 0, 0, 0, 0, 0
                                     /*rq->upl.variant, rq->upl.quality,
                                       rq->upl.timestamp, rq->upl.errors,
                                       &master_err, &master_qual,
                                       rq->upl.vartype, rq->upl.gr_lcid*/);
          loUNLOCK_DRIVER(se);
          if (loDR_CACHED != trid) loTridWait(se, trid);
         }
    case loRQ_OP_REFRESH:
       if (operation & loRQ_SYNC)
         UL_ERROR((LOGID, "SYNC REFRESH is invalid %x / %x", rq->operation, rq->upl.trqid));
       rio_refresh(cli, rq);
       break;
/********************************************/

    case loRQ_OP_CANCEL:
       cli->send_callback(0, rq->group_key, &rq->upl, operation);
       lo_req_free(rq);
       break;
/********************************************/

    default:
       UL_ERROR((LOGID, "BAD REQUEST %x / %x", rq->operation, rq->upl.trqid));
       lo_req_free(rq);
       break;
      }
#if 0
    if (rq) /*??*/
      {
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else
         {
          if (operation & loRQ_OPER_IO)
            cli->send_callback(0, rq->group_key, &rq->upl, operation);
          lo_req_free(rq);
         }
      }
#endif
    lw_mutex_lock(&cli->async.lk);
   }

 return 0;
}
Пример #8
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;
}