sp_log.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  1. #include "precompile.h"
  2. #include <stdarg.h>
  3. #include "sp_log.h"
  4. #include "sp_def.h"
  5. #include "sp_svc.h"
  6. #include "sp_env.h"
  7. #include "sp_uid.h"
  8. #include "sp_rsn.h"
  9. #include "SpBase.h"
  10. #include "memutil.h"
  11. #include "list.h"
  12. #include "array.h"
  13. #include "jhash.h"
  14. #include "refcnt.h"
  15. #include "y2k_time.h"
  16. #include "sp_dbg_export.h"
  17. #include <winpr/synch.h>
  18. #include <winpr/sysinfo.h>
  19. #include <winpr/thread.h>
  20. #define LOG_CMD_RECORD 0x01
  21. #define LOG_CMD_FLUSH 0x02
  22. #define LOG_CMD_SUBSCRIBE 0x03
  23. #define LOG_CMD_UNSUBSCRIBE 0x04
  24. #define LOG_CMD_LISTEN_RECORD 0x05
  25. #define DAEMON_LOG_TIMEOUT_INTERVAL 5
  26. #define LOG_FILTER_BIT_LOGTYPE 0
  27. #define LOG_FILTER_BIT_ENTITY 1
  28. #define LOG_FILTER_BIT_SEVERITY 2
  29. #define LOG_FILTER_BIT_SYSCODE 3
  30. #define BIT_MASK(bit) (1 << (bit))
  31. #define FILTER_HASHTABLE_SIZE 1023
  32. struct sp_log_client_t
  33. {
  34. int local_svc_id;
  35. sp_svc_t *svc;
  36. sp_iom_t *iom;
  37. };
  38. // svc == null, iom cannot be null, anonymous
  39. // svc != null, iom can be null
  40. int sp_log_client_create(sp_svc_t *svc, sp_iom_t *iom, sp_log_client_t **p_client)
  41. {
  42. sp_log_client_t *client = MALLOC_T(sp_log_client_t);
  43. if (client) {
  44. if (svc) {
  45. if (!iom) {
  46. iom = sp_svc_get_iom(svc);
  47. }
  48. }
  49. client->svc = svc;
  50. client->iom = iom;
  51. if (svc) {
  52. client->local_svc_id = sp_svc_get_id(svc);
  53. } else {
  54. client->local_svc_id = SP_INVALID_SVC_ID;
  55. }
  56. *p_client = client;
  57. return 0;
  58. } else {
  59. return -1;
  60. };
  61. }
  62. int sp_log_client_destroy(sp_log_client_t *client)
  63. {
  64. free(client);
  65. return 0;
  66. }
  67. // TODO: param size type [4/2/2020 12:50 Gifur]
  68. int sp_log_client_log(sp_log_client_t *client, int type, int severity, int sys_error, int usr_error, int param_cnt, int *params, const char *format, ...)
  69. {
  70. va_list arg;
  71. va_start(arg, format);
  72. return sp_log_client_logv(client, type, severity, sys_error, usr_error, param_cnt, params, format, arg);
  73. }
  74. // TODO: param size type [4/2/2020 12:50 Gifur]
  75. int sp_log_client_logv(sp_log_client_t *client, int type, int severity, int sys_error, int usr_error, int param_cnt, int *params, const char *format, va_list arg)
  76. {
  77. int i, n;
  78. int rc;
  79. iobuffer_t *info_pkt;
  80. sp_env_t *env = sp_get_env();
  81. sp_iom_t *iom = client->iom;
  82. int local_epid = sp_iom_get_epid(iom);
  83. u__int64_t log_id = 0;
  84. y2k_time_t log_time;
  85. sp_rsn_context_t *rsn_ctx;
  86. sp_entity_t *ent;
  87. n = format ? _vscprintf(format, arg) : 0;
  88. if (n < 0 || n > SP_LOG_MAX_LEN)
  89. {
  90. sp_dbg_info("client log len is not right, %d", n);
  91. return Error_Param;
  92. }
  93. ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, client->local_svc_id);
  94. if (!ent) {
  95. sp_dbg_info("client log sp_mod_mgr_find_entity_by_idx failed");
  96. return Error_Param;
  97. }
  98. log_time = y2k_time_now();
  99. rsn_ctx = client->svc ? sp_svc_get_runserial_context(client->svc) : NULL;
  100. info_pkt = iobuffer_create(-1, n + 112);
  101. iobuffer_write(info_pkt, IOBUF_T_I4, &ent->instance_id, 0);
  102. iobuffer_write(info_pkt, IOBUF_T_I8, &log_id, 0);
  103. if (rsn_ctx) {
  104. iobuffer_write(info_pkt, IOBUF_T_I8, &rsn_ctx->previous_rsn, 0);
  105. iobuffer_write(info_pkt, IOBUF_T_I8, &rsn_ctx->current_rsn, 0);
  106. iobuffer_write(info_pkt, IOBUF_T_I4, &rsn_ctx->original_type, 0);
  107. iobuffer_write(info_pkt, IOBUF_T_I4, &rsn_ctx->depth, 0);
  108. } else {
  109. u__int64_t invalid_rsn = 0;
  110. int t = 0;
  111. iobuffer_write(info_pkt, IOBUF_T_I8, &invalid_rsn, 0);
  112. iobuffer_write(info_pkt, IOBUF_T_I8, &invalid_rsn, 0);
  113. iobuffer_write(info_pkt, IOBUF_T_I4, &t, 0);
  114. iobuffer_write(info_pkt, IOBUF_T_I4, &t, 0);
  115. }
  116. iobuffer_write(info_pkt, IOBUF_T_I4, &log_time, 0);
  117. iobuffer_write(info_pkt, IOBUF_T_I4, &type, 0);
  118. iobuffer_write(info_pkt, IOBUF_T_I4, &client->local_svc_id, 0);
  119. iobuffer_write(info_pkt, IOBUF_T_I4, &local_epid, 0);
  120. iobuffer_write(info_pkt, IOBUF_T_I4, &severity, 0);
  121. iobuffer_write(info_pkt, IOBUF_T_I4, &sys_error, 0);
  122. iobuffer_write(info_pkt, IOBUF_T_I4, &usr_error, 0);
  123. iobuffer_write(info_pkt, IOBUF_T_I4, &param_cnt, 0);
  124. for (i = 0; i < param_cnt; ++i) {
  125. iobuffer_write(info_pkt, IOBUF_T_I4, &params[i], 0);
  126. }
  127. iobuffer_write(info_pkt, IOBUF_T_7BIT, &n, 0);
  128. if (n > 0) {
  129. n = vsprintf(iobuffer_data(info_pkt, -1), format, arg);
  130. iobuffer_push_count(info_pkt, n);
  131. }
  132. rc = sp_iom_post(client->iom, client->local_svc_id,
  133. SP_SHELL_MOD_ID, SP_SHELL_SVC_ID,
  134. SP_PKT_LOG|LOG_CMD_RECORD, 0, &info_pkt);
  135. if (info_pkt)
  136. iobuffer_dec_ref(info_pkt);
  137. return rc;
  138. }
  139. int sp_log_client_flush(sp_log_client_t *client)
  140. {
  141. int rc;
  142. rc = sp_iom_post(client->iom, client->local_svc_id, SP_SHELL_MOD_ID,
  143. SP_SHELL_SVC_ID, SP_PKT_LOG|LOG_CMD_FLUSH, 0, NULL);
  144. return rc;
  145. }
  146. //
  147. // listener
  148. //
  149. #define INDEX_HASHTABLE_SIZE 1023
  150. typedef struct sp_log_listener_cb // ��Ӧһ��SpEntity
  151. {
  152. struct list_head __entry; // < sp_log_listener_mgr_t . cb_list
  153. struct list_head __working_entry;
  154. struct list_head __list; // > listener_t . entry
  155. struct list_head __working_list;
  156. void *key;
  157. int enable;
  158. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  159. }sp_log_listener_cb;
  160. static sp_log_listener_cb* sp_log_listener_cb_create(void *key)
  161. {
  162. sp_log_listener_cb *cb = MALLOC_T(sp_log_listener_cb);
  163. cb->ref_cnt = 1;
  164. cb->enable = 1;
  165. cb->key = key;
  166. INIT_LIST_HEAD(&cb->__working_list);
  167. INIT_LIST_HEAD(&cb->__list);
  168. return cb;
  169. }
  170. static __inline void __sp_log_listener_cb_destroy(sp_log_listener_cb *cb){free(cb);}
  171. IMPLEMENT_REF_COUNT_MT_STATIC(sp_log_listener_cb, sp_log_listener_cb, ref_cnt, __sp_log_listener_cb_destroy)
  172. typedef struct listener_t // ��Ӧÿ��Subscribe
  173. {
  174. struct hlist_node hentry; // < sp_log_listener_mgr_t . index[slot]
  175. struct list_head entry; // < sp_log_listener_cb . __list
  176. struct list_head working_entry;
  177. unsigned int id;
  178. int ignore_msg_body;
  179. sp_log_listener_cb *cb;
  180. }listener_t;
  181. struct sp_log_listener_mgr_t
  182. {
  183. struct list_head cb_list; // > sp_log_listener_cb . __entry
  184. struct hlist_head index[INDEX_HASHTABLE_SIZE]; // > listener_t . hentry
  185. sp_svc_t *svc;
  186. sp_log_on_log on_log;
  187. strand_t *strand;
  188. int enabled;
  189. DECLARE_REF_COUNT_MEMBER(ref_cnt); ///
  190. };
  191. static listener_t *listener_find(sp_log_listener_mgr_t *mgr, unsigned int listen_id)
  192. {
  193. unsigned slot = listen_id % INDEX_HASHTABLE_SIZE;
  194. listener_t *tpos;
  195. struct hlist_node *pos;
  196. hlist_for_each_entry(tpos, pos, &mgr->index[slot], listener_t, hentry) {
  197. if (listen_id == tpos->id) {
  198. return tpos;
  199. }
  200. }
  201. return NULL;
  202. }
  203. static __inline void listener_add_index(sp_log_listener_mgr_t *mgr, listener_t *listener)
  204. {
  205. int slot = listener->id % INDEX_HASHTABLE_SIZE;
  206. hlist_add_head(&listener->hentry, &mgr->index[slot]);
  207. }
  208. static __inline void listener_del_index(sp_log_listener_mgr_t *mgr, listener_t *listener)
  209. {
  210. int slot = listener->id % INDEX_HASHTABLE_SIZE;
  211. listener_t *tpos;
  212. struct hlist_node *pos;
  213. hlist_for_each_entry(tpos, pos, &mgr->index[slot], listener_t, hentry) {
  214. if (tpos->id == listener->id) {
  215. hlist_del(pos);
  216. return;
  217. }
  218. }
  219. }
  220. static sp_log_listener_cb *listener_find_cb(sp_log_listener_mgr_t *mgr, void *key)
  221. {
  222. sp_log_listener_cb *pos;
  223. assert(key);
  224. list_for_each_entry(pos, &mgr->cb_list, sp_log_listener_cb, __entry) {
  225. if (pos->key == key)
  226. return pos;
  227. }
  228. return NULL;
  229. }
  230. static __inline void listener_invoke_cb(sp_log_listener_mgr_t *mgr, sp_log_listener_cb *cb,
  231. int nsub,
  232. u__int64_t *sub,
  233. int client_id,
  234. int log_epid,
  235. int client_instance_id,
  236. u__int64_t log_id,
  237. u__int64_t prev_rsn,
  238. u__int64_t curr_rsn,
  239. int original_rsn_type,
  240. int rsn_depth,
  241. unsigned int log_time,
  242. int log_type,
  243. int log_severity,
  244. int log_sys_error,
  245. int log_usr_error,
  246. int param_cnt,
  247. int *params,
  248. const char *msg)
  249. {
  250. mgr->on_log(mgr,
  251. nsub,
  252. sub,
  253. client_id,
  254. log_epid,
  255. client_instance_id,
  256. log_id,
  257. prev_rsn,
  258. curr_rsn,
  259. original_rsn_type,
  260. rsn_depth,
  261. log_time,
  262. log_type,
  263. log_severity,
  264. log_sys_error,
  265. log_usr_error,
  266. param_cnt,
  267. params,
  268. msg,
  269. cb->key);
  270. }
  271. static void listener_on_pkt_threadpool(threadpool_t *threadpool, void *arg)
  272. {
  273. iobuffer_t *pkt = (iobuffer_t*)arg;
  274. sp_log_listener_mgr_t *mgr = NULL;
  275. int epid, pkt_type, pkt_id, svc_id;
  276. sp_uid_t rsn;
  277. sp_rsn_context_t rsn_ctx;
  278. sp_svc_t *svc = NULL;
  279. int nsub = 0;
  280. int *sub;
  281. int instance_id;
  282. u__int64_t log_id;
  283. u__int64_t prev_rsn;
  284. u__int64_t curr_rsn;
  285. int original_rsn_type;
  286. int rsn_depth;
  287. unsigned int log_time;
  288. int log_type, log_severity, log_sys_error, log_usr_error, log_client_id, log_epid;
  289. char *msg = NULL;
  290. int param_cnt;
  291. int *params = NULL;
  292. int i;
  293. //assert(nsub);
  294. #ifdef _WIN32
  295. iobuffer_format_read(pkt, "44444", &mgr, &epid, &svc_id, &pkt_type, &pkt_id);
  296. #else
  297. iobuffer_format_read(pkt, "84444", &mgr, &epid, &svc_id, &pkt_type, &pkt_id);
  298. #endif //_WIN32
  299. svc = mgr->svc;
  300. rsn = sp_svc_new_runserial(svc);
  301. sp_rsn_context_init_original(rsn, SP_ORIGINAL_T_CALLBACK, &rsn_ctx);
  302. sp_svc_push_runserial_context(svc, &rsn_ctx);
  303. if (mgr->enabled) {
  304. svc = mgr->svc;
  305. nsub = pkt_id;
  306. sub = (int*)iobuffer_data(pkt, 0);
  307. iobuffer_pop_count(pkt, 4*nsub);
  308. iobuffer_format_read(pkt, "4888444444444", &instance_id, &log_id,
  309. &prev_rsn, &curr_rsn, &original_rsn_type, &rsn_depth,
  310. &log_time, &log_type, &log_client_id, &log_epid, &log_severity, &log_sys_error, &log_usr_error);
  311. iobuffer_read(pkt, IOBUF_T_I4, &param_cnt, NULL);
  312. if (param_cnt) {
  313. params = (int*)malloc(sizeof(int)*param_cnt);
  314. for (i = 0; i < param_cnt; ++i) {
  315. iobuffer_read(pkt, IOBUF_T_I4, &params[i], NULL);
  316. }
  317. }
  318. iobuffer_format_read(pkt, "s", &msg);
  319. {
  320. struct list_head cb_list;
  321. sp_log_listener_cb *pos;
  322. u__int64_t *tmp_sub;
  323. INIT_LIST_HEAD(&cb_list);
  324. for (i = 0; i < nsub; ++i) {
  325. unsigned int id = (unsigned int)sub[i];
  326. listener_t *listener = listener_find(mgr, id);
  327. if (listener) {
  328. sp_log_listener_cb *cb = listener->cb;
  329. if (list_empty(&cb->__working_list)) {
  330. list_add_tail(&cb->__working_entry, &cb_list);
  331. }
  332. list_add_tail(&listener->working_entry, &cb->__working_list);
  333. }
  334. }
  335. tmp_sub = (u__int64_t*)_alloca(nsub*8);
  336. list_for_each_entry(pos, &cb_list, sp_log_listener_cb, __working_entry) {
  337. listener_t *k_pos;
  338. int cnt = 0;
  339. list_for_each_entry(k_pos, &pos->__working_list, listener_t, working_entry) {
  340. tmp_sub[cnt++] = k_pos->id;
  341. }
  342. listener_invoke_cb(mgr, pos, cnt, tmp_sub, log_client_id, log_epid,
  343. instance_id, log_id, prev_rsn, curr_rsn, original_rsn_type, rsn_depth,
  344. log_time, log_type, log_severity, log_sys_error, log_usr_error, param_cnt, params, msg);
  345. INIT_LIST_HEAD(&pos->__working_list);
  346. }
  347. }
  348. toolkit_free(msg);
  349. free(params);
  350. }
  351. if (pkt)
  352. iobuffer_dec_ref(pkt);
  353. sp_log_listener_mgr_dec_ref(mgr);//@
  354. sp_svc_pop_runserial_context(svc);
  355. }
  356. static int listener_on_pkt(sp_svc_t *svc, int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt, void *user_data)
  357. {
  358. sp_log_listener_mgr_t *mgr = (sp_log_listener_mgr_t*)user_data;
  359. int log_cmd = SP_GET_TYPE(pkt_type);
  360. if (log_cmd == LOG_CMD_LISTEN_RECORD) {
  361. iobuffer_t *pkt = *p_pkt;
  362. *p_pkt = NULL;
  363. #ifdef _WIN32
  364. iobuffer_format_write_head(pkt, "44444", &pkt_id, &pkt_type, &svc_id, &epid, (void*)&mgr);
  365. #else
  366. iobuffer_format_write_head(pkt, "44448", &pkt_id, &pkt_type, &svc_id, &epid, (void*)&mgr);
  367. #endif //_WIN32
  368. sp_log_listener_mgr_inc_ref(mgr);//@
  369. if (threadpool_queue_workitem(sp_svc_get_threadpool(svc), mgr->strand, &listener_on_pkt_threadpool, pkt) != 0) {
  370. sp_log_listener_mgr_dec_ref(mgr);//@
  371. iobuffer_dec_ref(pkt);
  372. }
  373. return FALSE;
  374. }
  375. return TRUE; // continue
  376. }
  377. int sp_log_listener_mgr_create(sp_svc_t *svc, sp_log_on_log on_log, sp_log_listener_mgr_t **p_mgr)
  378. {
  379. sp_log_listener_mgr_t *mgr = MALLOC_T(sp_log_listener_mgr_t);
  380. if (mgr) {
  381. int i;
  382. INIT_LIST_HEAD(&mgr->cb_list);
  383. mgr->enabled = 0;
  384. mgr->strand = strand_create();
  385. mgr->on_log = on_log;
  386. mgr->ref_cnt = 1;
  387. mgr->svc = svc;
  388. for (i = 0; i < INDEX_HASHTABLE_SIZE; ++i) {
  389. INIT_HLIST_HEAD(&mgr->index[i]);
  390. }
  391. *p_mgr = mgr;
  392. return 0;
  393. }
  394. return Error_Resource;
  395. }
  396. int sp_log_listener_mgr_start(sp_log_listener_mgr_t *mgr)
  397. {
  398. mgr->enabled = 1;
  399. sp_svc_add_pkt_handler(mgr->svc, (int)mgr, SP_PKT_LOG, &listener_on_pkt, mgr);
  400. return 0;
  401. }
  402. int sp_log_listener_mgr_stop(sp_log_listener_mgr_t *mgr)
  403. {
  404. mgr->enabled = 0;
  405. sp_svc_remove_pkt_handler(mgr->svc, (int)mgr, SP_PKT_LOG);
  406. return 0;
  407. }
  408. int sp_log_listener_mgr_subscribe(sp_log_listener_mgr_t *mgr, unsigned int *listen_id, void *key, int ignore_msg_body, int log_type, int ent_id, int severity_filter, int sys_code, int user_code)
  409. {
  410. sp_env_t *env = sp_get_env();
  411. int new_id = sp_env_new_id(env);
  412. sp_log_listener_cb *cb = listener_find_cb(mgr, key);
  413. listener_t *listener = NULL;
  414. iobuffer_t *pkt = NULL;
  415. if (!cb) {
  416. cb = sp_log_listener_cb_create(key);
  417. if (!cb)
  418. return Error_Resource;
  419. list_add_tail(&cb->__entry, &mgr->cb_list);
  420. }
  421. listener = MALLOC_T(listener_t);
  422. listener->cb = cb;
  423. listener->id = new_id;
  424. listener->ignore_msg_body = ignore_msg_body;
  425. listener_add_index(mgr, listener);
  426. list_add_tail(&listener->entry, &cb->__list);
  427. pkt = iobuffer_create(-1, -1);
  428. iobuffer_format_write(pkt, "444444", &ignore_msg_body, &log_type, &ent_id, &severity_filter, &sys_code, &user_code);
  429. sp_svc_post(mgr->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_LOG|LOG_CMD_SUBSCRIBE, listener->id, &pkt);
  430. if (pkt)
  431. iobuffer_dec_ref(pkt);
  432. *listen_id = new_id;
  433. return 0;
  434. }
  435. int sp_log_listener_mgr_unsubscribe(sp_log_listener_mgr_t *mgr, unsigned int listen_id)
  436. {
  437. listener_t *listener = listener_find(mgr, listen_id);
  438. if (listener) {
  439. sp_log_listener_cb *cb = listener->cb;
  440. iobuffer_t *pkt = NULL;
  441. listener_del_index(mgr, listener);
  442. list_del(&listener->entry);
  443. if (list_empty(&cb->__list)) {
  444. // list_del(&mgr->cb_list); {bug}
  445. list_del(&cb->__entry);
  446. free(cb);
  447. }
  448. sp_svc_post(mgr->svc, SP_SHELL_MOD_ID, SP_SHELL_SVC_ID, SP_PKT_LOG|LOG_CMD_UNSUBSCRIBE, listener->id, NULL);
  449. free(listener);
  450. return 0;
  451. }
  452. return Error_NotExist;
  453. }
  454. static void __sp_log_listener_mgr_destroy(sp_log_listener_mgr_t *mgr)
  455. {
  456. strand_destroy(mgr->strand);
  457. free(mgr);
  458. }
  459. IMPLEMENT_REF_COUNT_MT(sp_log_listener_mgr, sp_log_listener_mgr_t, ref_cnt, __sp_log_listener_mgr_destroy)
  460. //
  461. // daemon
  462. //
  463. typedef struct log_filter_key_t log_filter_key_t;
  464. typedef struct log_listener_t log_listener_t;
  465. typedef struct log_listener_entity_t log_listener_entity_t;
  466. struct log_filter_key_t {
  467. int log_type;
  468. int ent_id;
  469. int severity_filter;
  470. int sys_code;
  471. int user_code; // -1 and -2 has special means, -2 means accept all, -1 means reject any
  472. unsigned int index_hash_code;
  473. };
  474. struct log_listener_t {
  475. struct list_head entry; // < log_listener_entity_t . listener_list
  476. int id;
  477. int ignore_msg_body;
  478. log_filter_key_t index_key;
  479. struct hlist_node index_hentry; // < sp_log_daemon_t . arr_filter_index
  480. struct hlist_node working_hentry;
  481. log_listener_entity_t *owner; // = log_listener_entity_t
  482. };
  483. struct log_listener_entity_t {
  484. struct list_head listener_list; // > log_listener_t . entry
  485. int epid;
  486. int svc_id;
  487. };
  488. struct sp_log_daemon_t
  489. {
  490. sp_log_on_log on_log;
  491. sp_log_on_flush on_flush;
  492. sp_log_on_timeout_interval on_timeout_interval;
  493. void *user_data;
  494. sp_svc_t *svc;
  495. CRITICAL_SECTION lock;
  496. iobuffer_queue_t *pkt_queue;
  497. HANDLE pkt_sem;
  498. HANDLE stop_evt;
  499. HANDLE worker_thread;
  500. sp_uid_t last_log_id;
  501. struct hlist_head arr_filter_index[FILTER_HASHTABLE_SIZE]; // log_listener_t . index_hentry
  502. int masks[16];
  503. int masks_cnt;
  504. array_header_t *arr_entity; // > log_listener_entity_t
  505. };
  506. static __inline void daemon_lock(sp_log_daemon_t *daemon)
  507. {
  508. EnterCriticalSection(&daemon->lock);
  509. }
  510. static __inline void daemon_unlock(sp_log_daemon_t *daemon)
  511. {
  512. LeaveCriticalSection(&daemon->lock);
  513. }
  514. static __inline unsigned int hash_filter(int log_type, int ent_id, int severity_filter, int sys_code, int user_code)
  515. {
  516. unsigned int t = (log_type << 16) | (ent_id << 8) | severity_filter;
  517. return jhash_3words(t, sys_code, user_code, 0);
  518. }
  519. static log_listener_entity_t* daemon_find_entity(sp_log_daemon_t *daemon, int ent_id)
  520. {
  521. int i;
  522. for (i = 0; i < daemon->arr_entity->nelts; ++i) {
  523. log_listener_entity_t *listen_ent = ARRAY_IDX(daemon->arr_entity, i, log_listener_entity_t*);
  524. if (listen_ent->svc_id == ent_id)
  525. return listen_ent;
  526. }
  527. return NULL;
  528. }
  529. static log_listener_t *daemon_find_listener(sp_log_daemon_t *daemon, int listen_id, int *idx)
  530. {
  531. int i;
  532. for (i = 0; i < daemon->arr_entity->nelts; ++i) {
  533. log_listener_entity_t *e = ARRAY_IDX(daemon->arr_entity, i, log_listener_entity_t*);
  534. log_listener_t *pos;
  535. list_for_each_entry(pos, &e->listener_list, log_listener_t, entry) {
  536. if (pos->id == listen_id) {
  537. if (idx)
  538. *idx = i;
  539. return pos;
  540. }
  541. }
  542. }
  543. return NULL;
  544. }
  545. static __inline int calc_filter_mask(int log_type, int ent_id, int severity_filter, int sys_code)
  546. {
  547. int filter_mask = 0;
  548. if (log_type == Log_Ignore)
  549. filter_mask |= 1 << LOG_FILTER_BIT_LOGTYPE;
  550. if (ent_id == -1)
  551. filter_mask |= 1 << LOG_FILTER_BIT_ENTITY;
  552. if (severity_filter == Severity_None)
  553. filter_mask |= 1 << LOG_FILTER_BIT_SEVERITY;
  554. if (sys_code == Error_IgnoreAll)
  555. filter_mask |= 1 << LOG_FILTER_BIT_SYSCODE;
  556. return filter_mask;
  557. }
  558. #define OP_ADD 1
  559. #define OP_DEL 0
  560. static void update_filter_mask_table(sp_log_daemon_t *daemon, int filter_mask, int op_add)
  561. {
  562. int i;
  563. if (op_add) {
  564. for (i = 0; i < daemon->masks_cnt; ++i)
  565. if ((daemon->masks[i]&0xffff) == filter_mask) {
  566. int cnt = (daemon->masks[i]&0xffff0000) >> 16;
  567. cnt++;
  568. daemon->masks[i] = filter_mask | (cnt << 16);
  569. break;
  570. }
  571. if (i == daemon->masks_cnt)
  572. daemon->masks[daemon->masks_cnt++] = filter_mask | (1<<16);
  573. } else {
  574. for (i = 0; i < daemon->masks_cnt; ++i) {
  575. if ((daemon->masks[i]&0xffff) == filter_mask) {
  576. int cnt = (daemon->masks[i] & 0xffff0000) >> 16;
  577. int filter_mask = daemon->masks[i] & 0xffff;
  578. cnt--;
  579. if (cnt == 0) {
  580. if (i != daemon->masks_cnt-1) {
  581. daemon->masks[i] = daemon->masks[daemon->masks_cnt-1];
  582. }
  583. daemon->masks_cnt--;
  584. } else {
  585. daemon->masks[i] = ((cnt-1) << 16) | filter_mask;
  586. }
  587. break;
  588. }
  589. }
  590. }
  591. }
  592. static __inline void daemon_add_index(sp_log_daemon_t *daemon, log_listener_t *e)
  593. {
  594. int filter_mask = 0;
  595. int slot = e->index_key.index_hash_code % FILTER_HASHTABLE_SIZE;
  596. hlist_add_head(&e->index_hentry, &daemon->arr_filter_index[slot]);
  597. filter_mask = calc_filter_mask(e->index_key.log_type, e->index_key.ent_id, e->index_key.severity_filter, e->index_key.sys_code);
  598. update_filter_mask_table(daemon, filter_mask, OP_ADD);
  599. }
  600. static __inline void daemon_del_index(sp_log_daemon_t *daemon, log_listener_t *e)
  601. {
  602. int filter_mask = 0;
  603. hlist_del(&e->index_hentry);
  604. filter_mask = calc_filter_mask(e->index_key.log_type, e->index_key.ent_id, e->index_key.severity_filter, e->index_key.sys_code);
  605. update_filter_mask_table(daemon, filter_mask, OP_DEL);
  606. }
  607. static int daemon_listener_need_log(sp_log_daemon_t *daemon,
  608. log_listener_t *e, int log_type,
  609. int log_severity,
  610. int log_sys_error,
  611. int log_usr_error,
  612. int log_client_id)
  613. {
  614. log_filter_key_t *key = &e->index_key;
  615. if (key->ent_id == -1 || key->ent_id == log_client_id) {
  616. if (key->log_type == Log_Ignore || key->log_type == log_type) {
  617. if (key->severity_filter == Severity_None || key->severity_filter == log_severity) {
  618. if (key->sys_code == Error_IgnoreAll || key->sys_code == log_sys_error) {
  619. if (key->user_code == -2 || (key->user_code == -1 && log_usr_error) || key->user_code == log_usr_error)
  620. return TRUE;
  621. }
  622. }
  623. }
  624. }
  625. return FALSE;
  626. }
  627. static void daemon_on_sys(sp_svc_t *svc,int epid, int state, void *user_data)
  628. {
  629. sp_log_daemon_t *daemon = (sp_log_daemon_t*)user_data;
  630. if (state == BUS_STATE_OFF) {
  631. int i = 0;
  632. daemon_lock(daemon);
  633. for (i = 0; i < daemon->arr_entity->nelts; ++i) {
  634. log_listener_entity_t *listen_ent = ARRAY_IDX(daemon->arr_entity, i, log_listener_entity_t*);
  635. if (listen_ent->epid == epid) {
  636. log_listener_t *pos, *n;
  637. list_for_each_entry_safe(pos, n, &listen_ent->listener_list, log_listener_t, entry) {
  638. list_del(&pos->entry);
  639. daemon_del_index(daemon, pos);
  640. free(pos);
  641. }
  642. ARRAY_DEL(daemon->arr_entity, i, log_listener_entity_t*);
  643. free(listen_ent);
  644. }
  645. }
  646. daemon_unlock(daemon);
  647. }
  648. }
  649. static int daemon_on_pkt(sp_svc_t *svc,int epid, int svc_id, int pkt_type, int pkt_id, iobuffer_t **p_pkt, void *user_data)
  650. {
  651. sp_log_daemon_t *daemon = (sp_log_daemon_t*)user_data;
  652. int log_cmd = SP_GET_TYPE(pkt_type);
  653. int log_client_id = pkt_id;
  654. if (log_cmd == LOG_CMD_RECORD || log_cmd == LOG_CMD_FLUSH) {
  655. iobuffer_write_head(*p_pkt, IOBUF_T_I4, &pkt_id, 0);
  656. iobuffer_write_head(*p_pkt, IOBUF_T_I4, &pkt_type, 0);
  657. iobuffer_write_head(*p_pkt, IOBUF_T_I4, &svc_id, 0);
  658. iobuffer_write_head(*p_pkt, IOBUF_T_I4, &epid, 0);
  659. daemon_lock(daemon);
  660. iobuffer_queue_enqueue(daemon->pkt_queue, *p_pkt);
  661. daemon_unlock(daemon);
  662. ReleaseSemaphore(daemon->pkt_sem, 1, NULL);
  663. *p_pkt = NULL;
  664. } else if (log_cmd == LOG_CMD_SUBSCRIBE) {
  665. int id = pkt_id;
  666. int ignore_msg_body;
  667. int log_type;
  668. int ent_id;
  669. int severity_filter;
  670. int sys_code;
  671. int user_code;
  672. log_listener_entity_t *listen_ent;
  673. iobuffer_format_read(*p_pkt, "444444", &ignore_msg_body, &log_type, &ent_id, &severity_filter, &sys_code, &user_code);
  674. daemon_lock(daemon);
  675. listen_ent = daemon_find_entity(daemon, svc_id);
  676. if (!listen_ent) {
  677. listen_ent = MALLOC_T(log_listener_entity_t);
  678. listen_ent->epid = epid;
  679. listen_ent->svc_id = svc_id;
  680. INIT_LIST_HEAD(&listen_ent->listener_list);
  681. ARRAY_PUSH(daemon->arr_entity, log_listener_entity_t*) = listen_ent;
  682. }
  683. if (daemon_find_listener(daemon, id, NULL) == NULL) {
  684. log_listener_t *listener = MALLOC_T(log_listener_t);
  685. log_filter_key_t *key = &listener->index_key;
  686. listener->owner = listen_ent;
  687. listener->ignore_msg_body = ignore_msg_body;
  688. listener->id = id;
  689. INIT_HLIST_NODE(&listener->working_hentry);
  690. key->ent_id = ent_id;
  691. key->log_type = log_type;
  692. key->severity_filter = severity_filter;
  693. key->sys_code = sys_code;
  694. key->user_code = user_code;
  695. key->index_hash_code = hash_filter(log_type, ent_id, severity_filter, sys_code, user_code);
  696. daemon_add_index(daemon, listener);
  697. list_add_tail(&listener->entry, &listen_ent->listener_list);
  698. }
  699. daemon_unlock(daemon);
  700. } else if (log_cmd == LOG_CMD_UNSUBSCRIBE) {
  701. int i;
  702. int id = pkt_id;
  703. log_listener_t* tmp;
  704. daemon_lock(daemon);
  705. tmp = daemon_find_listener(daemon, id, &i);
  706. if (tmp) {
  707. list_del(&tmp->entry);
  708. if (list_empty(&tmp->owner->listener_list)) {
  709. ARRAY_DEL(daemon->arr_entity, i, log_listener_entity_t*);
  710. free(tmp->owner);
  711. }
  712. daemon_del_index(daemon, tmp);
  713. free(tmp);
  714. }
  715. daemon_unlock(daemon);
  716. } else {
  717. assert(0);
  718. }
  719. return TRUE;
  720. }
  721. static int get_log_iobuffer_header_length(iobuffer_t *pkt)
  722. {
  723. //"4888444444444"
  724. int nparam;
  725. int len = 64;
  726. int rs = iobuffer_get_read_state(pkt);
  727. iobuffer_pop_count(pkt, len);
  728. iobuffer_read(pkt, IOBUF_T_I4, &nparam, 0);
  729. len += 4;
  730. len += 4 * nparam;
  731. iobuffer_restore_read_state(pkt, rs);
  732. return len;
  733. }
  734. static void daemon_bcast(sp_log_daemon_t *daemon, int from_client_id, iobuffer_t *pkt)
  735. {
  736. int i, j;
  737. int instance_id;
  738. u__int64_t prev_rsn;
  739. u__int64_t curr_rsn;
  740. int original_rsn_type;
  741. int rsn_depth;
  742. u__int64_t log_id;
  743. unsigned int log_time;
  744. int log_type, log_severity, log_sys_error, log_usr_error, log_client_id, log_epid;
  745. int rs = iobuffer_get_read_state(pkt);
  746. struct {
  747. struct hlist_head ent;
  748. int ignore_msg_body;
  749. }results[SP_MAX_ENTITY];
  750. for (i = 0; i < SP_MAX_ENTITY; ++i) {
  751. INIT_HLIST_HEAD(&results[i].ent);
  752. results[i].ignore_msg_body = 1;
  753. }
  754. iobuffer_format_read(pkt, "4888444444444", &instance_id, &log_id,
  755. &prev_rsn, &curr_rsn, &original_rsn_type, &rsn_depth,
  756. &log_time, &log_type, &log_client_id, &log_epid,
  757. &log_severity, &log_sys_error, &log_usr_error);
  758. iobuffer_restore_read_state(pkt, rs);
  759. daemon_lock(daemon);
  760. for (j = 0; j < 3; ++j)
  761. {
  762. int t_user_code;
  763. if (j == 0)
  764. {
  765. t_user_code = log_usr_error; // strict match
  766. }
  767. else if (j == 1)
  768. {
  769. t_user_code = -2; // accept any
  770. }
  771. else
  772. {
  773. if (log_usr_error) {
  774. t_user_code = -1; // reject ones that has no user code
  775. } else {
  776. continue;
  777. }
  778. }
  779. for (i = 0; i < daemon->masks_cnt; ++i) {
  780. int t = daemon->masks[i] & 0xffff;
  781. int t_log_type = (t & BIT_MASK(LOG_FILTER_BIT_LOGTYPE)) ? Log_Ignore : log_type;
  782. int t_ent_id = (t & BIT_MASK(LOG_FILTER_BIT_ENTITY)) ? -1 : log_client_id;
  783. int t_severity_filter = (t & BIT_MASK(LOG_FILTER_BIT_SEVERITY)) ? Severity_None : log_severity;
  784. int t_sys_code = (t & BIT_MASK(LOG_FILTER_BIT_SYSCODE)) ? Error_IgnoreAll : log_sys_error;
  785. unsigned int index_hash_code = hash_filter(t_log_type, t_ent_id, t_severity_filter, t_sys_code, t_user_code);
  786. log_listener_t *tpos;
  787. struct hlist_node *pos;
  788. hlist_for_each_entry(tpos, pos, &daemon->arr_filter_index[index_hash_code%FILTER_HASHTABLE_SIZE], log_listener_t, index_hentry) {
  789. if (index_hash_code == tpos->index_key.index_hash_code) {
  790. if (daemon_listener_need_log(daemon, tpos, log_type, log_severity, log_sys_error, log_usr_error, from_client_id))
  791. {
  792. if (tpos->working_hentry.pprev == NULL)
  793. {
  794. hlist_add_head(&tpos->working_hentry, &results[tpos->owner->svc_id].ent);
  795. results[tpos->owner->svc_id].ignore_msg_body &= tpos->ignore_msg_body;
  796. }
  797. }
  798. }
  799. }
  800. }
  801. }
  802. for (i = 0; i < SP_MAX_ENTITY; ++i) {
  803. if (!hlist_empty(&results[i].ent)) {
  804. int ignore_msg_body = results[i].ignore_msg_body;
  805. iobuffer_t *copy_pkt = iobuffer_create(-1, -1);
  806. struct hlist_node *pos, *n;
  807. log_listener_t *tpos;
  808. int cnt = 0;
  809. int epid = -1;
  810. int svc_id = -1;
  811. hlist_for_each_entry(tpos, pos, &results[i].ent, log_listener_t, working_hentry) {
  812. cnt++;
  813. if (epid == -1) {
  814. epid = tpos->owner->epid;
  815. svc_id = tpos->owner->svc_id;
  816. }
  817. }
  818. //iobuffer_write(copy_pkt, IOBUF_T_I4, &cnt, 0);
  819. hlist_for_each_entry_safe(tpos, pos, n, &results[i].ent, log_listener_t, working_hentry) {
  820. iobuffer_write(copy_pkt, IOBUF_T_I4, &tpos->id, 0);
  821. hlist_del(pos);
  822. }
  823. // ����ԭ������
  824. if (results[i].ignore_msg_body) {
  825. int msg_body_len = 0;
  826. int dat_len = get_log_iobuffer_header_length(pkt);
  827. void *dat = iobuffer_data(pkt, 0);
  828. iobuffer_write(copy_pkt, IOBUF_T_BUF, dat, dat_len);
  829. iobuffer_write(copy_pkt, IOBUF_T_7BIT, &msg_body_len, 0);
  830. } else {
  831. void *dat = iobuffer_data(pkt, 0);
  832. int dat_len = iobuffer_get_length(pkt);
  833. iobuffer_write(copy_pkt, IOBUF_T_BUF, dat, dat_len);
  834. }
  835. sp_svc_post(daemon->svc, epid, svc_id, SP_PKT_LOG|LOG_CMD_LISTEN_RECORD, cnt, &copy_pkt);
  836. if (copy_pkt)
  837. iobuffer_dec_ref(copy_pkt);
  838. }
  839. }
  840. daemon_unlock(daemon);
  841. }
  842. static unsigned int __stdcall daemon_work_proc(void *param)
  843. {
  844. sp_log_daemon_t *daemon = (sp_log_daemon_t*)param;
  845. HANDLE hs[] = {daemon->pkt_sem, daemon->stop_evt};
  846. sp_env_t *env = sp_get_env();
  847. for (;;) {
  848. DWORD dwRet = WaitForMultipleObjects(array_size(hs), &hs[0], FALSE, DAEMON_LOG_TIMEOUT_INTERVAL);
  849. if (dwRet == WAIT_OBJECT_0)
  850. {
  851. int pkt_id, svc_id, pkt_type, epid;
  852. iobuffer_t *pkt;
  853. daemon_lock(daemon);
  854. pkt = iobuffer_queue_deque(daemon->pkt_queue);
  855. daemon_unlock(daemon);
  856. iobuffer_read(pkt, IOBUF_T_I4, &epid, 0);
  857. iobuffer_read(pkt, IOBUF_T_I4, &svc_id, 0);
  858. iobuffer_read(pkt, IOBUF_T_I4, &pkt_type, 0);
  859. iobuffer_read(pkt, IOBUF_T_I4, &pkt_id, 0);
  860. if (SP_GET_TYPE(pkt_type) == LOG_CMD_RECORD)
  861. {
  862. int instance_id;
  863. u__int64_t log_id;
  864. u__int64_t prev_rsn;
  865. u__int64_t curr_rsn;
  866. int original_rsn_type;
  867. int rsn_depth;
  868. unsigned int log_time;
  869. int log_type, log_severity, log_sys_error, log_usr_error, log_client_id, log_epid;
  870. char *msg = NULL;
  871. int param_cnt;
  872. int *params = NULL;
  873. int i;
  874. iobuffer_read(pkt, IOBUF_T_I4, &instance_id, NULL);
  875. iobuffer_read(pkt, IOBUF_T_I8, &log_id, NULL);
  876. daemon->last_log_id = log_id = sp_uid_update(daemon->last_log_id);
  877. log_id = sp_uid_change_app_id(log_id, sp_cfg_get_devel_id(env->cfg, svc_id));
  878. iobuffer_write_head(pkt, IOBUF_T_I8, &log_id, 0);
  879. iobuffer_write_head(pkt, IOBUF_T_I4, &instance_id, 0);
  880. if (svc_id != SP_INVALID_SVC_ID)
  881. daemon_bcast(daemon, svc_id, pkt);
  882. iobuffer_read(pkt, IOBUF_T_I4, &instance_id, NULL);
  883. iobuffer_read(pkt, IOBUF_T_I8, &log_id, NULL);
  884. iobuffer_read(pkt, IOBUF_T_I8, &prev_rsn, NULL);
  885. iobuffer_read(pkt, IOBUF_T_I8, &curr_rsn, NULL);
  886. iobuffer_read(pkt, IOBUF_T_I4, &original_rsn_type, NULL);
  887. iobuffer_read(pkt, IOBUF_T_I4, &rsn_depth, NULL);
  888. iobuffer_read(pkt, IOBUF_T_I4, &log_time, NULL);
  889. iobuffer_read(pkt, IOBUF_T_I4, &log_type, NULL);
  890. iobuffer_read(pkt, IOBUF_T_I4, &log_client_id, NULL);
  891. iobuffer_read(pkt, IOBUF_T_I4, &log_epid, NULL);
  892. iobuffer_read(pkt, IOBUF_T_I4, &log_severity, NULL);
  893. iobuffer_read(pkt, IOBUF_T_I4, &log_sys_error, NULL);
  894. iobuffer_read(pkt, IOBUF_T_I4, &log_usr_error, NULL);
  895. // GPIO�ƶ��¼���д��־
  896. if (log_usr_error != 0x2090000A && log_usr_error != 0x20900009)
  897. {
  898. iobuffer_read(pkt, IOBUF_T_I4, &param_cnt, NULL);
  899. if (param_cnt) {
  900. params = (int*)malloc(sizeof(int)*param_cnt);
  901. for (i = 0; i < param_cnt; ++i) {
  902. iobuffer_read(pkt, IOBUF_T_I4, &params[i], NULL);
  903. }
  904. }
  905. iobuffer_format_read(pkt, "s", &msg);
  906. daemon->on_log(daemon, 0, 0, log_client_id, log_epid, instance_id,
  907. log_id, prev_rsn, curr_rsn, original_rsn_type, rsn_depth,
  908. log_time, log_type, log_severity, log_sys_error,
  909. log_usr_error, param_cnt, params, msg, daemon->user_data);
  910. toolkit_free(msg);
  911. free(params);
  912. }
  913. }
  914. else if (SP_GET_TYPE(pkt_type) == LOG_CMD_FLUSH)
  915. {
  916. SYSTEMTIME st;
  917. GetLocalTime(&st);
  918. daemon->on_flush(daemon, pkt_id, &st, daemon->user_data);
  919. }
  920. else
  921. {
  922. assert(0);
  923. }
  924. iobuffer_dec_ref(pkt);
  925. }
  926. else if (dwRet == WAIT_OBJECT_0+1) {
  927. break; // stop
  928. }
  929. else if (dwRet == WAIT_TIMEOUT) {
  930. SYSTEMTIME st;
  931. GetLocalTime(&st);
  932. daemon->on_timeout_interval(daemon, &st, daemon->user_data);
  933. }
  934. }
  935. return 0;
  936. }
  937. int sp_log_daemon_create(sp_log_on_log on_log,
  938. sp_log_on_flush on_flush,
  939. sp_log_on_timeout_interval on_timeout_interval,
  940. void *user_data,
  941. sp_svc_t *svc,
  942. sp_log_daemon_t **p_daemon)
  943. {
  944. sp_log_daemon_t *daemon = ZALLOC_T(sp_log_daemon_t);
  945. sp_env_t *env = sp_get_env();
  946. int i;
  947. daemon->on_log = on_log;
  948. daemon->on_flush = on_flush;
  949. daemon->on_timeout_interval = on_timeout_interval;
  950. daemon->user_data = user_data;
  951. daemon->svc = svc;
  952. daemon->pkt_queue = iobuffer_queue_create();
  953. daemon->arr_entity = array_make(0, sizeof(log_listener_entity_t*));
  954. InitializeCriticalSection(&daemon->lock);
  955. daemon->stop_evt = CreateEventA(NULL, TRUE, FALSE, NULL);
  956. daemon->pkt_sem = CreateSemaphoreA(NULL, 0, 0x7fffffff, NULL);
  957. daemon->last_log_id = sp_uid_make(0);
  958. daemon->masks_cnt = 0;
  959. for (i = 0; i < FILTER_HASHTABLE_SIZE; ++i) {
  960. INIT_HLIST_HEAD(&daemon->arr_filter_index[i]);
  961. }
  962. daemon->worker_thread = (HANDLE)_beginthreadex(NULL, 0, &daemon_work_proc, daemon, 0, NULL);
  963. if (!daemon->worker_thread) {
  964. sp_log_daemon_destroy(daemon);
  965. return Error_Resource;
  966. }
  967. sp_svc_add_pkt_handler(svc, (int)daemon, SP_PKT_LOG, &daemon_on_pkt, daemon);
  968. sp_svc_add_sys_handler(svc, (int)daemon, &daemon_on_sys, daemon);
  969. *p_daemon = daemon;
  970. return 0;
  971. }
  972. int sp_log_daemon_destroy(sp_log_daemon_t *daemon)
  973. {
  974. int i;
  975. if (daemon->worker_thread) {
  976. sp_svc_remove_pkt_handler(daemon->svc, (int)daemon, SP_PKT_LOG);
  977. sp_svc_remove_sys_handler(daemon->svc, (int)daemon);
  978. SetEvent(daemon->stop_evt);
  979. WaitForSingleObject(daemon->worker_thread, INFINITE);
  980. CloseHandle(daemon->worker_thread);
  981. }
  982. CloseHandle(daemon->stop_evt);
  983. for (i = 0; i < daemon->arr_entity->nelts; ++i) {
  984. log_listener_entity_t *tmp = ARRAY_IDX(daemon->arr_entity, i, log_listener_entity_t*);
  985. log_listener_t *pos, *n;
  986. list_for_each_entry_safe(pos, n, &tmp->listener_list, log_listener_t, entry) {
  987. list_del(&pos->entry);
  988. free(pos);
  989. }
  990. free(tmp);
  991. }
  992. array_free(daemon->arr_entity);
  993. if (daemon->pkt_sem) {
  994. CloseHandle(daemon->pkt_sem);
  995. }
  996. iobuffer_queue_destroy(daemon->pkt_queue);
  997. DeleteCriticalSection(&daemon->lock);
  998. free(daemon);
  999. return 0;
  1000. }