12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525 |
- #include "precompile.h"
- #include "sp_mod.h"
- #include "sp_svc.h"
- #include "sp_dbg_export.h"
- #include "sp_env.h"
- #include "sp_def.h"
- #include "SpBase.h"
- #include "shm_mem.h"
- #include "process_monitor.h"
- #include "refcnt.h"
- #include "spinlock.h"
- #include "strutil.h"
- #ifdef _WIN32
- #include <WtsApi32.h>
- #include <Userenv.h>
- #include "sp_groupProcess.h"
- #else
- #endif //_WIN32
- #include "sp_gui.h"
- #include "sp_env.h"
- #include<winpr/exception.h>
- #include <winpr/thread.h>
- #include <winpr/wtsapi.h>
- #include <winpr/synch.h>
- #include <winpr/string.h>
- #include "toolkit.h"
- #define BUFSIZE 512
- #define MOD_CMD_INIT 0
- #define MOD_CMD_TERM 1
- #define MOD_CMD_START 2
- #define MOD_CMD_STOP 3
- #define MOD_CMD_PAUSE 4
- #define MOD_CMD_CONTINUE 5
- #define MOD_CMD_TEST 6
- #define MOD_CMD_MOD_RESULT 7
- #define MOD_CMD_ENT_RESULT 8
- #define MOD_CMD_REPORT_CREATE_CONN 9
- #define MOD_CMD_REPROT_CLOSE_CONN 10
- #define MOD_CMD_REPORT_EXCEPTION 12
- #define MOD_CMD_SUBSCRIBE_STATE_LISTENER 13
- #define MOD_CMD_UNSUBSCRIBE_STATE_LISTENER 14
- #define MOD_CMD_SUBSCRIBE_LIFE_LISTENER 15
- #define MOD_CMD_UNSUBSCRIBE_LIFE_LISTENER 16
- #define MOD_CMD_RECORD_STATE_EVENT 17
- #define MOD_CMD_RECORD_CREATE_CONN 18
- #define MOD_CMD_RECORD_CLOSE_CONN 19
- #define MOD_CMD_RECORD_ENTITY_CLOSE 20
- #define MOD_CMD_RECORD_ENTITY_CREATE 21
- #define MOD_CMD_RECORD_ENTITY_EXCEPTION 22
- #define MOD_CMD_SWITCH_RUNNING_MODE 23
- #define MOD_CMD_USER_STATE_EVENT 24
- #define MOD_CMD_NOTIFY_REDIRECT_SUBSCRIBE 31 // shell -> entity
- #define MOD_CMD_REPORT_REDIRECT_SUBSCRIBE 32 // entity -> shell
- //#define PROCESS_TIMEOUT 10000
- #define PROCESS_TIMEOUT 120000
- #define PROCESS_EXIT_TIMEOUT 4000
- #define ENTITY_TEST_TIMEOUT 30000
- #ifdef _WIN32
- extern void sp_mod_mgr_lockEx(int EntityId);
- extern void sp_mod_mgr_unlockEx(int EntityId);
- extern void sp_mod_mgr_lockArrClean();
- #endif //_WIN32
- struct sp_mod_stub_t
- {
- sp_mod_stub_cb cb;
- sp_iom_t *iom;
- };
- struct sp_mod_entity_stub_t
- {
- sp_mod_entity_stub_cb cb;
- strand_t *strand;
- sp_svc_t *svc;
- };
- static int mod_on_pkt(sp_iom_t *iom, int to_svc_id, int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt, void *user_data)
- {
- sp_mod_stub_t *stub = (sp_mod_stub_t *)user_data;
- if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD) {
- int cmd_type = SP_GET_TYPE(pkt_type);
- int result = Error_Bug;
- int processed = 0;
- if (cmd_type == MOD_CMD_INIT) {
- int service_flag = 0;
- int multithread_flag = 0;
- sp_dbg_info("receive module init cmd!");
- __try {
- result = stub->cb.on_module_init(stub, stub->cb.user_data);
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- result = Error_Exception;
- }
- sp_iom_post(iom, SP_INVALID_SVC_ID, epid, svc_id, SP_PKT_MOD|MOD_CMD_MOD_RESULT, result, NULL);
- } else if (cmd_type == MOD_CMD_TERM) {
- sp_dbg_info("receive module term cmd!");
- __try {
- result = stub->cb.on_module_term(stub, stub->cb.user_data);
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- result = Error_Exception;
- }
- sp_iom_post(iom, SP_INVALID_SVC_ID, epid, svc_id, SP_PKT_MOD|MOD_CMD_MOD_RESULT, result, NULL);
- sp_iom_post_quit(iom);
- } else {
- return TRUE;
- }
- return FALSE;
- }
- return TRUE;
- }
- int sp_mod_stub_create(const sp_mod_stub_cb *cb, sp_iom_t *iom, sp_mod_stub_t **p_stub)
- {
- sp_mod_stub_t *stub = MALLOC_T(sp_mod_stub_t);
- memcpy(&stub->cb, cb, sizeof(sp_mod_stub_cb));
- stub->iom = iom;
- sp_iom_add_pkt_handler(iom, (int)stub, &mod_on_pkt, stub);
- *p_stub = stub;
- return 0;
- }
- void sp_mod_stub_destroy(sp_mod_stub_t *stub)
- {
- sp_iom_remove_pkt_handler(stub->iom, (int)stub);
- free(stub);
- }
- static void mod_entity_process_cmd(threadpool_t *threadpool, void *arg)
- {
- iobuffer_t *pkt = arg;
- sp_mod_entity_stub_t *stub;
- int epid;
- int svc_id;
- int pkt_type;
- int pkt_id;
- int cmd_type;
- sp_dbg_debug("==> %s", __FUNCTION__);
- iobuffer_read(pkt, IOBUF_T_PTR, &stub, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &epid, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &svc_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &pkt_type, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &pkt_id, NULL);
- cmd_type = SP_GET_TYPE(pkt_type);
- sp_dbg_debug("enter mod entity process cmd: %d", cmd_type);
- switch (cmd_type) {
- case MOD_CMD_TEST:
- {
- int trigger_entity_id;
- int test_type;
- iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &test_type, NULL);
- stub->cb.on_entity_test(stub, trigger_entity_id, test_type, stub->cb.user_data);
- }
- break;
- case MOD_CMD_CONTINUE:
- {
- int trigger_entity_id;
- iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
- stub->cb.on_entity_precontinue(stub, trigger_entity_id, stub->cb.user_data);
- }
- break;
- case MOD_CMD_PAUSE:
- {
- int trigger_entity_id;
- iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
- stub->cb.on_entity_prepause(stub, trigger_entity_id, stub->cb.user_data);
- }
- break;
- case MOD_CMD_STOP:
- {
- int trigger_entity_id;
- int cause_code;
- iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &cause_code, NULL);
- stub->cb.on_entity_stop(stub, trigger_entity_id, cause_code, stub->cb.user_data);
- }
- break;
- case MOD_CMD_START:
- {
- int slen = 0;
- char *cmdline = NULL;
- int numargs, numchars;
- char *p = NULL;
- int argc = 0;
- char **argv = NULL;
- int trigger_entity_id;
- iobuffer_read(pkt, IOBUF_T_STR, NULL, &slen);
- if (slen) {
- cmdline = malloc(slen+1);
- iobuffer_read(pkt, IOBUF_T_STR, cmdline, NULL);
- str_parse_cmdline(cmdline, NULL, NULL, &numargs, &numchars);
- p = malloc(numargs*sizeof(char*) + numchars);
- argc = numargs - 1;
- argv = (char**)p;
- str_parse_cmdline(cmdline, (char **)p, p + numargs * sizeof(char *), &numargs, &numchars);
- }
- iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
- sp_dbg_debug("before invoke on_entity_prestart(trigger %d)", trigger_entity_id);
- stub->cb.on_entity_prestart(stub, trigger_entity_id, argc, argv, stub->cb.user_data);
- sp_dbg_debug("after invoke on_entity_prestart(trigger %d)", trigger_entity_id);
- free(p);
- free(cmdline);
- }
- break;
- case MOD_CMD_NOTIFY_REDIRECT_SUBSCRIBE:
- {
- int slen = 0;
- int from_entity_id = pkt_id;
- sp_uid_t uid;
- char *param = NULL;
- iobuffer_read(pkt, IOBUF_T_I8, &uid, 0);
- iobuffer_read(pkt, IOBUF_T_STR, NULL, &slen);
- if (slen) {
- param = malloc(slen + 1);
- iobuffer_read(pkt, IOBUF_T_STR, param, NULL);
- }
- stub->cb.on_entity_redirect_subscribe(stub, &uid, from_entity_id, param, stub->cb.user_data);
- free(param);
- }
- break;
- default:
- assert(0);
- break;
- }
- iobuffer_dec_ref(pkt);
- }
- static int mod_entity_on_pkt(sp_svc_t *svc, int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt, void *user_data)
- {
- sp_mod_entity_stub_t *stub = (sp_mod_entity_stub_t *)user_data;
- if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD) {
- int cmd_type = SP_GET_TYPE(pkt_type);
- sp_dbg_debug("rx entity cmd %d !", cmd_type);
- if (cmd_type == MOD_CMD_START ||
- cmd_type == MOD_CMD_STOP ||
- cmd_type == MOD_CMD_PAUSE ||
- cmd_type == MOD_CMD_CONTINUE ||
- cmd_type == MOD_CMD_TEST ||
- cmd_type == MOD_CMD_NOTIFY_REDIRECT_SUBSCRIBE) {
- iobuffer_t *pkt = *p_pkt;
- *p_pkt = NULL;
- iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_id, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_type, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &svc_id, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &epid, 0);
- iobuffer_write_head(pkt, IOBUF_T_PTR, &stub, 0);
- threadpool_queue_workitem(sp_svc_get_threadpool(stub->svc), stub->strand, &mod_entity_process_cmd, pkt);
- return FALSE;
- }
- }
- return TRUE;
- }
- int sp_mod_entity_stub_create(const sp_mod_entity_stub_cb *cb, sp_svc_t *svc, sp_mod_entity_stub_t **p_stub)
- {
- sp_mod_entity_stub_t *stub = MALLOC_T(sp_mod_entity_stub_t);
- memcpy(&stub->cb, cb, sizeof(sp_mod_entity_stub_cb));
- stub->svc = svc;
- stub->strand = strand_create();
- sp_svc_add_pkt_handler(svc, (int)stub, SP_PKT_MOD, &mod_entity_on_pkt, stub);
- *p_stub = stub;
- return 0;
- }
- void sp_mod_entity_stub_destroy(sp_mod_entity_stub_t *stub)
- {
- sp_svc_remove_pkt_handler(stub->svc, (int)stub, SP_PKT_MOD);
- strand_destroy(stub->strand);
- free(stub);
- }
- int sp_mod_entity_stub_report_create_connection(sp_mod_entity_stub_t *stub, int remote_entity)
- {
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_REPORT_CREATE_CONN, remote_entity, NULL);
- return 0;
- }
- int sp_mod_entity_stub_report_close_connection(sp_mod_entity_stub_t *stub, int remote_entity)
- {
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_REPROT_CLOSE_CONN, remote_entity, NULL);
- return 0;
- }
- int sp_mod_entity_stub_report_exception(sp_mod_entity_stub_t *stub, int win32_exception_code, int eip, int in_func)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &win32_exception_code, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &eip, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &in_func, 0);
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_REPORT_EXCEPTION, SP_SHELL_SVC_ID, &pkt);
- if (pkt)
- iobuffer_dec_ref(pkt);
- return 0;
- }
- int sp_mod_entity_stub_switch_running_state(sp_mod_entity_stub_t *stub, int state)
- {
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_SWITCH_RUNNING_MODE, state, NULL);
- return 0;
- }
- int sp_mod_entity_stub_report_user_state_change(sp_mod_entity_stub_t *stub, int last_state, int curr_state)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &last_state, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &curr_state, 0);
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_USER_STATE_EVENT, 0, &pkt);
- if (pkt)
- iobuffer_dec_ref(pkt);
- return 0;
- }
- int sp_mod_entity_stub_finish_start(sp_mod_entity_stub_t *stub, int result)
- {
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
- return 0;
- }
- int sp_mod_entity_stub_finish_stop(sp_mod_entity_stub_t *stub, int result)
- {
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
- return 0;
- }
- int sp_mod_entity_stub_finish_pause(sp_mod_entity_stub_t *stub, int result)
- {
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
- return 0;
- }
- int sp_mod_entity_stub_finish_continue(sp_mod_entity_stub_t *stub, int result)
- {
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
- return 0;
- }
- int sp_mod_entity_stub_finish_test(sp_mod_entity_stub_t *stub, int result)
- {
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
- return 0;
- }
- int sp_mod_entity_stub_finish_redirect_subscribe(sp_mod_entity_stub_t *stub, sp_uid_t *uid, int suggest_entity_id)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I8, uid, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &suggest_entity_id, 0);
- sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_REPORT_REDIRECT_SUBSCRIBE, 0, &pkt);
- if (pkt)
- iobuffer_dec_ref(pkt);
- return 0;
- }
- //
- // entity event listener
- //
- struct sp_mod_entity_state_listener_t
- {
- sp_mod_entity_event_cb cb;
- sp_svc_t *svc;
- int target_entity_id;
- spinlock_t lock;
- strand_t *strand;
- int stop;
- void *user_data;
- DECLARE_REF_COUNT_MEMBER(ref_cnt);
- };
- DECLARE_REF_COUNT_STATIC(sp_mod_entity_state_listener, sp_mod_entity_state_listener_t)
- static void mod_entity_state_listener_process_cmd(threadpool_t *threadpool, void *arg)
- {
- sp_mod_entity_state_listener_t *listener;
- iobuffer_t *pkt = arg;
- iobuffer_read(pkt, IOBUF_T_PTR, &listener, NULL);
- spinlock_enter(&listener->lock, -1);
- if (!listener->stop) {
- int epid;
- int svc_id;
- int pkt_type;
- int pkt_id;
- int cmd_type;
- iobuffer_read(pkt, IOBUF_T_I4, &epid, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &svc_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &pkt_type, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &pkt_id, NULL);
- cmd_type = SP_GET_TYPE(pkt_type);
- if (cmd_type == MOD_CMD_RECORD_STATE_EVENT) {
- int entity_id;
- int trigger_entity_id;
- int last_state;
- int curr_state;
- iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &last_state, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &curr_state, NULL);
- if (listener->target_entity_id == -1 || listener->target_entity_id == entity_id)
- listener->cb.on_entity_state(listener, entity_id, trigger_entity_id, last_state, curr_state, listener->cb.user_data);
- }
- else if (cmd_type == MOD_CMD_USER_STATE_EVENT)
- {
- int entity_id;
- int last_state;
- int curr_state;
- iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &last_state, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &curr_state, NULL);
- if (listener->target_entity_id == -1 || listener->target_entity_id == entity_id)
- listener->cb.on_user_state(listener, entity_id, last_state, curr_state, listener->cb.user_data);
- }
- else if (cmd_type == MOD_CMD_RECORD_CREATE_CONN) {
- int src_entity_id;
- int dst_entity_id;
- iobuffer_read(pkt, IOBUF_T_I4, &src_entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &dst_entity_id, NULL);
- if (listener->target_entity_id == -1 || listener->target_entity_id == src_entity_id || listener->target_entity_id == dst_entity_id)
- listener->cb.on_create_connection(listener, src_entity_id, dst_entity_id, listener->cb.user_data);
- } else if (cmd_type == MOD_CMD_RECORD_CLOSE_CONN) {
- int src_entity_id;
- int dst_entity_id;
- iobuffer_read(pkt, IOBUF_T_I4, &src_entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &dst_entity_id, NULL);
- if (listener->target_entity_id == -1 || listener->target_entity_id == src_entity_id || listener->target_entity_id == dst_entity_id)
- listener->cb.on_close_connection(listener, src_entity_id, dst_entity_id, listener->cb.user_data);
- } else {
- assert(0);
- }
- }
- spinlock_leave(&listener->lock);
- iobuffer_dec_ref(pkt);
- sp_mod_entity_state_listener_dec_ref(listener);
- }
- static int mod_entity_state_listener_on_pkt(sp_svc_t *svc, int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt, void *user_data)
- {
- sp_mod_entity_state_listener_t *listener = (sp_mod_entity_state_listener_t *)user_data;
- if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD && !listener->stop) {
- int cmd_type = SP_GET_TYPE(pkt_type);
- if (cmd_type == MOD_CMD_RECORD_STATE_EVENT ||
- cmd_type == MOD_CMD_USER_STATE_EVENT ||
- cmd_type == MOD_CMD_RECORD_CREATE_CONN ||
- cmd_type == MOD_CMD_RECORD_CLOSE_CONN) {
- iobuffer_t *pkt = iobuffer_clone(*p_pkt);
- //sp_dbg_info("recv entity_state_listener pkt cmd_type %d", cmd_type);
- iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_id, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_type, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &svc_id, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &epid, 0);
- iobuffer_write_head(pkt, IOBUF_T_PTR, &listener, 0);
- sp_mod_entity_state_listener_inc_ref(listener);
- threadpool_queue_workitem(sp_svc_get_threadpool(listener->svc), listener->strand, mod_entity_state_listener_process_cmd, pkt);
- }
- }
- return TRUE;
- }
- int sp_mod_entity_listener_create(int target_entity_id, const sp_mod_entity_event_cb *cb, sp_svc_t *svc, void *tag, sp_mod_entity_state_listener_t **p_listener)
- {
- sp_mod_entity_state_listener_t *listener = MALLOC_T(sp_mod_entity_state_listener_t);
- memcpy(&listener->cb, cb, sizeof(sp_mod_entity_event_cb));
- listener->svc = svc;
- listener->stop = 0;
- listener->user_data = tag;
- listener->target_entity_id = target_entity_id;
- spinlock_init(&listener->lock);
- listener->strand = strand_create();
- REF_COUNT_INIT(&listener->ref_cnt);
- sp_svc_add_pkt_handler(svc, (int)listener, SP_PKT_MOD, &mod_entity_state_listener_on_pkt, listener);
- *p_listener = listener;
- sp_svc_post(svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_SUBSCRIBE_STATE_LISTENER, target_entity_id, NULL);
- return 0;
- }
- static void __sp_mod_entity_listener_destroy(sp_mod_entity_state_listener_t *listener)
- {
- strand_destroy(listener->strand);
- free(listener);
- }
- IMPLEMENT_REF_COUNT_MT_STATIC(sp_mod_entity_state_listener,sp_mod_entity_state_listener_t,ref_cnt, __sp_mod_entity_listener_destroy)
- void sp_mod_entity_listener_destroy(sp_mod_entity_state_listener_t *listener)
- {
- sp_svc_post(listener->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_UNSUBSCRIBE_STATE_LISTENER, listener->target_entity_id, NULL);
- spinlock_enter(&listener->lock, -1);
- listener->stop = TRUE;
- spinlock_leave(&listener->lock);
- sp_svc_remove_pkt_handler(listener->svc, (int)listener, SP_PKT_MOD);
- sp_mod_entity_state_listener_dec_ref(listener);
- }
- void sp_mod_entity_listener_set_tag(sp_mod_entity_state_listener_t *listener, void *data)
- {
- listener->user_data = data;
- }
- void *sp_mod_entity_listener_get_tag(sp_mod_entity_state_listener_t *listener)
- {
- return listener->user_data;
- }
- // entity life listener
- struct sp_mod_entity_life_listener_t
- {
- sp_mod_entity_life_cb cb;
- sp_svc_t *svc;
- spinlock_t lock;
- strand_t *strand;
- int stop;
- void *user_data;
- DECLARE_REF_COUNT_MEMBER(ref_cnt);
- };
- DECLARE_REF_COUNT_STATIC(sp_mod_entity_life_listener, sp_mod_entity_life_listener_t)
- static void mod_entity_life_listener_process_cmd(threadpool_t *threadpool, void *arg)
- {
- sp_mod_entity_life_listener_t *listener;
- iobuffer_t *pkt = arg;
- iobuffer_read(pkt, IOBUF_T_PTR, &listener, NULL);
- spinlock_enter(&listener->lock, -1);
- if (!listener->stop) {
- int epid;
- int svc_id;
- int pkt_type;
- int pkt_id;
- int cmd_type;
- iobuffer_read(pkt, IOBUF_T_I4, &epid, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &svc_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &pkt_type, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &pkt_id, NULL);
- cmd_type = SP_GET_TYPE(pkt_type);
- if (cmd_type == MOD_CMD_RECORD_ENTITY_CREATE) {
- int entity_id;
- int trigger_entity_id;
- iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
- listener->cb.on_entity_create(listener, entity_id, trigger_entity_id, listener->cb.user_data);
- } else if (cmd_type == MOD_CMD_RECORD_ENTITY_CLOSE) {
- int entity_id;
- int trigger_entity_id;
- int close_cause;
- iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &close_cause, NULL);
- listener->cb.on_entity_close(listener, entity_id, trigger_entity_id, close_cause, listener->cb.user_data);
- } else if (cmd_type == MOD_CMD_RECORD_ENTITY_EXCEPTION) {
- int entity_id;
- int error;
- int entity_state;
- iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &error, NULL);
- iobuffer_read(pkt, IOBUF_T_I4, &entity_state, NULL);
- listener->cb.on_entity_exception(listener, entity_id, error, entity_state, listener->cb.user_data);
- } else {
- assert(0);
- }
- }
- spinlock_leave(&listener->lock);
- iobuffer_dec_ref(pkt);
- sp_mod_entity_life_listener_dec_ref(listener);
- }
- static int mod_entity_life_listener_on_pkt(sp_svc_t *svc, int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt, void *user_data)
- {
- sp_mod_entity_life_listener_t *listener = (sp_mod_entity_life_listener_t *)user_data;
- if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD && !listener->stop) {
- int cmd_type = SP_GET_TYPE(pkt_type);
- if (cmd_type == MOD_CMD_RECORD_ENTITY_CREATE ||
- cmd_type == MOD_CMD_RECORD_ENTITY_CLOSE ||
- cmd_type == MOD_CMD_RECORD_ENTITY_EXCEPTION) {
- iobuffer_t *pkt = iobuffer_clone(*p_pkt);
- iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_id, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_type, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &svc_id, 0);
- iobuffer_write_head(pkt, IOBUF_T_I4, &epid, 0);
- iobuffer_write_head(pkt, IOBUF_T_PTR, &listener, 0);
- sp_mod_entity_life_listener_inc_ref(listener);
- threadpool_queue_workitem(sp_svc_get_threadpool(listener->svc), listener->strand, &mod_entity_life_listener_process_cmd, pkt);
- }
- }
- return TRUE;
- }
- int sp_mod_entity_life_listener_create(const sp_mod_entity_life_cb *cb, sp_svc_t *svc, void *tag, sp_mod_entity_life_listener_t **p_listener)
- {
- sp_mod_entity_life_listener_t *listener = MALLOC_T(sp_mod_entity_life_listener_t);
- memcpy(&listener->cb, cb, sizeof(sp_mod_entity_life_cb));
- listener->svc = svc;
- listener->stop = 0;
- listener->user_data = tag;
- spinlock_init(&listener->lock);
- listener->strand = strand_create();
- REF_COUNT_INIT(&listener->ref_cnt);
- sp_svc_add_pkt_handler(svc, (int)listener, SP_PKT_MOD, &mod_entity_life_listener_on_pkt, listener);
- *p_listener = listener;
- sp_svc_post(svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_SUBSCRIBE_LIFE_LISTENER, 0, NULL);
- return 0;
- }
- void __sp_mod_entity_life_listener_destroy(sp_mod_entity_life_listener_t *listener)
- {
- strand_destroy(listener->strand);
- free(listener);
- }
- IMPLEMENT_REF_COUNT_MT_STATIC(sp_mod_entity_life_listener, sp_mod_entity_life_listener_t, ref_cnt, __sp_mod_entity_life_listener_destroy)
- void sp_mod_entity_life_listener_destroy(sp_mod_entity_life_listener_t *listener)
- {
- sp_svc_post(listener->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_UNSUBSCRIBE_LIFE_LISTENER, 0, NULL);
- spinlock_enter(&listener->lock, -1);
- listener->stop = TRUE;
- spinlock_leave(&listener->lock);
- sp_svc_remove_pkt_handler(listener->svc, (int)listener, SP_PKT_MOD);
- sp_mod_entity_life_listener_dec_ref(listener);
- }
- void sp_mod_entity_life_listener_set_tag(sp_mod_entity_life_listener_t *listener, void *data)
- {
- listener->user_data = data;
- }
- void *sp_mod_entity_life_listener_get_tag(sp_mod_entity_life_listener_t *listener)
- {
- return listener->user_data;
- }
- typedef struct entity_state_subscribe_entry {
- struct list_head entry;
- int mod_id;
- int svc_id;
- int instance;
- int target_entity_id;
- }entity_state_subscribe_entry;
- typedef struct entity_life_subscribe_entry {
- struct list_head entry;
- int mod_id;
- int svc_id;
- int instance;
- }entity_life_subscribe_entry;
- struct sp_mod_mgr_t
- {
- sp_bcm_daemon_t *shell_daemon; // only for shell use
- sp_svc_t *shell_svc;
- CRITICAL_SECTION lock;
- process_monitor_t *process_monitor;
-
- spinlock_t entity_state_subscribe_lock;
- struct list_head entity_state_subscribe_list;
-
- spinlock_t entity_life_subscribe_lock;
- struct list_head entity_life_subscribe_list;
- struct list_head mod_list; // list of sp_mod_t*
- array_header_t *arr_mod; // array of sp_mod_t*
- array_header_t *arr_ent; // array of sp_entity_t*
- LONG instance_seq;
- };
- static __inline int mgr_new_instance_id(sp_mod_mgr_t *mgr)
- {
- return (int)InterlockedIncrement((LONG*)&mgr->instance_seq);
- }
- static int create_module_process(const char *mod_name, int epid, int range, int group, tk_process_t* new_process)
- {
- char app[MAX_PATH] = {'\0'};
- #ifdef _WIN32
- char writeParam[MAX_PATH] = "";
- char mutexName[MAX_PATH] = "";
- char eventName[MAX_PATH] = "";
- //BOOL bRet;
- STARTUPINFOA si = { sizeof(STARTUPINFOA) };
- PROCESS_INFORMATION pi;
- DWORD dwSessionId;
- HANDLE hUserTokenDup, hThisToken;
- HANDLE hProcess = NULL;
- HANDLE hMutex = NULL;
- int result = 0;
- sp_process_t* groupProcess = NULL;
- BOOL fConnected = FALSE;
- DWORD dwThreadId = 0;
- HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
- char lpszPipename[MAX_PATH] = "\\\\.\\pipe\\";
- if (0 != getNewGuid(mutexName)) {
- return -1;
- }
- sprintf(app, ".\\bin\\sphost.exe {%s}", mutexName);
- sprintf_s(writeParam, sizeof(writeParam), "%s %d %d %s %d", mod_name, epid, range, mutexName, group);
- if (0 == group)
- checkGroupProcesInfo(group, mod_name);
- groupProcess = findGroupProcessInfo(group, mod_name);//1,group为0时,基于每个group0_entityName的进程;2,gourp不为0,基于groupN的进程
- if (NULL == groupProcess) {
- tk_process_option_t option;
- tk_process_t* ret_process;
- sp_dbg_info("open group process, %s", mod_name);
- sprintf(lpszPipename, "%s{%s}", lpszPipename, mutexName);
- sprintf(eventName, "{%s}", mutexName);
- hPipe = CreateNamedPipe(lpszPipename,
- PIPE_ACCESS_DUPLEX,
- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
- BUFSIZE, BUFSIZE, 0, NULL);
- if (hPipe == INVALID_HANDLE_VALUE
- && !ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED)) {
- return -1;
- }
- dwSessionId = WTSGetActiveConsoleSessionId();
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hThisToken)) {
- sp_process_t* curProcess = ZALLOC_T(sp_process_t);
- LUID luid;
- TOKEN_PRIVILEGES tp;
- LPVOID pEnv = NULL;
- LookupPrivilegeValueA(NULL, SE_DEBUG_NAME, &luid);
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- DuplicateTokenEx(hThisToken, MAXIMUM_ALLOWED, NULL,
- SecurityIdentification, TokenPrimary, &hUserTokenDup);
- SetTokenInformation(hUserTokenDup,
- TokenSessionId, (void*)&dwSessionId, sizeof(DWORD));
- //提升权限
- AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
- (PTOKEN_PRIVILEGES)NULL, NULL);
- hMutex = CreateEvent(NULL, FALSE, FALSE, eventName);
- if (CreateProcessAsUserA(hUserTokenDup, NULL, app, NULL, NULL, FALSE, 0, pEnv, NULL, &si, &pi)) {
- new_process->pid = pi.dwProcessId;
- CloseHandle(pi.hThread);
- hProcess = pi.hProcess;
- curProcess->process_Handle = pi.hProcess;
- curProcess->pid = pi.dwProcessId;
- curProcess->group = group;
- curProcess->write_pipe = hPipe;
- curProcess->read_pipe = hPipe;
- AddGroupProcessInfo(group, curProcess, mod_name);
- sp_dbg_info("create process and add to gourp");
- }
- WaitForSingleObject(hMutex, 5000);
- CloseHandle(hMutex);
- CloseHandle(hUserTokenDup);
- CloseHandle(hThisToken);
- }
- else {
- sp_dbg_warn("open process token failed! Error : %d", GetLastError());
- }
- }
- sp_dbg_info("begin start mod by pipe, %s", mod_name);
- //通过管道通知进程创建实体线程
- if (NULL != (groupProcess = findGroupProcessInfo(group, mod_name))
- && 0 == startModByPipe(groupProcess, writeParam)) {
- char dstParam[10][MAX_PATH];
- int paramNum = 0;
- ZeroMemory(dstParam, sizeof(dstParam));
- sp_dbg_info("query mod by pipe, %s", mod_name);
- if (-1 != (paramNum = queryModByPipe(groupProcess, mod_name, dstParam))) //return paramNum
- {
- HANDLE processMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, dstParam[2]);
- sp_dbg_info("return processId %d", groupProcess->pid);
- new_process->pid = groupProcess->pid;
- new_process->handle = processMutex;
- return 0;
- }
- }
- #else
- tk_process_t* process = NULL;
- tk_process_option_t option;
- sprintf(app, "./bin/sphost %d %s %d", range, mod_name, epid);
- option.exit_cb = NULL;
- option.file = NULL;
- option.flags = 0;
- option.params = app;
-
- if (0 == process_spawn(&option, &process)) {
- new_process->pid = process->pid;
- new_process->handle = process->handle;
- FREE(process);
- return 0;
- }
- #endif //_WIN32
- return -1;
- }
- static void mgr_bcast_entity_state_event(sp_mod_mgr_t *mgr, sp_entity_t *changed_entity, int pkt_type, iobuffer_t *pkt)
- {
- entity_state_subscribe_entry *pos;
- spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
- list_for_each_entry(pos, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
- if (pos->target_entity_id == -1 || changed_entity->cfg->idx == pos->target_entity_id) {
- iobuffer_t *copy = iobuffer_clone(pkt);
- sp_svc_post(mgr->shell_svc, pos->mod_id, pos->svc_id, pkt_type, 0, ©);
- if (copy)
- iobuffer_dec_ref(copy);
- }
- }
- spinlock_leave(&mgr->entity_state_subscribe_lock);
- //sp_dbg_info("bcast entity state! changed_entity: %s", changed_entity->cfg->name);
- }
- static void mgr_bcast_entity_on_connection(sp_mod_mgr_t *mgr, sp_entity_t *entity_src, sp_entity_t *entity_dst, int pkt_type, iobuffer_t *pkt)
- {
- entity_state_subscribe_entry *pos;
- spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
- list_for_each_entry(pos, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
- if (pos->target_entity_id == -1 || entity_src->cfg->idx == pos->target_entity_id || entity_dst->cfg->idx == pos->target_entity_id) {
- iobuffer_t *copy = iobuffer_clone(pkt);
- sp_svc_post(mgr->shell_svc, pos->mod_id, pos->svc_id, pkt_type, 0, ©);
- if (copy)
- iobuffer_dec_ref(copy);
- }
- }
- spinlock_leave(&mgr->entity_state_subscribe_lock);
- sp_dbg_info("bcast entity on connection! src: %s, dst: %s", entity_src->cfg->name, entity_dst->cfg->name);
- }
- static void mgr_on_entity_state(sp_mod_mgr_t *mgr, sp_entity_t *entity, int trigger_entity_id, int last_state, int curr_state)
- {
- sp_env_t *env = NULL;
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &trigger_entity_id, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &last_state, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &curr_state, 0);
- mgr_bcast_entity_state_event(mgr, entity, SP_PKT_MOD|MOD_CMD_RECORD_STATE_EVENT, pkt);
- iobuffer_dec_ref(pkt);
- sp_dbg_info("entity %s change state from %d to %d", entity->cfg->name, last_state, curr_state);
- // gui显示实体状态变化
- env = sp_get_env();
- sp_gui_show_entity_info(env->gui, entity->cfg->name, curr_state);
- }
- static void mgr_on_user_state(sp_mod_mgr_t *mgr, sp_entity_t *entity, int last_state, int curr_state)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &last_state, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &curr_state, 0);
- mgr_bcast_entity_state_event(mgr, entity, SP_PKT_MOD|MOD_CMD_USER_STATE_EVENT, pkt);
- iobuffer_dec_ref(pkt);
- }
- static void mgr_on_create_connection(sp_mod_mgr_t *mgr, sp_entity_t *entity_src, sp_entity_t *entity_dst)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &entity_src->cfg->idx, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &entity_dst->cfg->idx, 0);
- mgr_bcast_entity_on_connection(mgr, entity_src, entity_dst, SP_PKT_MOD|MOD_CMD_RECORD_CREATE_CONN, pkt);
- iobuffer_dec_ref(pkt);
- }
- static void mgr_on_close_connection(sp_mod_mgr_t *mgr, sp_entity_t *entity_src, sp_entity_t *entity_dst)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &entity_src->cfg->idx, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &entity_dst->cfg->idx, 0);
- mgr_bcast_entity_on_connection(mgr, entity_src, entity_dst, SP_PKT_MOD|MOD_CMD_RECORD_CLOSE_CONN, pkt);
- iobuffer_dec_ref(pkt);
- }
- static void mgr_bcast_entity_life_event(sp_mod_mgr_t *mgr, int pkt_type, iobuffer_t *pkt)
- {
- entity_life_subscribe_entry *pos;
- spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
- list_for_each_entry(pos, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
- iobuffer_t *copy = iobuffer_clone(pkt);
- sp_svc_post(mgr->shell_svc, pos->mod_id, pos->svc_id, pkt_type, 0, ©);
- if (copy)
- iobuffer_dec_ref(copy);
- }
- spinlock_leave(&mgr->entity_life_subscribe_lock);
- }
- static void mgr_on_entity_create(sp_mod_mgr_t *mgr, sp_entity_t *entity, int trigger_entity_id)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &trigger_entity_id, 0);
- mgr_bcast_entity_life_event(mgr, SP_PKT_MOD|MOD_CMD_RECORD_ENTITY_CREATE, pkt);
- iobuffer_dec_ref(pkt);
- }
- static void mgr_on_entity_close(sp_mod_mgr_t *mgr, sp_entity_t *entity, int trigger_entity_id, int cause_code)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &trigger_entity_id, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &cause_code, 0);
- mgr_bcast_entity_life_event(mgr, SP_PKT_MOD|MOD_CMD_RECORD_ENTITY_CLOSE, pkt);
- iobuffer_dec_ref(pkt);
- }
- static void mgr_on_entity_exception(sp_mod_mgr_t *mgr, sp_entity_t *entity, int trigger_entity_id, int error)
- {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &error, 0);
- iobuffer_write(pkt, IOBUF_T_I4, &entity->state, 0);
- mgr_bcast_entity_life_event(mgr, SP_PKT_MOD|MOD_CMD_RECORD_ENTITY_EXCEPTION, pkt);
- iobuffer_dec_ref(pkt);
- }
- static int on_detect_process_end(process_monitor_t *monitor, HANDLE hproc, void *user_data)
- {
- sp_mod_mgr_t *mgr = (sp_mod_mgr_t*)user_data;
- sp_mod_t *mod;
- //sp_dbg_debug("enter on_detect_process_end, handle: 0x%08X", hproc);
- list_for_each_entry(mod, &mgr->mod_list, sp_mod_t, entry) {
- //sp_dbg_debug("%s state: %d, pid: %d, handle: 0x%08X", mod->cfg->name, mod->state, mod->process.pid, mod->process.handle);
- if (mod->state && mod->process.handle == hproc) {
- sp_entity_t *ent;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- sp_dbg_info("detect process [mod=%s] exit", mod->cfg->name); //no exit code
- process_close(&mod->process);
- mod->state = SP_MODULE_STATE_UNLOAD; //
- list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
- if (ent->state != EntityState_Killed && ent->state != EntityState_Close) { //
- int last_state = ent->state;
- ent->state = EntityState_Lost;
- mgr_on_entity_state(mgr, ent, ent->cfg->idx, last_state, ent->state);
- mgr_on_entity_close(mgr, ent, ent->cfg->idx, CloseCause_Lost);
- }
- }
- SetEvent(mod->evt_app_exit);
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- break;
- }
- }
- return TRUE; // delete process handle
- }
- static void subscribe_entity_state(sp_mod_mgr_t *mgr, int mod_id, int svc_id, int target_entity_id)
- {
- int found = 0;
- entity_state_subscribe_entry *pos;
- spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
- list_for_each_entry(pos, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
- if (pos->mod_id == mod_id && pos->svc_id == svc_id && pos->target_entity_id == target_entity_id) {
- found = TRUE;
- break;
- }
- }
- if (found) {
- pos->instance ++;
- } else {
- pos = MALLOC_T(entity_state_subscribe_entry);
- pos->instance = 1;
- pos->mod_id = mod_id;
- pos->svc_id = svc_id;
- pos->target_entity_id = target_entity_id;
- list_add_tail(&pos->entry, &mgr->entity_state_subscribe_list);
- }
- spinlock_leave(&mgr->entity_state_subscribe_lock);
- }
- static void unsubscribe_entity_state(sp_mod_mgr_t *mgr, int mod_id, int svc_id, int target_entity_id)
- {
- int found = 0;
- entity_state_subscribe_entry *pos;
- spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
- list_for_each_entry(pos, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
- if (pos->mod_id == mod_id && pos->svc_id == svc_id && pos->target_entity_id == target_entity_id) {
- found = TRUE;
- break;
- }
- }
- if (found) {
- pos->instance--;
- if (pos->instance == 0) {
- list_del(&pos->entry);
- free(pos);
- }
- }
- spinlock_leave(&mgr->entity_state_subscribe_lock);
- }
- static void subscribe_entity_life(sp_mod_mgr_t *mgr, int mod_id, int svc_id)
- {
- int found = 0;
- entity_life_subscribe_entry *pos;
- spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
- list_for_each_entry(pos, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
- if (pos->mod_id == mod_id && pos->svc_id == svc_id) {
- found = TRUE;
- break;
- }
- }
- if (found) {
- pos->instance ++;
- } else {
- pos = MALLOC_T(entity_life_subscribe_entry);
- pos->instance = 1;
- pos->mod_id = mod_id;
- pos->svc_id = svc_id;
- list_add_tail(&pos->entry, &mgr->entity_life_subscribe_list);
- }
- spinlock_leave(&mgr->entity_life_subscribe_lock);
- }
- static void unsubscribe_entity_life(sp_mod_mgr_t *mgr, int mod_id, int svc_id)
- {
- int found = 0;
- entity_life_subscribe_entry *pos;
- spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
- list_for_each_entry(pos, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
- if (pos->mod_id == mod_id && pos->svc_id == svc_id ) {
- found = TRUE;
- break;
- }
- }
- if (found) {
- pos->instance--;
- if (pos->instance == 0) {
- list_del(&pos->entry);
- free(pos);
- }
- }
- spinlock_leave(&mgr->entity_life_subscribe_lock);
- }
- static void clear_entity_state(sp_mod_mgr_t *mgr, int mod_id)
- {
- entity_state_subscribe_entry *pos, *n;
- spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
- list_for_each_entry_safe(pos, n, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
- if (pos->mod_id == mod_id) {
- list_del(&pos->entry);
- free(pos);
- }
- }
- spinlock_leave(&mgr->entity_state_subscribe_lock);
- }
- static void clear_entity_state_list_all(sp_mod_mgr_t *mgr)
- {
- entity_state_subscribe_entry *pos, *n;
- spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
- list_for_each_entry_safe(pos, n, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
- list_del(&pos->entry);
- free(pos);
- }
- spinlock_leave(&mgr->entity_state_subscribe_lock);
- }
- static void clear_entity_life(sp_mod_mgr_t *mgr, int mod_id)
- {
- entity_life_subscribe_entry *pos, *n;
- spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
- list_for_each_entry_safe(pos, n, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
- if (pos->mod_id == mod_id) {
- list_del(&pos->entry);
- free(pos);
- }
- }
- spinlock_leave(&mgr->entity_life_subscribe_lock);
- }
- static void clear_entity_life_list_all(sp_mod_mgr_t *mgr)
- {
- entity_life_subscribe_entry *pos, *n;
- spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
- list_for_each_entry_safe(pos, n, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
- list_del(&pos->entry);
- free(pos);
- }
- spinlock_leave(&mgr->entity_life_subscribe_lock);
- }
- static int mgr_on_pkt(sp_svc_t *svc,int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt, void *user_data)
- {
- sp_mod_mgr_t *mgr = (sp_mod_mgr_t *)user_data;
- if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD) {
- int result = pkt_id;
- int cmd_type = SP_GET_TYPE(pkt_type);
- sp_mod_t *mod;
- if (cmd_type == MOD_CMD_INIT || cmd_type == MOD_CMD_TERM) { // not necessary {bug}
- list_for_each_entry(mod, &mgr->mod_list, sp_mod_t, entry) {
- if (mod->cfg->idx == epid) {
- if (mod->doing) {
- mod->wait_result = result;
- SetEvent(mod->evt_wait_handle);
- }
- break;
- }
- }
- }
- else if (cmd_type == MOD_CMD_USER_STATE_EVENT)
- {
- int last_state, curr_state;
- sp_entity_t *entity = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
- iobuffer_read(*p_pkt, IOBUF_T_I4, &last_state, NULL);
- iobuffer_read(*p_pkt, IOBUF_T_I4, &curr_state, NULL);
- mgr_on_user_state(mgr, entity, last_state, curr_state);
- }
- else if (cmd_type == MOD_CMD_REPORT_CREATE_CONN) {
- sp_entity_t *entity_src = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
- sp_entity_t *entity_dst = sp_mod_mgr_find_entity_by_idx(mgr, pkt_id);
- if (entity_src && entity_dst)
- mgr_on_create_connection(mgr, entity_src, entity_dst);
- } else if (cmd_type == MOD_CMD_REPROT_CLOSE_CONN) {
- sp_entity_t *entity_src = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
- sp_entity_t *entity_dst = sp_mod_mgr_find_entity_by_idx(mgr, pkt_id);
- mgr_on_close_connection(mgr, entity_src, entity_dst);
- } else if (cmd_type == MOD_CMD_REPORT_EXCEPTION) {
- sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
- mgr_on_entity_exception(mgr, ent, ent->cfg->idx, Error_Exception);
- } else if (cmd_type == MOD_CMD_SWITCH_RUNNING_MODE) {
- // BugFix [4/3/2020 9:09 Gifur]
- mod = sp_mod_mgr_find_module_by_idx(mgr, epid);
- sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
- int state = pkt_id;
- if ((ent->state == EntityState_Idle || ent->state == EntityState_Busy) && state != ent->state) {
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (ent->state == EntityState_Idle || ent->state == EntityState_Busy) {
- if (ent->state != state) {
- int old_state = ent->state;
- ent->state = state;
- mgr_on_entity_state(mgr, ent, ent->cfg->idx, old_state, state);
- }
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- }
- } else if (cmd_type == MOD_CMD_SUBSCRIBE_STATE_LISTENER) {
- subscribe_entity_state(mgr, epid, svc_id, pkt_id);
- } else if (cmd_type == MOD_CMD_UNSUBSCRIBE_STATE_LISTENER) {
- unsubscribe_entity_state(mgr, epid, svc_id, pkt_id);
- } else if (cmd_type == MOD_CMD_SUBSCRIBE_LIFE_LISTENER) {
- subscribe_entity_life(mgr, epid, svc_id);
- } else if (cmd_type == MOD_CMD_UNSUBSCRIBE_LIFE_LISTENER) {
- unsubscribe_entity_life(mgr, epid, svc_id);
- } else if (cmd_type == MOD_CMD_ENT_RESULT) {
- sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
- if (ent->mod->doing) {
- ent->wait_result = result;
- SetEvent(ent->evt_wait_handle);
- }
- } else if (cmd_type == MOD_CMD_MOD_RESULT) {
- mod = sp_mod_mgr_find_module_by_idx(mgr, epid);
- if (mod->doing) {
- mod->wait_result = result;
- SetEvent(mod->evt_wait_handle);
- }
- } else if (cmd_type == MOD_CMD_REPORT_REDIRECT_SUBSCRIBE) {
- sp_uid_t uid;
- int suggest_entity_id;
- iobuffer_read(*p_pkt, IOBUF_T_I8, &uid, NULL);
- iobuffer_read(*p_pkt, IOBUF_T_I4, &suggest_entity_id, NULL);
- sp_bcm_daemon_process_redirect_subscribe(mgr->shell_daemon, svc_id, &uid, suggest_entity_id);
- } else {
- assert(0);
- }
- return FALSE;
- }
- return TRUE;
- }
- static void mgr_on_sys(sp_svc_t *svc,int epid, int state, void *user_data)
- {
- sp_mod_mgr_t *mgr = (sp_mod_mgr_t *)user_data;
- if (state == BUS_STATE_OFF) {
- clear_entity_state(mgr, epid);
- clear_entity_life(mgr, epid);
- }
- }
- int sp_mod_mgr_create(sp_mod_mgr_t **p_mgr)
- {
- sp_mod_mgr_t *mgr = shm_malloc(sizeof(sp_mod_mgr_t));
- memset(mgr, 0, sizeof(sp_mod_mgr_t));
- InitializeCriticalSection(&mgr->lock);
- INIT_LIST_HEAD(&mgr->mod_list);
- process_monitor_create(&mgr->process_monitor);
- process_monitor_set_cb(mgr->process_monitor, &on_detect_process_end, mgr);
- spinlock_init(&mgr->entity_life_subscribe_lock);
- INIT_LIST_HEAD(&mgr->entity_life_subscribe_list);
- spinlock_init(&mgr->entity_state_subscribe_lock);
- INIT_LIST_HEAD(&mgr->entity_state_subscribe_list);
- mgr->arr_ent = shm_array_make(SP_MAX_ENTITY, sizeof(sp_entity_t*));
- mgr->arr_mod = shm_array_make(SP_MAX_MODULE, sizeof(sp_mod_t*));
- mgr->instance_seq = 0;
- mgr->shell_svc = NULL;
- mgr->shell_daemon = NULL;
- *p_mgr = mgr;
- return 0;
- }
- void sp_mod_mgr_destroy(sp_mod_mgr_t *mgr)
- {
- assert(list_empty(&mgr->mod_list));
- process_monitor_destroy(mgr->process_monitor);
- DeleteCriticalSection(&mgr->lock);
- shm_free(mgr);
- }
- void sp_mod_mgr_bind_shell_svc(sp_mod_mgr_t *mgr, sp_svc_t *svc)
- {
- mgr->shell_svc = svc;
- }
- int sp_mod_mgr_add_module(sp_mod_mgr_t *mgr, sp_cfg_shell_module_t *cfg_mod)
- {
- sp_mod_t *mod;
- assert(mgr);
- mod = sp_mod_mgr_find_module_by_name(mgr, cfg_mod->name);
- if (!mod) {
- //int len;
- mod = shm_malloc(sizeof(sp_mod_t));
- //len = sp_dir_get_path(env->dir, SP_DIR_MODULE_BIN, mod_name, NULL, 0);
- //mod->path = shm_malloc(len+1);
- //sp_dir_get_path(env->dir, SP_DIR_MODULE_BIN, mod_name, mod->path, 0);
- mod->state = SP_MODULE_STATE_UNLOAD;
- mod->mgr = mgr;
- mod->cfg = cfg_mod;
- mod->doing = 0;
- mod->wait_result = 0;
- mod->start_time = 0;
- mod->evt_app_exit = CreateEventA(NULL, TRUE, TRUE, NULL);
- mod->evt_wait_handle = CreateEventA(NULL, TRUE, FALSE, NULL);
- process_init(&mod->process);
- INIT_LIST_HEAD(&mod->entity_list);
- list_add_tail(&mod->entry, &mgr->mod_list);
- ARRAY_IDX(mgr->arr_mod, cfg_mod->idx, sp_mod_t*) = mod;
- } else {
- sp_dbg_debug("module %s already exist!", cfg_mod->name);
- return Error_Duplication;
- }
- return 0;
- }
- int sp_mod_mgr_add_entity(sp_mod_mgr_t *mgr, sp_cfg_shell_entity_t *cfg_ent)
- {
- sp_mod_t *mod;
- sp_entity_t *ent;
- assert(mgr);
- mod = sp_mod_mgr_find_module_by_name(mgr, cfg_ent->mod->name);
- if (mod) {
- ent = sp_mod_find_entity_by_name(mod, cfg_ent->name);
- if (!ent) {
- ent = shm_malloc(sizeof(sp_entity_t));
- ent->state = EntityState_NoStart;
- ent->mod = mod;
- ent->wait_result = 0;
- ent->first_start_time = 0;
- ent->last_start_time = 0;
- ent->state_start_time = 0;
- ent->cfg = cfg_ent;
- ent->service_flag = 0;
- ent->evt_wait_handle = CreateEventA(NULL, TRUE, FALSE, NULL);
- ent->instance_id = 0;
- ent->user_state = 0;
- list_add_tail(&ent->entry, &mod->entity_list);
- ARRAY_IDX(mgr->arr_ent, cfg_ent->idx, sp_entity_t*) = ent;
- } else {
- return Error_Duplication;
- }
- } else {
- return Error_NotExist;
- }
- return 0;
- }
- int sp_mod_mgr_remove_module(sp_mod_mgr_t *mgr, const char *mod_name)
- {
- sp_mod_t *mod;
- assert(mgr);
- assert(mod_name);
- mod = sp_mod_mgr_find_module_by_name(mgr, mod_name);
- if (mod) {
- assert(mod->state == SP_MODULE_STATE_UNLOAD);
- assert(list_empty(&mod->entity_list));
- list_del(&mod->entry);
- CloseHandle(mod->evt_app_exit);
- CloseHandle(mod->evt_wait_handle);
- shm_free(mod);
- } else {
- return Error_NotExist;
- }
- return 0;
- }
- int sp_mod_mgr_remove_entity(sp_mod_mgr_t *mgr, const char *entity_name)
- {
- sp_entity_t *ent;
- assert(mgr);
- assert(entity_name);
- ent = sp_mod_mgr_find_entity_by_name(mgr, entity_name);
- if (ent) {
- list_del(&ent->entry);
- CloseHandle(ent->evt_wait_handle);
- shm_free(ent);
- } else {
- return Error_NotExist;
- }
- return 0;
- }
- int sp_mod_mgr_init(sp_mod_mgr_t *mgr)
- {
- int rc;
- sp_mod_t *mod_pos;
- list_for_each_entry(mod_pos, &mgr->mod_list, sp_mod_t, entry) { //遍历
- sp_entity_t *ent_pos;
- mgr->arr_mod->nelts++;
- list_for_each_entry(ent_pos, &mod_pos->entity_list, sp_entity_t, entry) {
- mgr->arr_ent->nelts++;
- }
- }
- rc = process_monitor_start(mgr->process_monitor);
- if (rc == 0) {
- rc = sp_svc_add_pkt_handler(mgr->shell_svc, (int)mgr, SP_PKT_MOD, &mgr_on_pkt, mgr);
- } else {
- rc = Error_Unexpect;
- }
- return rc;
- }
- void sp_mod_mgr_term(sp_mod_mgr_t *mgr)
- {
- sp_svc_remove_pkt_handler(mgr->shell_svc, (int)mgr, SP_PKT_MOD);
- process_monitor_stop(mgr->process_monitor);
- mgr->arr_ent->nelts = 0;
- mgr->arr_mod->nelts = 0;
- }
- void sp_mod_mgr_bind_bcm_daemon(sp_mod_mgr_t *mgr, sp_bcm_daemon_t *daemon)
- {
- mgr->shell_daemon = daemon;
- }
- void sp_mod_mgr_lock(sp_mod_mgr_t *mgr)
- {
- EnterCriticalSection(&mgr->lock);
- //sp_dbg_info("lock mgr %d, lock %d",mgr, &(mgr->lock));
- }
- void sp_mod_mgr_unlock(sp_mod_mgr_t *mgr)
- {
- LeaveCriticalSection(&mgr->lock);
- //sp_dbg_info("unlock mgr %d, lock %d", mgr, &(mgr->lock));
- }
- sp_mod_t *sp_mod_mgr_find_module_by_name(sp_mod_mgr_t *mgr, const char *mod_name)
- {
- sp_mod_t *mod;
- if (!mod_name)
- return NULL;
- list_for_each_entry(mod, &mgr->mod_list, sp_mod_t, entry) {
- if (_stricmp(mod_name, mod->cfg->name) == 0)
- return mod;
- }
- return NULL;
- }
- sp_mod_t *sp_mod_mgr_find_module_by_idx(sp_mod_mgr_t *mgr, int mod_idx)
- {
- if (mod_idx == -1 || mod_idx >= mgr->arr_mod->nelts)
- return NULL;
-
- return ARRAY_IDX(mgr->arr_mod, mod_idx, sp_mod_t*);
- }
- sp_entity_t *sp_mod_find_entity_by_name(sp_mod_t *mod, const char *entity_name)
- {
- sp_entity_t *ent;
- if (!entity_name)
- return NULL;
- list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
- if (_stricmp(ent->cfg->name, entity_name) == 0)
- return ent;
- }
- return NULL;
- }
- sp_entity_t *sp_mod_find_entity_by_idx(sp_mod_t *mod, int entity_idx)
- {
- if (entity_idx == -1 || entity_idx >= mod->mgr->arr_ent->nelts)
- return NULL;
- return ARRAY_IDX(mod->mgr->arr_ent, entity_idx, sp_entity_t*);
- }
- sp_entity_t *sp_mod_find_entity_by_devel_id(sp_mod_t *mod, int devel_id)
- {
- sp_entity_t *ent;
- list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
- if (ent->cfg->devel_id == devel_id)
- return ent;
- }
- return NULL;
- }
- sp_entity_t *sp_mod_find_entity_by_inst_id(sp_mod_t *mod, int inst_id)
- {
- sp_entity_t *ent;
- list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
- if (ent->instance_id == inst_id)
- return ent;
- }
- return NULL;
- }
- sp_entity_t *sp_mod_mgr_find_entity_by_name(sp_mod_mgr_t *mgr, const char *entity_name)
- {
- sp_mod_t *mod;
- if (!entity_name)
- return NULL;
- list_for_each_entry(mod, &mgr->mod_list, sp_mod_t, entry) {
- sp_entity_t *ent = sp_mod_find_entity_by_name(mod, entity_name);
- if (ent)
- return ent;
- }
- return NULL;
- }
- sp_entity_t *sp_mod_mgr_find_entity_by_idx(sp_mod_mgr_t *mgr, int entity_id)
- {
- if (entity_id == -1 || entity_id >= mgr->arr_ent->nelts)
- return NULL;
- return ARRAY_IDX(mgr->arr_ent, entity_id, sp_entity_t*);
- }
- sp_entity_t *sp_mod_mgr_find_entity_by_devel_id(sp_mod_mgr_t *mgr, int devel_id)
- {
- int i;
- for (i = 1; i < mgr->arr_ent->nelts; ++i) {
- sp_entity_t *ent = ARRAY_IDX(mgr->arr_ent, i, sp_entity_t*);
- if (ent->cfg->devel_id == devel_id)
- return ent;
- }
- return NULL;
- }
- sp_entity_t *sp_mod_mgr_find_entity_by_inst_id(sp_mod_mgr_t *mgr, int inst_id)
- {
- int i;
- for (i = 1; i < mgr->arr_ent->nelts; ++i) {
- sp_entity_t *ent = ARRAY_IDX(mgr->arr_ent, i, sp_entity_t*);
- if (ent->instance_id == inst_id)
- return ent;
- }
- return NULL;
- }
- struct list_head* sp_mod_mgr_get_module_list_head(sp_mod_mgr_t *mgr)
- {
- return &mgr->mod_list;
- }
- int sp_mod_mgr_get_entity_array_nelts(sp_mod_mgr_t *mgr)
- {
- return mgr->arr_ent->nelts;
- }
- static int try_lock_doing(sp_mod_mgr_t *mgr, sp_mod_t *mod)
- {
- int ok = FALSE;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (!mod->doing) {
- mod->doing = 1;
- ok = TRUE;
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- return ok;
- }
- static void unlock_doing(sp_mod_mgr_t *mgr, sp_mod_t *mod)
- {
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- mod->doing = 0;
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- }
- static int load_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
- {
- int rc = 0;
- sp_env_t *env = sp_get_env();
- sp_dbg_debug("begin load module %s", mod->cfg->name);
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (!mod->state) {
- ResetEvent(mod->evt_app_exit);
- if (0 != create_module_process(mod->cfg->name, mod->cfg->idx, env->shm_range, mod->cfg->group, &mod->process)) {
- sp_dbg_debug("sp_mod_mgr_load_module %s failed!, create module process failed", mod->cfg->name);
- rc = Error_Unexpect;
- }
- } else {
- rc = Error_Duplication;
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- const int interval = 50; //consider sleep operation below, here would consume 4 min at terriable situation.
- const int tries = PROCESS_TIMEOUT / interval;
- int i;
- ResetEvent(mod->evt_wait_handle);
- sp_dbg_debug("get remote entitiy state...");
- for (i = 0; i < tries; ++i) {
- int state = BUS_STATE_OFF;
- rc = sp_svc_get_state(mgr->shell_svc, mod->cfg->idx, &state);
- sp_dbg_debug("cfg::idx: %d, state: %d", mod->cfg->idx, state);
- if (rc == 0) {
- if (state != BUS_STATE_ON) {
- DWORD dwRet;
- dwRet = WaitForSingleObject(mod->process.handle, (DWORD)interval); //wait for entity thread end
- if (dwRet == WAIT_OBJECT_0) {
- sp_dbg_debug("detect process %s exit exception!", mod->cfg->name);
- rc = Error_Unexpect;
- break;
- }
- } else {
- sp_dbg_info("mod is online now!, %s", mod->cfg->name);
- break;
- }
- } else {
- sp_dbg_info("get epid state failed!");
- break;
- }
- }
- if (rc == 0)
- rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, SP_INVALID_SVC_ID, SP_PKT_MOD|MOD_CMD_INIT, 0, NULL);
- if (rc) {
- sp_dbg_error("send out mod init cmd failed!");
- } else {
- sp_dbg_info("send out mod init cmd ok!, %s", mod->cfg->name);
- for (i = 0; i < tries; ++i) {
- #ifdef _WIN32
- HANDLE hs[] = { mod->evt_wait_handle, mod->process.handle }; //wait for entity thread end
- DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, (DWORD)interval);
- #else
- DWORD dwRet = WaitForSingleObject(mod->evt_wait_handle, (DWORD)interval);
- if (dwRet == WAIT_TIMEOUT) {
- dwRet = WaitForSingleObject(mod->process.handle, 0);
- if (dwRet == WAIT_OBJECT_0) {
- dwRet = WAIT_OBJECT_0 + 1;
- }
- }
- #endif //_WIN32
- if (dwRet == WAIT_OBJECT_0) {
- sp_dbg_info("receive reply from module %s ok!", mod->cfg->name);
- rc = mod->wait_result;
- break;
- } else if (dwRet == WAIT_OBJECT_0+1) {
- sp_dbg_debug("detect process %s exit exception!", mod->cfg->name);
- rc = Error_Unexpect;
- break;
- } else if(dwRet == WAIT_TIMEOUT){
- rc = Error_TimeOut;
- }
- else {
- sp_dbg_error("wait for multi object failed!! err=%d", GetLastError());
- rc = Error_Unexpect;
- break;
- }
- }
- }
- }
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- mod->state = SP_MODULE_STATE_LOAD;
- mod->start_time = y2k_time_now();
- process_monitor_add(mgr->process_monitor, &mod->process);
- sp_dbg_info("load module ok! start time = %d, state = LOADED", mod->start_time);
- } else {
- #ifdef _WIN32
- killModByPipe(findGroupProcessInfo(mod->cfg->group, mod->cfg->name), mod->cfg->name);
- #else
- TerminateProcess(mod->process.handle, -1);
- #endif //_WIN32
- WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
- process_close(&mod->process);
- sp_dbg_info("load module failed!");
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- return rc;
- }
- static int unload_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
- {
- int rc = 0;
- sp_entity_t *pos;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (mod->state) {
- list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
- if (pos->state != EntityState_Killed &&
- pos->state != EntityState_Close && pos->state != EntityState_NoStart) {
- sp_dbg_debug("unload %s module, has entity not in idle state!", mod->cfg->name);
- rc = Error_Bug;
- break;
- }
- }
- if (rc == 0) {
- ResetEvent(mod->evt_wait_handle);
- rc = sp_svc_send(mod->mgr->shell_svc, mod->cfg->idx, SP_INVALID_SVC_ID, SP_PKT_MOD|MOD_CMD_TERM, 0, NULL);
- if (rc != 0) {
- sp_dbg_debug("unload %s module, send pkt cmd failed!", mod->cfg->name);
- }
- }
- } else {
- sp_dbg_debug("module %s already unloaded!", mod->cfg->name);
- rc = Error_NotInit;
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- int removed = 0;
- /*TODO: the clear job depend on different result seems no different.*/
- for (;;) {
- HANDLE hs[] = {mod->evt_app_exit, mod->evt_wait_handle};
- DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
- if (dwRet == WAIT_OBJECT_0) { // app exit
- break;
- } else if (dwRet == WAIT_OBJECT_0+1) {
- ResetEvent(mod->evt_wait_handle);
- if (mod->wait_result != 0) {
- HANDLE hprocess = mod->process.handle;
- if (hprocess && process_monitor_remove(mgr->process_monitor, &mod->process) == 0) {
- removed = 1;
- #ifdef _WIN32
- killModByPipe(findGroupProcessInfo(mod->cfg->group, mod->cfg->name), mod->cfg->name);
- #else
- TerminateProcess(mod->process.handle, -1);
- #endif //_WIN32
- WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
- process_close(&mod->process);
- break;
- }
- } else {
- HANDLE hprocess = mod->process.handle;
- if (hprocess && process_monitor_remove(mgr->process_monitor, &mod->process) == 0) {
- DWORD tmp;
- removed = 1;
- tmp = WaitForSingleObject(hprocess, PROCESS_EXIT_TIMEOUT);
- if (tmp == WAIT_TIMEOUT) {
- sp_dbg_warn("wait process %d normal exit timeout!", mod->cfg->name);
- #ifdef _WIN32
- killModByPipe(findGroupProcessInfo(mod->cfg->group, mod->cfg->name), mod->cfg->name);
- #else
- TerminateProcess(mod->process.handle, -1);
- #endif //_WIN32
- WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
- }
- process_close(&mod->process);
- break;
- }
- }
- } else {
- HANDLE hprocess = mod->process.handle;
- if (hprocess && process_monitor_remove(mgr->process_monitor, &mod->process) == 0) {
- removed = 1;
- #ifdef _WIN32
- killModByPipe(findGroupProcessInfo(mod->cfg->group, mod->cfg->name), mod->cfg->name);
- #else
- TerminateProcess(mod->process.handle, -1);
- #endif //_WIN32
- WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
- process_close(&mod->process);
- break;
- }
- }
- }
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (removed) {
- mod->state = SP_MODULE_STATE_UNLOAD;
- SetEvent(mod->evt_app_exit);
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- }
- return rc;
- }
- #ifdef _WIN32
- static int SpTerminateProcess(sp_mod_t* mod)
- {
- if (0 != killModByPipe(findGroupProcessInfo(mod->cfg->group, mod->cfg->name), mod->cfg->name)) {
- char szCmd[256];
- int nRet = 0;
- sp_dbg_debug("terminate %s fail: 0x%X, retry with taskkill", mod->cfg->name, GetLastError());
- sprintf_s(szCmd, 256, "TASKKILL /PID %d /F", mod->process.pid);
- WinExec(szCmd, SW_HIDE);
- //nRet = system(szCmd);
- return nRet != -1;
- }
- return 0;
- }
- #endif //_WIN32
- /*remove from monitor and kill it directory!!*/
- static int terminate_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
- {
- int rc = 0;
- sp_entity_t *pos;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (mod->state) {
- if (mod->process.handle) {
- if (process_monitor_remove(mgr->process_monitor, &mod->process) == 0) {
- #ifdef _WIN32
- SpTerminateProcess(mod);
- #else
- TerminateProcess(mod->process.handle, -1);
- #endif //_WIN32
- WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
- process_close(&mod->process);
- mod->state = 0;
- list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
- int old_state = pos->state;
- if (old_state != EntityState_Close && old_state != EntityState_Killed) {
- pos->state = EntityState_Killed;
- mgr_on_entity_state(mgr, pos, trigger_entity_id, old_state, pos->state);
- mgr_on_entity_close(mgr, pos, trigger_entity_id, CloseCause_Lost);
- }
- }
- SetEvent(mod->evt_app_exit);
- } else {
- sp_dbg_debug("mod %s is remove monitor failed!", mod->cfg->name);
- rc = -1;
- }
- } else {
- list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
- if (pos->state != EntityState_Killed && pos->state != EntityState_Close) {
- int old_state = pos->state;
- pos->state = EntityState_Killed;
- mgr_on_entity_state(mgr, pos, trigger_entity_id, old_state, pos->state);
- mgr_on_entity_close(mgr, pos, trigger_entity_id, CloseCause_Lost);
- }
- }
- mod->state = SP_MODULE_STATE_UNLOAD;
- }
- } else {
- list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
- if (pos->state != EntityState_Killed && pos->state != EntityState_Close && pos->state != EntityState_NoStart) {
- int old_state = pos->state;
- pos->state = EntityState_Killed;
- mgr_on_entity_state(mgr, pos, trigger_entity_id, old_state, pos->state);
- mgr_on_entity_close(mgr, pos, trigger_entity_id, CloseCause_Lost);
- }
- }
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- return rc;
- }
- static int start_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, const char *cmdline, int trigger_entity_id)
- {
- int rc = 0;
- sp_mod_t *mod = ent->mod;
- sp_dbg_debug("begin start entity %s", ent->cfg->name);
-
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (mod->state) {
- if (ent->state == EntityState_NoStart || ent->state == EntityState_Killed || ent->state == EntityState_Close) {
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_STR, cmdline, -1);
- iobuffer_write(pkt, IOBUF_T_I4, &trigger_entity_id, 0);
- ResetEvent(ent->evt_wait_handle);
- ent->instance_id = mgr_new_instance_id(mgr);
- rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_START, ent->cfg->idx, &pkt);
- if (rc == 0) {
- int last_state = ent->state;
- sp_dbg_debug("start entity %s, send cmd start ok!", ent->cfg->name);
- ent->state_start_time = y2k_time_now();
- if (ent->first_start_time == 0)
- ent->first_start_time = ent->state_start_time;
- ent->last_start_time = ent->state_start_time;
- ent->state = EntityState_Starting;
- mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
- } else {
- sp_dbg_debug("start entity %s, send cmd start failed!", ent->cfg->name);
- }
- if (pkt)
- iobuffer_dec_ref(pkt);
- } else {
- rc = Error_InvalidState;
- sp_dbg_debug("entity %s state is not correct!", ent->cfg->name);
- }
- } else {
- sp_dbg_debug("entity's %s 's module is not load or is pending!", ent->cfg->name);
- rc = Error_Pending;
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- int last_state = ent->state;
- HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
- DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
- if (dwRet == WAIT_OBJECT_0) {
- sp_dbg_debug("wait for start entity %s result, app exit!", ent->cfg->name);
- rc = Error_Unexpect;
- } else if (dwRet == WAIT_OBJECT_0+1) {
- sp_dbg_debug("wait for start entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
- rc = ent->wait_result;
- } else {
- sp_dbg_debug("wait for start entity %s timeout!", ent->cfg->name);
- rc = Error_TimeOut;
- }
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- ent->state = EntityState_Idle;
- ent->state_start_time = y2k_time_now();
- mgr_on_entity_create(mgr, ent, trigger_entity_id);
- } else {
- ent->state = EntityState_Lost;
- ent->state_start_time = y2k_time_now();
- mgr_on_entity_exception(mgr, ent, trigger_entity_id, Error_Exception);
- }
- mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- }
- return rc;
- }
- static int stop_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id, int cause_code)
- {
- int rc = 0;
- sp_mod_t *mod = ent->mod;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (mod->state) {
- if (ent->state == EntityState_Busy || ent->state == EntityState_Idle || ent->state == EntityState_Pause) {
- iobuffer_t *body = iobuffer_create(-1, -1);
- ResetEvent(ent->evt_wait_handle);
- iobuffer_write(body, IOBUF_T_I4, &trigger_entity_id, 0);
- iobuffer_write(body, IOBUF_T_I4, &cause_code, 0);
- rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_STOP, ent->cfg->idx, &body);
- if (rc == 0) {
- int last_state = ent->state;
- sp_dbg_debug("stop entity %s, send cmd stop ok!", ent->cfg->name);
- ent->state = EntityState_UnLoading;
- ent->state_start_time = y2k_time_now();
- mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
- } else {
- sp_dbg_debug("stop entity %s, send cmd stop failed!", ent->cfg->name);
- }
- if (body)
- iobuffer_dec_ref(body);
- } else {
- rc = Error_InvalidState;
- sp_dbg_debug("entity %s state is not correct, you may call TerminateEntity first!", ent->cfg->name);
- }
- } else {
- sp_dbg_debug("entity's %s mod %s is not load or is pending!", ent->cfg->name, mod->cfg->name);
- rc = Error_Pending;
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- int last_state = ent->state;
- HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
- DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
- if (dwRet == WAIT_OBJECT_0) {
- sp_dbg_debug("wait for stop entity %s result, app exit!", ent->cfg->name);
- rc = Error_Unexpect;
- } else if (dwRet == WAIT_OBJECT_0+1) {
- sp_dbg_debug("wait for stop entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
- rc = ent->wait_result;
- } else {
- sp_dbg_debug("wait for stop entity %s timeout!", ent->cfg->name);
- rc = Error_TimeOut;
- }
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- ent->state = EntityState_Close;
- ent->state_start_time = y2k_time_now();
- mgr_on_entity_close(mgr, ent, trigger_entity_id, trigger_entity_id != ent->cfg->idx ? CloseCause_Other : CloseCause_Self);
- } else {
- ent->state = EntityState_Lost;
- ent->state_start_time = y2k_time_now();
- mgr_on_entity_exception(mgr, ent, trigger_entity_id, Error_Exception);
- }
- mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- }
- return rc;
- }
- static int pause_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
- {
- int rc = 0;
- sp_mod_t *mod;
- mod = ent->mod;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (mod->state) {
- if (ent->state == EntityState_Busy || ent->state == EntityState_Idle) {
- iobuffer_t *body = iobuffer_create(-1, -1);
- ResetEvent(ent->evt_wait_handle);
- iobuffer_write(body, IOBUF_T_I4, &trigger_entity_id, 0);
- rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_PAUSE, ent->cfg->idx, &body);
- if (rc == 0) {
- sp_dbg_debug("pause entity %s, send cmd pause ok!", ent->cfg->name);
- } else {
- sp_dbg_debug("pause entity %s, send cmd pause failed!", ent->cfg->name);
- }
- if (body)
- iobuffer_dec_ref(body);
- } else {
- rc = Error_InvalidState;
- sp_dbg_debug("entity %s state is not correct!", ent->cfg->name);
- }
- } else {
- sp_dbg_debug("entity's %s mod %s is not load or is pending!", ent->cfg->name, mod->cfg->name);
- rc = Error_Unexpect;
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
- DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
- if (dwRet == WAIT_OBJECT_0) {
- sp_dbg_debug("wait for pause entity %s result, app exit!", ent->cfg->name);
- rc = Error_Unexpect;
- } else if (dwRet == WAIT_OBJECT_0+1) {
- sp_dbg_debug("wait for pause entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
- rc = ent->wait_result;
- } else {
- sp_dbg_debug("wait for pause entity %s timeout!", ent->cfg->name);
- rc = Error_TimeOut;
- }
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- int last_state = ent->state;
- ent->state = EntityState_Pause;
- ent->state_start_time = y2k_time_now();
- mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- }
- return rc;
- }
- static int continue_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
- {
- int rc = 0;
- sp_mod_t*mod;
- mod = ent->mod;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (mod->state) {
- if (ent->state == EntityState_Pause) {
- iobuffer_t *body = iobuffer_create(-1, -1);
- ResetEvent(ent->evt_wait_handle);
- iobuffer_write(body, IOBUF_T_I4, &trigger_entity_id, 0);
- rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_CONTINUE, ent->cfg->idx, &body);
- if (rc == 0) {
- sp_dbg_debug("continue entity %s, send cmd continue ok!", ent->cfg->name);
- } else {
- sp_dbg_debug("continue entity %s, send cmd continue failed!", ent->cfg->name);
- }
- if (body)
- iobuffer_dec_ref(body);
- } else {
- rc = Error_InvalidState;
- sp_dbg_debug("entity %s state is not correct!", ent->cfg->name);
- }
- } else {
- sp_dbg_debug("entity's %s mod %s is not load or is pending!", ent->cfg->name, mod->cfg->name);
- rc = Error_Unexpect;
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
- DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
- if (dwRet == WAIT_OBJECT_0) {
- sp_dbg_debug("wait for continue entity %s result, app exit!", ent->cfg->name);
- rc = Error_Unexpect;
- } else if (dwRet == WAIT_OBJECT_0+1) {
- sp_dbg_debug("wait for continue entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
- rc = ent->wait_result;
- } else {
- sp_dbg_debug("wait for continue entity %s timeout!", ent->cfg->name);
- rc = Error_TimeOut;
- }
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- ent->state = EntityState_Idle;
- ent->state_start_time = y2k_time_now();
- mgr_on_entity_state(mgr, ent, trigger_entity_id, EntityState_Pause, ent->state);
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- }
- return rc;
- }
- static int test_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, int test_type, int trigger_entity_id)
- {
- int rc = 0;
- sp_mod_t *mod;
- mod = ent->mod;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (mod->state) {
- if (ent->state == EntityState_Idle || ent->state == EntityState_Busy || ent->state == EntityState_Pause) {
- iobuffer_t *body = iobuffer_create(-1, -1);
- ResetEvent(ent->evt_wait_handle);
- iobuffer_write(body, IOBUF_T_I4, &trigger_entity_id, 0);
- iobuffer_write(body, IOBUF_T_I4, &test_type, 0);
- rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_TEST, ent->cfg->idx, &body);
- if (rc == 0) {
- sp_dbg_debug("test entity %s, send cmd test ok!", ent->cfg->name);
- } else {
- sp_dbg_debug("test entity %s, send cmd test failed!", ent->cfg->name);
- }
- if (body)
- iobuffer_dec_ref(body);
- } else {
- rc = Error_InvalidState;
- sp_dbg_debug("entity %s state is not correct!", ent->cfg->name);
- }
- } else {
- sp_dbg_debug("entity's %s mod %s is not load or is pending!", ent->cfg->name, mod->cfg->name);
- rc = Error_Unexpect;
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- if (rc == 0) {
- HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
- DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, ENTITY_TEST_TIMEOUT);
- if (dwRet == WAIT_OBJECT_0) {
- sp_dbg_debug("wait for test entity %s result, app exit!", ent->cfg->name);
- rc = Error_Unexpect;
- } else if (dwRet == WAIT_OBJECT_0+1) {
- sp_dbg_debug("wait for test entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
- rc = ent->wait_result;
- } else {
- sp_dbg_debug("wait for test entity %s timeout!", ent->cfg->name);
- rc = Error_TimeOut;
- }
- }
- return rc;
- }
- int sp_mod_mgr_start_entity(sp_mod_mgr_t *mgr, int entity_id, const char *cmdline, int trigger_entity_id)
- {
- sp_entity_t *ent;
- ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
- if (!ent)
- return Error_NotExist;
- return sp_mod_mgr_start_entity2(mgr, ent, cmdline, trigger_entity_id);
- }
- int sp_mod_mgr_stop_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id, int cause_code)
- {
- sp_entity_t *ent;
- ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
- if (!ent)
- return Error_NotExist;
- return sp_mod_mgr_stop_entity2(mgr, ent, trigger_entity_id, cause_code);
- }
- int sp_mod_mgr_terminate_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id)
- {
- sp_entity_t *ent;
- ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
- if (!ent)
- return Error_NotExist;
- return sp_mod_mgr_terminate_entity2(mgr, ent, trigger_entity_id);
- }
- int sp_mod_mgr_pause_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id)
- {
- sp_entity_t *ent;
- ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
- if (!ent)
- return Error_NotExist;
- return sp_mod_mgr_pause_entity2(mgr, ent, trigger_entity_id);
- }
- int sp_mod_mgr_continue_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id)
- {
- sp_entity_t *ent;
- ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
- if (!ent)
- return Error_NotExist;
- return sp_mod_mgr_continue_entity2(mgr, ent, trigger_entity_id);
- }
- int sp_mod_mgr_test_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id, int test_type)
- {
- sp_entity_t *ent;
- ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
- if (!ent)
- return Error_NotExist;
- return sp_mod_mgr_test_entity2(mgr, ent, trigger_entity_id, test_type);
- }
- int sp_mod_mgr_lost_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id)
- {
- sp_entity_t *ent;
- sp_mod_t *mod;
- ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
- if (!ent)
- return Error_NotExist;
- mod = ent->mod;
- #ifdef _WIN32
- sp_mod_mgr_lockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_lock(mgr);
- #endif //_WIN32
- if (mod->state) {
- int last_state = ent->state;
- sp_dbg_debug("set entity %s lost ok!", ent->cfg->name);
-
- ent->state = EntityState_Lost;
- mgr_on_entity_state(mgr, ent, ent->cfg->idx, last_state, ent->state);
- }
- #ifdef _WIN32
- sp_mod_mgr_unlockEx(mod->cfg->idx);
- #else
- sp_mod_mgr_unlock(mgr);
- #endif //_WIN32
- return Error_Succeed;
- }
- int sp_mod_mgr_terminate_all_entity(sp_mod_mgr_t* mgr, int trigger_entity_id)
- {
- int i;
- int rc = 0;
- assert(mgr);
- for (i = 1; i < mgr->arr_ent->nelts; ++i) {
- int res;
- sp_entity_t* ent = ARRAY_IDX(mgr->arr_ent, i, sp_entity_t*);
- res = sp_mod_mgr_terminate_entity2(mgr, ent, trigger_entity_id);
- if (res != 0)
- rc = res;
- }
- return rc;
- }
- int sp_mod_mgr_start_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, const char *cmdline, int trigger_entity_id)
- {
- int rc = 0;
- if (!ent)
- return Error_NotExist;
- if (try_lock_doing(mgr, ent->mod)) {
- if (!ent->mod->state) {
- rc = load_module(mgr, ent->mod, trigger_entity_id);
- }
- if (rc == 0) {
- rc = start_entity(mgr, ent, cmdline, trigger_entity_id);
- }
- unlock_doing(mgr, ent->mod);
- } else {
- rc = Error_InvalidState;
- }
- return rc;
- }
- /*send {MOD_CMD_STOP} cmd and then {MOD_CMD_TERM} cmd*/
- int sp_mod_mgr_stop_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id, int cause_code)
- {
- int rc;
- if (!ent)
- return Error_NotExist;
- if (try_lock_doing(mgr, ent->mod)) {
- rc = stop_entity(mgr, ent, trigger_entity_id, cause_code);
- if (rc == 0) {
- sp_mod_t *mod = ent->mod;
- sp_entity_t *pos;
- int unload = TRUE;
- list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
- if ((pos->state != EntityState_Close && pos->state != EntityState_Killed && pos->state != EntityState_NoStart) ){
- unload = FALSE;
- break;
- }
- }
- if (unload) {
- rc = unload_module(mgr, mod, trigger_entity_id);
- }
- }
- unlock_doing(mgr, ent->mod);
- } else {
- rc = Error_Unexpect;
- }
- return rc;
- }
- int sp_mod_mgr_terminate_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
- {
- int rc;
- if (!ent)
- return Error_NotExist;
-
- if (try_lock_doing(mgr, ent->mod)) {
- rc = terminate_module(mgr, ent->mod, trigger_entity_id);
- unlock_doing(mgr, ent->mod);
- } else {
- rc = Error_InvalidState;
- }
- return rc;
- }
- int sp_mod_mgr_pause_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
- {
- int rc;
- if (!ent)
- return Error_NotExist;
- if (try_lock_doing(mgr, ent->mod)) {
- rc = pause_entity(mgr, ent, trigger_entity_id);
- unlock_doing(mgr, ent->mod);
- } else {
- rc = Error_InvalidState;
- }
- return rc;
- }
- int sp_mod_mgr_continue_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
- {
- int rc;
- if (!ent)
- return Error_NotExist;
- if (try_lock_doing(mgr, ent->mod)) {
- rc = continue_entity(mgr, ent, trigger_entity_id);
- unlock_doing(mgr, ent->mod);
- } else {
- rc = Error_InvalidState;
- }
- return rc;
- }
- int sp_mod_mgr_test_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id, int test_type)
- {
- int rc;
- if (!ent)
- return Error_NotExist;
- if (try_lock_doing(mgr, ent->mod)) {
- rc = test_entity(mgr, ent, test_type, trigger_entity_id);
- unlock_doing(mgr, ent->mod);
- } else {
- rc = Error_InvalidState;
- }
- return rc;
- }
- // from shell-> entity
- int sp_mod_mgr_notify_redirect_subscribe(sp_mod_mgr_t *mgr, sp_entity_t *entity, sp_uid_t *uid, int from_entity_id, const char *param)
- {
- int rc;
- iobuffer_t *pkt = iobuffer_create(-1, -1);
- iobuffer_write(pkt, IOBUF_T_I8, uid, 0);
- iobuffer_write(pkt, IOBUF_T_STR, param, -1);
- rc = sp_svc_post(mgr->shell_svc, entity->mod->cfg->idx, entity->cfg->idx, SP_PKT_MOD|MOD_CMD_NOTIFY_REDIRECT_SUBSCRIBE, from_entity_id, &pkt);
- if (pkt)
- iobuffer_dec_ref(pkt);
- return rc;
- }
|