⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lopcser.cpp

📁 OPCSERVER源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   {
    WR_lock(&lk_remove);
     lock_write();//lw_rw_wrlock(&lk_all);
      del_all(ldFlags & loDf_DWG);
     unlock();//lw_rw_unlock(&lk_all);
    lw_rw_unlock(&lk_remove);
   }
// else del_all(initphase & ifFORCEDELETE);
}

void LightOPCServer::set_state(int oper, int state, const loWchar *reason)
{
 int ost = 0xeee;

 if (loIS_VALID(this))
   {
    UL_TRACE((LOG_SR("Server::set_state(%X/%d) ..."), oper, state));

/* DISCONNECT is possible whenever async is `outof01` but
   in this case it could be done by sheduler.
   here we warrant all possible disconnects will be done before
   loSetStete() returned. */
       if (oper & loOP_DISCONNECT)
         {
          unsigned gcount;
          IUnknown *grp, **grpl;
          UL_TRACE((LOG_SR("Server::DISCONNECT...")));
          otrk.ot_disconnect_all(0);
          lock_read();
          grpl = (IUnknown**)grl.gl_list;
          for(gcount = grl.gl_count; gcount--;)
            if (grp = grpl[gcount]) LO_CO_DISCONNECT(grp, 0);
          LO_CO_DISCONNECT((IOPCServer*)this, 0);
          unlock();
          UL_TRACE((LOG_SR("Server::DISCONNECT Enums...")));
          otrk.ot_disconnect_all(0);
         }

    lw_mutex_lock(&async.lk);
    if (!loThrControl_outof01(&async))
      {
       ost = otrk.ot_stopped;

       if (oper & loOP_OPERATE)
         {
          if (otrk.ot_stopped && !(oper & loOP_STOP)) otrk.ot_stopped = 0;
          if (shuttingdown && !(oper & loOP_SHUTDOWN)) shuttingdown = 0;
         }

       if ((oper & loOP_SHUTDOWN) &&
          !shuttingdown) shuttingdown = 1;

       if ((oper & (loOP_STOP | loOP_DESTROY)) &&
          !otrk.ot_stopped) otrk.ot_stopped = 1;

       if (0 != state) ostatus.dwServerState = (OPCSERVERSTATE)state;
       if (0 != reason) loPWstrdup(&shutdown_conn.reason, reason);

       if (oper & loOP_DESTROY)
         {
          async.tstate = 2;
          lw_conds_signal(&async.cond);
         }
       else if (ost != otrk.ot_stopped || shuttingdown)
         {
          if (0 == async.tstate) async.tstate = 1;
          lw_conds_signal(&async.cond);
         }
      } /* if (!loThControl_outof01( */
    ost = otrk.ot_stopped << 8 | shuttingdown << 4 | async.tstate;
    lw_mutex_unlock(&async.lk);    
   }
 UL_TRACE((LOG_SR("Server::set_state(%X/%d) finished =%03x"), oper, state, ost));
}

int LightOPCServer::attach(void)
{
 int err = EBADF;
 UL_TRACE((LOG_SR("Server::attach() ...")));
 if (loIS_VALID(this) && loIS_VALID(se))
   {
    lw_mutex_lock(&se->lkList);
    if (!se->shutdown)
      {
       loClient *srv;
       unsigned serv_id = se->serv_key;
NewKey:
       if (0 == ++serv_id) ++serv_id;
       srv = se->servlist;
       while(srv)
         if (srv->serv_key != serv_id) srv = srv->serv_next;
         else goto NewKey;

       se->serv_key = serv_key = serv_id;
       serv_next = se->servlist;
       se->servlist = this;
       initphase |= ifATTACHED;
       err = 0;
      }
    else err = ENOENT;
    lw_mutex_unlock(&se->lkList);

    if (0 == err)
      err = loThrControl_start(&async, 1, run_client_scheduler, this);
   }

 UL_NOTICE((LOG_SR("Server::attach() %s"), err? "FAILED": "Ok"));
 return err;
}

int LightOPCServer::detach(void)
{
 int godown = 0;
 UL_TRACE((LOG_SR("Server::detach() ...")));
/*
 LO_CO_DISCONNECT((IOPCServer*)this, 0);
*/
 clear_all();
 UL_TRACE((LOG_SR("Server::detach() continued...")));

 if ((initphase & ifATTACHED) && loIS_VALID(se))
   {
    LightOPCServer **les;
    lw_mutex_lock(&se->lkList);
    les = &se->servlist;
    while(*les)
      if (*les != this) les = &(*les)->serv_next;
      else
        {
         *les = serv_next; serv_next = 0;
         godown = (se->shutdown && !se->servlist)? -1: 1;
//         break;
        }
    if (godown) initphase &= ~ifATTACHED;
    lw_mutex_unlock(&se->lkList);
    if (0 > godown)
      {
       UL_NOTICE((LOG_SR("going down")));
       loInternalServiceDestroy(se);
      }
   }

 clear_all();
 UL_NOTICE((LOG_SR("Server::detach() finished %d"), godown));
 return godown;
}


