void loShutdownConn_clear(loShutdownConn *sc) { if (sc->request) sc->request->Release(); UL_DEBUG((LOGID, "loShutdownConn_clear(%p)", sc->request)); if (sc->reason) freeX(sc->reason); loShutdownConn_init(sc); }
int loSetState(loService *se, loClient *cli, int oper, int state, const char *reason) { int rv; loWchar *ureason = 0; if (reason) ureason = loMWstrdup(reason); rv = loSetStateW(se, cli, oper, state, ureason); if (ureason) freeX(ureason); return rv; }
void loShutdownConn_call(loShutdownConn *sc) { if (sc->request) { UL_NOTICE((LOGID, "Going to ShutdownRequest(%ls)", loWnul(sc->reason))); sc->request->ShutdownRequest(sc->reason? sc->reason: L""); sc->request->Release(); sc->request = 0; } #if 1 /* we need a duplicate of "reason" to perform the call; using reason[] is good idea */ if (sc->reason) freeX(sc->reason), sc->reason = 0; #endif }
loEnum<BASE,ITEM,IFACE>::~loEnum() { LO_IAM_INVALIDATE(); // UL_WARNING((LOGID, "IEnum::Delete -> %p %p ref=%u", this, iam, RefCount)); RefCount = 0; total = curpos = 0; if (count) { count = 0; if (list) freeX(list), list = 0; } list = 0; if (base) base->Release(), base = 0; #if LO_USE_FREEMARSH_ENUM if (freemarsh) { freemarsh->Release(); freemarsh = 0; } #endif }
STDMETHODIMP LightOPCServer::BrowseOPCItemIDs( /* [in] */ OPCBROWSETYPE dwBrowseFilterType, /* [string][in] */ LPCWSTR szFilterCriteria, /* [in] */ VARTYPE vtDataTypeFilter, /* [in] */ DWORD dwAccessRightsFilter, /* [out] */ LPENUMSTRING *ppIEnumString) { HRESULT hr = S_OK; loEnumString *ulist = 0; LO_CHECK_STATEz1("BrowseOPCItemIDs", ppIEnumString); if (szFilterCriteria && !*szFilterCriteria) szFilterCriteria = 0; if (!ppIEnumString || dwBrowseFilterType != OPC_FLAT && dwBrowseFilterType != OPC_BRANCH && dwBrowseFilterType != OPC_LEAF) { hr = E_INVALIDARG; goto Return; } if (!(ulist = new loEnumString(0))) { hr = E_OUTOFMEMORY; goto Return; } { loTagId ti; lo_hash *hash_list = 0; loWchar brsep = se->branch_sep; BOOL casesens = 0 == (/*se->driver.*/ldFlags & loDF_IGNCASE); loWchar *brpos = 0; unsigned brlen = 0; int am_mask; loCallerx cctx = ctxt; loStringBuf aname; loStringBuf_init(&aname); lock_browse(); if (browsepos.sb_str) { brlen = wcslen(browsepos.sb_str); brpos = loWstrdup(browsepos.sb_str); } cctx.cta.vc_lcid = ctxt.cta.vc_lcid; unlock_browse(); if (brlen && !brpos) { hr = E_OUTOFMEMORY; goto Return; } if (!brsep) dwBrowseFilterType = OPC_FLAT; // level = lo_name_level(brsep, browsepos.sb_str); UL_TRACE((LOG_SR("Browse for: %u/%ls/ access %d"), brlen, loWnul(brpos), dwAccessRightsFilter)); dwAccessRightsFilter &= loOPC_RIGHTS; if (dwAccessRightsFilter == (OPC_READABLE | OPC_WRITEABLE)) dwAccessRightsFilter = 0; am_mask = dwAccessRightsFilter; if (access_mode & loAM_RDONLY_BROWSE) am_mask &= ~OPC_WRITEABLE; //loMilliSec stst = lo_millisec(); loLOCK_MGMT_O(&se->lkMgmt); for(ti = 0; ti = lo_browse_tag(se, ti, brpos, brlen, dwBrowseFilterType); ti++) { unsigned alen; loTagEntry *te = &se->tags[ti]; const loWchar *item = te->attr.taName + brlen; if (!*item) continue; /* don't return itself */ if (brsep == *item) item++; switch(dwBrowseFilterType) { case OPC_LEAF: if (wcschr(item, brsep)) continue; //if (1 < lo_name_level(brsep, item)) continue; case OPC_FLAT: alen = wcslen(item); if (dwAccessRightsFilter && !(am_mask/*dwAccessRightsFilter*/ & te->attr.taRights)) continue; if (vtDataTypeFilter != VT_EMPTY && S_OK != lo_checktype(&cctx, &te->attr, vtDataTypeFilter)) continue; break; case OPC_BRANCH: if (!wcschr(item, brsep)) continue; //if (1 >= lo_name_level(brsep, item)) continue; alen = lo_name_levlen(brsep, item, 1); { loWchar *uit; if (ulist->total && !se->wstrncmp(item, uit = ulist->list[ulist->total - 1], alen) && 0 == uit[alen]) continue; /* duplicate */ } break; } if (!loStringBuf_REALLOC(&aname, alen + 1)) { hr = E_OUTOFMEMORY; break; } wcsncpy(aname.sb_str, item, alen); aname.sb_str[alen] = 0; if (szFilterCriteria && !MatchPattern(aname.sb_str, szFilterCriteria, casesens)) continue; if (OPC_BRANCH == dwBrowseFilterType) { unsigned uu; lo_hash a_hash = loSTRHASH(se, aname.sb_str); for(uu = ulist->total; uu; uu--) if (a_hash == hash_list[uu-1] && !se->wstrcmp(aname.sb_str, ulist->list[uu-1]) ) break; if (uu) continue; if (!preallocX((void**)&hash_list, sizeof(*hash_list)*(ulist->total+1))) { hr = E_OUTOFMEMORY; break; } hash_list[ulist->total] = a_hash; } //UL_DEBUG((LOG_SR("Browse %ls"), aname.sb_str)); hr = ulist->add_item(&aname.sb_str); if (S_OK != hr) break; } /* end of for() */ loUnLOCK_MGMT_O(&se->lkMgmt); /* UL_WARNING((LOG_SR("BrowseOPC <%ls> %d TIME %d"), loWnul(brpos), ulist->total, lo_millisec() - stst)); //*/ if (brpos) freeX(brpos); if (hash_list) freeX(hash_list); loStringBuf_clear(&aname); } Return: if (S_OK == hr && S_OK == (hr = ulist->initiate(&otrk))) { *ppIEnumString = (LPENUMSTRING)ulist; UL_NOTICE((LOG_SR("BrowseOPCItemIDs() = %u"), ulist->total)); if (!ulist->total) { ENUM_EMPTY(hr, ldFlags, ppIEnumString); } } else { if (ulist) { delete ulist; ulist = 0; } UL_INFO((LOG_SR("BrowseOPCItemIDs() = %s"), loStrError(hr))); } LO_FINISH(); 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; }
int loInternalServiceDestroy(loService *se) { int rv0, rv; unilog *log; UL_TRACE((LOGID, "loInternalServiceDestroy(%p)...", se)); if (!loIS_VALID(se)) { UL_ERROR((LOGID, "loInternalServiceDestroy(%p) illegal pointer", se)); return EBADF; } se->iam = 0; log = (unilog*)se->log; se->log = 0; rv = 0; if ((se->initphase & ifLKSEC) && (rv0 = loThrControl_destroy(&se->update_pipe)) && !rv) rv = rv0; if ((se->initphase & ifLKMGMT) && (rv0 = lw_rwlock_destroy(&se->lkMgmt)) && !rv) rv = rv0; if ((se->initphase & ifLKPRIM) && (rv0 = lw_rwlock_destroy(&se->lkPrim)) && !rv) rv = rv0; if ((se->initphase & ifLKDR) && (rv0 = lw_mutex_destroy(&se->lkDr)) && !rv) rv = rv0; if ((se->initphase & ifLKLIST) && (rv0 = lw_mutex_destroy(&se->lkList)) && !rv) rv = rv0; if ((se->initphase & ifTRWAIT) && (rv0 = lw_condb_destroy(&se->lkTridWait)) && !rv) rv = rv0; se->initphase = 0; /* cleanup the CACHE & ATTRIB */ if (se->secondary) loTagValue_clear(se->secondary, se->tag_count); if (se->tags) loTagEntry_clear(se->tags, se->tag_count); se->tag_count = 0; lo_proplist_clear(se); se->ts_size = 0; if (se->ts_prim != se->ts_sec && se->ts_sec) freeX(se->ts_sec); se->ts_sec = 0; if (se->ts_prim) freeX(se->ts_prim); se->ts_prim = 0; freeX(se); if (rv) UL_WARNING((LOGID, "%!e loDelete() finished", rv)); else UL_TRACE((LOGID, "loDelete() finished = %u", rv)); { #if 0 != LO_USE_MALLOCX // extern long mallocX_count; UL_WARNING((LOGID, "loDelete()::mallocX = %ld xobjref = %ld", mallocX_count, lo_X_objcount)); #endif mallocX_trap(); } if (log) unilog_Delete(log); return rv; }