sp_svc.c 7.7 KB

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