sp_ses.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006
  1. #include "precompile.h"
  2. #include "sp_ses.h"
  3. #include "sp_def.h"
  4. #include "sp_svc.h"
  5. #include "sp_dbg_export.h"
  6. #include "sp_mod.h"
  7. #include "sp_env.h"
  8. #include "SpBase.h"
  9. #include "memutil.h"
  10. #include "refcnt.h"
  11. #include "list.h"
  12. #include "jhash.h"
  13. #include "hashset.h"
  14. #include "spinlock.h"
  15. #include "sp_logwithlinkforc.h"
  16. #include "dbgutil.h"
  17. #define TAG SPBASE_TAG("sp_ses")
  18. #define CONN_BUCKET_SIZE 127
  19. #define TSX_BUCKET_SIZE 511
  20. #define MAX_REDIRECT 10
  21. #define SES_CMD_REQ 0 /* uac -> uas two way call */
  22. #define SES_CMD_TMPANS 1 /* uas -> uac middle response */
  23. #define SES_CMD_ANS 2 /* uas -> uac the end response */
  24. #define SES_CMD_INFO 3 /* uac -> uas one way call */
  25. #define SES_CMD_CONNACK 4 /* uas -> uac */
  26. #define SES_CMD_FINC 5 /* uac -> uas session close */
  27. #define SES_CMD_FINS 6 /* uas -> uac session close */
  28. #define SES_CMD_CONN 7 /* uac -> uas */
  29. #define SES_CMD_ERRC 8 /* uac -> uas, session broken */
  30. #define SES_CMD_ERRS 9 /* uas -> uac, session broken */
  31. #define SES_CMD_REDIRECT 10 /* uas -> uac, session redirect */
  32. struct sp_ses_mgr_t
  33. {
  34. struct hlist_head uac_buckets[CONN_BUCKET_SIZE];
  35. struct hlist_head uas_buckets[CONN_BUCKET_SIZE];
  36. struct hlist_head uac_tsx_buckets[TSX_BUCKET_SIZE];
  37. struct hlist_head uas_tsx_buckets[TSX_BUCKET_SIZE];
  38. sp_ses_mgr_callback_t cb;
  39. sp_svc_t *svc;
  40. int ses_cnt;
  41. CRITICAL_SECTION lock;
  42. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  43. };
  44. DECLARE_REF_COUNT_STATIC(sp_ses_mgr, sp_ses_mgr_t)
  45. struct sp_ses_uac_t
  46. {
  47. struct hlist_node hentry; // element of mgr->uac_buckets
  48. sp_ses_uac_callback cb;
  49. sp_ses_mgr_t *mgr;
  50. int remote_epid;
  51. int remote_svc_id;
  52. unsigned int conn_id;
  53. int state;
  54. int error;
  55. int tsx_cnt;
  56. int redirect_cnt;
  57. y2k_time_t begin_time;
  58. y2k_time_t state_begin_time;
  59. spinlock_t lock;
  60. timer_entry *op_timer;
  61. struct list_head tsx_list; // list of sp_tsx_uac_t->entry
  62. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  63. };
  64. DECLARE_REF_COUNT_STATIC(sp_ses_uac, sp_ses_uac_t)
  65. struct sp_tsx_uac_t
  66. {
  67. struct hlist_node hentry; // element of mgr->uac_tsx_buckets
  68. struct list_head entry; // element of sp_ses_uac_t->tsx_list
  69. int state;
  70. int tsx_id;
  71. int method_id;
  72. int method_sig;
  73. spinlock_t lock;
  74. sp_tsx_uac_callback cb;
  75. sp_ses_uac_t *uac;
  76. timer_entry *op_timer;
  77. strand_t *strand;
  78. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  79. };
  80. DECLARE_REF_COUNT_STATIC(sp_tsx_uac, sp_tsx_uac_t)
  81. typedef struct method_strand_t {
  82. int type;
  83. strand_t *strand;
  84. struct hlist_node node;
  85. }method_strand_t;
  86. struct sp_ses_uas_t
  87. {
  88. struct hlist_node hentry; // element of mgr->uas_buckets
  89. sp_ses_uas_callback cb;
  90. sp_ses_mgr_t *mgr;
  91. int remote_epid;
  92. int remote_svc_id;
  93. int conn_id;
  94. int state;
  95. int error;
  96. int tsx_cnt;
  97. y2k_time_t begin_time;
  98. y2k_time_t state_begin_time;
  99. spinlock_t lock;
  100. strand_t *strand;
  101. hashset_t *method_strand;
  102. struct list_head tsx_list; // list of sp_tsx_uas_t->entry
  103. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  104. };
  105. DECLARE_REF_COUNT_STATIC(sp_ses_uas, sp_ses_uas_t)
  106. struct sp_tsx_uas_t
  107. {
  108. struct hlist_node hentry; // element of mgr->uas_tsx_buckets
  109. struct list_head entry; // element of sp_ses_uas_t->tsx_list
  110. int state;
  111. int tsx_id;
  112. spinlock_t lock;
  113. sp_tsx_uas_callback cb;
  114. sp_ses_uas_t *uas;
  115. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  116. };
  117. DECLARE_REF_COUNT_STATIC(sp_tsx_uas, sp_tsx_uas_t)
  118. static void uac_process_connack(sp_ses_uac_t *uac, int epid, int svc_id, int conn_id);
  119. static void uac_process_redirect(sp_ses_uac_t *uac, int epid, int svc_id, int conn_id, int redirect_ent_id, iobuffer_t **p_pkt);
  120. static void tsx_uac_process_ans(sp_tsx_uac_t *tsx, int end, iobuffer_t **ans_pkt);
  121. static void uac_process_errs(sp_ses_uac_t *uac, int error);
  122. static void uas_process_errc(sp_ses_uas_t *uas, int error);
  123. static void uas_process_info(sp_ses_uas_t *uas, int method_id, int method_sig, iobuffer_t **info_pkt);
  124. static void uas_process_req(sp_ses_uas_t *uas, int tsx_id, int method_id, int method_sig, int timeout, iobuffer_t **req_pkt);
  125. static void uac_trigger(sp_ses_uac_t *uac, int error, int connect);
  126. static void tsx_uac_process_errs(sp_tsx_uac_t *tsx, int error);
  127. static void uas_trigger(sp_ses_uas_t *uas, int error);
  128. static __inline void mgr_lock(sp_ses_mgr_t *mgr)
  129. {
  130. EnterCriticalSection(&mgr->lock);
  131. }
  132. static __inline void mgr_unlock(sp_ses_mgr_t *mgr)
  133. {
  134. LeaveCriticalSection(&mgr->lock);
  135. }
  136. static sp_ses_uac_t *mgr_find_uac(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id)
  137. {
  138. int slot;
  139. sp_ses_uac_t *tpos;
  140. struct hlist_node *pos;
  141. slot = ((unsigned int)conn_id) % CONN_BUCKET_SIZE;
  142. hlist_for_each_entry(tpos, pos, &mgr->uac_buckets[slot], sp_ses_uac_t, hentry) {
  143. if (tpos->conn_id == conn_id)
  144. return tpos;
  145. }
  146. return NULL;
  147. }
  148. static sp_ses_uas_t *mgr_find_uas(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id)
  149. {
  150. int slot;
  151. sp_ses_uas_t *tpos;
  152. struct hlist_node *pos;
  153. slot = ((unsigned int)conn_id) % CONN_BUCKET_SIZE;
  154. hlist_for_each_entry(tpos, pos, &mgr->uas_buckets[slot], sp_ses_uas_t, hentry) {
  155. if (tpos->conn_id == conn_id)
  156. return tpos;
  157. }
  158. return NULL;
  159. }
  160. sp_ses_info_t* sp_ses_mgr_get_ses_info(sp_ses_mgr_t *mgr, int *cnt)
  161. {
  162. sp_ses_info_t* ret = NULL;
  163. int index = 0;
  164. int i = 0;
  165. *cnt = mgr->ses_cnt;
  166. if (*cnt <=0)
  167. return NULL;
  168. ret = (sp_ses_info_t*) malloc(sizeof(sp_ses_info_t)*(*cnt));
  169. for(i=0; i<CONN_BUCKET_SIZE; i++)
  170. {
  171. sp_ses_uac_t *tpos;
  172. struct hlist_node *pos;
  173. hlist_for_each_entry(tpos, pos, &mgr->uac_buckets[i], sp_ses_uac_t, hentry)
  174. {
  175. ret[index].from_svc_id = sp_svc_get_id(mgr->svc);
  176. ret[index].to_svc_id = tpos->remote_svc_id;
  177. ret[index].begin_time = tpos->begin_time;
  178. ret[index].state_begin_time = tpos->state_begin_time;
  179. ret[index].state = tpos->state == SP_SES_STATE_CONNECTED ? 1 : 3;
  180. index++;
  181. }
  182. }
  183. for(i=0; i<CONN_BUCKET_SIZE; i++)
  184. {
  185. sp_ses_uas_t *tpos;
  186. struct hlist_node *pos;
  187. hlist_for_each_entry(tpos, pos, &mgr->uas_buckets[i], sp_ses_uas_t, hentry)
  188. {
  189. ret[index].from_svc_id = tpos->remote_svc_id;
  190. ret[index].to_svc_id = sp_svc_get_id(mgr->svc);
  191. ret[index].begin_time = tpos->begin_time;
  192. ret[index].state_begin_time = tpos->state_begin_time;
  193. ret[index].state = tpos->state == SP_SES_STATE_CONNECTED ? 1 : 3;
  194. index++;
  195. }
  196. }
  197. TOOLKIT_ASSERT(index == *cnt);
  198. return ret;
  199. }
  200. static sp_tsx_uac_t *mgr_find_tsx_uac(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, int tsx_id)
  201. {
  202. int slot;
  203. sp_tsx_uac_t *tpos;
  204. struct hlist_node *pos;
  205. slot = jhash_3words(svc_id, conn_id, tsx_id, 0) % TSX_BUCKET_SIZE;
  206. hlist_for_each_entry(tpos, pos, &mgr->uac_tsx_buckets[slot], sp_tsx_uac_t, hentry) {
  207. if (tpos->uac->remote_svc_id == svc_id && tpos->uac->conn_id == conn_id && tpos->tsx_id == tsx_id)
  208. return tpos;
  209. }
  210. return NULL;
  211. }
  212. static sp_tsx_uas_t *mgr_find_tsx_uas(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, int tsx_id)
  213. {
  214. int slot;
  215. sp_tsx_uas_t *tpos;
  216. struct hlist_node *pos;
  217. slot = jhash_3words(svc_id, conn_id, tsx_id, 0) % TSX_BUCKET_SIZE;
  218. hlist_for_each_entry(tpos, pos, &mgr->uas_tsx_buckets[slot], sp_tsx_uas_t, hentry) {
  219. if (tpos->uas->remote_svc_id == svc_id && tpos->uas->conn_id == conn_id && tpos->tsx_id == tsx_id)
  220. return tpos;
  221. }
  222. return NULL;
  223. }
  224. static void mgr_process_connack(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id)
  225. {
  226. sp_ses_uac_t *uac;
  227. mgr_lock(mgr);
  228. uac = mgr_find_uac(mgr, epid, svc_id, conn_id);
  229. if (uac)
  230. sp_ses_uac_inc_ref(uac); // lock
  231. mgr_unlock(mgr);
  232. if (!uac) {
  233. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "connack find no peer!");
  234. sp_svc_post(mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_ERRC, conn_id, NULL);
  235. return;
  236. }
  237. uac_process_connack(uac, epid, svc_id, conn_id);
  238. sp_ses_uac_dec_ref(uac); // unlock
  239. }
  240. static void mgr_process_redirect(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, int redirect_ent_id, iobuffer_t **p_pkt)
  241. {
  242. sp_ses_uac_t *uac;
  243. mgr_lock(mgr);
  244. uac = mgr_find_uac(mgr, epid, svc_id, conn_id);
  245. if (uac)
  246. sp_ses_uac_inc_ref(uac); // lock
  247. mgr_unlock(mgr);
  248. if (!uac) {
  249. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "redirect cannot find uac!");
  250. return;
  251. }
  252. uac_process_redirect(uac, epid, svc_id, conn_id, redirect_ent_id, p_pkt);
  253. sp_ses_uac_dec_ref(uac); // unlock
  254. }
  255. static void mgr_process_ans(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, int end, int tsx_id, iobuffer_t **ans_pkt)
  256. {
  257. sp_tsx_uac_t *tsx;
  258. mgr_lock(mgr);
  259. tsx = mgr_find_tsx_uac(mgr, epid, svc_id, conn_id, tsx_id);
  260. if (tsx)
  261. sp_tsx_uac_inc_ref(tsx); // lock
  262. mgr_unlock(mgr);
  263. if (!tsx) {
  264. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "ack find no peer!");
  265. return;
  266. }
  267. tsx_uac_process_ans(tsx, end, ans_pkt);
  268. sp_tsx_uac_dec_ref(tsx); // unlock
  269. }
  270. static void mgr_process_errs(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, int error)
  271. {
  272. sp_ses_uac_t *uac;
  273. mgr_lock(mgr);
  274. uac = mgr_find_uac(mgr, epid, svc_id, conn_id);
  275. if (uac)
  276. sp_ses_uac_inc_ref(uac); // @ lock uac no delete
  277. mgr_unlock(mgr);
  278. if (uac) {
  279. uac_process_errs(uac, error);
  280. sp_ses_uac_dec_ref(uac); // @ unlock
  281. }
  282. }
  283. static void mgr_process_errc(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, int error)
  284. {
  285. sp_ses_uas_t *uas;
  286. mgr_lock(mgr);
  287. uas = mgr_find_uas(mgr, epid, svc_id, conn_id);
  288. if (uas)
  289. sp_ses_uas_inc_ref(uas); // @ lock uac no delete
  290. mgr_unlock(mgr);
  291. if (uas) {
  292. uas_process_errc(uas, error);
  293. sp_ses_uas_dec_ref(uas); // @ unlock
  294. }
  295. }
  296. static void mgr_process_fins(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id)
  297. {
  298. mgr_process_errs(mgr, epid, svc_id, conn_id, Error_PeerClose);
  299. }
  300. static void __threadpool_mgr_process_conn(threadpool_t *threadpool, void *arg, param_size_t param1, param_size_t param2)
  301. {
  302. sp_ses_mgr_t *mgr = (sp_ses_mgr_t*)arg;
  303. iobuffer_t *conn_pkt = (iobuffer_t*)param1;
  304. int epid;
  305. int svc_id;
  306. int conn_id;
  307. int redirect_target = 0;
  308. int rc;
  309. int read_state;
  310. sp_rsn_context_t from_rsn;
  311. sp_rsn_context_t rsn;
  312. iobuffer_read(conn_pkt, IOBUF_T_I4, &epid, 0);
  313. iobuffer_read(conn_pkt, IOBUF_T_I4, &svc_id, 0);
  314. iobuffer_read(conn_pkt, IOBUF_T_I4, &conn_id, 0);
  315. read_state = iobuffer_get_read_state(conn_pkt);
  316. WLog_DBG(TAG, "begin on_accept, from epid:%d, svc_id:%d, conn_id:%d", epid, svc_id, conn_id);
  317. iobuffer_read(conn_pkt, IOBUF_T_I4, &from_rsn.depth, 0);
  318. iobuffer_read(conn_pkt, IOBUF_T_I4, &from_rsn.original_type, 0);
  319. iobuffer_read(conn_pkt, IOBUF_T_I8, &from_rsn.current_rsn, 0);
  320. iobuffer_read(conn_pkt, IOBUF_T_I8, &from_rsn.previous_rsn, 0);
  321. sp_rsn_context_init_downstream(sp_svc_new_runserial(mgr->svc), &from_rsn, &rsn);
  322. sp_svc_push_runserial_context(mgr->svc, &rsn);
  323. rc = mgr->cb.on_accept(mgr, epid, svc_id, conn_id, &conn_pkt, &redirect_target, mgr->cb.user_data);
  324. sp_svc_pop_runserial_context(mgr->svc);
  325. if (rc) {
  326. if (redirect_target) {
  327. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "conn from svc_id %d redirect to %d!", svc_id, redirect_target);
  328. iobuffer_restore_read_state(conn_pkt, read_state);
  329. iobuffer_write_head(conn_pkt, IOBUF_T_I4, &redirect_target, 0);
  330. sp_svc_post(mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_REDIRECT, conn_id, &conn_pkt);
  331. } else {
  332. iobuffer_t *pkt = iobuffer_create(-1, -1);
  333. iobuffer_write(pkt, IOBUF_T_I4, &rc, 0);
  334. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "conn from svc_id %d reject! rc: %d", svc_id, rc);
  335. sp_svc_post(mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_ERRS, conn_id, &pkt);
  336. if (pkt)
  337. iobuffer_dec_ref(pkt);
  338. }
  339. } else {
  340. DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "on accept ok!");
  341. }
  342. if (conn_pkt) {
  343. iobuffer_dec_ref(conn_pkt);
  344. }
  345. sp_ses_mgr_dec_ref(mgr); // @
  346. }
  347. static void mgr_process_conn(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, iobuffer_t **conn_pkt)
  348. {
  349. sp_ses_uas_t *uas;
  350. int err;
  351. sp_entity_t *ent;
  352. mgr_lock(mgr);
  353. uas = mgr_find_uas(mgr, epid, svc_id, conn_id);
  354. mgr_unlock(mgr);
  355. ent = sp_mod_mgr_find_entity_by_idx(sp_get_env()->mod_mgr, sp_svc_get_id(mgr->svc));
  356. if (ent) {
  357. if (ent->state == EntityState_Lost) {
  358. iobuffer_t *pkt = iobuffer_create(-1, -1);
  359. int rc = Error_Losted;
  360. iobuffer_write(pkt, IOBUF_T_I4, &rc, 0);
  361. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "reject connection because of lost state!");
  362. sp_svc_post(mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_ERRS, conn_id, &pkt);
  363. if (pkt)
  364. iobuffer_dec_ref(pkt);
  365. return;
  366. }
  367. } else {
  368. TOOLKIT_ASSERT(0);// never go here
  369. }
  370. if (uas) { // already exist, duplicate
  371. iobuffer_t *pkt = iobuffer_create(-1, -1);
  372. int rc = Error_Duplication;
  373. iobuffer_write(pkt, IOBUF_T_I4, &rc, 0);
  374. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "conn duplicate!");
  375. sp_svc_post(mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_ERRS, conn_id, &pkt);
  376. if (pkt)
  377. iobuffer_dec_ref(pkt);
  378. return;
  379. }
  380. iobuffer_write_head(*conn_pkt, IOBUF_T_I4, &conn_id, 0);
  381. iobuffer_write_head(*conn_pkt, IOBUF_T_I4, &svc_id, 0);
  382. iobuffer_write_head(*conn_pkt, IOBUF_T_I4, &epid, 0);
  383. sp_ses_mgr_inc_ref(mgr); // @
  384. err = threadpool_queue_workitem2(sp_svc_get_threadpool(mgr->svc), NULL, &__threadpool_mgr_process_conn, mgr, (param_size_t)*conn_pkt, 0);
  385. if (err)
  386. {
  387. iobuffer_t *pkt = iobuffer_create(-1, -1);
  388. int rc = Error_PeerReject;
  389. iobuffer_write(pkt, IOBUF_T_I4, &rc, 0);
  390. sp_ses_mgr_dec_ref(mgr); // @
  391. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "conn from svc_id %d reject!", svc_id);
  392. sp_svc_post(mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_ERRS, conn_id, &pkt);
  393. if (pkt)
  394. iobuffer_dec_ref(pkt);
  395. return;
  396. } else {
  397. *conn_pkt = NULL;
  398. }
  399. }
  400. static void mgr_process_info(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, int method_id, int method_sig, iobuffer_t **info_pkt)
  401. {
  402. sp_ses_uas_t *uas;
  403. mgr_lock(mgr);
  404. uas = mgr_find_uas(mgr, epid, svc_id, conn_id);
  405. if (uas) {
  406. sp_ses_uas_inc_ref(uas); // @
  407. }
  408. mgr_unlock(mgr);
  409. if (!uas) {
  410. iobuffer_t *pkt = iobuffer_create(-1, -1);
  411. int rc = Error_NotExist;
  412. iobuffer_write(pkt, IOBUF_T_I4, &rc, 0);
  413. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "cannot find uas session!");
  414. sp_svc_post(mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_ERRS, conn_id, &pkt);
  415. if (pkt)
  416. iobuffer_dec_ref(pkt);
  417. return;
  418. }
  419. uas_process_info(uas, method_id, method_sig, info_pkt);
  420. sp_ses_uas_dec_ref(uas); // @
  421. }
  422. static void mgr_process_req(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, int tsx_id, int method_id, int method_sig, int timeout, iobuffer_t **req_pkt)
  423. {
  424. sp_ses_uas_t *uas;
  425. mgr_lock(mgr);
  426. uas = mgr_find_uas(mgr, epid, svc_id, conn_id);
  427. if (uas) {
  428. sp_ses_uas_inc_ref(uas); // @
  429. }
  430. mgr_unlock(mgr);
  431. if (!uas) {
  432. iobuffer_t *pkt = iobuffer_create(-1, -1);
  433. int rc = Error_NotExist;
  434. iobuffer_write(pkt, IOBUF_T_I4, &rc, 0);
  435. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "cannot find uas session!");
  436. sp_svc_post(mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_ERRS, conn_id, &pkt);
  437. if (pkt)
  438. iobuffer_dec_ref(pkt);
  439. return;
  440. }
  441. uas_process_req(uas, tsx_id, method_id, method_sig, timeout, req_pkt);
  442. sp_ses_uas_dec_ref(uas); // @
  443. }
  444. static void mgr_process_finc(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id)
  445. {
  446. mgr_process_errc(mgr, epid, svc_id, conn_id, Error_PeerClose);
  447. }
  448. 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)
  449. {
  450. sp_ses_mgr_t *mgr = (sp_ses_mgr_t*)user_data;
  451. int cmd_type;
  452. int tsx_id;
  453. int method_id;
  454. int method_sig;
  455. int timeout;
  456. int redirect_ent_id;
  457. int rc = 0;
  458. WLog_DBG(TAG, "sp_ses::mgr_on_pkt: epid:%d, svc_id: %d, pkt_type:0x%08X, pkt_id: %d, mgr:%d", epid, svc_id, pkt_type, pkt_id, SP_GET_TYPE(pkt_type));
  459. TOOLKIT_ASSERT(SP_GET_PKT_TYPE(pkt_type) == SP_PKT_SES);
  460. cmd_type = SP_GET_TYPE(pkt_type);
  461. switch (cmd_type) {
  462. case SES_CMD_INFO:
  463. iobuffer_read(*p_pkt, IOBUF_T_I4, &method_id, NULL);
  464. iobuffer_read(*p_pkt, IOBUF_T_I4, &method_sig, NULL);
  465. mgr_process_info(mgr, epid, svc_id, pkt_id, method_id, method_sig, p_pkt);
  466. break;
  467. case SES_CMD_CONN:
  468. mgr_process_conn(mgr, epid, svc_id, pkt_id, p_pkt);
  469. break;
  470. case SES_CMD_CONNACK:
  471. mgr_process_connack(mgr, epid, svc_id, pkt_id);
  472. break;
  473. case SES_CMD_FINC:
  474. mgr_process_finc(mgr, epid, svc_id, pkt_id);
  475. break;
  476. case SES_CMD_FINS:
  477. mgr_process_fins(mgr, epid, svc_id, pkt_id);
  478. break;
  479. case SES_CMD_ERRC:
  480. mgr_process_errc(mgr, epid, svc_id, pkt_id, Error_NetBroken);
  481. break;
  482. case SES_CMD_ERRS:
  483. if (p_pkt != NULL && *p_pkt != NULL)
  484. {
  485. iobuffer_read(*p_pkt, IOBUF_T_I4, &rc, NULL);
  486. iobuffer_dec_ref(*p_pkt);
  487. *p_pkt = NULL;
  488. }
  489. else
  490. rc = Error_NetBroken;
  491. mgr_process_errs(mgr, epid, svc_id, pkt_id, rc);
  492. break;
  493. case SES_CMD_REQ:
  494. iobuffer_read(*p_pkt, IOBUF_T_I4, &tsx_id, NULL);
  495. iobuffer_read(*p_pkt, IOBUF_T_I4, &method_id, NULL);
  496. iobuffer_read(*p_pkt, IOBUF_T_I4, &method_sig, NULL);
  497. iobuffer_read(*p_pkt, IOBUF_T_I4, &timeout, NULL);
  498. mgr_process_req(mgr, epid, svc_id, pkt_id, tsx_id, method_id, method_sig, timeout, p_pkt);
  499. break;
  500. case SES_CMD_TMPANS:
  501. iobuffer_read(*p_pkt, IOBUF_T_I4, &tsx_id, NULL);
  502. mgr_process_ans(mgr, epid, svc_id, pkt_id, 0, tsx_id, p_pkt);
  503. break;
  504. case SES_CMD_ANS:
  505. iobuffer_read(*p_pkt, IOBUF_T_I4, &tsx_id, NULL);
  506. mgr_process_ans(mgr, epid, svc_id, pkt_id, 1, tsx_id, p_pkt);
  507. break;
  508. case SES_CMD_REDIRECT:
  509. iobuffer_read(*p_pkt, IOBUF_T_I4, &redirect_ent_id, NULL);
  510. mgr_process_redirect(mgr, epid, svc_id, pkt_id, redirect_ent_id, p_pkt);
  511. break;
  512. default:
  513. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "recv unknown ses pkt!");
  514. TOOLKIT_ASSERT(0);
  515. break;
  516. }
  517. return FALSE;
  518. }
  519. static void mgr_on_sys(sp_svc_t *svc,int epid, int state, void *user_data)
  520. {
  521. sp_ses_mgr_t *mgr = (sp_ses_mgr_t*)user_data;
  522. if (state == BUS_STATE_OFF) {
  523. int i;
  524. mgr_lock(mgr);
  525. for (i = 0; i < CONN_BUCKET_SIZE; ++i) {
  526. sp_ses_uas_t *tpos;
  527. struct hlist_node *pos, *n;
  528. hlist_for_each_entry_safe(tpos, pos, n, &mgr->uas_buckets[i], sp_ses_uas_t, hentry) {
  529. if (epid == tpos->remote_epid) {
  530. uas_process_errc(tpos, Error_NetBroken);
  531. }
  532. }
  533. }
  534. for (i = 0; i < CONN_BUCKET_SIZE; ++i) {
  535. sp_ses_uac_t *tpos;
  536. struct hlist_node *pos, *n;
  537. hlist_for_each_entry_safe(tpos, pos, n, &mgr->uac_buckets[i], sp_ses_uac_t, hentry) {
  538. if (epid == tpos->remote_epid) {
  539. uac_process_errs(tpos, Error_NetBroken);
  540. }
  541. }
  542. }
  543. mgr_unlock(mgr);
  544. }
  545. }
  546. int sp_ses_mgr_create(sp_svc_t *svc, sp_ses_mgr_callback_t *cb, sp_ses_mgr_t **p_mgr)
  547. {
  548. sp_ses_mgr_t *mgr = MALLOC_T(sp_ses_mgr_t);
  549. int i;
  550. mgr->ses_cnt = 0;
  551. mgr->svc = svc;
  552. memcpy(&mgr->cb, cb, sizeof(sp_ses_mgr_callback_t));
  553. REF_COUNT_INIT(&mgr->ref_cnt);
  554. for (i = 0;i < CONN_BUCKET_SIZE; ++i) {
  555. INIT_HLIST_HEAD(&mgr->uac_buckets[i]);
  556. INIT_HLIST_HEAD(&mgr->uas_buckets[i]);
  557. }
  558. for (i = 0; i < TSX_BUCKET_SIZE; ++i) {
  559. INIT_HLIST_HEAD(&mgr->uac_tsx_buckets[i]);
  560. INIT_HLIST_HEAD(&mgr->uas_tsx_buckets[i]);
  561. }
  562. InitializeCriticalSection(&mgr->lock);
  563. *p_mgr = mgr;
  564. return 0;
  565. }
  566. void sp_ses_mgr_destroy(sp_ses_mgr_t *mgr)
  567. {
  568. sp_ses_mgr_dec_ref(mgr);
  569. }
  570. int sp_ses_mgr_cancel_all(sp_ses_mgr_t *mgr)
  571. {
  572. int i;
  573. mgr_lock(mgr);
  574. for (i = 0; i < CONN_BUCKET_SIZE; ++i) {
  575. sp_ses_uas_t *tpos;
  576. struct hlist_node *pos;
  577. hlist_for_each_entry(tpos, pos, &mgr->uas_buckets[i], sp_ses_uas_t, hentry) {
  578. sp_ses_uas_close(tpos);
  579. }
  580. }
  581. for (i = 0; i < CONN_BUCKET_SIZE; ++i) {
  582. sp_ses_uac_t *tpos;
  583. struct hlist_node *pos;
  584. hlist_for_each_entry(tpos, pos, &mgr->uac_buckets[i], sp_ses_uac_t, hentry) {
  585. sp_ses_uac_close(tpos);
  586. }
  587. }
  588. mgr_unlock(mgr);
  589. return 0;
  590. }
  591. int sp_ses_mgr_get_conn_cnt(sp_ses_mgr_t *mgr)
  592. {
  593. return mgr->ses_cnt;
  594. }
  595. int sp_ses_mgr_start(sp_ses_mgr_t *mgr)
  596. {
  597. int rc;
  598. rc = sp_svc_add_pkt_handler(mgr->svc, (int)mgr, SP_PKT_SES, &mgr_on_pkt, mgr);
  599. if (rc == 0)
  600. rc = sp_svc_add_sys_handler(mgr->svc, (int)mgr, &mgr_on_sys, mgr);
  601. return rc;
  602. }
  603. int sp_ses_mgr_stop(sp_ses_mgr_t *mgr)
  604. {
  605. int rc;
  606. rc = sp_svc_remove_pkt_handler(mgr->svc, (int)mgr, SP_PKT_SES);
  607. if (rc == 0)
  608. rc = sp_svc_remove_sys_handler(mgr->svc, (int)mgr);
  609. return rc;
  610. }
  611. sp_svc_t *sp_ses_mgr_get_svc(sp_ses_mgr_t *mgr)
  612. {
  613. return mgr->svc;
  614. }
  615. static void __sp_ses_mgr_destroy(sp_ses_mgr_t *mgr)
  616. {
  617. if (mgr->cb.on_destroy)
  618. mgr->cb.on_destroy(mgr, mgr->cb.user_data);
  619. TOOLKIT_ASSERT(mgr->ses_cnt == 0);
  620. DeleteCriticalSection(&mgr->lock);
  621. free(mgr);
  622. }
  623. IMPLEMENT_REF_COUNT_MT_STATIC(sp_ses_mgr, sp_ses_mgr_t, ref_cnt, __sp_ses_mgr_destroy)
  624. static __inline void uac_lock(sp_ses_uac_t *ses)
  625. {
  626. spinlock_enter(&ses->lock, -1);
  627. }
  628. static __inline void uac_unlock(sp_ses_uac_t *ses)
  629. {
  630. spinlock_leave(&ses->lock);
  631. }
  632. static void uac_process_connack(sp_ses_uac_t *uac, int epid, int svc_id, int conn_id)
  633. {
  634. int trigger = 0;
  635. uac_lock(uac);
  636. if (uac->state == SP_SES_STATE_CONNECTING) {
  637. uac->state = SP_SES_STATE_CONNECTED;
  638. uac->state_begin_time = y2k_time_now();
  639. if (uac->op_timer) {
  640. sp_iom_cancel_timer(sp_svc_get_iom(uac->mgr->svc), uac->op_timer, 1);
  641. uac->op_timer = NULL;
  642. }
  643. trigger++;
  644. } else {
  645. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "current state is not connecting!");
  646. sp_svc_post(uac->mgr->svc, epid, svc_id, SP_PKT_SES|SES_CMD_ERRC, conn_id, NULL);
  647. }
  648. if (trigger)
  649. uac_trigger(uac, 0, 1);
  650. uac_unlock(uac);
  651. }
  652. static void uac_process_redirect(sp_ses_uac_t *uac, int epid, int svc_id, int conn_id, int redirect_ent_id, iobuffer_t **p_pkt)
  653. {
  654. uac_lock(uac);
  655. if (uac->state == SP_SES_STATE_CONNECTING) {
  656. ++uac->redirect_cnt;
  657. if (uac->redirect_cnt >= MAX_REDIRECT) {
  658. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "uac has exceed max_direct value, maybe redirection enter end loop!");
  659. if (uac->op_timer) {
  660. sp_iom_cancel_timer(sp_svc_get_iom(uac->mgr->svc), uac->op_timer, 1);
  661. uac->op_timer = NULL;
  662. }
  663. uac->state = SP_SES_STATE_ERROR;
  664. uac->state_begin_time = y2k_time_now();
  665. uac_trigger(uac, Error_NetBroken, 1);
  666. } else {
  667. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(sp_get_env()->mod_mgr, redirect_ent_id);
  668. if (ent->state == EntityState_Killed || ent->state == EntityState_Lost || ent->state == EntityState_NoStart) {
  669. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "redirected failed! redirect ent state invalid! redirect id:%d", redirect_ent_id);
  670. if (uac->op_timer) {
  671. sp_iom_cancel_timer(sp_svc_get_iom(uac->mgr->svc), uac->op_timer, 1);
  672. uac->op_timer = NULL;
  673. }
  674. uac->state = SP_SES_STATE_ERROR;
  675. uac->state_begin_time = y2k_time_now();
  676. uac_trigger(uac, Error_InvalidState, 1);
  677. } else {
  678. uac->remote_epid = ent->mod->cfg->idx;
  679. uac->remote_svc_id = ent->cfg->idx;
  680. sp_svc_post(uac->mgr->svc, uac->remote_epid, uac->remote_svc_id, SP_PKT_SES|SES_CMD_CONN, conn_id, p_pkt);
  681. //DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "svc_post, epid:%d, svc_id:%d", uac->remote_epid, uac->remote_svc_id);
  682. }
  683. }
  684. }
  685. uac_unlock(uac);
  686. }
  687. static void uac_process_errs(sp_ses_uac_t *uac, int error)
  688. {
  689. int trigger = 0;
  690. int connect = 0;
  691. uac_lock(uac);
  692. if (uac->state == SP_SES_STATE_INIT) {
  693. uac->state = SP_SES_STATE_ERROR;
  694. uac->state_begin_time = y2k_time_now();
  695. uac->error = error;
  696. } else if (uac->state == SP_SES_STATE_CONNECTING) {
  697. trigger++;
  698. uac->state = SP_SES_STATE_ERROR;
  699. uac->state_begin_time = y2k_time_now();
  700. uac->error = error;
  701. connect ++;
  702. if (uac->op_timer) {
  703. sp_iom_cancel_timer(sp_svc_get_iom(uac->mgr->svc), uac->op_timer, 1);
  704. uac->op_timer = NULL;
  705. }
  706. } else if (uac->state == SP_SES_STATE_CONNECTED) {
  707. sp_tsx_uac_t *pos, *n;
  708. uac->state = SP_SES_STATE_ERROR;
  709. uac->state_begin_time = y2k_time_now();
  710. uac->error = error;
  711. list_for_each_entry_safe(pos, n, &uac->tsx_list, sp_tsx_uac_t, entry) {
  712. tsx_uac_process_errs(pos, error);
  713. }
  714. trigger++;
  715. }
  716. if (trigger)
  717. uac_trigger(uac, error, connect);
  718. uac_unlock(uac);
  719. }
  720. static void __threadpool_uac_trigger_close(threadpool_t *threadpool, void *arg, param_size_t param1, param_size_t param2)
  721. {
  722. sp_ses_uac_t *uac = (sp_ses_uac_t*)arg;
  723. sp_ses_mgr_t *mgr = uac->mgr;
  724. int error = (int)param1;
  725. sp_uid_t rsn = sp_svc_new_runserial(mgr->svc);
  726. sp_rsn_context_t rsn_ctx;
  727. sp_rsn_context_init_original(rsn, SP_ORIGINAL_T_FRAMEWORK, &rsn_ctx);
  728. sp_svc_push_runserial_context(mgr->svc, &rsn_ctx);
  729. uac->cb.on_close(uac, error, uac->cb.user_data);
  730. sp_ses_uac_dec_ref(uac); // @
  731. sp_svc_pop_runserial_context(mgr->svc);
  732. }
  733. static void uac_trigger(sp_ses_uac_t *uac, int error, int connect)
  734. {
  735. if (connect) {
  736. uac->cb.on_connect(uac, error, uac->cb.user_data);
  737. sp_ses_uac_dec_ref(uac); // @
  738. } else {
  739. if (sp_iom_get_poll_thread_id(sp_svc_get_iom(uac->mgr->svc)) == GetCurrentThreadId()) { //
  740. int rc;
  741. sp_ses_uac_inc_ref(uac); // @
  742. rc = threadpool_queue_workitem2(sp_svc_get_threadpool(uac->mgr->svc), NULL, &__threadpool_uac_trigger_close, uac, error, 0);
  743. if (rc != 0) {
  744. sp_ses_uac_dec_ref(uac); // @
  745. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "thread pool queue uac_trirget_close event failed!");
  746. }
  747. } else {
  748. uac->cb.on_close(uac, error, uac->cb.user_data);
  749. }
  750. }
  751. }
  752. static void uac_on_timer(timer_queue_t *q, timer_entry *timer, int err)
  753. {
  754. sp_ses_uac_t *uac = (sp_ses_uac_t*)timer->user_data;
  755. if (!err && uac->op_timer == timer && uac->state == SP_SES_STATE_CONNECTING) {
  756. int trigger = 0;
  757. uac_lock(uac);
  758. if (uac->op_timer == timer) {
  759. if (uac->state == SP_SES_STATE_CONNECTING) {
  760. uac->state = SP_SES_STATE_ERROR; // time out
  761. uac->state_begin_time = y2k_time_now();
  762. trigger ++;
  763. }
  764. uac->op_timer = NULL;
  765. }
  766. if (trigger)
  767. uac_trigger(uac, Error_TimeOut, 1);
  768. uac_unlock(uac);
  769. }
  770. sp_ses_uac_dec_ref(uac); // @2
  771. free(timer);
  772. }
  773. int sp_ses_uac_create(sp_ses_mgr_t *mgr, int remote_epid, int remote_svc_id, sp_ses_uac_callback *cb, sp_ses_uac_t **p_ses)
  774. {
  775. sp_ses_uac_t *ses;
  776. int slot;
  777. if (!cb || !cb->on_connect)
  778. return Error_Param;
  779. ses = MALLOC_T(sp_ses_uac_t);
  780. ses->mgr = mgr;
  781. ses->conn_id = sp_env_new_id(sp_get_env());
  782. ses->remote_svc_id = remote_svc_id;
  783. ses->remote_epid = remote_epid;
  784. ses->state = SP_SES_STATE_INIT;
  785. ses->state_begin_time = y2k_time_now();
  786. ses->error = 0;
  787. ses->op_timer = NULL;
  788. ses->tsx_cnt = 0;
  789. ses->begin_time = y2k_time_now();
  790. ses->redirect_cnt = 0;
  791. memcpy(&ses->cb, cb, sizeof(sp_ses_uac_callback));
  792. INIT_HLIST_NODE(&ses->hentry);
  793. REF_COUNT_INIT(&ses->ref_cnt);
  794. spinlock_init(&ses->lock);
  795. INIT_LIST_HEAD(&ses->tsx_list);
  796. sp_ses_mgr_inc_ref(mgr);
  797. slot = ses->conn_id % CONN_BUCKET_SIZE;
  798. sp_ses_uac_inc_ref(ses);
  799. mgr_lock(mgr);
  800. hlist_add_head(&ses->hentry, &mgr->uac_buckets[slot]);
  801. mgr->ses_cnt++;
  802. mgr_unlock(mgr);
  803. *p_ses = ses;
  804. //DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "ses uac created!");
  805. return 0;
  806. }
  807. void sp_ses_uac_destroy(sp_ses_uac_t *uac)
  808. {
  809. TOOLKIT_ASSERT(uac->state == SP_SES_STATE_TERM);
  810. mgr_lock(uac->mgr);
  811. uac->mgr->ses_cnt--;
  812. hlist_del_init(&uac->hentry);
  813. mgr_unlock(uac->mgr);
  814. sp_ses_uac_dec_ref(uac);
  815. sp_ses_uac_dec_ref(uac);
  816. }
  817. int sp_ses_uac_async_connect(sp_ses_uac_t *uac, int timeout, iobuffer_t **conn_pkt)
  818. {
  819. int rc;
  820. if (uac->state != SP_SES_STATE_INIT)
  821. return Error_Unexpect;
  822. sp_ses_uac_inc_ref(uac);
  823. uac_lock(uac);
  824. if (uac->state == SP_SES_STATE_INIT) {
  825. sp_rsn_context_t *rsn_ctx = sp_svc_get_runserial_context(uac->mgr->svc);
  826. sp_ses_uac_inc_ref(uac); // @1
  827. if (rsn_ctx) {
  828. iobuffer_write_head(*conn_pkt, IOBUF_T_I8, &rsn_ctx->previous_rsn, 0);
  829. iobuffer_write_head(*conn_pkt, IOBUF_T_I8, &rsn_ctx->current_rsn, 0);
  830. iobuffer_write_head(*conn_pkt, IOBUF_T_I4, &rsn_ctx->original_type, 0);
  831. iobuffer_write_head(*conn_pkt, IOBUF_T_I4, &rsn_ctx->depth, 0);
  832. } else {
  833. u__int64_t rsn = 0;
  834. int t = 0;
  835. iobuffer_write_head(*conn_pkt, IOBUF_T_I8, &rsn, 0);
  836. iobuffer_write_head(*conn_pkt, IOBUF_T_I8, &rsn, 0);
  837. iobuffer_write_head(*conn_pkt, IOBUF_T_I4, &t, 0);
  838. iobuffer_write_head(*conn_pkt, IOBUF_T_I4, &t, 0);
  839. }
  840. rc = sp_svc_send(uac->mgr->svc, uac->remote_epid, uac->remote_svc_id, SP_PKT_SES|SES_CMD_CONN, uac->conn_id, conn_pkt);
  841. WLog_DBG(TAG, "svc_send, epid:%d, svc_id:%d, rc: %d", uac->remote_epid, uac->remote_svc_id, rc);
  842. if (rc == 0) {
  843. if (timeout >= 0) {
  844. uac->op_timer = MALLOC_T(timer_entry);
  845. uac->op_timer->cb = &uac_on_timer;
  846. uac->op_timer->user_data = uac;
  847. sp_ses_uac_inc_ref(uac); // @2
  848. rc = sp_iom_schedule_timer(sp_svc_get_iom(uac->mgr->svc), uac->op_timer, (unsigned int)timeout);
  849. if (rc != 0) {
  850. iobuffer_pop_count(*conn_pkt, 24);
  851. sp_ses_uac_dec_ref(uac); // @2
  852. sp_ses_uac_dec_ref(uac); // @1
  853. free(uac->op_timer);
  854. uac->op_timer = NULL;
  855. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "post conn, create timer failed!");
  856. }
  857. }
  858. } else {
  859. iobuffer_pop_count(*conn_pkt, 24);
  860. sp_ses_uac_dec_ref(uac); // @1
  861. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "uac issue async connect failed, post msg failed, may be remote party offline!");
  862. rc = Error_IO;
  863. }
  864. } else {
  865. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "uac state is not INIT !");
  866. rc = Error_Unexpect;
  867. }
  868. uac->state = rc ? SP_SES_STATE_ERROR : SP_SES_STATE_CONNECTING;
  869. uac->state_begin_time = y2k_time_now();
  870. uac_unlock(uac);
  871. sp_ses_uac_dec_ref(uac);
  872. return rc;
  873. }
  874. int sp_ses_uac_close(sp_ses_uac_t *uac)
  875. {
  876. int rc = 0;
  877. int trigger = 0;
  878. int connected = 0;
  879. DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "sp_ses_uac_close invoked!");
  880. sp_ses_uac_inc_ref(uac);
  881. uac_lock(uac);
  882. if (uac->state == SP_SES_STATE_INIT) {
  883. uac->state = SP_SES_STATE_TERM;
  884. uac->state_begin_time = y2k_time_now();
  885. } else if (uac->state == SP_SES_STATE_CONNECTING) {
  886. trigger++;
  887. uac->state = SP_SES_STATE_TERM;
  888. uac->state_begin_time = y2k_time_now();
  889. if (uac->op_timer) {
  890. sp_iom_cancel_timer(sp_svc_get_iom(uac->mgr->svc), uac->op_timer, 1);
  891. uac->op_timer = NULL;
  892. }
  893. connected++;
  894. } else if (uac->state == SP_SES_STATE_CONNECTED) {
  895. sp_tsx_uac_t *pos, *n;
  896. uac->state = SP_SES_STATE_TERM;
  897. uac->state_begin_time = y2k_time_now();
  898. list_for_each_entry_safe(pos, n, &uac->tsx_list, sp_tsx_uac_t, entry) {
  899. sp_tsx_uac_close(pos);
  900. }
  901. trigger++;
  902. } else if (uac->state == SP_SES_STATE_ERROR) {
  903. uac->state = SP_SES_STATE_TERM;
  904. uac->state_begin_time = y2k_time_now();
  905. } else {
  906. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "uac->state = %d", uac->state);
  907. rc = Error_Duplication;
  908. }
  909. if (trigger)
  910. uac_trigger(uac, Error_Closed, connected);
  911. uac_unlock(uac);
  912. if (rc == 0) {
  913. sp_svc_post(uac->mgr->svc, uac->remote_epid, uac->remote_svc_id, SP_PKT_SES|SES_CMD_FINC, uac->conn_id, NULL);
  914. }
  915. sp_ses_uac_dec_ref(uac);
  916. return rc;
  917. }
  918. int sp_ses_uac_get_state(sp_ses_uac_t *uac)
  919. {
  920. return uac->state;
  921. }
  922. int sp_ses_uac_send_info(sp_ses_uac_t *uac, int method_id, int method_sig, iobuffer_t **info_pkt)
  923. {
  924. int rc;
  925. if (uac->state == SP_SES_STATE_CONNECTED) {
  926. sp_rsn_context_t *rsn_ctx = sp_svc_get_runserial_context(uac->mgr->svc);
  927. if (rsn_ctx) {
  928. iobuffer_write_head(*info_pkt, IOBUF_T_I8, &rsn_ctx->previous_rsn, 0);
  929. iobuffer_write_head(*info_pkt, IOBUF_T_I8, &rsn_ctx->current_rsn, 0);
  930. iobuffer_write_head(*info_pkt, IOBUF_T_I4, &rsn_ctx->original_type, 0);
  931. iobuffer_write_head(*info_pkt, IOBUF_T_I4, &rsn_ctx->depth, 0);
  932. } else {
  933. u__int64_t rsn = 0;
  934. int t = 0;
  935. iobuffer_write_head(*info_pkt, IOBUF_T_I8, &rsn, 0);
  936. iobuffer_write_head(*info_pkt, IOBUF_T_I8, &rsn, 0);
  937. iobuffer_write_head(*info_pkt, IOBUF_T_I4, &t, 0);
  938. iobuffer_write_head(*info_pkt, IOBUF_T_I4, &t, 0);
  939. }
  940. iobuffer_write_head(*info_pkt, IOBUF_T_I4, &method_sig, 0);
  941. iobuffer_write_head(*info_pkt, IOBUF_T_I4, &method_id, 0);
  942. rc = sp_svc_post(uac->mgr->svc, uac->remote_epid, uac->remote_svc_id, SP_PKT_SES|SES_CMD_INFO, uac->conn_id, info_pkt);
  943. WLog_INFO(TAG, "sp_ses_uac_send_info from %d", uac->remote_epid);
  944. } else {
  945. DbgWithLinkForC(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM, "send info failed, uac is not in connected state!");
  946. rc = Error_IO;
  947. }
  948. return rc;
  949. }
  950. int sp_ses_uac_get_remote_epid(sp_ses_uac_t *uac)
  951. {
  952. return uac->remote_epid;
  953. }
  954. int sp_ses_uac_get_remote_svc_id(sp_ses_uac_t *uac)
  955. {
  956. return uac->remote_svc_id;
  957. }
  958. int sp_ses_uac_get_conn_id(sp_ses_uac_t *uac)
  959. {
  960. return uac->conn_id;
  961. }
  962. sp_ses_mgr_t *sp_ses_uac_get_mgr(sp_ses_uac_t *uac)
  963. {
  964. return uac->mgr;
  965. }
  966. int sp_ses_uac_get_tsx_cnt(sp_ses_uac_t *uac)
  967. {
  968. return uac->tsx_cnt;
  969. }
  970. static void __sp_ses_uac_destroy(sp_ses_uac_t *uac)
  971. {
  972. if (uac->cb.on_destroy)
  973. uac->cb.on_destroy(uac, uac->cb.user_data);
  974. sp_ses_mgr_dec_ref(uac->mgr);
  975. free(uac);
  976. DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "ses uac destroyed!");
  977. }
  978. IMPLEMENT_REF_COUNT_MT_STATIC(sp_ses_uac, sp_ses_uac_t, ref_cnt, __sp_ses_uac_destroy)
  979. static __inline void tsx_uac_lock(sp_tsx_uac_t *tsx)
  980. {
  981. spinlock_enter(&tsx->lock, -1);
  982. }
  983. static __inline void tsx_uac_unlock(sp_tsx_uac_t *tsx)
  984. {
  985. spinlock_leave(&tsx->lock);
  986. }
  987. static void tsx_uac_trigger(sp_tsx_uac_t *tsx, int error, int end, iobuffer_t **ans_pkt)
  988. {
  989. iobuffer_t *pkt = ans_pkt ? *ans_pkt : NULL;
  990. tsx->cb.on_ans(tsx, error, end, ans_pkt, tsx->cb.user_data);
  991. if (error || end)
  992. sp_tsx_uac_dec_ref(tsx); // @
  993. }
  994. static void tsx_uac_on_timer(timer_queue_t *q, timer_entry *timer, int err)
  995. {
  996. sp_tsx_uac_t *tsx = (sp_tsx_uac_t*)timer->user_data;
  997. if (!err && tsx->op_timer == timer && tsx->state == SP_TSX_UAC_STATE_REQ) {
  998. int trigger = 0;
  999. tsx_uac_lock(tsx);
  1000. if (tsx->op_timer == timer) {
  1001. if (tsx->state == SP_TSX_UAC_STATE_REQ) {
  1002. tsx->state = SP_TSX_UAC_STATE_ERROR; // time out
  1003. trigger ++;
  1004. }
  1005. tsx->op_timer = NULL;
  1006. }
  1007. if (trigger)
  1008. tsx_uac_trigger(tsx, Error_TimeOut, 1, NULL);
  1009. tsx_uac_unlock(tsx);
  1010. }
  1011. sp_tsx_uac_dec_ref(tsx); // @2
  1012. free(timer);
  1013. }
  1014. static void tsx_uac_process_ans(sp_tsx_uac_t *tsx, int end, iobuffer_t **ans_pkt)
  1015. {
  1016. int trigger = 0;
  1017. tsx_uac_lock(tsx);
  1018. if (tsx->state == SP_TSX_UAC_STATE_REQ || tsx->state == SP_TSX_UAC_STATE_TMPANS) {
  1019. if (tsx->op_timer) {
  1020. sp_iom_cancel_timer(sp_svc_get_iom(tsx->uac->mgr->svc), tsx->op_timer, 1);
  1021. tsx->op_timer = NULL;
  1022. }
  1023. if (end) {
  1024. tsx->state = SP_TSX_UAC_STATE_ANS;
  1025. } else if (tsx->state == SP_TSX_UAC_STATE_INIT) {
  1026. tsx->state = SP_TSX_UAC_STATE_TMPANS;
  1027. }
  1028. trigger++;
  1029. } else {
  1030. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "tsx uac current state cannot recv ack!");
  1031. sp_svc_post(tsx->uac->mgr->svc, tsx->uac->remote_epid, tsx->uac->remote_svc_id, SP_PKT_SES|SES_CMD_ERRC, tsx->uac->conn_id, NULL);
  1032. WLog_INFO(TAG, "tsx_uac_process_ans remote_epid:%d, remote_svc_id:%d", tsx->uac->remote_epid, tsx->uac->remote_svc_id);
  1033. }
  1034. if (trigger)
  1035. tsx_uac_trigger(tsx, 0, end, ans_pkt);
  1036. tsx_uac_unlock(tsx);
  1037. }
  1038. static void tsx_uac_process_errs(sp_tsx_uac_t *tsx, int error)
  1039. {
  1040. int trigger = 0;
  1041. sp_tsx_uac_inc_ref(tsx);
  1042. tsx_uac_lock(tsx);
  1043. if (tsx->state == SP_TSX_UAC_STATE_REQ || tsx->state == SP_TSX_UAC_STATE_TMPANS) {
  1044. trigger++;
  1045. if (tsx->op_timer) {
  1046. sp_iom_cancel_timer(sp_svc_get_iom(tsx->uac->mgr->svc), tsx->op_timer, 1);
  1047. tsx->op_timer = NULL;
  1048. }
  1049. }
  1050. if (tsx->state != SP_TSX_UAC_STATE_TERM)
  1051. tsx->state = SP_TSX_UAC_STATE_ERROR;
  1052. if (trigger)
  1053. tsx_uac_trigger(tsx, error, 1, NULL);
  1054. tsx_uac_unlock(tsx);
  1055. sp_tsx_uac_dec_ref(tsx);
  1056. }
  1057. int sp_tsx_uac_create(sp_ses_uac_t *uac, int tsx_id, int method_id, int method_sig, sp_tsx_uac_callback *cb, sp_tsx_uac_t **p_tsx)
  1058. {
  1059. sp_tsx_uac_t *tsx;
  1060. unsigned int slot;
  1061. if (!cb || !cb->on_ans)
  1062. return Error_Param;
  1063. switch ( uac->state ) {
  1064. case SP_SES_STATE_INIT:
  1065. case SP_SES_STATE_CONNECTING:
  1066. return Error_NotInit;
  1067. case SP_SES_STATE_TERM:
  1068. case SP_SES_STATE_ERROR:
  1069. return Error_NetBroken;
  1070. }
  1071. tsx = MALLOC_T(sp_tsx_uac_t);
  1072. tsx->state = SP_TSX_UAC_STATE_INIT;
  1073. tsx->tsx_id = tsx_id;
  1074. tsx->method_id = method_id;
  1075. tsx->method_sig = method_sig;
  1076. tsx->uac = uac;
  1077. tsx->op_timer = NULL;
  1078. memcpy(&tsx->cb, cb, sizeof(sp_tsx_uac_callback));
  1079. spinlock_init(&tsx->lock);
  1080. INIT_HLIST_NODE(&tsx->hentry);
  1081. REF_COUNT_INIT(&tsx->ref_cnt);
  1082. tsx->strand = strand_create();
  1083. sp_ses_uac_inc_ref(uac);
  1084. sp_tsx_uac_inc_ref(tsx);
  1085. uac_lock(uac);
  1086. list_add_tail(&tsx->entry, &uac->tsx_list);
  1087. uac->tsx_cnt++;
  1088. uac_unlock(uac);
  1089. slot = jhash_3words(uac->remote_svc_id, uac->conn_id, tsx_id, 0) % TSX_BUCKET_SIZE;
  1090. sp_tsx_uac_inc_ref(tsx);
  1091. mgr_lock(uac->mgr);
  1092. hlist_add_head(&tsx->hentry, &uac->mgr->uac_tsx_buckets[slot]);
  1093. mgr_unlock(uac->mgr);
  1094. *p_tsx = tsx;
  1095. //DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "tsx uac created!");
  1096. return 0;
  1097. }
  1098. void sp_tsx_uac_destroy(sp_tsx_uac_t *tsx)
  1099. {
  1100. sp_ses_uac_t *uac = tsx->uac;
  1101. TOOLKIT_ASSERT(tsx->state == SP_TSX_UAC_STATE_TERM);
  1102. uac_lock(uac);
  1103. uac->tsx_cnt--;
  1104. list_del_init(&tsx->entry);
  1105. uac_unlock(uac);
  1106. sp_tsx_uac_dec_ref(tsx);
  1107. mgr_lock(uac->mgr);
  1108. hlist_del_init(&tsx->hentry);
  1109. mgr_unlock(uac->mgr);
  1110. sp_tsx_uac_dec_ref(tsx);
  1111. sp_tsx_uac_dec_ref(tsx);
  1112. }
  1113. int sp_tsx_uac_async_req(sp_tsx_uac_t *tsx, int timeout, iobuffer_t **req_pkt)
  1114. {
  1115. int rc;
  1116. sp_ses_uac_t *uac;
  1117. if (tsx->state != SP_TSX_UAC_STATE_INIT)
  1118. return Error_Unexpect;
  1119. uac = tsx->uac;
  1120. if (uac->state != SP_SES_STATE_CONNECTED)
  1121. return Error_NetBroken;
  1122. tsx_uac_lock(tsx);
  1123. if (tsx->state == SP_TSX_UAC_STATE_INIT) {
  1124. sp_rsn_context_t *rsn_ctx = sp_svc_get_runserial_context(uac->mgr->svc);
  1125. if (rsn_ctx) {
  1126. iobuffer_write_head(*req_pkt, IOBUF_T_I8, &rsn_ctx->previous_rsn, 0);
  1127. iobuffer_write_head(*req_pkt, IOBUF_T_I8, &rsn_ctx->current_rsn, 0);
  1128. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &rsn_ctx->original_type, 0);
  1129. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &rsn_ctx->depth, 0);
  1130. } else {
  1131. u__int64_t rsn = 0;
  1132. int t = 0;
  1133. iobuffer_write_head(*req_pkt, IOBUF_T_I8, &rsn, 0);
  1134. iobuffer_write_head(*req_pkt, IOBUF_T_I8, &rsn, 0);
  1135. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &t, 0);
  1136. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &t, 0);
  1137. }
  1138. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &timeout, 0);
  1139. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &tsx->method_sig, 0);
  1140. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &tsx->method_id, 0);
  1141. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &tsx->tsx_id, 0);
  1142. sp_tsx_uac_inc_ref(tsx); // @1
  1143. rc = sp_svc_post(uac->mgr->svc, uac->remote_epid, uac->remote_svc_id, SP_PKT_SES|SES_CMD_REQ, uac->conn_id, req_pkt);
  1144. WLog_INFO(TAG, "sp_tsx_uac_async_req remote_epid:%d, remote_svc_id:%d, method_sig:%d, method_id:%d", uac->remote_epid, uac->remote_svc_id, tsx->method_sig, tsx->method_id);
  1145. if (rc == 0) {
  1146. if (timeout >= 0) {
  1147. tsx->op_timer = MALLOC_T(timer_entry);
  1148. tsx->op_timer->cb = &tsx_uac_on_timer;
  1149. tsx->op_timer->user_data = tsx;
  1150. sp_tsx_uac_inc_ref(tsx); // @2
  1151. rc = sp_iom_schedule_timer(sp_svc_get_iom(uac->mgr->svc), tsx->op_timer, (unsigned int)timeout);
  1152. if (rc != 0) {
  1153. sp_tsx_uac_dec_ref(tsx); // @2
  1154. sp_tsx_uac_dec_ref(tsx); // @1
  1155. free(tsx->op_timer);
  1156. tsx->op_timer = NULL;
  1157. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "uac tsx async_req, create timer failed!");
  1158. }
  1159. }
  1160. } else {
  1161. sp_tsx_uac_dec_ref(tsx); // @1
  1162. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "tsx uac issue async req failed, may be remote party offline!");
  1163. rc = Error_IO;
  1164. }
  1165. } else {
  1166. rc = Error_Unexpect;
  1167. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "tsx uac state is not INIT!");
  1168. }
  1169. tsx->state = rc ? SP_TSX_UAC_STATE_ERROR : SP_TSX_UAC_STATE_REQ;
  1170. tsx_uac_unlock(tsx);
  1171. return rc;
  1172. }
  1173. int sp_tsx_uac_close(sp_tsx_uac_t *tsx)
  1174. {
  1175. int trigger = 0;
  1176. tsx_uac_lock(tsx);
  1177. if (tsx->state == SP_TSX_UAC_STATE_REQ || tsx->state == SP_TSX_UAC_STATE_TMPANS) {
  1178. trigger++;
  1179. if (tsx->op_timer) {
  1180. sp_iom_cancel_timer(sp_svc_get_iom(tsx->uac->mgr->svc), tsx->op_timer, 1);
  1181. tsx->op_timer = NULL;
  1182. }
  1183. }
  1184. if (tsx->state != SP_TSX_UAC_STATE_TERM)
  1185. tsx->state = SP_TSX_UAC_STATE_TERM;
  1186. if (trigger)
  1187. tsx_uac_trigger(tsx, Error_Closed, 1, NULL);
  1188. tsx_uac_unlock(tsx);
  1189. return 0;
  1190. }
  1191. sp_ses_uac_t *sp_tsx_uac_get_session(sp_tsx_uac_t *tsx)
  1192. {
  1193. return tsx->uac;
  1194. }
  1195. int sp_tsx_uac_get_state(sp_tsx_uac_t *tsx)
  1196. {
  1197. return tsx->state;
  1198. }
  1199. int sp_tsx_uac_get_id(sp_tsx_uac_t *tsx)
  1200. {
  1201. return tsx->tsx_id;
  1202. }
  1203. static void __sp_tsx_uac_destroy(sp_tsx_uac_t *tsx)
  1204. {
  1205. if (tsx->cb.on_destroy)
  1206. tsx->cb.on_destroy(tsx, tsx->cb.user_data);
  1207. sp_ses_uac_dec_ref(tsx->uac);
  1208. strand_destroy(tsx->strand);
  1209. free(tsx);
  1210. //DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "tsx uac destroyed!");
  1211. }
  1212. IMPLEMENT_REF_COUNT_MT_STATIC(sp_tsx_uac, sp_tsx_uac_t, ref_cnt, __sp_tsx_uac_destroy)
  1213. static __inline void uas_lock(sp_ses_uas_t *uas)
  1214. {
  1215. spinlock_enter(&uas->lock, -1);
  1216. }
  1217. static __inline void uas_unlock(sp_ses_uas_t *uas)
  1218. {
  1219. spinlock_leave(&uas->lock);
  1220. }
  1221. static const void* method_strand_getkey(const void *obj)
  1222. {
  1223. method_strand_t *ms = (method_strand_t *)obj;
  1224. return (const void*)ms->type;
  1225. }
  1226. static unsigned int method_strand_hash(const void *key)
  1227. {
  1228. return (unsigned int)key;
  1229. }
  1230. static int method_strand_cmpkey(const void *key_x, const void *key_y)
  1231. {
  1232. return (int)key_x - (int)key_y;
  1233. }
  1234. static __inline method_strand_t* create_method_strand(int type)
  1235. {
  1236. method_strand_t *ms = MALLOC_T(method_strand_t);
  1237. ms->strand = strand_create();
  1238. ms->type = type;
  1239. INIT_HLIST_NODE(&ms->node);
  1240. return ms;
  1241. }
  1242. static __inline void delete_method_strand(method_strand_t *ms)
  1243. {
  1244. strand_destroy(ms->strand);
  1245. free(ms);
  1246. }
  1247. static void uas_process_errc(sp_ses_uas_t *uas, int error)
  1248. {
  1249. int trigger = 0;
  1250. uas_lock(uas);
  1251. if (uas->state == SP_SES_STATE_INIT) {
  1252. trigger++;
  1253. uas->state = SP_SES_STATE_ERROR;
  1254. uas->state_begin_time = y2k_time_now();
  1255. uas->error = error;
  1256. } else if (uas->state == SP_SES_STATE_CONNECTED) {
  1257. trigger++;
  1258. uas->state = SP_SES_STATE_ERROR;
  1259. uas->state_begin_time = y2k_time_now();
  1260. uas->error = error;
  1261. }
  1262. uas_unlock(uas);
  1263. if (trigger)
  1264. uas_trigger(uas, error);
  1265. }
  1266. static void __threadpool_uas_trigger(threadpool_t *threadpool, void *arg, param_size_t param1, param_size_t param2)
  1267. {
  1268. sp_ses_uas_t *uas = (sp_ses_uas_t*)arg;
  1269. sp_ses_mgr_t *mgr = uas->mgr;
  1270. int error = (int)param1;
  1271. sp_uid_t rsn = sp_svc_new_runserial(mgr->svc);
  1272. sp_rsn_context_t rsn_ctx;
  1273. sp_rsn_context_init_original(rsn, SP_ORIGINAL_T_FRAMEWORK, &rsn_ctx);
  1274. sp_svc_push_runserial_context(mgr->svc, &rsn_ctx);
  1275. if (uas->cb.on_close) {
  1276. if (error != Error_Closed) {
  1277. sp_ses_uas_close(uas);
  1278. }
  1279. uas->cb.on_close(uas, error, uas->cb.user_data);
  1280. }
  1281. sp_ses_uas_dec_ref(uas); // @
  1282. sp_svc_pop_runserial_context(mgr->svc);
  1283. }
  1284. static void uas_trigger(sp_ses_uas_t *uas, int error)
  1285. {
  1286. int rc;
  1287. sp_ses_uas_inc_ref(uas); // @
  1288. rc = threadpool_queue_workitem2(sp_svc_get_threadpool(uas->mgr->svc), uas->strand, &__threadpool_uas_trigger, uas, error, 0);
  1289. if (rc != 0) {
  1290. sp_ses_uas_dec_ref(uas); // @
  1291. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "uas_trigger, queue work item failed!");
  1292. }
  1293. }
  1294. static strand_t *uas_get_strand(sp_ses_uas_t *uas, int method_id)
  1295. {
  1296. method_strand_t *ms;
  1297. uas_lock(uas);
  1298. ms = hashset_find(uas->method_strand, (const void *)method_id);
  1299. if (!ms) {
  1300. ms = create_method_strand(method_id);
  1301. hashset_add(uas->method_strand, ms);
  1302. }
  1303. uas_unlock(uas);
  1304. return ms->strand;
  1305. }
  1306. static void __threadpool_uas_process_info(threadpool_t *threadpool, void *arg, param_size_t param1, param_size_t param2)
  1307. {
  1308. sp_ses_uas_t *uas = (sp_ses_uas_t*)arg;
  1309. sp_ses_mgr_t *mgr = uas->mgr;
  1310. int method_id = (int)param1;
  1311. int method_sig;
  1312. iobuffer_t *info_pkt = (iobuffer_t*)param2;
  1313. iobuffer_read(info_pkt, IOBUF_T_I4, &method_sig, 0);
  1314. if (uas->state == SP_SES_STATE_CONNECTED ||
  1315. (uas->state == SP_SES_STATE_ERROR && uas->error == Error_PeerClose)) {
  1316. sp_rsn_context_t from_rsn;
  1317. sp_rsn_context_t rsn;
  1318. iobuffer_read(info_pkt, IOBUF_T_I4, &from_rsn.depth, 0);
  1319. iobuffer_read(info_pkt, IOBUF_T_I4, &from_rsn.original_type, 0);
  1320. iobuffer_read(info_pkt, IOBUF_T_I8, &from_rsn.current_rsn, 0);
  1321. iobuffer_read(info_pkt, IOBUF_T_I8, &from_rsn.previous_rsn, 0);
  1322. sp_rsn_context_init_downstream(sp_svc_new_runserial(mgr->svc), &from_rsn, &rsn);
  1323. sp_svc_push_runserial_context(mgr->svc, &rsn);
  1324. uas->cb.on_info(uas, method_id, method_sig, &info_pkt, uas->cb.user_data);
  1325. sp_svc_pop_runserial_context(mgr->svc);
  1326. }
  1327. if (info_pkt)
  1328. iobuffer_dec_ref(info_pkt);
  1329. sp_ses_uas_dec_ref(uas);//@
  1330. }
  1331. static strand_t *uas_decide_strand(sp_ses_uas_t *uas, int method_id, int overlap)
  1332. {
  1333. strand_t *strand = NULL;
  1334. if (uas->strand) {
  1335. if (overlap) {
  1336. strand = NULL;
  1337. } else {
  1338. strand = uas->strand;
  1339. }
  1340. } else {
  1341. if (!overlap) {
  1342. strand = uas_get_strand(uas, method_id);
  1343. }
  1344. }
  1345. return strand;
  1346. }
  1347. static void uas_process_info(sp_ses_uas_t *uas, int method_id, int method_sig, iobuffer_t **info_pkt)
  1348. {
  1349. int rc;
  1350. int overlap;
  1351. rc = (*uas->cb.get_method_attr)(uas, method_id, method_sig, &overlap, uas->cb.user_data);
  1352. if (rc == 0) {
  1353. strand_t *strand = uas_decide_strand(uas, method_id, overlap);
  1354. iobuffer_write_head(*info_pkt, IOBUF_T_I4, &method_sig, 0);
  1355. sp_ses_uas_inc_ref(uas); //@
  1356. rc = threadpool_queue_workitem2(sp_svc_get_threadpool(uas->mgr->svc), strand, &__threadpool_uas_process_info, uas, method_id, (param_size_t)*info_pkt);
  1357. if (rc != 0) {
  1358. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "process info queue work item failed!");
  1359. sp_ses_uas_dec_ref(uas); //@
  1360. } else {
  1361. *info_pkt = NULL;
  1362. }
  1363. } else {
  1364. DbgWithLinkForC(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM, "method signature not match: method_id=%d, method_sig=%d, error=%d", method_id, method_sig, rc);
  1365. }
  1366. }
  1367. static void uas_process_req_reply_error(sp_ses_uas_t *uas, int tsx_id, int err)
  1368. {
  1369. int v = 0;
  1370. char* tmpStr = "";
  1371. iobuffer_t *ans_pkt = iobuffer_create(-1, -1);
  1372. TOOLKIT_ASSERT(err != 0);
  1373. iobuffer_write(ans_pkt, IOBUF_T_I4, &err, 0); // sys error
  1374. iobuffer_write(ans_pkt, IOBUF_T_I4, &v, 0); // user error
  1375. iobuffer_write(ans_pkt, IOBUF_T_STR, tmpStr, 0);
  1376. iobuffer_write_head(ans_pkt, IOBUF_T_I4, &tsx_id, 0);
  1377. sp_svc_post(uas->mgr->svc, uas->remote_epid, uas->remote_svc_id, SP_PKT_SES|SES_CMD_ANS, uas->conn_id, &ans_pkt);
  1378. WLog_INFO(TAG, "uas_process_req_reply_error remote_epid:%d, remote_svc_id:%d", uas->remote_epid, uas->remote_svc_id);
  1379. if (ans_pkt)
  1380. iobuffer_dec_ref(ans_pkt);
  1381. }
  1382. static void __threadpool_uas_process_req(threadpool_t *threadpool, void *arg, param_size_t param1, param_size_t param2)
  1383. {
  1384. sp_ses_uas_t *uas = (sp_ses_uas_t*)arg;
  1385. sp_ses_mgr_t *mgr = uas->mgr;
  1386. int tsx_id = (int)param1;
  1387. int method_id;
  1388. int method_sig;
  1389. int timeout;
  1390. iobuffer_t *req_pkt = (iobuffer_t*)param2;
  1391. /** 这个数据是准的,不然实体层不会找到对应的接口序号和签名,不一定,这些数据是过来的时候才塞进去的 [Gifur@2022624]*/
  1392. //WLog_DBG(TAG, "read method info");
  1393. iobuffer_read(req_pkt, IOBUF_T_I4, &method_id, 0);
  1394. iobuffer_read(req_pkt, IOBUF_T_I4, &method_sig, 0);
  1395. iobuffer_read(req_pkt, IOBUF_T_I4, &timeout, 0);
  1396. if (uas->state == SP_SES_STATE_CONNECTED) {
  1397. sp_rsn_context_t from_rsn;
  1398. sp_rsn_context_t rsn;
  1399. iobuffer_read(req_pkt, IOBUF_T_I4, &from_rsn.depth, 0);
  1400. iobuffer_read(req_pkt, IOBUF_T_I4, &from_rsn.original_type, 0);
  1401. iobuffer_read(req_pkt, IOBUF_T_I8, &from_rsn.current_rsn, 0);
  1402. iobuffer_read(req_pkt, IOBUF_T_I8, &from_rsn.previous_rsn, 0);
  1403. sp_rsn_context_init_downstream(sp_svc_new_runserial(mgr->svc), &from_rsn, &rsn);
  1404. sp_svc_push_runserial_context(mgr->svc, &rsn);
  1405. uas->cb.on_req(uas, tsx_id, method_id, method_sig, timeout, &req_pkt, uas->cb.user_data);
  1406. sp_svc_pop_runserial_context(mgr->svc);
  1407. } else {
  1408. uas_process_req_reply_error(uas, tsx_id, Error_InvalidState);
  1409. }
  1410. if (req_pkt)
  1411. iobuffer_dec_ref(req_pkt);
  1412. sp_ses_uas_dec_ref(uas); //@
  1413. }
  1414. static void uas_process_req(sp_ses_uas_t *uas, int tsx_id, int method_id, int method_sig, int timeout, iobuffer_t **req_pkt)
  1415. {
  1416. int rc;
  1417. int overlap;
  1418. rc = uas->cb.get_method_attr(uas, method_id, method_sig, &overlap, uas->cb.user_data);
  1419. if (rc == 0) {
  1420. strand_t *strand = uas_decide_strand(uas, method_id, overlap);
  1421. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &timeout, 0);
  1422. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &method_sig, 0);
  1423. iobuffer_write_head(*req_pkt, IOBUF_T_I4, &method_id, 0);
  1424. sp_ses_uas_inc_ref(uas); //@
  1425. rc = threadpool_queue_workitem2(sp_svc_get_threadpool(uas->mgr->svc), strand, &__threadpool_uas_process_req, uas, tsx_id, (param_size_t)*req_pkt);
  1426. if (rc != 0) {
  1427. uas_process_req_reply_error(uas, tsx_id, rc);
  1428. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "process req queue work item failed!");
  1429. sp_ses_uas_dec_ref(uas); //@
  1430. } else {
  1431. *req_pkt = NULL;
  1432. }
  1433. } else {
  1434. uas_process_req_reply_error(uas, tsx_id, rc);
  1435. DbgWithLinkForC(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM, "method signature not match: tsx_id=%d, method_id=%d, method_sig=%d, error=%d", tsx_id, method_id, method_sig, rc);
  1436. }
  1437. }
  1438. int sp_ses_uas_create(sp_ses_mgr_t *mgr, int remote_epid, int remote_svc_id, int conn_id, int overlap, sp_ses_uas_callback *cb, sp_ses_uas_t **p_uas)
  1439. {
  1440. unsigned int slot;
  1441. sp_ses_uas_t *uas;
  1442. if (!cb || !cb->on_req || !cb->on_info)
  1443. return Error_Param;
  1444. uas = MALLOC_T(sp_ses_uas_t);
  1445. uas->mgr = mgr;
  1446. uas->conn_id = conn_id;
  1447. uas->remote_epid = remote_epid;
  1448. uas->remote_svc_id = remote_svc_id;
  1449. spinlock_init(&uas->lock);
  1450. INIT_HLIST_NODE(&uas->hentry);
  1451. memcpy(&uas->cb, cb, sizeof(sp_ses_uas_callback));
  1452. uas->state = SP_SES_STATE_INIT;
  1453. uas->state_begin_time = y2k_time_now();
  1454. uas->error = 0;
  1455. uas->tsx_cnt = 0;
  1456. uas->begin_time = y2k_time_now();
  1457. uas->strand = overlap ? NULL : strand_create();
  1458. INIT_LIST_HEAD(&uas->tsx_list);
  1459. REF_COUNT_INIT(&uas->ref_cnt);
  1460. uas->method_strand = overlap ? hashset_create(offset_of(method_strand_t, node), &method_strand_getkey, &method_strand_hash, &method_strand_cmpkey) : NULL;
  1461. sp_ses_mgr_inc_ref(mgr);
  1462. slot = ((unsigned int)conn_id) % CONN_BUCKET_SIZE;
  1463. sp_ses_uas_inc_ref(uas);
  1464. mgr_lock(mgr);
  1465. hlist_add_head(&uas->hentry, &mgr->uas_buckets[slot]);
  1466. mgr->ses_cnt++;
  1467. mgr_unlock(mgr);
  1468. *p_uas = uas;
  1469. //DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "ses uas created!");
  1470. return 0;
  1471. }
  1472. void sp_ses_uas_destroy(sp_ses_uas_t *uas)
  1473. {
  1474. TOOLKIT_ASSERT(uas->state == SP_SES_STATE_TERM);
  1475. mgr_lock(uas->mgr);
  1476. uas->mgr->ses_cnt--;
  1477. hlist_del_init(&uas->hentry);
  1478. mgr_unlock(uas->mgr);
  1479. sp_ses_uas_dec_ref(uas);
  1480. sp_ses_uas_dec_ref(uas);
  1481. }
  1482. int sp_ses_uas_close(sp_ses_uas_t *uas)
  1483. {
  1484. int rc = 0;
  1485. int trigger = 0;
  1486. sp_ses_uas_inc_ref(uas);
  1487. uas_lock(uas);
  1488. if (uas->state == SP_SES_STATE_INIT) {
  1489. uas->state = SP_SES_STATE_TERM;
  1490. uas->state_begin_time = y2k_time_now();
  1491. trigger++;
  1492. } else if (uas->state == SP_SES_STATE_CONNECTED) {
  1493. sp_tsx_uas_t *pos, *n;
  1494. uas->state = SP_SES_STATE_TERM;
  1495. uas->state_begin_time = y2k_time_now();
  1496. trigger++;
  1497. list_for_each_entry_safe(pos, n, &uas->tsx_list, sp_tsx_uas_t, entry) {
  1498. sp_tsx_uas_close(pos);
  1499. }
  1500. } else if (uas->state == SP_SES_STATE_ERROR) {
  1501. uas->state = SP_SES_STATE_TERM;
  1502. uas->state_begin_time = y2k_time_now();
  1503. } else if (uas->state == SP_SES_STATE_TERM) {
  1504. rc = Error_Duplication;
  1505. } else {
  1506. rc = Error_Unexpect;
  1507. }
  1508. if (trigger)
  1509. uas_trigger(uas, Error_Closed);
  1510. uas_unlock(uas);
  1511. if (rc == 0) {
  1512. sp_svc_post(uas->mgr->svc, uas->remote_epid, uas->remote_svc_id, SP_PKT_SES|SES_CMD_FINS, uas->conn_id, NULL);
  1513. }
  1514. sp_ses_uas_dec_ref(uas);
  1515. return rc;
  1516. }
  1517. int sp_ses_uas_get_remote_epid(sp_ses_uas_t *uas)
  1518. {
  1519. return uas->remote_epid;
  1520. }
  1521. int sp_ses_uas_get_remote_svc_id(sp_ses_uas_t *uas)
  1522. {
  1523. return uas->remote_svc_id;
  1524. }
  1525. int sp_ses_uas_get_conn_id(sp_ses_uas_t *uas)
  1526. {
  1527. return uas->conn_id;
  1528. }
  1529. sp_ses_mgr_t *sp_ses_uas_get_mgr(sp_ses_uas_t *uas)
  1530. {
  1531. return uas->mgr;
  1532. }
  1533. int sp_ses_uas_get_state(sp_ses_uas_t *uas)
  1534. {
  1535. return uas->state;
  1536. }
  1537. int sp_ses_uas_get_tsx_cnt(sp_ses_uas_t *uas)
  1538. {
  1539. return uas->tsx_cnt;
  1540. }
  1541. int sp_ses_uas_accept(sp_ses_uas_t *uas)
  1542. {
  1543. int rc;
  1544. uas_lock(uas);
  1545. if (uas->state == SP_SES_STATE_INIT) {
  1546. uas->state = SP_SES_STATE_CONNECTED;
  1547. uas->state_begin_time = y2k_time_now();
  1548. rc = Error_Succeed;
  1549. } else if (uas->state == SP_SES_STATE_CONNECTED) {
  1550. rc = Error_Duplication;
  1551. } else {
  1552. rc = Error_NetBroken;
  1553. }
  1554. uas_unlock(uas);
  1555. if (rc == 0) {
  1556. iobuffer_t *pkt = iobuffer_create(-1, -1);
  1557. sp_rsn_context_t *rsn_ctx = sp_svc_get_runserial_context(uas->mgr->svc);
  1558. if (rsn_ctx) {
  1559. iobuffer_write_head(pkt, IOBUF_T_I8, &rsn_ctx->previous_rsn, 0);
  1560. iobuffer_write_head(pkt, IOBUF_T_I8, &rsn_ctx->current_rsn, 0);
  1561. iobuffer_write_head(pkt, IOBUF_T_I4, &rsn_ctx->original_type, 0);
  1562. iobuffer_write_head(pkt, IOBUF_T_I4, &rsn_ctx->depth, 0);
  1563. } else {
  1564. u__int64_t rsn = 0;
  1565. int t = 0;
  1566. iobuffer_write_head(pkt, IOBUF_T_I8, &rsn, 0);
  1567. iobuffer_write_head(pkt, IOBUF_T_I8, &rsn, 0);
  1568. iobuffer_write_head(pkt, IOBUF_T_I4, &t, 0);
  1569. iobuffer_write_head(pkt, IOBUF_T_I4, &t, 0);
  1570. }
  1571. rc = sp_svc_post(uas->mgr->svc, uas->remote_epid, uas->remote_svc_id, SP_PKT_SES|SES_CMD_CONNACK, uas->conn_id, &pkt);
  1572. if (pkt) {
  1573. iobuffer_dec_ref(pkt);
  1574. }
  1575. }
  1576. return rc;
  1577. }
  1578. static void __sp_ses_uas_destroy(sp_ses_uas_t *uas)
  1579. {
  1580. if (uas->cb.on_destroy) {
  1581. uas->cb.on_destroy(uas, uas->cb.user_data);
  1582. }
  1583. sp_ses_mgr_dec_ref(uas->mgr);
  1584. if (uas->strand)
  1585. strand_destroy(uas->strand);
  1586. if (uas->method_strand) {
  1587. method_strand_t *tpos;
  1588. struct hlist_node *pos, *n;
  1589. int slot;
  1590. hashset_for_each_safe(tpos, pos, n, slot, uas->method_strand, method_strand_t) {
  1591. hashset_remove(uas->method_strand, (void*)tpos->type);
  1592. delete_method_strand(tpos);
  1593. }
  1594. hashset_destroy(uas->method_strand);
  1595. }
  1596. free(uas);
  1597. //DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "ses uas destroy!");
  1598. }
  1599. IMPLEMENT_REF_COUNT_MT_STATIC(sp_ses_uas, sp_ses_uas_t, ref_cnt, __sp_ses_uas_destroy)
  1600. static __inline void tsx_uas_lock(sp_tsx_uas_t *tsx)
  1601. {
  1602. spinlock_enter(&tsx->lock, -1);
  1603. }
  1604. static __inline void tsx_uas_unlock(sp_tsx_uas_t *tsx)
  1605. {
  1606. spinlock_leave(&tsx->lock);
  1607. }
  1608. int sp_tsx_uas_create(sp_ses_uas_t *uas, int tsx_id, sp_tsx_uas_callback *cb, sp_tsx_uas_t **p_tsx)
  1609. {
  1610. sp_tsx_uas_t *tsx = MALLOC_T(sp_tsx_uas_t);
  1611. unsigned int slot;
  1612. tsx->state = SP_TSX_UAS_STATE_INIT;
  1613. uas->state_begin_time = y2k_time_now();
  1614. tsx->uas = uas;
  1615. tsx->tsx_id = tsx_id;
  1616. spinlock_init(&tsx->lock);
  1617. memcpy(&tsx->cb, cb, sizeof(sp_tsx_uas_callback));
  1618. INIT_HLIST_NODE(&tsx->hentry);
  1619. REF_COUNT_INIT(&tsx->ref_cnt);
  1620. sp_ses_uas_inc_ref(uas);
  1621. uas_lock(uas);
  1622. sp_tsx_uas_inc_ref(tsx);
  1623. list_add_tail(&tsx->entry, &uas->tsx_list);
  1624. uas->tsx_cnt++;
  1625. uas_unlock(uas);
  1626. slot = jhash_3words(uas->remote_svc_id, uas->conn_id, tsx_id, 0) % TSX_BUCKET_SIZE;
  1627. mgr_lock(uas->mgr);
  1628. sp_tsx_uas_inc_ref(tsx);
  1629. hlist_add_head(&tsx->hentry, &uas->mgr->uas_tsx_buckets[slot]);
  1630. mgr_unlock(uas->mgr);
  1631. *p_tsx = tsx;
  1632. //DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "tsx uas created!");
  1633. return 0;
  1634. }
  1635. void sp_tsx_uas_destroy(sp_tsx_uas_t *tsx)
  1636. {
  1637. sp_ses_uas_t *uas = tsx->uas;
  1638. TOOLKIT_ASSERT(tsx->state == SP_TSX_UAS_STATE_TERM);
  1639. uas_lock(uas);
  1640. uas->tsx_cnt--;
  1641. list_del_init(&tsx->entry);
  1642. uas_unlock(uas);
  1643. sp_tsx_uas_dec_ref(tsx);
  1644. mgr_lock(uas->mgr);
  1645. hlist_del_init(&tsx->hentry);
  1646. mgr_unlock(uas->mgr);
  1647. sp_tsx_uas_dec_ref(tsx);
  1648. sp_tsx_uas_dec_ref(tsx);
  1649. }
  1650. sp_ses_uas_t *sp_tsx_uas_get_session(sp_tsx_uas_t *tsx)
  1651. {
  1652. return tsx->uas;
  1653. }
  1654. int sp_tsx_uas_get_state(sp_tsx_uas_t *tsx)
  1655. {
  1656. return tsx->state;
  1657. }
  1658. int sp_tsx_uas_get_id(sp_tsx_uas_t *tsx)
  1659. {
  1660. return tsx->tsx_id;
  1661. }
  1662. int sp_tsx_uas_close(sp_tsx_uas_t *tsx)
  1663. {
  1664. int rc;
  1665. tsx_uas_lock(tsx);
  1666. if (tsx->state != SP_TSX_UAS_STATE_TERM) {
  1667. tsx->state = SP_TSX_UAS_STATE_TERM;
  1668. rc = 0;
  1669. } else {
  1670. rc = Error_Duplication;
  1671. }
  1672. tsx_uas_unlock(tsx);
  1673. return rc;
  1674. }
  1675. int sp_tsx_uas_answer(sp_tsx_uas_t *tsx, int end, iobuffer_t **ans_pkt)
  1676. {
  1677. int rc;
  1678. int trigger = 0;
  1679. tsx_uas_lock(tsx);
  1680. if (tsx->state == SP_TSX_UAS_STATE_INIT) {
  1681. trigger++;
  1682. rc = 0;
  1683. tsx->state = end ? SP_TSX_UAS_STATE_ANS : SP_TSX_UAS_STATE_TMPANS;
  1684. } else if (tsx->state == SP_TSX_UAS_STATE_TMPANS) {
  1685. trigger++;
  1686. rc = 0;
  1687. tsx->state = end ? SP_TSX_UAS_STATE_ANS : SP_TSX_UAS_STATE_TMPANS;
  1688. } else {
  1689. rc = Error_Bug;
  1690. }
  1691. tsx_uas_unlock(tsx);
  1692. if (trigger) {
  1693. iobuffer_write_head(*ans_pkt, IOBUF_T_I4, &tsx->tsx_id, 0);
  1694. rc = sp_svc_post(tsx->uas->mgr->svc, tsx->uas->remote_epid, tsx->uas->remote_svc_id, SP_PKT_SES | (end ? SES_CMD_ANS : SES_CMD_TMPANS), tsx->uas->conn_id, ans_pkt);
  1695. }
  1696. return rc;
  1697. }
  1698. static void __sp_tsx_uas_destroy(sp_tsx_uas_t *tsx)
  1699. {
  1700. if (tsx->cb.on_destroy)
  1701. tsx->cb.on_destroy(tsx, tsx->cb.user_data);
  1702. sp_ses_uas_dec_ref(tsx->uas);
  1703. free(tsx);
  1704. //DbgWithLinkForC(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM, "tsx uas destroyed!");
  1705. }
  1706. IMPLEMENT_REF_COUNT_MT_STATIC(sp_tsx_uas, sp_tsx_uas_t, ref_cnt, __sp_tsx_uas_destroy)