sp_mod.c 73 KB

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