sp_mod.c 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
  1. #include "precompile.h"
  2. #include "sp_mod.h"
  3. #include "sp_svc.h"
  4. #include "sp_dbg_export.h"
  5. #include "sp_env.h"
  6. #include "sp_def.h"
  7. #include "SpBase.h"
  8. #include "shm_mem.h"
  9. #include "process_monitor.h"
  10. #include "refcnt.h"
  11. #include "spinlock.h"
  12. #include "strutil.h"
  13. #ifdef _WIN32
  14. #include <WtsApi32.h>
  15. #include <Userenv.h>
  16. #include "sp_groupProcess.h"
  17. #else
  18. #endif //_WIN32
  19. #include "sp_gui.h"
  20. #include "sp_env.h"
  21. #include<winpr/exception.h>
  22. #include <winpr/thread.h>
  23. #include <winpr/wtsapi.h>
  24. #include <winpr/synch.h>
  25. #include <winpr/string.h>
  26. #include "toolkit.h"
  27. #define BUFSIZE 512
  28. #define MOD_CMD_INIT 0
  29. #define MOD_CMD_TERM 1
  30. #define MOD_CMD_START 2
  31. #define MOD_CMD_STOP 3
  32. #define MOD_CMD_PAUSE 4
  33. #define MOD_CMD_CONTINUE 5
  34. #define MOD_CMD_TEST 6
  35. #define MOD_CMD_MOD_RESULT 7
  36. #define MOD_CMD_ENT_RESULT 8
  37. #define MOD_CMD_REPORT_CREATE_CONN 9
  38. #define MOD_CMD_REPROT_CLOSE_CONN 10
  39. #define MOD_CMD_REPORT_EXCEPTION 12
  40. #define MOD_CMD_SUBSCRIBE_STATE_LISTENER 13
  41. #define MOD_CMD_UNSUBSCRIBE_STATE_LISTENER 14
  42. #define MOD_CMD_SUBSCRIBE_LIFE_LISTENER 15
  43. #define MOD_CMD_UNSUBSCRIBE_LIFE_LISTENER 16
  44. #define MOD_CMD_RECORD_STATE_EVENT 17
  45. #define MOD_CMD_RECORD_CREATE_CONN 18
  46. #define MOD_CMD_RECORD_CLOSE_CONN 19
  47. #define MOD_CMD_RECORD_ENTITY_CLOSE 20
  48. #define MOD_CMD_RECORD_ENTITY_CREATE 21
  49. #define MOD_CMD_RECORD_ENTITY_EXCEPTION 22
  50. #define MOD_CMD_SWITCH_RUNNING_MODE 23
  51. #define MOD_CMD_USER_STATE_EVENT 24
  52. #define MOD_CMD_NOTIFY_REDIRECT_SUBSCRIBE 31 // shell -> entity
  53. #define MOD_CMD_REPORT_REDIRECT_SUBSCRIBE 32 // entity -> shell
  54. //#define PROCESS_TIMEOUT 10000
  55. #define PROCESS_TIMEOUT 120000
  56. #define PROCESS_EXIT_TIMEOUT 4000
  57. #define ENTITY_TEST_TIMEOUT 30000
  58. #ifdef _WIN32
  59. extern void sp_mod_mgr_lockEx(int EntityId);
  60. extern void sp_mod_mgr_unlockEx(int EntityId);
  61. extern void sp_mod_mgr_lockArrClean();
  62. #endif //_WIN32
  63. struct sp_mod_stub_t
  64. {
  65. sp_mod_stub_cb cb;
  66. sp_iom_t *iom;
  67. };
  68. struct sp_mod_entity_stub_t
  69. {
  70. sp_mod_entity_stub_cb cb;
  71. strand_t *strand;
  72. sp_svc_t *svc;
  73. };
  74. static inline int mod_kill_process(sp_mod_t* mod)
  75. {
  76. sp_dbg_debug("mod %s is hanging on gallows.", mod->cfg->name);
  77. #ifdef _WIN32
  78. if (0 != killModByPipe(findGroupProcessInfo(mod->cfg->group, mod->cfg->name), mod->cfg->name)) {
  79. char szCmd[256];
  80. int nRet = 0;
  81. sp_dbg_warn("terminate %s fail: 0x%X, retry with taskkill", mod->cfg->name, GetLastError());
  82. sprintf_s(szCmd, 256, "TASKKILL /PID %d /F", mod->process.pid);
  83. WinExec(szCmd, SW_HIDE);
  84. //nRet = system(szCmd);
  85. //return nRet != -1;
  86. }
  87. return 0;
  88. #else
  89. return (TerminateProcess(mod->process.handle, -1) ? 0 : -1);
  90. #endif //_WIN32
  91. }
  92. 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)
  93. {
  94. sp_mod_stub_t *stub = (sp_mod_stub_t *)user_data;
  95. if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD) {
  96. int cmd_type = SP_GET_TYPE(pkt_type);
  97. int result = Error_Bug;
  98. int processed = 0;
  99. if (cmd_type == MOD_CMD_INIT) {
  100. int service_flag = 0;
  101. int multithread_flag = 0;
  102. sp_dbg_info("receive module init cmd!");
  103. __try {
  104. result = stub->cb.on_module_init(stub, stub->cb.user_data);
  105. } __except(EXCEPTION_EXECUTE_HANDLER) {
  106. result = Error_Exception;
  107. }
  108. sp_iom_post(iom, SP_INVALID_SVC_ID, epid, svc_id, SP_PKT_MOD|MOD_CMD_MOD_RESULT, result, NULL);
  109. } else if (cmd_type == MOD_CMD_TERM) {
  110. sp_dbg_info("receive module term cmd!");
  111. __try {
  112. result = stub->cb.on_module_term(stub, stub->cb.user_data);
  113. } __except(EXCEPTION_EXECUTE_HANDLER) {
  114. result = Error_Exception;
  115. }
  116. sp_iom_post(iom, SP_INVALID_SVC_ID, epid, svc_id, SP_PKT_MOD|MOD_CMD_MOD_RESULT, result, NULL);
  117. sp_iom_post_quit(iom);
  118. } else {
  119. return TRUE;
  120. }
  121. return FALSE;
  122. }
  123. return TRUE;
  124. }
  125. int sp_mod_stub_create(const sp_mod_stub_cb *cb, sp_iom_t *iom, sp_mod_stub_t **p_stub)
  126. {
  127. sp_mod_stub_t *stub = MALLOC_T(sp_mod_stub_t);
  128. memcpy(&stub->cb, cb, sizeof(sp_mod_stub_cb));
  129. stub->iom = iom;
  130. sp_iom_add_pkt_handler(iom, (int)stub, &mod_on_pkt, stub);
  131. *p_stub = stub;
  132. return 0;
  133. }
  134. void sp_mod_stub_destroy(sp_mod_stub_t *stub)
  135. {
  136. sp_iom_remove_pkt_handler(stub->iom, (int)stub);
  137. free(stub);
  138. }
  139. static void mod_entity_process_cmd(threadpool_t *threadpool, void *arg)
  140. {
  141. iobuffer_t *pkt = arg;
  142. sp_mod_entity_stub_t *stub;
  143. int epid;
  144. int svc_id;
  145. int pkt_type;
  146. int pkt_id;
  147. int cmd_type;
  148. sp_dbg_debug("==> %s", __FUNCTION__);
  149. iobuffer_read(pkt, IOBUF_T_PTR, &stub, NULL);
  150. iobuffer_read(pkt, IOBUF_T_I4, &epid, NULL);
  151. iobuffer_read(pkt, IOBUF_T_I4, &svc_id, NULL);
  152. iobuffer_read(pkt, IOBUF_T_I4, &pkt_type, NULL);
  153. iobuffer_read(pkt, IOBUF_T_I4, &pkt_id, NULL);
  154. cmd_type = SP_GET_TYPE(pkt_type);
  155. sp_dbg_debug("enter mod entity process cmd: %d", cmd_type);
  156. switch (cmd_type) {
  157. case MOD_CMD_TEST:
  158. {
  159. int trigger_entity_id;
  160. int test_type;
  161. iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
  162. iobuffer_read(pkt, IOBUF_T_I4, &test_type, NULL);
  163. stub->cb.on_entity_test(stub, trigger_entity_id, test_type, stub->cb.user_data);
  164. }
  165. break;
  166. case MOD_CMD_CONTINUE:
  167. {
  168. int trigger_entity_id;
  169. iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
  170. stub->cb.on_entity_precontinue(stub, trigger_entity_id, stub->cb.user_data);
  171. }
  172. break;
  173. case MOD_CMD_PAUSE:
  174. {
  175. int trigger_entity_id;
  176. iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
  177. stub->cb.on_entity_prepause(stub, trigger_entity_id, stub->cb.user_data);
  178. }
  179. break;
  180. case MOD_CMD_STOP:
  181. {
  182. int trigger_entity_id;
  183. int cause_code;
  184. iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
  185. iobuffer_read(pkt, IOBUF_T_I4, &cause_code, NULL);
  186. stub->cb.on_entity_stop(stub, trigger_entity_id, cause_code, stub->cb.user_data);
  187. }
  188. break;
  189. case MOD_CMD_START:
  190. {
  191. int slen = 0;
  192. char *cmdline = NULL;
  193. int numargs, numchars;
  194. char *p = NULL;
  195. int argc = 0;
  196. char **argv = NULL;
  197. int trigger_entity_id;
  198. iobuffer_read(pkt, IOBUF_T_STR, NULL, &slen);
  199. if (slen) {
  200. cmdline = malloc(slen+1);
  201. iobuffer_read(pkt, IOBUF_T_STR, cmdline, NULL);
  202. str_parse_cmdline(cmdline, NULL, NULL, &numargs, &numchars);
  203. p = malloc(numargs*sizeof(char*) + numchars);
  204. argc = numargs - 1; /*except program.exe name, and actually it doesn't exist*/
  205. argv = (char**)p;
  206. str_parse_cmdline(cmdline, (char **)p, p + numargs * sizeof(char *), &numargs, &numchars);
  207. }
  208. iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
  209. sp_dbg_debug("before invoke on_entity_prestart(trigger %d)", trigger_entity_id);
  210. stub->cb.on_entity_prestart(stub, trigger_entity_id, argc, argv, stub->cb.user_data);
  211. sp_dbg_debug("after invoke on_entity_prestart(trigger %d)", trigger_entity_id);
  212. free(p);
  213. free(cmdline);
  214. }
  215. break;
  216. case MOD_CMD_NOTIFY_REDIRECT_SUBSCRIBE:
  217. {
  218. int slen = 0;
  219. int from_entity_id = pkt_id;
  220. sp_uid_t uid;
  221. char *param = NULL;
  222. iobuffer_read(pkt, IOBUF_T_I8, &uid, 0);
  223. iobuffer_read(pkt, IOBUF_T_STR, NULL, &slen);
  224. if (slen) {
  225. param = malloc(slen + 1);
  226. iobuffer_read(pkt, IOBUF_T_STR, param, NULL);
  227. }
  228. stub->cb.on_entity_redirect_subscribe(stub, &uid, from_entity_id, param, stub->cb.user_data);
  229. free(param);
  230. }
  231. break;
  232. default:
  233. assert(0);
  234. break;
  235. }
  236. iobuffer_dec_ref(pkt);
  237. }
  238. 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)
  239. {
  240. sp_mod_entity_stub_t *stub = (sp_mod_entity_stub_t *)user_data;
  241. if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD) {
  242. int cmd_type = SP_GET_TYPE(pkt_type);
  243. sp_dbg_debug("rx entity cmd %d !", cmd_type);
  244. if (cmd_type == MOD_CMD_START ||
  245. cmd_type == MOD_CMD_STOP ||
  246. cmd_type == MOD_CMD_PAUSE ||
  247. cmd_type == MOD_CMD_CONTINUE ||
  248. cmd_type == MOD_CMD_TEST ||
  249. cmd_type == MOD_CMD_NOTIFY_REDIRECT_SUBSCRIBE) {
  250. iobuffer_t *pkt = *p_pkt;
  251. *p_pkt = NULL;
  252. iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_id, 0);
  253. iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_type, 0);
  254. iobuffer_write_head(pkt, IOBUF_T_I4, &svc_id, 0);
  255. iobuffer_write_head(pkt, IOBUF_T_I4, &epid, 0);
  256. iobuffer_write_head(pkt, IOBUF_T_PTR, &stub, 0);
  257. threadpool_queue_workitem(sp_svc_get_threadpool(stub->svc), stub->strand, &mod_entity_process_cmd, pkt);
  258. return FALSE;
  259. }
  260. }
  261. return TRUE;
  262. }
  263. int sp_mod_entity_stub_create(const sp_mod_entity_stub_cb *cb, sp_svc_t *svc, sp_mod_entity_stub_t **p_stub)
  264. {
  265. sp_mod_entity_stub_t *stub = MALLOC_T(sp_mod_entity_stub_t);
  266. memcpy(&stub->cb, cb, sizeof(sp_mod_entity_stub_cb));
  267. stub->svc = svc;
  268. stub->strand = strand_create();
  269. sp_svc_add_pkt_handler(svc, (int)stub, SP_PKT_MOD, &mod_entity_on_pkt, stub);
  270. *p_stub = stub;
  271. return 0;
  272. }
  273. void sp_mod_entity_stub_destroy(sp_mod_entity_stub_t *stub)
  274. {
  275. sp_svc_remove_pkt_handler(stub->svc, (int)stub, SP_PKT_MOD);
  276. strand_destroy(stub->strand);
  277. free(stub);
  278. }
  279. int sp_mod_entity_stub_report_create_connection(sp_mod_entity_stub_t *stub, int remote_entity)
  280. {
  281. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_REPORT_CREATE_CONN, remote_entity, NULL);
  282. return 0;
  283. }
  284. int sp_mod_entity_stub_report_close_connection(sp_mod_entity_stub_t *stub, int remote_entity)
  285. {
  286. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_REPROT_CLOSE_CONN, remote_entity, NULL);
  287. return 0;
  288. }
  289. int sp_mod_entity_stub_report_exception(sp_mod_entity_stub_t *stub, int win32_exception_code, int eip, int in_func)
  290. {
  291. iobuffer_t *pkt = iobuffer_create(-1, -1);
  292. iobuffer_write(pkt, IOBUF_T_I4, &win32_exception_code, 0);
  293. iobuffer_write(pkt, IOBUF_T_I4, &eip, 0);
  294. iobuffer_write(pkt, IOBUF_T_I4, &in_func, 0);
  295. 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);
  296. if (pkt)
  297. iobuffer_dec_ref(pkt);
  298. return 0;
  299. }
  300. int sp_mod_entity_stub_switch_running_state(sp_mod_entity_stub_t *stub, int state)
  301. {
  302. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_SWITCH_RUNNING_MODE, state, NULL);
  303. return 0;
  304. }
  305. int sp_mod_entity_stub_report_user_state_change(sp_mod_entity_stub_t *stub, int last_state, int curr_state)
  306. {
  307. iobuffer_t *pkt = iobuffer_create(-1, -1);
  308. iobuffer_write(pkt, IOBUF_T_I4, &last_state, 0);
  309. iobuffer_write(pkt, IOBUF_T_I4, &curr_state, 0);
  310. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_USER_STATE_EVENT, 0, &pkt);
  311. if (pkt)
  312. iobuffer_dec_ref(pkt);
  313. return 0;
  314. }
  315. int sp_mod_entity_stub_finish_start(sp_mod_entity_stub_t *stub, int result)
  316. {
  317. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
  318. return 0;
  319. }
  320. int sp_mod_entity_stub_finish_stop(sp_mod_entity_stub_t *stub, int result)
  321. {
  322. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
  323. return 0;
  324. }
  325. int sp_mod_entity_stub_finish_pause(sp_mod_entity_stub_t *stub, int result)
  326. {
  327. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
  328. return 0;
  329. }
  330. int sp_mod_entity_stub_finish_continue(sp_mod_entity_stub_t *stub, int result)
  331. {
  332. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
  333. return 0;
  334. }
  335. int sp_mod_entity_stub_finish_test(sp_mod_entity_stub_t *stub, int result)
  336. {
  337. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_ENT_RESULT, result, NULL);
  338. return 0;
  339. }
  340. int sp_mod_entity_stub_finish_redirect_subscribe(sp_mod_entity_stub_t *stub, sp_uid_t *uid, int suggest_entity_id)
  341. {
  342. iobuffer_t *pkt = iobuffer_create(-1, -1);
  343. iobuffer_write(pkt, IOBUF_T_I8, uid, 0);
  344. iobuffer_write(pkt, IOBUF_T_I4, &suggest_entity_id, 0);
  345. sp_svc_post(stub->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_REPORT_REDIRECT_SUBSCRIBE, 0, &pkt);
  346. if (pkt)
  347. iobuffer_dec_ref(pkt);
  348. return 0;
  349. }
  350. //
  351. // entity event listener
  352. //
  353. struct sp_mod_entity_state_listener_t
  354. {
  355. sp_mod_entity_event_cb cb;
  356. sp_svc_t *svc;
  357. int target_entity_id;
  358. spinlock_t lock;
  359. strand_t *strand;
  360. int stop;
  361. void *user_data;
  362. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  363. };
  364. DECLARE_REF_COUNT_STATIC(sp_mod_entity_state_listener, sp_mod_entity_state_listener_t)
  365. static void mod_entity_state_listener_process_cmd(threadpool_t *threadpool, void *arg)
  366. {
  367. sp_mod_entity_state_listener_t *listener;
  368. iobuffer_t *pkt = arg;
  369. iobuffer_read(pkt, IOBUF_T_PTR, &listener, NULL);
  370. spinlock_enter(&listener->lock, -1);
  371. if (!listener->stop) {
  372. int epid;
  373. int svc_id;
  374. int pkt_type;
  375. int pkt_id;
  376. int cmd_type;
  377. iobuffer_read(pkt, IOBUF_T_I4, &epid, NULL);
  378. iobuffer_read(pkt, IOBUF_T_I4, &svc_id, NULL);
  379. iobuffer_read(pkt, IOBUF_T_I4, &pkt_type, NULL);
  380. iobuffer_read(pkt, IOBUF_T_I4, &pkt_id, NULL);
  381. cmd_type = SP_GET_TYPE(pkt_type);
  382. if (cmd_type == MOD_CMD_RECORD_STATE_EVENT) {
  383. int entity_id;
  384. int trigger_entity_id;
  385. int last_state;
  386. int curr_state;
  387. iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
  388. iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
  389. iobuffer_read(pkt, IOBUF_T_I4, &last_state, NULL);
  390. iobuffer_read(pkt, IOBUF_T_I4, &curr_state, NULL);
  391. if (listener->target_entity_id == -1 || listener->target_entity_id == entity_id)
  392. listener->cb.on_entity_state(listener, entity_id, trigger_entity_id, last_state, curr_state, listener->cb.user_data);
  393. }
  394. else if (cmd_type == MOD_CMD_USER_STATE_EVENT)
  395. {
  396. int entity_id;
  397. int last_state;
  398. int curr_state;
  399. iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
  400. iobuffer_read(pkt, IOBUF_T_I4, &last_state, NULL);
  401. iobuffer_read(pkt, IOBUF_T_I4, &curr_state, NULL);
  402. if (listener->target_entity_id == -1 || listener->target_entity_id == entity_id)
  403. listener->cb.on_user_state(listener, entity_id, last_state, curr_state, listener->cb.user_data);
  404. }
  405. else if (cmd_type == MOD_CMD_RECORD_CREATE_CONN) {
  406. int src_entity_id;
  407. int dst_entity_id;
  408. iobuffer_read(pkt, IOBUF_T_I4, &src_entity_id, NULL);
  409. iobuffer_read(pkt, IOBUF_T_I4, &dst_entity_id, NULL);
  410. if (listener->target_entity_id == -1 || listener->target_entity_id == src_entity_id || listener->target_entity_id == dst_entity_id)
  411. listener->cb.on_create_connection(listener, src_entity_id, dst_entity_id, listener->cb.user_data);
  412. } else if (cmd_type == MOD_CMD_RECORD_CLOSE_CONN) {
  413. int src_entity_id;
  414. int dst_entity_id;
  415. iobuffer_read(pkt, IOBUF_T_I4, &src_entity_id, NULL);
  416. iobuffer_read(pkt, IOBUF_T_I4, &dst_entity_id, NULL);
  417. if (listener->target_entity_id == -1 || listener->target_entity_id == src_entity_id || listener->target_entity_id == dst_entity_id)
  418. listener->cb.on_close_connection(listener, src_entity_id, dst_entity_id, listener->cb.user_data);
  419. } else {
  420. assert(0);
  421. }
  422. }
  423. spinlock_leave(&listener->lock);
  424. iobuffer_dec_ref(pkt);
  425. sp_mod_entity_state_listener_dec_ref(listener);
  426. }
  427. 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)
  428. {
  429. sp_mod_entity_state_listener_t *listener = (sp_mod_entity_state_listener_t *)user_data;
  430. if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD && !listener->stop) {
  431. int cmd_type = SP_GET_TYPE(pkt_type);
  432. if (cmd_type == MOD_CMD_RECORD_STATE_EVENT ||
  433. cmd_type == MOD_CMD_USER_STATE_EVENT ||
  434. cmd_type == MOD_CMD_RECORD_CREATE_CONN ||
  435. cmd_type == MOD_CMD_RECORD_CLOSE_CONN) {
  436. iobuffer_t *pkt = iobuffer_clone(*p_pkt);
  437. //sp_dbg_info("recv entity_state_listener pkt cmd_type %d", cmd_type);
  438. iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_id, 0);
  439. iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_type, 0);
  440. iobuffer_write_head(pkt, IOBUF_T_I4, &svc_id, 0);
  441. iobuffer_write_head(pkt, IOBUF_T_I4, &epid, 0);
  442. iobuffer_write_head(pkt, IOBUF_T_PTR, &listener, 0);
  443. sp_mod_entity_state_listener_inc_ref(listener);
  444. threadpool_queue_workitem(sp_svc_get_threadpool(listener->svc), listener->strand, mod_entity_state_listener_process_cmd, pkt);
  445. }
  446. }
  447. return TRUE;
  448. }
  449. 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)
  450. {
  451. sp_mod_entity_state_listener_t *listener = MALLOC_T(sp_mod_entity_state_listener_t);
  452. memcpy(&listener->cb, cb, sizeof(sp_mod_entity_event_cb));
  453. listener->svc = svc;
  454. listener->stop = 0;
  455. listener->user_data = tag;
  456. listener->target_entity_id = target_entity_id;
  457. spinlock_init(&listener->lock);
  458. listener->strand = strand_create();
  459. REF_COUNT_INIT(&listener->ref_cnt);
  460. sp_svc_add_pkt_handler(svc, (int)listener, SP_PKT_MOD, &mod_entity_state_listener_on_pkt, listener);
  461. *p_listener = listener;
  462. sp_svc_post(svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_SUBSCRIBE_STATE_LISTENER, target_entity_id, NULL);
  463. return 0;
  464. }
  465. static void __sp_mod_entity_listener_destroy(sp_mod_entity_state_listener_t *listener)
  466. {
  467. strand_destroy(listener->strand);
  468. free(listener);
  469. }
  470. IMPLEMENT_REF_COUNT_MT_STATIC(sp_mod_entity_state_listener,sp_mod_entity_state_listener_t,ref_cnt, __sp_mod_entity_listener_destroy)
  471. void sp_mod_entity_listener_destroy(sp_mod_entity_state_listener_t *listener)
  472. {
  473. 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);
  474. spinlock_enter(&listener->lock, -1);
  475. listener->stop = TRUE;
  476. spinlock_leave(&listener->lock);
  477. sp_svc_remove_pkt_handler(listener->svc, (int)listener, SP_PKT_MOD);
  478. sp_mod_entity_state_listener_dec_ref(listener);
  479. }
  480. void sp_mod_entity_listener_set_tag(sp_mod_entity_state_listener_t *listener, void *data)
  481. {
  482. listener->user_data = data;
  483. }
  484. void *sp_mod_entity_listener_get_tag(sp_mod_entity_state_listener_t *listener)
  485. {
  486. return listener->user_data;
  487. }
  488. // entity life listener
  489. struct sp_mod_entity_life_listener_t
  490. {
  491. sp_mod_entity_life_cb cb;
  492. sp_svc_t *svc;
  493. spinlock_t lock;
  494. strand_t *strand;
  495. int stop;
  496. void *user_data;
  497. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  498. };
  499. DECLARE_REF_COUNT_STATIC(sp_mod_entity_life_listener, sp_mod_entity_life_listener_t)
  500. static void mod_entity_life_listener_process_cmd(threadpool_t *threadpool, void *arg)
  501. {
  502. sp_mod_entity_life_listener_t *listener;
  503. iobuffer_t *pkt = arg;
  504. iobuffer_read(pkt, IOBUF_T_PTR, &listener, NULL);
  505. spinlock_enter(&listener->lock, -1);
  506. if (!listener->stop) {
  507. int epid;
  508. int svc_id;
  509. int pkt_type;
  510. int pkt_id;
  511. int cmd_type;
  512. iobuffer_read(pkt, IOBUF_T_I4, &epid, NULL);
  513. iobuffer_read(pkt, IOBUF_T_I4, &svc_id, NULL);
  514. iobuffer_read(pkt, IOBUF_T_I4, &pkt_type, NULL);
  515. iobuffer_read(pkt, IOBUF_T_I4, &pkt_id, NULL);
  516. cmd_type = SP_GET_TYPE(pkt_type);
  517. if (cmd_type == MOD_CMD_RECORD_ENTITY_CREATE) {
  518. int entity_id;
  519. int trigger_entity_id;
  520. iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
  521. iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
  522. listener->cb.on_entity_create(listener, entity_id, trigger_entity_id, listener->cb.user_data);
  523. } else if (cmd_type == MOD_CMD_RECORD_ENTITY_CLOSE) {
  524. int entity_id;
  525. int trigger_entity_id;
  526. int close_cause;
  527. iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
  528. iobuffer_read(pkt, IOBUF_T_I4, &trigger_entity_id, NULL);
  529. iobuffer_read(pkt, IOBUF_T_I4, &close_cause, NULL);
  530. listener->cb.on_entity_close(listener, entity_id, trigger_entity_id, close_cause, listener->cb.user_data);
  531. } else if (cmd_type == MOD_CMD_RECORD_ENTITY_EXCEPTION) {
  532. int entity_id;
  533. int error;
  534. int entity_state;
  535. iobuffer_read(pkt, IOBUF_T_I4, &entity_id, NULL);
  536. iobuffer_read(pkt, IOBUF_T_I4, &error, NULL);
  537. iobuffer_read(pkt, IOBUF_T_I4, &entity_state, NULL);
  538. listener->cb.on_entity_exception(listener, entity_id, error, entity_state, listener->cb.user_data);
  539. } else {
  540. assert(0);
  541. }
  542. }
  543. spinlock_leave(&listener->lock);
  544. iobuffer_dec_ref(pkt);
  545. sp_mod_entity_life_listener_dec_ref(listener);
  546. }
  547. 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)
  548. {
  549. sp_mod_entity_life_listener_t *listener = (sp_mod_entity_life_listener_t *)user_data;
  550. if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD && !listener->stop) {
  551. int cmd_type = SP_GET_TYPE(pkt_type);
  552. if (cmd_type == MOD_CMD_RECORD_ENTITY_CREATE ||
  553. cmd_type == MOD_CMD_RECORD_ENTITY_CLOSE ||
  554. cmd_type == MOD_CMD_RECORD_ENTITY_EXCEPTION) {
  555. iobuffer_t *pkt = iobuffer_clone(*p_pkt);
  556. iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_id, 0);
  557. iobuffer_write_head(pkt, IOBUF_T_I4, &pkt_type, 0);
  558. iobuffer_write_head(pkt, IOBUF_T_I4, &svc_id, 0);
  559. iobuffer_write_head(pkt, IOBUF_T_I4, &epid, 0);
  560. iobuffer_write_head(pkt, IOBUF_T_PTR, &listener, 0);
  561. sp_mod_entity_life_listener_inc_ref(listener);
  562. threadpool_queue_workitem(sp_svc_get_threadpool(listener->svc), listener->strand, &mod_entity_life_listener_process_cmd, pkt);
  563. }
  564. }
  565. return TRUE;
  566. }
  567. 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)
  568. {
  569. sp_mod_entity_life_listener_t *listener = MALLOC_T(sp_mod_entity_life_listener_t);
  570. memcpy(&listener->cb, cb, sizeof(sp_mod_entity_life_cb));
  571. listener->svc = svc;
  572. listener->stop = 0;
  573. listener->user_data = tag;
  574. spinlock_init(&listener->lock);
  575. listener->strand = strand_create();
  576. REF_COUNT_INIT(&listener->ref_cnt);
  577. sp_svc_add_pkt_handler(svc, (int)listener, SP_PKT_MOD, &mod_entity_life_listener_on_pkt, listener);
  578. *p_listener = listener;
  579. sp_svc_post(svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_SUBSCRIBE_LIFE_LISTENER, 0, NULL);
  580. return 0;
  581. }
  582. void __sp_mod_entity_life_listener_destroy(sp_mod_entity_life_listener_t *listener)
  583. {
  584. strand_destroy(listener->strand);
  585. free(listener);
  586. }
  587. IMPLEMENT_REF_COUNT_MT_STATIC(sp_mod_entity_life_listener, sp_mod_entity_life_listener_t, ref_cnt, __sp_mod_entity_life_listener_destroy)
  588. void sp_mod_entity_life_listener_destroy(sp_mod_entity_life_listener_t *listener)
  589. {
  590. sp_svc_post(listener->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_MOD|MOD_CMD_UNSUBSCRIBE_LIFE_LISTENER, 0, NULL);
  591. spinlock_enter(&listener->lock, -1);
  592. listener->stop = TRUE;
  593. spinlock_leave(&listener->lock);
  594. sp_svc_remove_pkt_handler(listener->svc, (int)listener, SP_PKT_MOD);
  595. sp_mod_entity_life_listener_dec_ref(listener);
  596. }
  597. void sp_mod_entity_life_listener_set_tag(sp_mod_entity_life_listener_t *listener, void *data)
  598. {
  599. listener->user_data = data;
  600. }
  601. void *sp_mod_entity_life_listener_get_tag(sp_mod_entity_life_listener_t *listener)
  602. {
  603. return listener->user_data;
  604. }
  605. typedef struct entity_state_subscribe_entry {
  606. struct list_head entry;
  607. int mod_id;
  608. int svc_id;
  609. int instance;
  610. int target_entity_id;
  611. }entity_state_subscribe_entry;
  612. typedef struct entity_life_subscribe_entry {
  613. struct list_head entry;
  614. int mod_id;
  615. int svc_id;
  616. int instance;
  617. }entity_life_subscribe_entry;
  618. struct sp_mod_mgr_t
  619. {
  620. sp_bcm_daemon_t *shell_daemon; // only for shell use
  621. sp_svc_t *shell_svc;
  622. CRITICAL_SECTION lock;
  623. process_monitor_t *process_monitor;
  624. spinlock_t entity_state_subscribe_lock;
  625. struct list_head entity_state_subscribe_list;
  626. spinlock_t entity_life_subscribe_lock;
  627. struct list_head entity_life_subscribe_list;
  628. struct list_head mod_list; // list of sp_mod_t*
  629. array_header_t *arr_mod; // array of sp_mod_t*
  630. array_header_t *arr_ent; // array of sp_entity_t*
  631. LONG instance_seq;
  632. };
  633. static __inline int mgr_new_instance_id(sp_mod_mgr_t *mgr)
  634. {
  635. return (int)InterlockedIncrement((LONG*)&mgr->instance_seq);
  636. }
  637. static int create_module_process(const char *mod_name, int epid, int range, int group, tk_process_t* new_process)
  638. {
  639. char app[MAX_PATH] = {'\0'};
  640. #ifdef _WIN32
  641. char writeParam[MAX_PATH] = "";
  642. char mutexName[MAX_PATH] = "";
  643. char eventName[MAX_PATH] = "";
  644. //BOOL bRet;
  645. STARTUPINFOA si = { sizeof(STARTUPINFOA) };
  646. PROCESS_INFORMATION pi;
  647. DWORD dwSessionId;
  648. HANDLE hUserTokenDup, hThisToken;
  649. HANDLE hProcess = NULL;
  650. HANDLE hMutex = NULL;
  651. int result = 0;
  652. sp_process_t* groupProcess = NULL;
  653. BOOL fConnected = FALSE;
  654. DWORD dwThreadId = 0;
  655. HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
  656. char lpszPipename[MAX_PATH] = "\\\\.\\pipe\\";
  657. if (0 != getNewGuid(mutexName)) {
  658. return -1;
  659. }
  660. sprintf(app, ".\\bin\\sphost.exe {%s}", mutexName);
  661. sprintf_s(writeParam, sizeof(writeParam), "%s %d %d %s %d", mod_name, epid, range, mutexName, group);
  662. if (0 == group)
  663. checkGroupProcesInfo(group, mod_name);
  664. groupProcess = findGroupProcessInfo(group, mod_name);//1,group为0时,基于每个group0_entityName的进程;2,gourp不为0,基于groupN的进程
  665. if (NULL == groupProcess) {
  666. tk_process_option_t option;
  667. tk_process_t* ret_process;
  668. sp_dbg_info("open group process, %s", mod_name);
  669. sprintf(lpszPipename, "%s{%s}", lpszPipename, mutexName);
  670. sprintf(eventName, "{%s}", mutexName);
  671. hPipe = CreateNamedPipe(lpszPipename,
  672. PIPE_ACCESS_DUPLEX,
  673. PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
  674. BUFSIZE, BUFSIZE, 0, NULL);
  675. if (hPipe == INVALID_HANDLE_VALUE
  676. && !ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED)) {
  677. return -1;
  678. }
  679. dwSessionId = WTSGetActiveConsoleSessionId();
  680. if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hThisToken)) {
  681. sp_process_t* curProcess = ZALLOC_T(sp_process_t);
  682. LUID luid;
  683. TOKEN_PRIVILEGES tp;
  684. LPVOID pEnv = NULL;
  685. LookupPrivilegeValueA(NULL, SE_DEBUG_NAME, &luid);
  686. tp.PrivilegeCount = 1;
  687. tp.Privileges[0].Luid = luid;
  688. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  689. DuplicateTokenEx(hThisToken, MAXIMUM_ALLOWED, NULL,
  690. SecurityIdentification, TokenPrimary, &hUserTokenDup);
  691. SetTokenInformation(hUserTokenDup,
  692. TokenSessionId, (void*)&dwSessionId, sizeof(DWORD));
  693. //提升权限
  694. AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
  695. (PTOKEN_PRIVILEGES)NULL, NULL);
  696. hMutex = CreateEvent(NULL, FALSE, FALSE, eventName);
  697. if (CreateProcessAsUserA(hUserTokenDup, NULL, app, NULL, NULL, FALSE, 0, pEnv, NULL, &si, &pi)) {
  698. new_process->pid = pi.dwProcessId;
  699. CloseHandle(pi.hThread);
  700. hProcess = pi.hProcess;
  701. curProcess->process_Handle = pi.hProcess;
  702. curProcess->pid = pi.dwProcessId;
  703. curProcess->group = group;
  704. curProcess->write_pipe = hPipe;
  705. curProcess->read_pipe = hPipe;
  706. AddGroupProcessInfo(group, curProcess, mod_name);
  707. sp_dbg_info("create process and add to gourp");
  708. }
  709. WaitForSingleObject(hMutex, 5000);
  710. CloseHandle(hMutex);
  711. CloseHandle(hUserTokenDup);
  712. CloseHandle(hThisToken);
  713. }
  714. else {
  715. sp_dbg_warn("open process token failed! Error : %d", GetLastError());
  716. }
  717. }
  718. sp_dbg_info("begin start mod by pipe, %s", mod_name);
  719. //通过管道通知进程创建实体线程
  720. if (NULL != (groupProcess = findGroupProcessInfo(group, mod_name))
  721. && 0 == startModByPipe(groupProcess, writeParam)) {
  722. char dstParam[10][MAX_PATH];
  723. int paramNum = 0;
  724. ZeroMemory(dstParam, sizeof(dstParam));
  725. sp_dbg_info("query mod by pipe, %s", mod_name);
  726. if (-1 != (paramNum = queryModByPipe(groupProcess, mod_name, dstParam))) //return paramNum
  727. {
  728. HANDLE processMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, dstParam[2]);
  729. sp_dbg_info("return processId %d", groupProcess->pid);
  730. new_process->pid = groupProcess->pid;
  731. new_process->handle = processMutex;
  732. return 0;
  733. }
  734. }
  735. #else
  736. tk_process_t* process = NULL;
  737. tk_process_option_t option;
  738. sprintf(app, "./bin/sphost %d %s %d", range, mod_name, epid);
  739. option.exit_cb = NULL;
  740. option.file = NULL;
  741. option.flags = 0;
  742. option.params = app;
  743. if (0 == process_spawn(&option, &process)) {
  744. new_process->pid = process->pid;
  745. new_process->handle = process->handle;
  746. FREE(process);
  747. return 0;
  748. }
  749. #endif //_WIN32
  750. return -1;
  751. }
  752. static void mgr_bcast_entity_state_event(sp_mod_mgr_t *mgr, sp_entity_t *changed_entity, int pkt_type, iobuffer_t *pkt)
  753. {
  754. entity_state_subscribe_entry *pos;
  755. spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
  756. list_for_each_entry(pos, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
  757. if (pos->target_entity_id == -1 || changed_entity->cfg->idx == pos->target_entity_id) {
  758. iobuffer_t *copy = iobuffer_clone(pkt);
  759. sp_svc_post(mgr->shell_svc, pos->mod_id, pos->svc_id, pkt_type, 0, &copy);
  760. if (copy)
  761. iobuffer_dec_ref(copy);
  762. }
  763. }
  764. spinlock_leave(&mgr->entity_state_subscribe_lock);
  765. //sp_dbg_info("bcast entity state! changed_entity: %s", changed_entity->cfg->name);
  766. }
  767. 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)
  768. {
  769. entity_state_subscribe_entry *pos;
  770. spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
  771. list_for_each_entry(pos, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
  772. if (pos->target_entity_id == -1 || entity_src->cfg->idx == pos->target_entity_id || entity_dst->cfg->idx == pos->target_entity_id) {
  773. iobuffer_t *copy = iobuffer_clone(pkt);
  774. sp_svc_post(mgr->shell_svc, pos->mod_id, pos->svc_id, pkt_type, 0, &copy);
  775. if (copy)
  776. iobuffer_dec_ref(copy);
  777. }
  778. }
  779. spinlock_leave(&mgr->entity_state_subscribe_lock);
  780. sp_dbg_info("bcast entity on connection! src: %s, dst: %s", entity_src->cfg->name, entity_dst->cfg->name);
  781. }
  782. 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)
  783. {
  784. sp_env_t *env = NULL;
  785. iobuffer_t *pkt = iobuffer_create(-1, -1);
  786. iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
  787. iobuffer_write(pkt, IOBUF_T_I4, &trigger_entity_id, 0);
  788. iobuffer_write(pkt, IOBUF_T_I4, &last_state, 0);
  789. iobuffer_write(pkt, IOBUF_T_I4, &curr_state, 0);
  790. mgr_bcast_entity_state_event(mgr, entity, SP_PKT_MOD|MOD_CMD_RECORD_STATE_EVENT, pkt);
  791. iobuffer_dec_ref(pkt);
  792. sp_dbg_info("entity %s change state from %d to %d", entity->cfg->name, last_state, curr_state);
  793. // gui显示实体状态变化
  794. env = sp_get_env();
  795. sp_gui_show_entity_info(env->gui, entity->cfg->name, curr_state);
  796. }
  797. static void mgr_on_user_state(sp_mod_mgr_t *mgr, sp_entity_t *entity, int last_state, int curr_state)
  798. {
  799. iobuffer_t *pkt = iobuffer_create(-1, -1);
  800. iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
  801. iobuffer_write(pkt, IOBUF_T_I4, &last_state, 0);
  802. iobuffer_write(pkt, IOBUF_T_I4, &curr_state, 0);
  803. mgr_bcast_entity_state_event(mgr, entity, SP_PKT_MOD|MOD_CMD_USER_STATE_EVENT, pkt);
  804. iobuffer_dec_ref(pkt);
  805. }
  806. static void mgr_on_create_connection(sp_mod_mgr_t *mgr, sp_entity_t *entity_src, sp_entity_t *entity_dst)
  807. {
  808. iobuffer_t *pkt = iobuffer_create(-1, -1);
  809. iobuffer_write(pkt, IOBUF_T_I4, &entity_src->cfg->idx, 0);
  810. iobuffer_write(pkt, IOBUF_T_I4, &entity_dst->cfg->idx, 0);
  811. mgr_bcast_entity_on_connection(mgr, entity_src, entity_dst, SP_PKT_MOD|MOD_CMD_RECORD_CREATE_CONN, pkt);
  812. iobuffer_dec_ref(pkt);
  813. }
  814. static void mgr_on_close_connection(sp_mod_mgr_t *mgr, sp_entity_t *entity_src, sp_entity_t *entity_dst)
  815. {
  816. iobuffer_t *pkt = iobuffer_create(-1, -1);
  817. iobuffer_write(pkt, IOBUF_T_I4, &entity_src->cfg->idx, 0);
  818. iobuffer_write(pkt, IOBUF_T_I4, &entity_dst->cfg->idx, 0);
  819. mgr_bcast_entity_on_connection(mgr, entity_src, entity_dst, SP_PKT_MOD|MOD_CMD_RECORD_CLOSE_CONN, pkt);
  820. iobuffer_dec_ref(pkt);
  821. }
  822. static void mgr_bcast_entity_life_event(sp_mod_mgr_t *mgr, int pkt_type, iobuffer_t *pkt)
  823. {
  824. entity_life_subscribe_entry *pos;
  825. spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
  826. list_for_each_entry(pos, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
  827. iobuffer_t *copy = iobuffer_clone(pkt);
  828. sp_svc_post(mgr->shell_svc, pos->mod_id, pos->svc_id, pkt_type, 0, &copy);
  829. if (copy)
  830. iobuffer_dec_ref(copy);
  831. }
  832. spinlock_leave(&mgr->entity_life_subscribe_lock);
  833. }
  834. static void mgr_on_entity_create(sp_mod_mgr_t *mgr, sp_entity_t *entity, int trigger_entity_id)
  835. {
  836. iobuffer_t *pkt = iobuffer_create(-1, -1);
  837. iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
  838. iobuffer_write(pkt, IOBUF_T_I4, &trigger_entity_id, 0);
  839. mgr_bcast_entity_life_event(mgr, SP_PKT_MOD|MOD_CMD_RECORD_ENTITY_CREATE, pkt);
  840. iobuffer_dec_ref(pkt);
  841. }
  842. static void mgr_on_entity_close(sp_mod_mgr_t *mgr, sp_entity_t *entity, int trigger_entity_id, int cause_code)
  843. {
  844. iobuffer_t *pkt = iobuffer_create(-1, -1);
  845. iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
  846. iobuffer_write(pkt, IOBUF_T_I4, &trigger_entity_id, 0);
  847. iobuffer_write(pkt, IOBUF_T_I4, &cause_code, 0);
  848. mgr_bcast_entity_life_event(mgr, SP_PKT_MOD|MOD_CMD_RECORD_ENTITY_CLOSE, pkt);
  849. iobuffer_dec_ref(pkt);
  850. }
  851. static void mgr_on_entity_exception(sp_mod_mgr_t *mgr, sp_entity_t *entity, int trigger_entity_id, int error)
  852. {
  853. iobuffer_t *pkt = iobuffer_create(-1, -1);
  854. iobuffer_write(pkt, IOBUF_T_I4, &entity->cfg->idx, 0);
  855. iobuffer_write(pkt, IOBUF_T_I4, &error, 0);
  856. iobuffer_write(pkt, IOBUF_T_I4, &entity->state, 0);
  857. mgr_bcast_entity_life_event(mgr, SP_PKT_MOD|MOD_CMD_RECORD_ENTITY_EXCEPTION, pkt);
  858. iobuffer_dec_ref(pkt);
  859. }
  860. static int on_detect_process_end(process_monitor_t *monitor, HANDLE hproc, void *user_data)
  861. {
  862. sp_mod_mgr_t *mgr = (sp_mod_mgr_t*)user_data;
  863. sp_mod_t *mod;
  864. //sp_dbg_debug("enter on_detect_process_end, handle: 0x%08X", hproc);
  865. list_for_each_entry(mod, &mgr->mod_list, sp_mod_t, entry) {
  866. //sp_dbg_debug("%s state: %d, pid: %d, handle: 0x%08X", mod->cfg->name, mod->state, mod->process.pid, mod->process.handle);
  867. if (mod->state && mod->process.handle == hproc) {
  868. sp_entity_t *ent;
  869. #ifdef _WIN32
  870. sp_mod_mgr_lockEx(mod->cfg->idx);
  871. #else
  872. sp_mod_mgr_lock(mgr);
  873. #endif //_WIN32
  874. sp_dbg_info("detect process [mod=%s] exit", mod->cfg->name); //no exit code
  875. process_close(&mod->process);
  876. mod->state = SP_MODULE_STATE_UNLOAD; //
  877. list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
  878. if (ent->state != EntityState_Killed && ent->state != EntityState_Close) { //
  879. int last_state = ent->state;
  880. ent->state = EntityState_Lost;
  881. mgr_on_entity_state(mgr, ent, ent->cfg->idx, last_state, ent->state);
  882. mgr_on_entity_close(mgr, ent, ent->cfg->idx, CloseCause_Lost);
  883. }
  884. }
  885. SetEvent(mod->evt_app_exit);
  886. #ifdef _WIN32
  887. sp_mod_mgr_unlockEx(mod->cfg->idx);
  888. #else
  889. sp_mod_mgr_unlock(mgr);
  890. #endif //_WIN32
  891. break;
  892. }
  893. }
  894. return TRUE; // delete process handle
  895. }
  896. static void subscribe_entity_state(sp_mod_mgr_t *mgr, int mod_id, int svc_id, int target_entity_id)
  897. {
  898. int found = 0;
  899. entity_state_subscribe_entry *pos;
  900. spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
  901. list_for_each_entry(pos, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
  902. if (pos->mod_id == mod_id && pos->svc_id == svc_id && pos->target_entity_id == target_entity_id) {
  903. found = TRUE;
  904. break;
  905. }
  906. }
  907. if (found) {
  908. pos->instance ++;
  909. } else {
  910. pos = MALLOC_T(entity_state_subscribe_entry);
  911. pos->instance = 1;
  912. pos->mod_id = mod_id;
  913. pos->svc_id = svc_id;
  914. pos->target_entity_id = target_entity_id;
  915. list_add_tail(&pos->entry, &mgr->entity_state_subscribe_list);
  916. }
  917. spinlock_leave(&mgr->entity_state_subscribe_lock);
  918. }
  919. static void unsubscribe_entity_state(sp_mod_mgr_t *mgr, int mod_id, int svc_id, int target_entity_id)
  920. {
  921. int found = 0;
  922. entity_state_subscribe_entry *pos;
  923. spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
  924. list_for_each_entry(pos, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
  925. if (pos->mod_id == mod_id && pos->svc_id == svc_id && pos->target_entity_id == target_entity_id) {
  926. found = TRUE;
  927. break;
  928. }
  929. }
  930. if (found) {
  931. pos->instance--;
  932. if (pos->instance == 0) {
  933. list_del(&pos->entry);
  934. free(pos);
  935. }
  936. }
  937. spinlock_leave(&mgr->entity_state_subscribe_lock);
  938. }
  939. static void subscribe_entity_life(sp_mod_mgr_t *mgr, int mod_id, int svc_id)
  940. {
  941. int found = 0;
  942. entity_life_subscribe_entry *pos;
  943. spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
  944. list_for_each_entry(pos, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
  945. if (pos->mod_id == mod_id && pos->svc_id == svc_id) {
  946. found = TRUE;
  947. break;
  948. }
  949. }
  950. if (found) {
  951. pos->instance ++;
  952. } else {
  953. pos = MALLOC_T(entity_life_subscribe_entry);
  954. pos->instance = 1;
  955. pos->mod_id = mod_id;
  956. pos->svc_id = svc_id;
  957. list_add_tail(&pos->entry, &mgr->entity_life_subscribe_list);
  958. }
  959. spinlock_leave(&mgr->entity_life_subscribe_lock);
  960. }
  961. static void unsubscribe_entity_life(sp_mod_mgr_t *mgr, int mod_id, int svc_id)
  962. {
  963. int found = 0;
  964. entity_life_subscribe_entry *pos;
  965. spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
  966. list_for_each_entry(pos, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
  967. if (pos->mod_id == mod_id && pos->svc_id == svc_id ) {
  968. found = TRUE;
  969. break;
  970. }
  971. }
  972. if (found) {
  973. pos->instance--;
  974. if (pos->instance == 0) {
  975. list_del(&pos->entry);
  976. free(pos);
  977. }
  978. }
  979. spinlock_leave(&mgr->entity_life_subscribe_lock);
  980. }
  981. static void clear_entity_state(sp_mod_mgr_t *mgr, int mod_id)
  982. {
  983. entity_state_subscribe_entry *pos, *n;
  984. spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
  985. list_for_each_entry_safe(pos, n, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
  986. if (pos->mod_id == mod_id) {
  987. list_del(&pos->entry);
  988. free(pos);
  989. }
  990. }
  991. spinlock_leave(&mgr->entity_state_subscribe_lock);
  992. }
  993. static void clear_entity_state_list_all(sp_mod_mgr_t *mgr)
  994. {
  995. entity_state_subscribe_entry *pos, *n;
  996. spinlock_enter(&mgr->entity_state_subscribe_lock, -1);
  997. list_for_each_entry_safe(pos, n, &mgr->entity_state_subscribe_list, entity_state_subscribe_entry, entry) {
  998. list_del(&pos->entry);
  999. free(pos);
  1000. }
  1001. spinlock_leave(&mgr->entity_state_subscribe_lock);
  1002. }
  1003. static void clear_entity_life(sp_mod_mgr_t *mgr, int mod_id)
  1004. {
  1005. entity_life_subscribe_entry *pos, *n;
  1006. spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
  1007. list_for_each_entry_safe(pos, n, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
  1008. if (pos->mod_id == mod_id) {
  1009. list_del(&pos->entry);
  1010. free(pos);
  1011. }
  1012. }
  1013. spinlock_leave(&mgr->entity_life_subscribe_lock);
  1014. }
  1015. static void clear_entity_life_list_all(sp_mod_mgr_t *mgr)
  1016. {
  1017. entity_life_subscribe_entry *pos, *n;
  1018. spinlock_enter(&mgr->entity_life_subscribe_lock, -1);
  1019. list_for_each_entry_safe(pos, n, &mgr->entity_life_subscribe_list, entity_life_subscribe_entry, entry) {
  1020. list_del(&pos->entry);
  1021. free(pos);
  1022. }
  1023. spinlock_leave(&mgr->entity_life_subscribe_lock);
  1024. }
  1025. 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)
  1026. {
  1027. sp_mod_mgr_t *mgr = (sp_mod_mgr_t *)user_data;
  1028. if (SP_GET_PKT_TYPE(pkt_type) == SP_PKT_MOD) {
  1029. int result = pkt_id;
  1030. int cmd_type = SP_GET_TYPE(pkt_type);
  1031. sp_mod_t *mod;
  1032. if (cmd_type == MOD_CMD_INIT || cmd_type == MOD_CMD_TERM) { // not necessary {bug}
  1033. list_for_each_entry(mod, &mgr->mod_list, sp_mod_t, entry) {
  1034. if (mod->cfg->idx == epid) {
  1035. if (mod->doing) {
  1036. mod->wait_result = result;
  1037. SetEvent(mod->evt_wait_handle);
  1038. }
  1039. break;
  1040. }
  1041. }
  1042. }
  1043. else if (cmd_type == MOD_CMD_USER_STATE_EVENT)
  1044. {
  1045. int last_state, curr_state;
  1046. sp_entity_t *entity = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
  1047. iobuffer_read(*p_pkt, IOBUF_T_I4, &last_state, NULL);
  1048. iobuffer_read(*p_pkt, IOBUF_T_I4, &curr_state, NULL);
  1049. mgr_on_user_state(mgr, entity, last_state, curr_state);
  1050. }
  1051. else if (cmd_type == MOD_CMD_REPORT_CREATE_CONN) {
  1052. sp_entity_t *entity_src = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
  1053. sp_entity_t *entity_dst = sp_mod_mgr_find_entity_by_idx(mgr, pkt_id);
  1054. if (entity_src && entity_dst)
  1055. mgr_on_create_connection(mgr, entity_src, entity_dst);
  1056. } else if (cmd_type == MOD_CMD_REPROT_CLOSE_CONN) {
  1057. sp_entity_t *entity_src = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
  1058. sp_entity_t *entity_dst = sp_mod_mgr_find_entity_by_idx(mgr, pkt_id);
  1059. mgr_on_close_connection(mgr, entity_src, entity_dst);
  1060. } else if (cmd_type == MOD_CMD_REPORT_EXCEPTION) {
  1061. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
  1062. mgr_on_entity_exception(mgr, ent, ent->cfg->idx, Error_Exception);
  1063. } else if (cmd_type == MOD_CMD_SWITCH_RUNNING_MODE) {
  1064. // BugFix [4/3/2020 9:09 Gifur]
  1065. mod = sp_mod_mgr_find_module_by_idx(mgr, epid);
  1066. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
  1067. int state = pkt_id;
  1068. if ((ent->state == EntityState_Idle || ent->state == EntityState_Busy) && state != ent->state) {
  1069. #ifdef _WIN32
  1070. sp_mod_mgr_lockEx(mod->cfg->idx);
  1071. #else
  1072. sp_mod_mgr_lock(mgr);
  1073. #endif //_WIN32
  1074. if (ent->state == EntityState_Idle || ent->state == EntityState_Busy) {
  1075. if (ent->state != state) {
  1076. int old_state = ent->state;
  1077. ent->state = state;
  1078. mgr_on_entity_state(mgr, ent, ent->cfg->idx, old_state, state);
  1079. }
  1080. }
  1081. #ifdef _WIN32
  1082. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1083. #else
  1084. sp_mod_mgr_unlock(mgr);
  1085. #endif //_WIN32
  1086. }
  1087. } else if (cmd_type == MOD_CMD_SUBSCRIBE_STATE_LISTENER) {
  1088. subscribe_entity_state(mgr, epid, svc_id, pkt_id);
  1089. } else if (cmd_type == MOD_CMD_UNSUBSCRIBE_STATE_LISTENER) {
  1090. unsubscribe_entity_state(mgr, epid, svc_id, pkt_id);
  1091. } else if (cmd_type == MOD_CMD_SUBSCRIBE_LIFE_LISTENER) {
  1092. subscribe_entity_life(mgr, epid, svc_id);
  1093. } else if (cmd_type == MOD_CMD_UNSUBSCRIBE_LIFE_LISTENER) {
  1094. unsubscribe_entity_life(mgr, epid, svc_id);
  1095. } else if (cmd_type == MOD_CMD_ENT_RESULT) {
  1096. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mgr, svc_id);
  1097. if (ent->mod->doing) {
  1098. ent->wait_result = result;
  1099. SetEvent(ent->evt_wait_handle);
  1100. }
  1101. } else if (cmd_type == MOD_CMD_MOD_RESULT) {
  1102. mod = sp_mod_mgr_find_module_by_idx(mgr, epid);
  1103. if (mod->doing) {
  1104. mod->wait_result = result;
  1105. SetEvent(mod->evt_wait_handle);
  1106. }
  1107. } else if (cmd_type == MOD_CMD_REPORT_REDIRECT_SUBSCRIBE) {
  1108. sp_uid_t uid;
  1109. int suggest_entity_id;
  1110. iobuffer_read(*p_pkt, IOBUF_T_I8, &uid, NULL);
  1111. iobuffer_read(*p_pkt, IOBUF_T_I4, &suggest_entity_id, NULL);
  1112. sp_bcm_daemon_process_redirect_subscribe(mgr->shell_daemon, svc_id, &uid, suggest_entity_id);
  1113. } else {
  1114. assert(0);
  1115. }
  1116. return FALSE;
  1117. }
  1118. return TRUE;
  1119. }
  1120. static void mgr_on_sys(sp_svc_t *svc,int epid, int state, void *user_data)
  1121. {
  1122. sp_mod_mgr_t *mgr = (sp_mod_mgr_t *)user_data;
  1123. if (state == BUS_STATE_OFF) {
  1124. clear_entity_state(mgr, epid);
  1125. clear_entity_life(mgr, epid);
  1126. }
  1127. }
  1128. int sp_mod_mgr_create(sp_mod_mgr_t **p_mgr)
  1129. {
  1130. sp_mod_mgr_t *mgr = shm_malloc(sizeof(sp_mod_mgr_t));
  1131. memset(mgr, 0, sizeof(sp_mod_mgr_t));
  1132. InitializeCriticalSection(&mgr->lock);
  1133. INIT_LIST_HEAD(&mgr->mod_list);
  1134. process_monitor_create(&mgr->process_monitor);
  1135. process_monitor_set_cb(mgr->process_monitor, &on_detect_process_end, mgr);
  1136. spinlock_init(&mgr->entity_life_subscribe_lock);
  1137. INIT_LIST_HEAD(&mgr->entity_life_subscribe_list);
  1138. spinlock_init(&mgr->entity_state_subscribe_lock);
  1139. INIT_LIST_HEAD(&mgr->entity_state_subscribe_list);
  1140. mgr->arr_ent = shm_array_make(SP_MAX_ENTITY, sizeof(sp_entity_t*));
  1141. mgr->arr_mod = shm_array_make(SP_MAX_MODULE, sizeof(sp_mod_t*));
  1142. mgr->instance_seq = 0;
  1143. mgr->shell_svc = NULL;
  1144. mgr->shell_daemon = NULL;
  1145. *p_mgr = mgr;
  1146. return 0;
  1147. }
  1148. void sp_mod_mgr_destroy(sp_mod_mgr_t *mgr)
  1149. {
  1150. assert(list_empty(&mgr->mod_list));
  1151. process_monitor_destroy(mgr->process_monitor);
  1152. DeleteCriticalSection(&mgr->lock);
  1153. shm_free(mgr);
  1154. }
  1155. void sp_mod_mgr_bind_shell_svc(sp_mod_mgr_t *mgr, sp_svc_t *svc)
  1156. {
  1157. mgr->shell_svc = svc;
  1158. }
  1159. int sp_mod_mgr_add_module(sp_mod_mgr_t *mgr, sp_cfg_shell_module_t *cfg_mod)
  1160. {
  1161. sp_mod_t *mod;
  1162. assert(mgr);
  1163. mod = sp_mod_mgr_find_module_by_name(mgr, cfg_mod->name);
  1164. if (!mod) {
  1165. //int len;
  1166. mod = shm_malloc(sizeof(sp_mod_t));
  1167. //len = sp_dir_get_path(env->dir, SP_DIR_MODULE_BIN, mod_name, NULL, 0);
  1168. //mod->path = shm_malloc(len+1);
  1169. //sp_dir_get_path(env->dir, SP_DIR_MODULE_BIN, mod_name, mod->path, 0);
  1170. mod->state = SP_MODULE_STATE_UNLOAD;
  1171. mod->mgr = mgr;
  1172. mod->cfg = cfg_mod;
  1173. mod->doing = 0;
  1174. mod->wait_result = 0;
  1175. mod->start_time = 0;
  1176. mod->evt_app_exit = CreateEventA(NULL, TRUE, TRUE, NULL);
  1177. mod->evt_wait_handle = CreateEventA(NULL, TRUE, FALSE, NULL);
  1178. process_init(&mod->process);
  1179. INIT_LIST_HEAD(&mod->entity_list);
  1180. list_add_tail(&mod->entry, &mgr->mod_list);
  1181. ARRAY_IDX(mgr->arr_mod, cfg_mod->idx, sp_mod_t*) = mod;
  1182. } else {
  1183. sp_dbg_debug("module %s already exist!", cfg_mod->name);
  1184. return Error_Duplication;
  1185. }
  1186. return 0;
  1187. }
  1188. int sp_mod_mgr_add_entity(sp_mod_mgr_t *mgr, sp_cfg_shell_entity_t *cfg_ent)
  1189. {
  1190. sp_mod_t *mod;
  1191. sp_entity_t *ent;
  1192. assert(mgr);
  1193. mod = sp_mod_mgr_find_module_by_name(mgr, cfg_ent->mod->name);
  1194. if (mod) {
  1195. ent = sp_mod_find_entity_by_name(mod, cfg_ent->name);
  1196. if (!ent) {
  1197. ent = shm_malloc(sizeof(sp_entity_t));
  1198. ent->state = EntityState_NoStart;
  1199. ent->mod = mod;
  1200. ent->wait_result = 0;
  1201. ent->first_start_time = 0;
  1202. ent->last_start_time = 0;
  1203. ent->state_start_time = 0;
  1204. ent->cfg = cfg_ent;
  1205. ent->service_flag = 0;
  1206. ent->evt_wait_handle = CreateEventA(NULL, TRUE, FALSE, NULL);
  1207. ent->instance_id = 0;
  1208. ent->user_state = 0;
  1209. list_add_tail(&ent->entry, &mod->entity_list);
  1210. ARRAY_IDX(mgr->arr_ent, cfg_ent->idx, sp_entity_t*) = ent;
  1211. } else {
  1212. return Error_Duplication;
  1213. }
  1214. } else {
  1215. return Error_NotExist;
  1216. }
  1217. return 0;
  1218. }
  1219. int sp_mod_mgr_remove_module(sp_mod_mgr_t *mgr, const char *mod_name)
  1220. {
  1221. sp_mod_t *mod;
  1222. assert(mgr);
  1223. assert(mod_name);
  1224. mod = sp_mod_mgr_find_module_by_name(mgr, mod_name);
  1225. if (mod) {
  1226. assert(mod->state == SP_MODULE_STATE_UNLOAD);
  1227. assert(list_empty(&mod->entity_list));
  1228. list_del(&mod->entry);
  1229. CloseHandle(mod->evt_app_exit);
  1230. CloseHandle(mod->evt_wait_handle);
  1231. shm_free(mod);
  1232. } else {
  1233. return Error_NotExist;
  1234. }
  1235. return 0;
  1236. }
  1237. int sp_mod_mgr_remove_entity(sp_mod_mgr_t *mgr, const char *entity_name)
  1238. {
  1239. sp_entity_t *ent;
  1240. assert(mgr);
  1241. assert(entity_name);
  1242. ent = sp_mod_mgr_find_entity_by_name(mgr, entity_name);
  1243. if (ent) {
  1244. list_del(&ent->entry);
  1245. CloseHandle(ent->evt_wait_handle);
  1246. shm_free(ent);
  1247. } else {
  1248. return Error_NotExist;
  1249. }
  1250. return 0;
  1251. }
  1252. int sp_mod_mgr_init(sp_mod_mgr_t *mgr)
  1253. {
  1254. int rc;
  1255. sp_mod_t *mod_pos;
  1256. list_for_each_entry(mod_pos, &mgr->mod_list, sp_mod_t, entry) { //遍历
  1257. sp_entity_t *ent_pos;
  1258. mgr->arr_mod->nelts++;
  1259. list_for_each_entry(ent_pos, &mod_pos->entity_list, sp_entity_t, entry) {
  1260. mgr->arr_ent->nelts++;
  1261. }
  1262. }
  1263. rc = process_monitor_start(mgr->process_monitor);
  1264. if (rc == 0) {
  1265. rc = sp_svc_add_pkt_handler(mgr->shell_svc, (int)mgr, SP_PKT_MOD, &mgr_on_pkt, mgr);
  1266. } else {
  1267. rc = Error_Unexpect;
  1268. }
  1269. return rc;
  1270. }
  1271. void sp_mod_mgr_term(sp_mod_mgr_t *mgr)
  1272. {
  1273. sp_svc_remove_pkt_handler(mgr->shell_svc, (int)mgr, SP_PKT_MOD);
  1274. process_monitor_stop(mgr->process_monitor);
  1275. mgr->arr_ent->nelts = 0;
  1276. mgr->arr_mod->nelts = 0;
  1277. }
  1278. void sp_mod_mgr_bind_bcm_daemon(sp_mod_mgr_t *mgr, sp_bcm_daemon_t *daemon)
  1279. {
  1280. mgr->shell_daemon = daemon;
  1281. }
  1282. void sp_mod_mgr_lock(sp_mod_mgr_t *mgr)
  1283. {
  1284. EnterCriticalSection(&mgr->lock);
  1285. //sp_dbg_info("lock mgr %d, lock %d",mgr, &(mgr->lock));
  1286. }
  1287. void sp_mod_mgr_unlock(sp_mod_mgr_t *mgr)
  1288. {
  1289. LeaveCriticalSection(&mgr->lock);
  1290. //sp_dbg_info("unlock mgr %d, lock %d", mgr, &(mgr->lock));
  1291. }
  1292. sp_mod_t *sp_mod_mgr_find_module_by_name(sp_mod_mgr_t *mgr, const char *mod_name)
  1293. {
  1294. sp_mod_t *mod;
  1295. if (!mod_name)
  1296. return NULL;
  1297. list_for_each_entry(mod, &mgr->mod_list, sp_mod_t, entry) {
  1298. if (_stricmp(mod_name, mod->cfg->name) == 0)
  1299. return mod;
  1300. }
  1301. return NULL;
  1302. }
  1303. sp_mod_t *sp_mod_mgr_find_module_by_idx(sp_mod_mgr_t *mgr, int mod_idx)
  1304. {
  1305. if (mod_idx == -1 || mod_idx >= mgr->arr_mod->nelts)
  1306. return NULL;
  1307. return ARRAY_IDX(mgr->arr_mod, mod_idx, sp_mod_t*);
  1308. }
  1309. sp_entity_t *sp_mod_find_entity_by_name(sp_mod_t *mod, const char *entity_name)
  1310. {
  1311. sp_entity_t *ent;
  1312. if (!entity_name)
  1313. return NULL;
  1314. list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
  1315. if (_stricmp(ent->cfg->name, entity_name) == 0)
  1316. return ent;
  1317. }
  1318. return NULL;
  1319. }
  1320. sp_entity_t *sp_mod_find_entity_by_idx(sp_mod_t *mod, int entity_idx)
  1321. {
  1322. if (entity_idx == -1 || entity_idx >= mod->mgr->arr_ent->nelts)
  1323. return NULL;
  1324. return ARRAY_IDX(mod->mgr->arr_ent, entity_idx, sp_entity_t*);
  1325. }
  1326. sp_entity_t *sp_mod_find_entity_by_devel_id(sp_mod_t *mod, int devel_id)
  1327. {
  1328. sp_entity_t *ent;
  1329. list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
  1330. if (ent->cfg->devel_id == devel_id)
  1331. return ent;
  1332. }
  1333. return NULL;
  1334. }
  1335. sp_entity_t *sp_mod_find_entity_by_inst_id(sp_mod_t *mod, int inst_id)
  1336. {
  1337. sp_entity_t *ent;
  1338. list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
  1339. if (ent->instance_id == inst_id)
  1340. return ent;
  1341. }
  1342. return NULL;
  1343. }
  1344. sp_entity_t *sp_mod_mgr_find_entity_by_name(sp_mod_mgr_t *mgr, const char *entity_name)
  1345. {
  1346. sp_mod_t *mod;
  1347. if (!entity_name)
  1348. return NULL;
  1349. list_for_each_entry(mod, &mgr->mod_list, sp_mod_t, entry) {
  1350. sp_entity_t *ent = sp_mod_find_entity_by_name(mod, entity_name);
  1351. if (ent)
  1352. return ent;
  1353. }
  1354. return NULL;
  1355. }
  1356. sp_entity_t *sp_mod_mgr_find_entity_by_idx(sp_mod_mgr_t *mgr, int entity_id)
  1357. {
  1358. if (entity_id == -1 || entity_id >= mgr->arr_ent->nelts)
  1359. return NULL;
  1360. return ARRAY_IDX(mgr->arr_ent, entity_id, sp_entity_t*);
  1361. }
  1362. sp_entity_t *sp_mod_mgr_find_entity_by_devel_id(sp_mod_mgr_t *mgr, int devel_id)
  1363. {
  1364. int i;
  1365. for (i = 1; i < mgr->arr_ent->nelts; ++i) {
  1366. sp_entity_t *ent = ARRAY_IDX(mgr->arr_ent, i, sp_entity_t*);
  1367. if (ent->cfg->devel_id == devel_id)
  1368. return ent;
  1369. }
  1370. return NULL;
  1371. }
  1372. sp_entity_t *sp_mod_mgr_find_entity_by_inst_id(sp_mod_mgr_t *mgr, int inst_id)
  1373. {
  1374. int i;
  1375. for (i = 1; i < mgr->arr_ent->nelts; ++i) {
  1376. sp_entity_t *ent = ARRAY_IDX(mgr->arr_ent, i, sp_entity_t*);
  1377. if (ent->instance_id == inst_id)
  1378. return ent;
  1379. }
  1380. return NULL;
  1381. }
  1382. struct list_head* sp_mod_mgr_get_module_list_head(sp_mod_mgr_t *mgr)
  1383. {
  1384. return &mgr->mod_list;
  1385. }
  1386. int sp_mod_mgr_get_entity_array_nelts(sp_mod_mgr_t *mgr)
  1387. {
  1388. return mgr->arr_ent->nelts;
  1389. }
  1390. static int try_lock_doing(sp_mod_mgr_t *mgr, sp_mod_t *mod)
  1391. {
  1392. int ok = FALSE;
  1393. #ifdef _WIN32
  1394. sp_mod_mgr_lockEx(mod->cfg->idx);
  1395. #else
  1396. sp_mod_mgr_lock(mgr);
  1397. #endif //_WIN32
  1398. if (!mod->doing) {
  1399. mod->doing = 1;
  1400. ok = TRUE;
  1401. }
  1402. #ifdef _WIN32
  1403. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1404. #else
  1405. sp_mod_mgr_unlock(mgr);
  1406. #endif //_WIN32
  1407. return ok;
  1408. }
  1409. static void unlock_doing(sp_mod_mgr_t *mgr, sp_mod_t *mod)
  1410. {
  1411. #ifdef _WIN32
  1412. sp_mod_mgr_lockEx(mod->cfg->idx);
  1413. #else
  1414. sp_mod_mgr_lock(mgr);
  1415. #endif //_WIN32
  1416. mod->doing = 0;
  1417. #ifdef _WIN32
  1418. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1419. #else
  1420. sp_mod_mgr_unlock(mgr);
  1421. #endif //_WIN32
  1422. }
  1423. static int load_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
  1424. {
  1425. int rc = 0;
  1426. sp_env_t *env = sp_get_env();
  1427. sp_dbg_debug("begin load module %s", mod->cfg->name);
  1428. #ifdef _WIN32
  1429. sp_mod_mgr_lockEx(mod->cfg->idx);
  1430. #else
  1431. sp_mod_mgr_lock(mgr);
  1432. #endif //_WIN32
  1433. if (!mod->state) {
  1434. ResetEvent(mod->evt_app_exit);
  1435. if (0 != create_module_process(mod->cfg->name, mod->cfg->idx, env->shm_range, mod->cfg->group, &mod->process)) {
  1436. sp_dbg_debug("sp_mod_mgr_load_module %s failed!, create module process failed", mod->cfg->name);
  1437. rc = Error_Unexpect;
  1438. }
  1439. } else {
  1440. rc = Error_Duplication;
  1441. }
  1442. #ifdef _WIN32
  1443. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1444. #else
  1445. sp_mod_mgr_unlock(mgr);
  1446. #endif //_WIN32
  1447. if (rc == 0) {
  1448. const int interval = 50; //consider sleep operation below, here would consume 4 min at terriable situation.
  1449. const int tries = PROCESS_TIMEOUT / interval;
  1450. int i;
  1451. ResetEvent(mod->evt_wait_handle);
  1452. sp_dbg_debug("get remote entitiy state...");
  1453. for (i = 0; i < tries; ++i) {
  1454. int state = BUS_STATE_OFF;
  1455. rc = sp_svc_get_state(mgr->shell_svc, mod->cfg->idx, &state);
  1456. sp_dbg_debug("cfg::idx: %d, state: %d", mod->cfg->idx, state);
  1457. if (rc == 0) {
  1458. if (state != BUS_STATE_ON) {
  1459. DWORD dwRet;
  1460. dwRet = WaitForSingleObject(mod->process.handle, (DWORD)interval); //wait for entity thread end
  1461. if (dwRet == WAIT_OBJECT_0) {
  1462. sp_dbg_debug("detect process %s exit exception!", mod->cfg->name);
  1463. rc = Error_Unexpect;
  1464. break;
  1465. }
  1466. } else {
  1467. sp_dbg_info("mod is online now!, %s", mod->cfg->name);
  1468. break;
  1469. }
  1470. } else {
  1471. sp_dbg_info("get epid state failed!");
  1472. break;
  1473. }
  1474. }
  1475. if (rc == 0)
  1476. rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, SP_INVALID_SVC_ID, SP_PKT_MOD|MOD_CMD_INIT, 0, NULL);
  1477. if (rc) {
  1478. sp_dbg_error("send out mod init cmd failed!");
  1479. } else {
  1480. sp_dbg_info("send out mod init cmd ok!, %s", mod->cfg->name);
  1481. for (i = 0; i < tries; ++i) {
  1482. #ifdef _WIN32
  1483. HANDLE hs[] = { mod->evt_wait_handle, mod->process.handle }; //wait for entity thread end
  1484. DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, (DWORD)interval);
  1485. #else
  1486. DWORD dwRet = WaitForSingleObject(mod->evt_wait_handle, (DWORD)interval);
  1487. if (dwRet == WAIT_TIMEOUT) {
  1488. dwRet = WaitForSingleObject(mod->process.handle, 0);
  1489. if (dwRet == WAIT_OBJECT_0) {
  1490. dwRet = WAIT_OBJECT_0 + 1;
  1491. }
  1492. }
  1493. #endif //_WIN32
  1494. if (dwRet == WAIT_OBJECT_0) {
  1495. sp_dbg_info("receive reply from module %s ok!", mod->cfg->name);
  1496. rc = mod->wait_result;
  1497. break;
  1498. } else if (dwRet == WAIT_OBJECT_0+1) {
  1499. sp_dbg_debug("detect process %s exit exception!", mod->cfg->name);
  1500. rc = Error_Unexpect;
  1501. break;
  1502. } else if(dwRet == WAIT_TIMEOUT){
  1503. rc = Error_TimeOut;
  1504. }
  1505. else {
  1506. sp_dbg_error("wait for multi object failed!! err=%d", GetLastError());
  1507. rc = Error_Unexpect;
  1508. break;
  1509. }
  1510. }
  1511. }
  1512. }
  1513. #ifdef _WIN32
  1514. sp_mod_mgr_lockEx(mod->cfg->idx);
  1515. #else
  1516. sp_mod_mgr_lock(mgr);
  1517. #endif //_WIN32
  1518. if (rc == 0) {
  1519. mod->state = SP_MODULE_STATE_LOAD;
  1520. mod->start_time = y2k_time_now();
  1521. process_monitor_add(mgr->process_monitor, &mod->process);
  1522. sp_dbg_info("load module ok! start time = %d, state = LOADED", mod->start_time);
  1523. } else {
  1524. mod_kill_process(mod);
  1525. WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
  1526. process_close(&mod->process);
  1527. sp_dbg_info("load module failed!");
  1528. }
  1529. #ifdef _WIN32
  1530. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1531. #else
  1532. sp_mod_mgr_unlock(mgr);
  1533. #endif //_WIN32
  1534. return rc;
  1535. }
  1536. static int unload_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
  1537. {
  1538. int rc = 0;
  1539. sp_entity_t *pos;
  1540. #ifdef _WIN32
  1541. sp_mod_mgr_lockEx(mod->cfg->idx);
  1542. #else
  1543. sp_mod_mgr_lock(mgr);
  1544. #endif //_WIN32
  1545. if (mod->state) {
  1546. list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
  1547. if (pos->state != EntityState_Killed &&
  1548. pos->state != EntityState_Close && pos->state != EntityState_NoStart) {
  1549. sp_dbg_debug("unload %s module, has entity not in idle state!", mod->cfg->name);
  1550. rc = Error_Bug;
  1551. break;
  1552. }
  1553. }
  1554. if (rc == 0) {
  1555. ResetEvent(mod->evt_wait_handle);
  1556. rc = sp_svc_send(mod->mgr->shell_svc, mod->cfg->idx, SP_INVALID_SVC_ID, SP_PKT_MOD|MOD_CMD_TERM, 0, NULL);
  1557. if (rc == 0) {
  1558. sp_dbg_debug("unload %s module, send pkt cmd ok!", mod->cfg->name);
  1559. } else {
  1560. sp_dbg_error("unload %s module, send pkt cmd failed: %d!", mod->cfg->name, rc);
  1561. }
  1562. }
  1563. } else {
  1564. sp_dbg_debug("module %s already unloaded!", mod->cfg->name);
  1565. rc = Error_NotInit;
  1566. }
  1567. #ifdef _WIN32
  1568. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1569. #else
  1570. sp_mod_mgr_unlock(mgr);
  1571. #endif //_WIN32
  1572. if (rc == 0) {
  1573. int removed = 0;
  1574. /*TODO: the clear job depend on different result seems no different.*/
  1575. for (;;) {
  1576. HANDLE hs[] = {mod->evt_app_exit, mod->evt_wait_handle};
  1577. DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
  1578. if (dwRet == WAIT_OBJECT_0) { // app exit
  1579. break;
  1580. } else if (dwRet == WAIT_OBJECT_0+1) {
  1581. ResetEvent(mod->evt_wait_handle);
  1582. if (mod->wait_result != 0) {
  1583. HANDLE hprocess = mod->process.handle;
  1584. if (hprocess && process_monitor_remove(mgr->process_monitor, &mod->process) == 0) {
  1585. removed = 1;
  1586. mod_kill_process(mod);
  1587. WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
  1588. process_close(&mod->process);
  1589. break;
  1590. } //TODO:
  1591. } else {
  1592. HANDLE hprocess = mod->process.handle;
  1593. if (hprocess && process_monitor_remove(mgr->process_monitor, &mod->process) == 0) {
  1594. DWORD tmp;
  1595. removed = 1;
  1596. tmp = WaitForSingleObject(hprocess, PROCESS_EXIT_TIMEOUT);
  1597. if (tmp == WAIT_TIMEOUT) {
  1598. sp_dbg_warn("wait process %d normal exit timeout!", mod->cfg->name);
  1599. mod_kill_process(mod);
  1600. WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
  1601. }
  1602. process_close(&mod->process);
  1603. break;
  1604. }
  1605. }
  1606. } else {
  1607. HANDLE hprocess = mod->process.handle;
  1608. if (hprocess && process_monitor_remove(mgr->process_monitor, &mod->process) == 0) {
  1609. removed = 1;
  1610. mod_kill_process(mod);
  1611. WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
  1612. process_close(&mod->process);
  1613. break;
  1614. }
  1615. }
  1616. }
  1617. #ifdef _WIN32
  1618. sp_mod_mgr_lockEx(mod->cfg->idx);
  1619. #else
  1620. sp_mod_mgr_lock(mgr);
  1621. #endif //_WIN32
  1622. if (removed) {
  1623. mod->state = SP_MODULE_STATE_UNLOAD;
  1624. SetEvent(mod->evt_app_exit);
  1625. }
  1626. #ifdef _WIN32
  1627. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1628. #else
  1629. sp_mod_mgr_unlock(mgr);
  1630. #endif //_WIN32
  1631. }
  1632. return rc;
  1633. }
  1634. /*remove from monitor and kill it directory!!*/
  1635. static int terminate_module(sp_mod_mgr_t *mgr, sp_mod_t *mod, int trigger_entity_id)
  1636. {
  1637. int rc = 0;
  1638. sp_entity_t *pos;
  1639. #ifdef _WIN32
  1640. sp_mod_mgr_lockEx(mod->cfg->idx);
  1641. #else
  1642. sp_mod_mgr_lock(mgr);
  1643. #endif //_WIN32
  1644. if (mod->state) {
  1645. if (mod->process.handle) {
  1646. if (process_monitor_remove(mgr->process_monitor, &mod->process) == 0) {
  1647. mod_kill_process(mod);
  1648. WaitForSingleObject(mod->process.handle, PROCESS_EXIT_TIMEOUT);
  1649. sp_dbg_debug("mod %s 's process removed now!", mod->cfg->name);
  1650. process_close(&mod->process);
  1651. mod->state = SP_MODULE_STATE_UNLOAD;
  1652. list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
  1653. int old_state = pos->state;
  1654. if (old_state != EntityState_Close && old_state != EntityState_Killed) {
  1655. pos->state = EntityState_Killed;
  1656. mgr_on_entity_state(mgr, pos, trigger_entity_id, old_state, pos->state);
  1657. mgr_on_entity_close(mgr, pos, trigger_entity_id, CloseCause_Lost);
  1658. }
  1659. }
  1660. SetEvent(mod->evt_app_exit);
  1661. } else {
  1662. sp_dbg_debug("mod %s is remove monitor failed!", mod->cfg->name);
  1663. rc = -1;
  1664. }
  1665. } else {
  1666. list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
  1667. if (pos->state != EntityState_Killed && pos->state != EntityState_Close) {
  1668. int old_state = pos->state;
  1669. pos->state = EntityState_Killed;
  1670. mgr_on_entity_state(mgr, pos, trigger_entity_id, old_state, pos->state);
  1671. mgr_on_entity_close(mgr, pos, trigger_entity_id, CloseCause_Lost);
  1672. }
  1673. }
  1674. mod->state = SP_MODULE_STATE_UNLOAD;
  1675. }
  1676. } else {
  1677. list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
  1678. if (pos->state != EntityState_Killed && pos->state != EntityState_Close && pos->state != EntityState_NoStart) {
  1679. int old_state = pos->state;
  1680. pos->state = EntityState_Killed;
  1681. mgr_on_entity_state(mgr, pos, trigger_entity_id, old_state, pos->state);
  1682. mgr_on_entity_close(mgr, pos, trigger_entity_id, CloseCause_Lost);
  1683. }
  1684. }
  1685. }
  1686. #ifdef _WIN32
  1687. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1688. #else
  1689. sp_mod_mgr_unlock(mgr);
  1690. #endif //_WIN32
  1691. return rc;
  1692. }
  1693. static int start_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, const char *cmdline, int trigger_entity_id)
  1694. {
  1695. int rc = 0;
  1696. sp_mod_t *mod = ent->mod;
  1697. sp_dbg_debug("begin start entity %s", ent->cfg->name);
  1698. #ifdef _WIN32
  1699. sp_mod_mgr_lockEx(mod->cfg->idx);
  1700. #else
  1701. sp_mod_mgr_lock(mgr);
  1702. #endif //_WIN32
  1703. if (mod->state) {
  1704. if (ent->state == EntityState_NoStart || ent->state == EntityState_Killed || ent->state == EntityState_Close) {
  1705. iobuffer_t *pkt = iobuffer_create(-1, -1);
  1706. iobuffer_write(pkt, IOBUF_T_STR, cmdline, -1);
  1707. iobuffer_write(pkt, IOBUF_T_I4, &trigger_entity_id, 0);
  1708. ResetEvent(ent->evt_wait_handle);
  1709. ent->instance_id = mgr_new_instance_id(mgr);
  1710. rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_START, ent->cfg->idx, &pkt);
  1711. if (rc == 0) {
  1712. int last_state = ent->state;
  1713. sp_dbg_debug("start entity %s, send cmd start ok!", ent->cfg->name);
  1714. ent->state_start_time = y2k_time_now();
  1715. if (ent->first_start_time == 0)
  1716. ent->first_start_time = ent->state_start_time;
  1717. ent->last_start_time = ent->state_start_time;
  1718. ent->state = EntityState_Starting;
  1719. mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
  1720. } else {
  1721. sp_dbg_debug("start entity %s, send cmd start failed!", ent->cfg->name);
  1722. }
  1723. if (pkt)
  1724. iobuffer_dec_ref(pkt);
  1725. } else {
  1726. rc = Error_InvalidState;
  1727. sp_dbg_debug("entity %s state is not correct!", ent->cfg->name);
  1728. }
  1729. } else {
  1730. sp_dbg_debug("entity's %s 's module is not load or is pending!", ent->cfg->name);
  1731. rc = Error_Pending;
  1732. }
  1733. #ifdef _WIN32
  1734. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1735. #else
  1736. sp_mod_mgr_unlock(mgr);
  1737. #endif //_WIN32
  1738. if (rc == 0) {
  1739. int last_state = ent->state;
  1740. HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
  1741. DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
  1742. if (dwRet == WAIT_OBJECT_0) {
  1743. sp_dbg_debug("wait for start entity %s result, app exit!", ent->cfg->name);
  1744. rc = Error_Unexpect;
  1745. } else if (dwRet == WAIT_OBJECT_0+1) {
  1746. sp_dbg_debug("wait for start entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
  1747. rc = ent->wait_result;
  1748. } else {
  1749. sp_dbg_debug("wait for start entity %s timeout!", ent->cfg->name);
  1750. rc = Error_TimeOut;
  1751. }
  1752. #ifdef _WIN32
  1753. sp_mod_mgr_lockEx(mod->cfg->idx);
  1754. #else
  1755. sp_mod_mgr_lock(mgr);
  1756. #endif //_WIN32
  1757. if (rc == 0) {
  1758. ent->state = EntityState_Idle;
  1759. ent->state_start_time = y2k_time_now();
  1760. mgr_on_entity_create(mgr, ent, trigger_entity_id);
  1761. } else {
  1762. ent->state = EntityState_Lost;
  1763. ent->state_start_time = y2k_time_now();
  1764. mgr_on_entity_exception(mgr, ent, trigger_entity_id, Error_Exception);
  1765. }
  1766. mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
  1767. #ifdef _WIN32
  1768. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1769. #else
  1770. sp_mod_mgr_unlock(mgr);
  1771. #endif //_WIN32
  1772. }
  1773. return rc;
  1774. }
  1775. static int stop_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id, int cause_code)
  1776. {
  1777. int rc = 0;
  1778. sp_mod_t *mod = ent->mod;
  1779. #ifdef _WIN32
  1780. sp_mod_mgr_lockEx(mod->cfg->idx);
  1781. #else
  1782. sp_mod_mgr_lock(mgr);
  1783. #endif //_WIN32
  1784. if (mod->state) {//judge module state
  1785. if (ent->state == EntityState_Busy || ent->state == EntityState_Idle || ent->state == EntityState_Pause) {
  1786. iobuffer_t *body = iobuffer_create(-1, -1);
  1787. ResetEvent(ent->evt_wait_handle);
  1788. iobuffer_write(body, IOBUF_T_I4, &trigger_entity_id, 0);
  1789. iobuffer_write(body, IOBUF_T_I4, &cause_code, 0);
  1790. rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_STOP, ent->cfg->idx, &body);
  1791. if (rc == 0) {
  1792. int last_state = ent->state;
  1793. sp_dbg_debug("stop entity %s, send cmd stop ok!", ent->cfg->name);
  1794. ent->state = EntityState_UnLoading;
  1795. ent->state_start_time = y2k_time_now();
  1796. mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
  1797. } else {
  1798. sp_dbg_debug("stop entity %s, send cmd stop failed!", ent->cfg->name);
  1799. }
  1800. if (body)
  1801. iobuffer_dec_ref(body);
  1802. } else {
  1803. rc = Error_InvalidState;
  1804. sp_dbg_debug("entity %s state is not correct, you may call TerminateEntity first!", ent->cfg->name);
  1805. }
  1806. } else {
  1807. sp_dbg_warn("%s's mod %s is not load or is pending!", ent->cfg->name, mod->cfg->name);
  1808. rc = Error_Pending;
  1809. }
  1810. #ifdef _WIN32
  1811. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1812. #else
  1813. sp_mod_mgr_unlock(mgr);
  1814. #endif //_WIN32
  1815. if (rc == 0) {
  1816. int last_state = ent->state;
  1817. HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
  1818. DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT); //2mins
  1819. if (dwRet == WAIT_OBJECT_0) {
  1820. sp_dbg_debug("wait for stop entity %s result, app exit!", ent->cfg->name);
  1821. rc = Error_Unexpect;
  1822. } else if (dwRet == WAIT_OBJECT_0+1) {
  1823. sp_dbg_debug("wait for stop entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
  1824. rc = ent->wait_result;
  1825. } else {
  1826. sp_dbg_debug("wait for stop entity %s timeout!", ent->cfg->name);
  1827. rc = Error_TimeOut;
  1828. }
  1829. #ifdef _WIN32
  1830. sp_mod_mgr_lockEx(mod->cfg->idx);
  1831. #else
  1832. sp_mod_mgr_lock(mgr);
  1833. #endif //_WIN32
  1834. if (rc == 0) {
  1835. ent->state = EntityState_Close;
  1836. ent->state_start_time = y2k_time_now();
  1837. mgr_on_entity_close(mgr, ent, trigger_entity_id, trigger_entity_id != ent->cfg->idx ? CloseCause_Other : CloseCause_Self);
  1838. } else {
  1839. ent->state = EntityState_Lost;
  1840. ent->state_start_time = y2k_time_now();
  1841. mgr_on_entity_exception(mgr, ent, trigger_entity_id, Error_Exception);
  1842. }
  1843. mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
  1844. #ifdef _WIN32
  1845. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1846. #else
  1847. sp_mod_mgr_unlock(mgr);
  1848. #endif //_WIN32
  1849. }
  1850. return rc;
  1851. }
  1852. static int pause_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
  1853. {
  1854. int rc = 0;
  1855. sp_mod_t *mod;
  1856. mod = ent->mod;
  1857. #ifdef _WIN32
  1858. sp_mod_mgr_lockEx(mod->cfg->idx);
  1859. #else
  1860. sp_mod_mgr_lock(mgr);
  1861. #endif //_WIN32
  1862. if (mod->state) {
  1863. if (ent->state == EntityState_Busy || ent->state == EntityState_Idle) {
  1864. iobuffer_t *body = iobuffer_create(-1, -1);
  1865. ResetEvent(ent->evt_wait_handle);
  1866. iobuffer_write(body, IOBUF_T_I4, &trigger_entity_id, 0);
  1867. rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_PAUSE, ent->cfg->idx, &body);
  1868. if (rc == 0) {
  1869. sp_dbg_debug("pause entity %s, send cmd pause ok!", ent->cfg->name);
  1870. } else {
  1871. sp_dbg_debug("pause entity %s, send cmd pause failed!", ent->cfg->name);
  1872. }
  1873. if (body)
  1874. iobuffer_dec_ref(body);
  1875. } else {
  1876. rc = Error_InvalidState;
  1877. sp_dbg_debug("entity %s state is not correct! current state: %d", ent->cfg->name, (int)ent->state);
  1878. }
  1879. } else {
  1880. sp_dbg_debug("entity's %s mod %s is not load or is pending!", ent->cfg->name, mod->cfg->name);
  1881. rc = Error_Unexpect;
  1882. }
  1883. #ifdef _WIN32
  1884. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1885. #else
  1886. sp_mod_mgr_unlock(mgr);
  1887. #endif //_WIN32
  1888. if (rc == 0) {
  1889. HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
  1890. DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
  1891. if (dwRet == WAIT_OBJECT_0) {
  1892. sp_dbg_debug("wait for pause entity %s result, app exit!", ent->cfg->name);
  1893. rc = Error_Unexpect;
  1894. } else if (dwRet == WAIT_OBJECT_0+1) {
  1895. sp_dbg_debug("wait for pause entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
  1896. rc = ent->wait_result;
  1897. } else {
  1898. sp_dbg_debug("wait for pause entity %s timeout!", ent->cfg->name);
  1899. rc = Error_TimeOut;
  1900. }
  1901. #ifdef _WIN32
  1902. sp_mod_mgr_lockEx(mod->cfg->idx);
  1903. #else
  1904. sp_mod_mgr_lock(mgr);
  1905. #endif //_WIN32
  1906. if (rc == 0) {
  1907. int last_state = ent->state;
  1908. ent->state = EntityState_Pause;
  1909. ent->state_start_time = y2k_time_now();
  1910. mgr_on_entity_state(mgr, ent, trigger_entity_id, last_state, ent->state);
  1911. }
  1912. #ifdef _WIN32
  1913. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1914. #else
  1915. sp_mod_mgr_unlock(mgr);
  1916. #endif //_WIN32
  1917. }
  1918. return rc;
  1919. }
  1920. static int continue_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
  1921. {
  1922. int rc = 0;
  1923. sp_mod_t*mod;
  1924. mod = ent->mod;
  1925. #ifdef _WIN32
  1926. sp_mod_mgr_lockEx(mod->cfg->idx);
  1927. #else
  1928. sp_mod_mgr_lock(mgr);
  1929. #endif //_WIN32
  1930. if (mod->state) {
  1931. if (ent->state == EntityState_Pause) {
  1932. iobuffer_t *body = iobuffer_create(-1, -1);
  1933. ResetEvent(ent->evt_wait_handle);
  1934. iobuffer_write(body, IOBUF_T_I4, &trigger_entity_id, 0);
  1935. rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_CONTINUE, ent->cfg->idx, &body);
  1936. if (rc == 0) {
  1937. sp_dbg_debug("continue entity %s, send cmd continue ok!", ent->cfg->name);
  1938. } else {
  1939. sp_dbg_debug("continue entity %s, send cmd continue failed!", ent->cfg->name);
  1940. }
  1941. if (body)
  1942. iobuffer_dec_ref(body);
  1943. } else {
  1944. rc = Error_InvalidState;
  1945. sp_dbg_debug("entity %s state is not correct!", ent->cfg->name);
  1946. }
  1947. } else {
  1948. sp_dbg_debug("entity's %s mod %s is not load or is pending!", ent->cfg->name, mod->cfg->name);
  1949. rc = Error_Unexpect;
  1950. }
  1951. #ifdef _WIN32
  1952. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1953. #else
  1954. sp_mod_mgr_unlock(mgr);
  1955. #endif //_WIN32
  1956. if (rc == 0) {
  1957. HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
  1958. DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, PROCESS_TIMEOUT);
  1959. if (dwRet == WAIT_OBJECT_0) {
  1960. sp_dbg_debug("wait for continue entity %s result, app exit!", ent->cfg->name);
  1961. rc = Error_Unexpect;
  1962. } else if (dwRet == WAIT_OBJECT_0+1) {
  1963. sp_dbg_debug("wait for continue entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
  1964. rc = ent->wait_result;
  1965. } else {
  1966. sp_dbg_debug("wait for continue entity %s timeout!", ent->cfg->name);
  1967. rc = Error_TimeOut;
  1968. }
  1969. #ifdef _WIN32
  1970. sp_mod_mgr_lockEx(mod->cfg->idx);
  1971. #else
  1972. sp_mod_mgr_lock(mgr);
  1973. #endif //_WIN32
  1974. if (rc == 0) {
  1975. ent->state = EntityState_Idle;
  1976. ent->state_start_time = y2k_time_now();
  1977. mgr_on_entity_state(mgr, ent, trigger_entity_id, EntityState_Pause, ent->state);
  1978. }
  1979. #ifdef _WIN32
  1980. sp_mod_mgr_unlockEx(mod->cfg->idx);
  1981. #else
  1982. sp_mod_mgr_unlock(mgr);
  1983. #endif //_WIN32
  1984. }
  1985. return rc;
  1986. }
  1987. static int test_entity(sp_mod_mgr_t *mgr, sp_entity_t *ent, int test_type, int trigger_entity_id)
  1988. {
  1989. int rc = 0;
  1990. sp_mod_t *mod;
  1991. mod = ent->mod;
  1992. #ifdef _WIN32
  1993. sp_mod_mgr_lockEx(mod->cfg->idx);
  1994. #else
  1995. sp_mod_mgr_lock(mgr);
  1996. #endif //_WIN32
  1997. if (mod->state) {
  1998. if (ent->state == EntityState_Idle || ent->state == EntityState_Busy || ent->state == EntityState_Pause) {
  1999. iobuffer_t *body = iobuffer_create(-1, -1);
  2000. ResetEvent(ent->evt_wait_handle);
  2001. iobuffer_write(body, IOBUF_T_I4, &trigger_entity_id, 0);
  2002. iobuffer_write(body, IOBUF_T_I4, &test_type, 0);
  2003. rc = sp_svc_send(mgr->shell_svc, mod->cfg->idx, ent->cfg->idx, SP_PKT_MOD|MOD_CMD_TEST, ent->cfg->idx, &body);
  2004. if (rc == 0) {
  2005. sp_dbg_debug("test entity %s, send cmd test ok!", ent->cfg->name);
  2006. } else {
  2007. sp_dbg_debug("test entity %s, send cmd test failed!", ent->cfg->name);
  2008. }
  2009. if (body)
  2010. iobuffer_dec_ref(body);
  2011. } else {
  2012. rc = Error_InvalidState;
  2013. sp_dbg_debug("entity %s state is not correct!", ent->cfg->name);
  2014. }
  2015. } else {
  2016. sp_dbg_debug("entity's %s mod %s is not load or is pending!", ent->cfg->name, mod->cfg->name);
  2017. rc = Error_Unexpect;
  2018. }
  2019. #ifdef _WIN32
  2020. sp_mod_mgr_unlockEx(mod->cfg->idx);
  2021. #else
  2022. sp_mod_mgr_unlock(mgr);
  2023. #endif //_WIN32
  2024. if (rc == 0) {
  2025. HANDLE hs[] = {mod->evt_app_exit, ent->evt_wait_handle};
  2026. DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, ENTITY_TEST_TIMEOUT);
  2027. if (dwRet == WAIT_OBJECT_0) {
  2028. sp_dbg_debug("wait for test entity %s result, app exit!", ent->cfg->name);
  2029. rc = Error_Unexpect;
  2030. } else if (dwRet == WAIT_OBJECT_0+1) {
  2031. sp_dbg_debug("wait for test entity %s result ok, result = %d!", ent->cfg->name, ent->wait_result);
  2032. rc = ent->wait_result;
  2033. } else {
  2034. sp_dbg_debug("wait for test entity %s timeout!", ent->cfg->name);
  2035. rc = Error_TimeOut;
  2036. }
  2037. }
  2038. return rc;
  2039. }
  2040. int sp_mod_mgr_start_entity(sp_mod_mgr_t *mgr, int entity_id, const char *cmdline, int trigger_entity_id)
  2041. {
  2042. sp_entity_t *ent;
  2043. ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
  2044. if (!ent)
  2045. return Error_NotExist;
  2046. return sp_mod_mgr_start_entity2(mgr, ent, cmdline, trigger_entity_id);
  2047. }
  2048. int sp_mod_mgr_stop_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id, int cause_code)
  2049. {
  2050. sp_entity_t *ent;
  2051. ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
  2052. if (!ent)
  2053. return Error_NotExist;
  2054. return sp_mod_mgr_stop_entity2(mgr, ent, trigger_entity_id, cause_code);
  2055. }
  2056. int sp_mod_mgr_terminate_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id)
  2057. {
  2058. sp_entity_t *ent;
  2059. ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
  2060. if (!ent)
  2061. return Error_NotExist;
  2062. return sp_mod_mgr_terminate_entity2(mgr, ent, trigger_entity_id);
  2063. }
  2064. int sp_mod_mgr_pause_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id)
  2065. {
  2066. sp_entity_t *ent;
  2067. ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
  2068. if (!ent)
  2069. return Error_NotExist;
  2070. return sp_mod_mgr_pause_entity2(mgr, ent, trigger_entity_id);
  2071. }
  2072. int sp_mod_mgr_continue_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id)
  2073. {
  2074. sp_entity_t *ent;
  2075. ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
  2076. if (!ent)
  2077. return Error_NotExist;
  2078. return sp_mod_mgr_continue_entity2(mgr, ent, trigger_entity_id);
  2079. }
  2080. int sp_mod_mgr_test_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id, int test_type)
  2081. {
  2082. sp_entity_t *ent;
  2083. ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
  2084. if (!ent)
  2085. return Error_NotExist;
  2086. return sp_mod_mgr_test_entity2(mgr, ent, trigger_entity_id, test_type);
  2087. }
  2088. int sp_mod_mgr_lost_entity(sp_mod_mgr_t *mgr, int entity_id, int trigger_entity_id)
  2089. {
  2090. sp_entity_t *ent;
  2091. sp_mod_t *mod;
  2092. ent = sp_mod_mgr_find_entity_by_idx(mgr, entity_id);
  2093. if (!ent)
  2094. return Error_NotExist;
  2095. mod = ent->mod;
  2096. #ifdef _WIN32
  2097. sp_mod_mgr_lockEx(mod->cfg->idx);
  2098. #else
  2099. sp_mod_mgr_lock(mgr);
  2100. #endif //_WIN32
  2101. if (mod->state) {
  2102. int last_state = ent->state;
  2103. sp_dbg_debug("set entity %s lost ok!", ent->cfg->name);
  2104. ent->state = EntityState_Lost;
  2105. mgr_on_entity_state(mgr, ent, ent->cfg->idx, last_state, ent->state);
  2106. }
  2107. #ifdef _WIN32
  2108. sp_mod_mgr_unlockEx(mod->cfg->idx);
  2109. #else
  2110. sp_mod_mgr_unlock(mgr);
  2111. #endif //_WIN32
  2112. return Error_Succeed;
  2113. }
  2114. int sp_mod_mgr_terminate_all_entity(sp_mod_mgr_t* mgr, int trigger_entity_id)
  2115. {
  2116. int i;
  2117. int rc = 0;
  2118. assert(mgr);
  2119. for (i = 1; i < mgr->arr_ent->nelts; ++i) {
  2120. int res;
  2121. sp_entity_t* ent = ARRAY_IDX(mgr->arr_ent, i, sp_entity_t*);
  2122. res = sp_mod_mgr_terminate_entity2(mgr, ent, trigger_entity_id);
  2123. if (res != 0)
  2124. rc = res;
  2125. }
  2126. return rc;
  2127. }
  2128. int sp_mod_mgr_start_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, const char *cmdline, int trigger_entity_id)
  2129. {
  2130. int rc = 0;
  2131. if (!ent)
  2132. return Error_NotExist;
  2133. if (try_lock_doing(mgr, ent->mod)) {
  2134. if (!ent->mod->state) {
  2135. rc = load_module(mgr, ent->mod, trigger_entity_id);
  2136. }
  2137. if (rc == 0) {
  2138. rc = start_entity(mgr, ent, cmdline, trigger_entity_id);
  2139. }
  2140. unlock_doing(mgr, ent->mod);
  2141. } else {
  2142. sp_dbg_warn("mod %s is busy doing now! line: %d", ent->mod->cfg->name, __LINE__);
  2143. rc = Error_Busy;
  2144. }
  2145. return rc;
  2146. }
  2147. /*send {MOD_CMD_STOP} cmd and then {MOD_CMD_TERM} cmd*/
  2148. int sp_mod_mgr_stop_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id, int cause_code)
  2149. {
  2150. int rc;
  2151. if (!ent)
  2152. return Error_NotExist;
  2153. if (try_lock_doing(mgr, ent->mod)) {
  2154. rc = stop_entity(mgr, ent, trigger_entity_id, cause_code);
  2155. if (rc == 0) {
  2156. sp_mod_t *mod = ent->mod;
  2157. sp_entity_t *pos;
  2158. int unload = TRUE;
  2159. list_for_each_entry(pos, &mod->entity_list, sp_entity_t, entry) {
  2160. if ((pos->state != EntityState_Close && pos->state != EntityState_Killed && pos->state != EntityState_NoStart) ){
  2161. unload = FALSE;
  2162. break;
  2163. }
  2164. }
  2165. if (unload) {
  2166. rc = unload_module(mgr, mod, trigger_entity_id);
  2167. }
  2168. }
  2169. unlock_doing(mgr, ent->mod);
  2170. } else {
  2171. sp_dbg_warn("mod %s is busy doing now! line: %d", ent->mod->cfg->name, __LINE__);
  2172. rc = Error_Busy;
  2173. }
  2174. return rc;
  2175. }
  2176. int sp_mod_mgr_terminate_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
  2177. {
  2178. int rc;
  2179. if (!ent)
  2180. return Error_NotExist;
  2181. if (try_lock_doing(mgr, ent->mod)) {
  2182. rc = terminate_module(mgr, ent->mod, trigger_entity_id);
  2183. unlock_doing(mgr, ent->mod);
  2184. } else {
  2185. sp_dbg_warn("mod %s is busy doing now! line: %d", ent->mod->cfg->name, __LINE__);
  2186. rc = Error_Busy;
  2187. }
  2188. return rc;
  2189. }
  2190. int sp_mod_mgr_pause_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
  2191. {
  2192. int rc;
  2193. if (!ent)
  2194. return Error_NotExist;
  2195. if (try_lock_doing(mgr, ent->mod)) {
  2196. rc = pause_entity(mgr, ent, trigger_entity_id);
  2197. unlock_doing(mgr, ent->mod);
  2198. } else {
  2199. sp_dbg_warn("mod %s is busy doing now! line: %d", ent->mod->cfg->name, __LINE__);
  2200. rc = Error_Busy;
  2201. }
  2202. return rc;
  2203. }
  2204. int sp_mod_mgr_continue_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id)
  2205. {
  2206. int rc;
  2207. if (!ent)
  2208. return Error_NotExist;
  2209. if (try_lock_doing(mgr, ent->mod)) {
  2210. rc = continue_entity(mgr, ent, trigger_entity_id);
  2211. unlock_doing(mgr, ent->mod);
  2212. } else {
  2213. sp_dbg_warn("mod %s is busy doing now! line: %d", ent->mod->cfg->name, __LINE__);
  2214. rc = Error_Busy;
  2215. }
  2216. return rc;
  2217. }
  2218. int sp_mod_mgr_test_entity2(sp_mod_mgr_t *mgr, sp_entity_t *ent, int trigger_entity_id, int test_type)
  2219. {
  2220. int rc;
  2221. if (!ent)
  2222. return Error_NotExist;
  2223. if (try_lock_doing(mgr, ent->mod)) {
  2224. rc = test_entity(mgr, ent, test_type, trigger_entity_id);
  2225. unlock_doing(mgr, ent->mod);
  2226. } else {
  2227. sp_dbg_warn("mod %s is busy doing now! line: %d", ent->mod->cfg->name, __LINE__);
  2228. rc = Error_Busy;
  2229. }
  2230. return rc;
  2231. }
  2232. // from shell-> entity
  2233. 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)
  2234. {
  2235. int rc;
  2236. iobuffer_t *pkt = iobuffer_create(-1, -1);
  2237. iobuffer_write(pkt, IOBUF_T_I8, uid, 0);
  2238. iobuffer_write(pkt, IOBUF_T_STR, param, -1);
  2239. 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);
  2240. if (pkt)
  2241. iobuffer_dec_ref(pkt);
  2242. return rc;
  2243. }