📄 system.c
字号:
}// -- cSystems -----------------------------------------------------------------cSystemLink *cSystems::first=0;int cSystems::nextSysIdent=0x1000;void cSystems::Register(cSystemLink *sysLink){ PRINTF(L_CORE_DYN,"systems: registering CA system %s, pri %d, ident %04X",sysLink->name,sysLink->pri,nextSysIdent); sysLink->next=first; sysLink->sysIdent=nextSysIdent++; first=sysLink;}int cSystems::Provides(const unsigned short *SysIds, bool ff){ int n=0; for(; *SysIds; SysIds++) { if(ScSetup.Ignore(*SysIds)) continue; cSystemLink *sl=first; while(sl) { if(sl->CanHandle(*SysIds)) { if(sl->noFF && ff) return 0; n++; break; } sl=sl->next; } } return n;}cSystemLink *cSystems::FindByName(const char *Name){ cSystemLink *sl=first; while(sl) { if(!strcasecmp(sl->name,Name)) return sl; sl=sl->next; } return 0;}cSystemLink *cSystems::FindById(unsigned short SysId, bool ff, int oldPri){ // all pri's are negative! // oldPri = 0 -> get highest pri system // oldPri < 0 -> get highest pri system with pri<oldPri // oldPri > 0 -> get lowest pri system cSystemLink *sl=first, *csl=0; while(sl) { if((!ff || !sl->noFF) && sl->CanHandle(SysId) && sl->pri<oldPri && (!csl || (oldPri<=0 && sl->pri>csl->pri) || (oldPri>0 && sl->pri<csl->pri) ) ) csl=sl; sl=sl->next; } return csl;}cSystemLink *cSystems::FindByIdent(int ident){ cSystemLink *sl=first; while(sl) { if(sl->sysIdent==ident) return sl; sl=sl->next; } return 0;}cSystem *cSystems::FindBySysName(unsigned short SysId, bool ff, const char *Name){ cSystemLink *sl=FindByName(Name); if(sl && (!ff || !sl->noFF) && !ScSetup.Ignore(SysId) && sl->CanHandle(SysId)) return sl->Create(); return 0;}cSystem *cSystems::FindBySysId(unsigned short SysId, bool ff, int oldPri){ if(!ScSetup.Ignore(SysId)) { cSystemLink *csl=FindById(SysId,ff,oldPri); if(csl) return csl->Create(); } return 0;}int cSystems::FindIdentBySysId(unsigned short SysId, bool ff, int &Pri){ if(!ScSetup.Ignore(SysId)) { cSystemLink *csl=FindById(SysId,ff,Pri); if(csl) { Pri=csl->pri; return csl->sysIdent; } } return 0;}cSystem *cSystems::FindBySysIdent(int ident){ cSystemLink *csl=FindByIdent(ident); return csl ? csl->Create() : 0;}bool cSystems::Init(const char *cfgdir){ PRINTF(L_CORE_LOAD,"** registered systems:"); for(cSystemLink *sl=first; sl; sl=sl->next) PRINTF(L_CORE_LOAD,"** %-16s (pri %3d)",sl->name,sl->pri); for(cSystemLink *sl=first; sl; sl=sl->next) if(!sl->Init(cfgdir)) return false; return true;}void cSystems::Clean(void){ for(cSystemLink *sl=first; sl; sl=sl->next) sl->Clean();}bool cSystems::ConfigParse(const char *Name, const char *Value){ char sysName[32]; unsigned int i; for(i=0; Name[i] && Name[i]!='.' && i<sizeof(sysName); i++) sysName[i]=Name[i]; if(Name[i]) { sysName[i]=0; i++; cSystemLink *sl=FindByName(sysName); if(sl && sl->opts) return sl->opts->Parse(&Name[i],Value); } return false;}void cSystems::ConfigStore(bool AsIs){ for(cSystemLink *sl=first; sl; sl=sl->next) if(sl->opts && sl->opts->Store(AsIs)) sl->NewConfig();}cOpts *cSystems::GetSystemOpts(bool start){ static cSystemLink *sl=0; sl=(start || !sl) ? first : sl->next; while(sl) { if(sl->opts) return sl->opts; sl=sl->next; } return 0;}// -- cMsgCache ----------------------------------------------------------------#define FREE 0x00 // modes#define FAIL1 0x01#define FAIL2 0x3D#define FAILN 0x3E#define GOOD 0x3F#define MASK 0x3F#define QUEUED 0x40#define WAIT 0x80struct Cache { int crc; int mode; };cMsgCache::cMsgCache(int NumCache, int StoreSize){ numCache=NumCache; storeSize=StoreSize; ptr=0; stores=0; maxFail=2; caches=MALLOC(struct Cache,numCache); if(caches) { Clear(); if(storeSize>0) { stores=MALLOC(unsigned char,numCache*storeSize); if(!stores) PRINTF(L_GEN_ERROR,"msgcache: no memory for store area"); } } else PRINTF(L_GEN_ERROR,"msgcache: no memory for cache");}cMsgCache::~cMsgCache(){ free(caches); free(stores);}void cMsgCache::SetMaxFail(int maxfail){ maxFail=min(maxfail,FAILN); PRINTF(L_CORE_MSGCACHE,"%d/%p: maxFail set to %d",getpid(),this,maxFail);}void cMsgCache::Clear(void){ cMutexLock lock(&mutex); memset(caches,0,sizeof(struct Cache)*numCache); ptr=0; PRINTF(L_CORE_MSGCACHE,"%d/%p: clear",getpid(),this);}struct Cache *cMsgCache::FindMsg(int crc){ int i=ptr; while(1) { if(--i<0) i=numCache-1; struct Cache * const s=&caches[i]; if(!s->mode) break; if(s->crc==crc) return s; if(i==ptr) break; } return 0;}// returns:// -1 - msg cached as failed (max failed)// 0 - msg cached as good, result stored// >0 - msg not cached, queue idint cMsgCache::Get(const unsigned char *msg, int len, unsigned char *store){ int crc=crc32_le(0,msg,len); cMutexLock lock(&mutex); if(!caches || (storeSize>0 && !stores)) return -1; // sanity struct Cache *s; while((s=FindMsg(crc))) { if(!(s->mode&QUEUED)) break; s->mode|=WAIT; PRINTF(L_CORE_MSGCACHE,"%d/%p: msg already queued. waiting to complete",getpid(),this); wait.Wait(mutex); } int id; if(!s) { while(1) { s=&caches[ptr]; if(!(s->mode&QUEUED)) break; s->mode|=WAIT; PRINTF(L_CORE_MSGCACHE,"%d/%p: queue overwrite protection id=%d",getpid(),this,ptr+1); wait.Wait(mutex); // don't overwrite queued msg's } id=ptr+1; s->crc=crc; s->mode=QUEUED; PRINTF(L_CORE_MSGCACHE,"%d/%p: queued msg with id=%d",getpid(),this,id); ptr++; if(ptr>=numCache) { ptr=0; PRINTF(L_CORE_MSGCACHE,"msgcache: roll-over (%d)",numCache); } return id; } else { id=(s-&caches[0])+1; switch(s->mode) { case GOOD: if(store && storeSize>0) memcpy(store,&stores[(id-1)*storeSize],storeSize); PRINTF(L_CORE_MSGCACHE,"%d/%p: msg is cached as GOOD (%d)",getpid(),this,id); return 0; case FAIL1...FAIL2: PRINTF(L_CORE_MSGCACHE,"%d/%p: msg is cached as FAIL%d (%d)",getpid(),this,s->mode,id); s->mode|=QUEUED; return id; case FAILN: default: PRINTF(L_CORE_MSGCACHE,"%d/%p: msg is cached as FAILN (%d)",getpid(),this,id); return -1; } }}int cMsgCache::Cache(int id, bool result, const unsigned char *store){ cMutexLock lock(&mutex); if(id<1 || !caches || (storeSize>0 && !stores)) return 0; // sanity struct Cache *s=&caches[id-1]; LBSTARTF(L_CORE_MSGCACHE); LBPUT("%d/%p: de-queued msg with id=%d ",getpid(),this,id); if(s->mode&WAIT) wait.Broadcast(); if(result) { if(store && storeSize>0) memcpy(&stores[(id-1)*storeSize],store,storeSize); s->mode=GOOD; LBPUT("(GOOD)"); return 0; } else { switch(s->mode&MASK) { case GOOD: s->mode=FREE; // fall through case FREE: case FAIL1...FAIL2: s->mode=(s->mode&MASK)+1; if(s->mode<maxFail) { LBPUT("(FAIL%d)",s->mode); break; } // fall through case FAILN: s->mode=FAILN; LBPUT("(FAILN)"); break; } return s->mode; } LBEND();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -