sp_svc.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #include "precompile.h"
  2. #include <winpr/synch.h>
  3. #include "sp_svc.h"
  4. #include "sp_dbg_export.h"
  5. #include "sp_def.h"
  6. #include "log_define.h"
  7. #include "array.h"
  8. #include "memutil.h"
  9. #include "list.h"
  10. #include "spinlock.h"
  11. #include "sp_logwithlinkforc.h"
  12. #include "dbgutil.h"
  13. #define DEFAULT_MT_THREAD 1
  14. #define DEFAUTL_MAX_MT_THREAD 32
  15. #define DEFAULT_THREAD_TTL 300000 // 5min
  16. #define MAX_RUNTIMESERIAL_LEVEL 16
  17. typedef struct pkt_handler_t {
  18. struct hlist_node hentry;
  19. int key; //TODO: at 64bit arch [4/2/2020 14:06 Gifur]
  20. sp_svc_on_pkt on_pkt;
  21. void *user_data;
  22. }pkt_handler_t;
  23. typedef struct sys_handler_t {
  24. struct hlist_node hentry;
  25. int key;
  26. sp_svc_on_sys on_sys;
  27. void *user_data;
  28. }sys_handler_t;
  29. struct sp_svc_t
  30. {
  31. sp_iom_t *iom;
  32. int mt;
  33. int id;
  34. threadpool_t *threadpool;
  35. sp_tmr_mgr_t *tmr_mgr;
  36. spinlock_t lock;
  37. struct hlist_head pkt_handler_list[SP_PKT_MAX_NUM];
  38. struct hlist_head sys_handler_list;
  39. int stop;
  40. sp_uid_t last_runserial;
  41. sp_rsn_context_t *rsn_stack[MAX_RUNTIMESERIAL_LEVEL];
  42. int rsn_stack_sp;
  43. };
  44. static __inline void svc_lock(sp_svc_t *svc)
  45. {
  46. spinlock_enter(&svc->lock, -1);
  47. }
  48. static __inline void svc_unlock(sp_svc_t *svc)
  49. {
  50. spinlock_leave(&svc->lock);
  51. }
  52. static pkt_handler_t* find_pkt_handler(sp_svc_t *svc, int key, int pkt_type)
  53. {
  54. pkt_handler_t *tpos;
  55. struct hlist_node *pos;
  56. hlist_for_each_entry(tpos, pos, &svc->pkt_handler_list[pkt_type >> SP_TYPE_SHIFT], pkt_handler_t, hentry) {
  57. if (key == tpos->key)
  58. return tpos;
  59. }
  60. return NULL;
  61. }
  62. static sys_handler_t* find_sys_handler(sp_svc_t *svc, int key)
  63. {
  64. sys_handler_t *tpos;
  65. struct hlist_node *pos;
  66. hlist_for_each_entry(tpos, pos, &svc->sys_handler_list, sys_handler_t, hentry) {
  67. if (tpos->key == key) {
  68. return tpos;
  69. }
  70. }
  71. return NULL;
  72. }
  73. static int on_rx_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)
  74. {
  75. sp_svc_t *svc = (sp_svc_t*)user_data;
  76. pkt_handler_t *pkt_handler;
  77. struct hlist_node *pos;
  78. int pkt_handler_slot = SP_GET_PKT_TYPE(pkt_type) >> SP_TYPE_SHIFT;
  79. if (svc->id != to_svc_id)
  80. return TRUE;
  81. svc_lock(svc);
  82. hlist_for_each_entry(pkt_handler, pos, &svc->pkt_handler_list[pkt_handler_slot], pkt_handler_t, hentry) {
  83. if (pkt_handler->on_pkt) {
  84. int count;
  85. /** 这里没有读取任何数据,哦,可以on_pkt中会读 [Gifur@2022624]*/
  86. int read_state = iobuffer_get_read_state(*p_pkt);
  87. int write_state = iobuffer_get_write_state(*p_pkt);
  88. /*很多地方会注册处理器,见sp_svc_add_pkt_handle*/
  89. count = pkt_handler->on_pkt(svc, epid, svc_id, pkt_type, pkt_id, p_pkt, pkt_handler->user_data);
  90. if (count && p_pkt && *p_pkt) {
  91. iobuffer_restore_read_state(*p_pkt, read_state);
  92. iobuffer_restore_write_state(*p_pkt, write_state);
  93. } else {
  94. break;
  95. }
  96. }
  97. }
  98. svc_unlock(svc);
  99. return FALSE;
  100. }
  101. static void on_rx_sys(sp_iom_t *iom, int epid, int state, void *user_data)
  102. {
  103. sp_svc_t *svc = (sp_svc_t*)user_data;
  104. sys_handler_t *sys_handler;
  105. struct hlist_node *pos;
  106. svc_lock(svc);
  107. hlist_for_each_entry(sys_handler, pos, &svc->sys_handler_list, sys_handler_t, hentry) {
  108. if (sys_handler->on_sys) {
  109. sys_handler->on_sys(svc, epid, state, sys_handler->user_data);
  110. }
  111. }
  112. svc_unlock(svc);
  113. }
  114. int sp_svc_create(sp_iom_t *iom, int multithread, int svc_id, int devel_id, sp_svc_t **p_svc)
  115. {
  116. sp_svc_t *svc;
  117. int rc;
  118. int i;
  119. TOOLKIT_ASSERT(iom);
  120. svc = ZALLOC_T(sp_svc_t);
  121. svc->mt = !!multithread;
  122. svc->iom = iom;
  123. rc = threadpool_create(&svc->threadpool);
  124. if (rc != 0) {
  125. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "create thread pool failed!");
  126. goto on_error;
  127. }
  128. DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM,"create thread poll succ %p", svc->threadpool);
  129. rc = sp_tmr_mgr_create(svc, &svc->tmr_mgr);
  130. if (rc != 0) {
  131. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "create timer mgr failed!");
  132. goto on_error;
  133. }
  134. spinlock_init(&svc->lock);
  135. for (i = 0; i < SP_PKT_MAX_NUM; ++i) {
  136. INIT_HLIST_HEAD(&svc->pkt_handler_list[i]);
  137. }
  138. INIT_HLIST_HEAD(&svc->sys_handler_list);
  139. svc->id = svc_id;
  140. svc->rsn_stack_sp = 0;
  141. svc->last_runserial = sp_uid_make((unsigned short)devel_id);
  142. *p_svc = svc;
  143. return 0;
  144. on_error:
  145. if (svc->iom) {
  146. sp_iom_destroy(svc->iom);
  147. svc->iom = NULL;
  148. }
  149. if (svc->tmr_mgr) {
  150. sp_tmr_mgr_destroy(svc->tmr_mgr);
  151. svc->tmr_mgr = NULL;
  152. }
  153. if (svc->threadpool) {
  154. threadpool_destroy(svc->threadpool);
  155. svc->threadpool = NULL;
  156. }
  157. free(svc);
  158. return Error_Unexpect;
  159. }
  160. void sp_svc_destroy(sp_svc_t *svc)
  161. {
  162. sp_iom_destroy(svc->iom);
  163. sp_tmr_mgr_destroy(svc->tmr_mgr);
  164. threadpool_destroy(svc->threadpool);
  165. free(svc);
  166. }
  167. int sp_svc_add_pkt_handler(sp_svc_t *svc, int key, int pkt_type, sp_svc_on_pkt on_pkt, void *user_data)
  168. {
  169. int rc = 0;
  170. pkt_handler_t *pkt_handler;
  171. svc_lock(svc);
  172. pkt_handler = find_pkt_handler(svc, key, pkt_type);
  173. if (!pkt_handler) {
  174. pkt_handler = MALLOC_T(pkt_handler_t);
  175. pkt_handler->key = key;
  176. pkt_handler->on_pkt = on_pkt;
  177. pkt_handler->user_data = user_data;
  178. hlist_add_head(&pkt_handler->hentry, &svc->pkt_handler_list[pkt_type >> SP_TYPE_SHIFT]);
  179. } else {
  180. rc = Error_Duplication;
  181. }
  182. svc_unlock(svc);
  183. return rc;
  184. }
  185. int sp_svc_remove_pkt_handler(sp_svc_t *svc, int key, int pkt_type)
  186. {
  187. int rc = 0;
  188. pkt_handler_t *pkt_handler;
  189. svc_lock(svc);
  190. pkt_handler = find_pkt_handler(svc, key, pkt_type);
  191. if (pkt_handler) {
  192. hlist_del(&pkt_handler->hentry);
  193. free(pkt_handler);
  194. } else {
  195. rc = Error_NotExist;
  196. }
  197. svc_unlock(svc);
  198. return rc;
  199. }
  200. int sp_svc_add_sys_handler(sp_svc_t *svc, int key, sp_svc_on_sys on_sys, void *user_data)
  201. {
  202. int rc = 0;
  203. sys_handler_t *sys_handler;
  204. svc_lock(svc);
  205. sys_handler = find_sys_handler(svc, key);
  206. if (!sys_handler) {
  207. sys_handler = MALLOC_T(sys_handler_t);
  208. sys_handler->key = key;
  209. sys_handler->on_sys = on_sys;
  210. sys_handler->user_data = user_data;
  211. hlist_add_head(&sys_handler->hentry, &svc->sys_handler_list);
  212. } else {
  213. rc = Error_Duplication;
  214. }
  215. svc_unlock(svc);
  216. return rc;
  217. }
  218. int sp_svc_remove_sys_handler(sp_svc_t *svc, int key)
  219. {
  220. int rc = 0;
  221. sys_handler_t *sys_handler;
  222. svc_lock(svc);
  223. sys_handler = find_sys_handler(svc, key);
  224. if (sys_handler) {
  225. hlist_del(&sys_handler->hentry);
  226. free(sys_handler);
  227. } else {
  228. rc = Error_NotExist;
  229. }
  230. svc_unlock(svc);
  231. return rc;
  232. }
  233. int sp_svc_start(sp_svc_t *svc)
  234. {
  235. int rc;
  236. if (!svc->mt) {
  237. DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM,"single thread mode.");
  238. rc = threadpool_start(svc->threadpool, 1, 0, 0, 0);
  239. } else {
  240. rc = threadpool_start(svc->threadpool, DEFAULT_MT_THREAD, DEFAUTL_MAX_MT_THREAD, DEFAULT_THREAD_TTL, 0);
  241. }
  242. if (rc == 0) {
  243. sp_iom_add_pkt_handler(svc->iom, (int)svc, &on_rx_pkt, svc);
  244. sp_iom_add_sys_handler(svc->iom, (int)svc, &on_rx_sys, svc);
  245. }
  246. return rc;
  247. }
  248. int sp_svc_stop(sp_svc_t *svc)
  249. {
  250. sp_iom_remove_pkt_handler(svc->iom, (int)svc);
  251. sp_iom_remove_sys_handler(svc->iom, (int)svc);
  252. sp_tmr_mgr_cancel_all_tmr(svc->tmr_mgr);
  253. while (sp_tmr_mgr_tmr_cnt(svc->tmr_mgr)) {
  254. Sleep(1);
  255. }
  256. threadpool_stop(svc->threadpool);
  257. return 0;
  258. }
  259. sp_tmr_mgr_t* sp_svc_get_tmr_mgr(sp_svc_t *svc)
  260. {
  261. return svc->tmr_mgr;
  262. }
  263. sp_iom_t *sp_svc_get_iom(sp_svc_t *svc)
  264. {
  265. return svc->iom;
  266. }
  267. threadpool_t *sp_svc_get_threadpool(sp_svc_t *svc)
  268. {
  269. return svc->threadpool;
  270. }
  271. int sp_svc_get_id(sp_svc_t *svc)
  272. {
  273. return svc->id;
  274. }
  275. int sp_svc_send(sp_svc_t *svc, int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt)
  276. {
  277. return sp_iom_send(svc->iom, svc->id, epid, svc_id, pkt_type, pkt_id, p_pkt);
  278. }
  279. int sp_svc_post(sp_svc_t *svc, int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt)
  280. {
  281. return sp_iom_post(svc->iom, svc->id, epid, svc_id, pkt_type, pkt_id, p_pkt);
  282. }
  283. int sp_svc_get_state(sp_svc_t *svc, int epid, int *state)
  284. {
  285. return sp_iom_get_state(svc->iom, epid, state);
  286. }
  287. sp_uid_t sp_svc_new_runserial(sp_svc_t *svc)
  288. {
  289. return svc->last_runserial = sp_uid_update(svc->last_runserial);
  290. }
  291. void sp_svc_push_runserial_context(sp_svc_t *svc, sp_rsn_context_t *rsn)
  292. {
  293. TOOLKIT_ASSERT(svc->rsn_stack_sp < MAX_RUNTIMESERIAL_LEVEL);
  294. svc->rsn_stack[svc->rsn_stack_sp++] = rsn;
  295. }
  296. void sp_svc_pop_runserial_context(sp_svc_t *svc)
  297. {
  298. TOOLKIT_ASSERT(svc->rsn_stack_sp > 0);
  299. svc->rsn_stack[--svc->rsn_stack_sp] = NULL;
  300. }
  301. sp_rsn_context_t *sp_svc_get_runserial_context(sp_svc_t *svc)
  302. {
  303. if (svc->rsn_stack_sp) {
  304. return svc->rsn_stack[svc->rsn_stack_sp-1];
  305. } else {
  306. return NULL;
  307. }
  308. }