HRESULT LightOPCServer::mk_unique(loWchar buf[loUNIQUE_LEN], const void *ptr)
{
 int tc;

 if (!buf) return E_FAIL;
 for(tc = 0; tc < 1000; tc++)
   {
     /*InterlockedIncrement()*/++unique_GroupName;
    swprintf(buf, L"G-%03lu.%lx", unique_GroupName,
                                  0xfffff & (((unsigned long)ptr) >> 5));
/* the value may be not same as result of InterlockedIncrement(),
   but don't worried about */
    if (!by_name(buf)) return S_OK;
   }
 UL_WARNING((LOG_SR("Can not make unique name %lu"), unique_GroupName));
 return E_FAIL;
}

unsigned LightOPCServer::by_handle(OPCHANDLE sgh)
{
 LightOPCGroup *grp;
 unsigned uu = grl.gl_count;
 while(uu--)
   if ((grp = (LightOPCGroup*)grl.gl_list[uu]) && grp->ServerHandle == sgh)
     return uu + 1;
 return 0;
}

LightOPCGroup *LightOPCServer::by_handle_g(unsigned sgh)
{
 LightOPCGroup *grp;
 unsigned uu = grl.gl_count;
 while(uu--)
   if ((grp = (LightOPCGroup*)grl.gl_list[uu]) && grp->ServerHandle == sgh)
     return grp;
 return 0;
}

LightOPCGroup *LightOPCServer::by_name(const loWchar *name)
{
 if (name)
   {
    LightOPCGroup *grp, **groups = (LightOPCGroup **)grl.gl_list;
    unsigned uu = grl.gl_count;
    while(uu--)
      if ((grp = *groups++) && grp->name &&
          !wcscmp(name, grp->name)) return grp;
   }
 return 0;
}

unsigned LightOPCServer::add(LightOPCGroup *grp)
{
 unsigned slot;

 if (!grp) return 0;
 if (slot = gl_insert(&grl, grp, 0))
   {
    grp->AddRef();
    grp->attach(this);
   }
 return slot;
}

int LightOPCServer::del(unsigned index, int force)
{
 int rv = -1;
 LightOPCGroup *grp;
 if (grp = (LightOPCGroup*)gl_remove(&grl, index))
   {
    rv = (1 != grp->RefCount);
    grp->detach(this);
    if (force) 
      { 
       LO_CO_DISCONNECT((IOPCGroupStateMgt*)grp, 0);
       delete grp; 
       rv = 0; 
      }
    else 
      {
       rv /*|*/= (0 != grp->Release());
      }
   }
 return rv;
}

void LightOPCServer::del_all(int force)
{
 unsigned uu;
 for(uu = grl.gl_count; uu > 0; uu--) del(uu, force);
 glGrowList_clear(&grl);
}

/*********************************** LightOPCGroup:: stuff **************************/

int LightOPCGroup::iam_attached(void) // for logging only
{
 return loIS_VALID(this) && (initphase & ifATTACHED) && loIS_VALID(owner);
}


int LightOPCGroup::lock_state(const char *msg)
{
 LightOPCServer *own = owner;
 lw_rwlock *removelock = &own->lk_remove;
// UL_DEBUG((LOGID, "Group:%u(%p) <%s> Entering...", ServerHandle, this, msg? msg: ""));
 if (loIS_VALID(this) && (initphase & ifATTACHED) /*&&
     owner */ && !own->lock_state(msg, 0))
   {
    if (0 == own->RD_lock(removelock))
      {
       if (loIS_VALID(this) && (initphase & ifATTACHED))
         {
          return 0;
         }
       lw_rw_unlock(removelock);
      }
    own->unlock_state();
   }
 UL_WARNING((LOGID, "Group:%u(%p) <%s> interface closed",
            ServerHandle, this, msg? msg: ""));
 return -1;
}

#if 0
void LightOPCGroup::unlock_state(void)
{
 if (!(initphase & ifATTACHED) && (gl_count || advise_present))
   {
    lock_write();
    clear_all();
    unlock();
   }
 lw_rw_unlock(&owner->lk_remove);
 owner->unlock_state();
// UL_DEBUG((LOGID, "Group:%u(%p) Leave.Ok", ServerHandle, this));
}
#endif

LightOPCGroup::LightOPCGroup()
{
 /* IUnknown implementation */
 initphase = 0;
 glGrowList_init(&itl);
 RefCount = 0;
 owner = 0;
 name = 0;

 ClientHandle = ServerHandle = grLCID = TimeBias = 0;
 Active = 0;
 justactuated = 0;
 Deadband = 0.;
 UpdateRate = LastUpdate = 0;

 conn_databack = 0;
 conn_dataonly = conn_datatime = conn_writecompl = 0;
 advise_present = 0;
 advise_enabled = loRQ_CONN_DATA;
 active_count = 0;
 last_trid = 0;
#if LO_USE_FREEMARSHALL
 freemarsh = 0;
#endif
 iam = this;
}

