sp_svc.c 7.7 KB

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