sp_mod.c 75 KB

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