LightOPCGroup::~LightOPCGroup()
{
 iam = 0;
 initphase &= ~ifATTACHED;
 UL_TRACE((LOGID, "~LightOPCGroup(%ls)", loWnul(name)));
 LO_HEAPCHECK(this);
/*
 LO_CO_DISCONNECT((IOPCGroupStateMgt*)this, 0);
*/
 if (name) { freeX(name); name = 0; }
 clear_all();
#if LO_USE_FREEMARSHALL
 if (freemarsh) { freemarsh->Release(); freemarsh = 0; }
#endif
 initphase = 0;
 glGrowList_clear(&itl);
 LO_HEAPCHECK(this);
}

void LightOPCGroup::clear_advise(void)
{
 UL_DEBUG((LOGID, "LightOPCGroup::clear_advise(%ls)", loWnul(name)));
 advise_present = 0;
 if (conn_databack)   loRELEASE_IFACE(conn_databack, IOPCDataCallback, initphase);
 if (conn_dataonly)   loRELEASE_IFACE(conn_dataonly, IAdviseSink, initphase);
 if (conn_datatime)   loRELEASE_IFACE(conn_datatime, IAdviseSink, initphase);
 if (conn_writecompl) loRELEASE_IFACE(conn_writecompl, IAdviseSink, initphase);
}

void LightOPCGroup::clear_all(void)
{
 del_all();
 active_count = 0;
 if (advise_present) clear_advise();

 /* delete anything else here */
}

void LightOPCGroup::actuate_async(int justActuated) /* touch owner->async & set just_activated */
{
 if (Active && (advise_present & advise_enabled))
   {
    if (justActuated) justactuated = 1, last_trid = 0;
    owner->touch_scheduler();
    UL_NOTICE((LOG_GRHO("group::actuate(%ls)"), loWnul(name)));
   }
}

void LightOPCGroup::attach(LightOPCServer *own)
{
 if (owner) UL_ERROR((LOG_GRHO("group::attach(%ls) BAD OWNER"), loWnul(name)));
 if (owner = own)
   {
    initphase = ifATTACHED | own->ldFlags & loDf_BOTHMODEL;
#if LO_USE_FREEMARSHALL
    if (own->/*se->driver.*/ldFlags & loDf_FREEMARSH)
      CoCreateFreeThreadedMarshaler((IOPCGroupStateMgt*)this, &freemarsh);
     /* there are nothing bad if it fails */
#endif
   }
}

void LightOPCGroup::detach(LightOPCServer *own)
{
 if (own == owner)
   UL_TRACE((LOG_GRHO("group::detach(%ls)"), loWnul(name)));
 else UL_ERROR((LOG_GRHO("group::detach(%ls) BAD OWNER"), loWnul(name)));
// LO_CO_DISCONNECT((IOPCGroupStateMgt*)this, 0);
 if (initphase & ifATTACHED)
   {
    set_active(0);
    initphase &= ~ifATTACHED;
   }
 clear_all();
}

int LightOPCGroup::del(unsigned indx)
{
 LightOPCItem *item;
 if (item = (LightOPCItem*)gl_remove(&itl, indx))
   { delete item; return 0; }
 return -1;
}

void LightOPCGroup::del_all(void)
{
 unsigned uu;
 for(uu = itl.gl_count; uu > 0; uu--) del(uu);
 glGrowList_clear(&itl);
}

/*********************** LightOPCGroup::IConnectionPoint stuff **********************/

HRESULT LightOPCGroup::icp_AddRef(void)
{
 if (!AddRef()) return LO_E_SHUTDOWN;
 LO_CHECK_STATEz0("Group::IConnPoint::AddRef");
 return S_OK; }
}

void LightOPCGroup::icp_Release(void)
{
 { LO_FINISH();
 Release();
}

loObjTracker *LightOPCGroup::icp_ObjTracker(void)
{
  return owner? &owner->otrk: 0;
}
/*********************************** LightOPCItem:: stuff **************************/

LightOPCItem::LightOPCItem()
{
 szItemID = 0;
 szAccessPath = 0;
 bActive = 0;
 tid = 0;
 convtype = loCONV_CHANGE;
/* hClient;*/
 vtRequestedDataType = VT_EMPTY;

 Quality = -1;
 AcPath = 0;
 last_changed = 0;
 numeric = 0;
 lastsent = 0;
}

LightOPCItem::~LightOPCItem()
{
 if (szItemID) { freeX(szItemID); szItemID = 0; }
 if (szAccessPath) { freeX(szAccessPath); szAccessPath = 0; }
 if (lastsent) { freeX(lastsent); lastsent = 0; }
}



/* end of lopcser.cpp */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -