Chinaunix首页 | 论坛 | 博客
  • 博客访问: 939674
  • 博文数量: 116
  • 博客积分: 3923
  • 博客等级: 中校
  • 技术积分: 1337
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-23 01:22
文章分类

全部博文(116)

文章存档

2013年(1)

2012年(17)

2011年(69)

2009年(29)

分类: WINDOWS

2011-09-18 19:00:52

http://vincent.blog.chinaunix.net

这两天终于把debugx写完,主要是针对windows平台,还没有porting到linux平台,下一步就是porting到linux,不过还有一些还完善的,如何信号发消息时还有个MOD_POOL_FIX的分支还没实现,或者到时可能把自己以前写的xmalloc和xfree用上,不用系统的那个,这样可能更适合自己,不过主要任务还是得同时支持linux的gcc编译器,之前没任何linux的C开发经验,对我来说又是一个很好的锻炼机会,爽~~~

file: debugx.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #ifndef _DEBUGX_H_
  7. #define _DEBUGX_H_

  8. #include <stdio.h>
  9. #include <stdarg.h>


  10. #define REPORTE out2file

  11. #define MAX_OUTPUT 100

  12. /* where to output */
  13. #define out2screen 1
  14. #define out2file 2

  15. #if defined(WIN32)&&(_MSC_VER < 1300) /* if lower or equal to VC6 under win32 */
  16. #    define __func__ "?"
  17. #    if REPORTE!=out2screen && REPORTE!=out2file
  18.         void outputx(const char* fmt,...){}
  19. #    else
  20.         extern void outputx(const char* fmt,...);     
  21. #    endif
  22. #else
  23. #    define __func__ __FUNCTION__
  24. #    if REPORTE!=out2screen && REPORTE!=out2file
  25. #        define outputx(fmt,...)
  26. #    else
  27.         extern void outputx(const char* fmt,...);
  28. #    endif
  29. #endif


  30. #define __bit(x) ((unsigned)1<<(x))

  31. /** generic data dump */
  32. #define xinfo        __bit(0)
  33. #define xdata        __bit(1)
  34. /** function invoke */
  35. #define xentry        __bit(2)
  36. /** interruption signal */
  37. #define xevent        __bit(3)
  38. #define xmsg        __bit(4)
  39. /** warning level */
  40. #define xwarn        __bit(5)
  41. #define xerror        __bit(6)
  42. #define xfatal        __bit(7)

  43. /** debug level */
  44. #define debugx_level0    (0)
  45. #define debugx_level1    (xinfo|xdata|xentry)
  46. #define debugx_level2    (xevent|xmsg)
  47. #define debugx_level3    (xwarn|xerror|xfatal)
  48. #define debugx_level4    (debugx_level1|debugx_level2|debugx_level3)

  49. extern unsigned int dbx;

  50. #define DBX(x)    "debug(" #x ",%s,%d): "

  51. #define INFO __func__, __LINE__ /** function name and line information */

  52. #if defined(WIN32)&&(_MSC_VER < 1300) /* if lower or equal to VC6 under win32 */
  53.     extern void debugx(unsigned int level,const char* fmt,...);
  54. #else
  55. #    define debugx_xinfo(fmt,...) do {if (dbx & xinfo) outputx(DBX(info) fmt, INFO, __VA_ARGS__);} while(0)
  56. #    define debugx_xdata(fmt,...) do {if (dbx & xdata) outputx(DBX(data) fmt, INFO, __VA_ARGS__);} while(0)
  57. #    define debugx_xentry(fmt,...) do {if (dbx & xentry) outputx(DBX(entry) fmt,INFO, __VA_ARGS__);} while(0)
  58. #    define debugx_xevent(fmt,...) do {if (dbx & xevent) outputx(DBX(event) fmt,INFO, __VA_ARGS__);} while(0)
  59. #    define debugx_xmsg(fmt,...) do {if (dbx & xmsg) outputx(DBX(msg) fmt, INFO, __VA_ARGS__);} while(0)
  60. #    define debugx_xwarn(fmt,...) do {if (dbx & xwarn) outputx(DBX(warn) fmt,INFO, __VA_ARGS__);} while(0)
  61. #    define debugx_xerror(fmt,...) do {if (dbx & xerror) outputx(DBX(error) fmt,INFO, __VA_ARGS__);} while(0)
  62. #    define debugx_xfatal(fmt,...) do {if (dbx & xfatal) outputx(DBX(fatal) fmt,INFO, __VA_ARGS__);} while(0)
  63. #    define debugx(level,fmt,...) debugx_##level(fmt, __VA_ARGS__)
  64. #endif



  65. #endif

file: debugx.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #include "debugx.h"

  7. unsigned int dbx = debugx_level4;

  8. #ifdef    WIN32
  9. #    define vsnprintf    _vsnprintf
  10. #endif

  11. /** you should define your output2file by yourself */
  12. extern int output2file(const char* pszbuf);

  13. /** */
  14. #if REPORTE==out2screen
  15. #    define xprintf printf
  16. #else
  17. #    define xprintf output2file
  18. #endif

  19. #if REPORTE==out2screen || REPORTE==out2file
  20. void outputx(const char* fmt,...)
  21. {
  22.     int ret;
  23.     char buf[MAX_OUTPUT]="";
  24.     va_list args;
  25.     va_start(args, fmt);    
  26.     ret = vsnprintf(buf, sizeof(buf), fmt, args);
  27.     if(ret<0) buf[MAX_OUTPUT-1]=0; /** output has been truncated */
  28.     xprintf(buf);
  29.     va_end(args);
  30. }
  31. #endif

  32. #if defined(WIN32)&&(_MSC_VER < 1300) /* if lower or equal to VC6 under win32 */

  33. #define OUTPUT_MSG(lv) \
  34. {\
  35.     int ret;\
  36.     char buf[MAX_OUTPUT]="";\
  37.     va_list args;\
  38.     va_start(args, fmt);\
  39.     ret = vsnprintf(buf, sizeof(buf), fmt, args);\
  40.     if(ret<0) buf[MAX_OUTPUT-1]=0;\
  41.     xprintf(buf);\
  42.     va_end(args);\
  43. }

  44. void debugx(unsigned int level,const char* fmt,...)
  45. {
  46.     switch (level)
  47.     {
  48.     case xinfo: if (dbx & xinfo) OUTPUT_MSG(info) break;
  49.     case xdata: if (dbx & xdata) OUTPUT_MSG(data) break;
  50.     case xentry: if (dbx & xentry) OUTPUT_MSG(entry) break;
  51.     case xevent: if (dbx & xevent) OUTPUT_MSG(event) break;
  52.     case xmsg: if (dbx & xmsg) OUTPUT_MSG(msg) break;
  53.     case xwarn: if (dbx & xwarn) OUTPUT_MSG(warn) break;
  54.     case xerror: if (dbx & xerror) OUTPUT_MSG(error) break;
  55.     case xfatal: if (dbx & xfatal) OUTPUT_MSG(fatal) break;
  56.     default: return;
  57.     }
  58. }
  59. #endif

file: logx.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #ifndef _LOGX_H_
  7. #define _LOGX_H_

  8. #include <stdio.h>

  9. #define LOG_MOD    LOG_MUL_THREAD

  10. #define LOG_MUL_THREAD 1
  11. #define LOG_SIG_THREAD 2

  12. #ifndef __assert
  13. #define __assert(x)
  14. #endif

  15. #include "signalx.h"

  16. typedef struct logx_s{
  17.     
  18.     int (*writex)(struct logx_s *this, const char* pbuf, size_t sz);
  19.     int (*openx)(struct logx_s *this, const char* psz_path);
  20.     int (*clo***)(struct logx_s *this);
  21.     int (*initx)(struct logx_s *this, int mode);
  22.     int (*exitx)(struct logx_s *this);    
  23.     
  24.     int mode;
  25.     FILE *fh;
  26.     signalx_t signalx;
  27. }logx_t;

  28. extern void logx_init(const char* psz_path, int mode);
  29. extern void logx_exit();

  30. extern void logx_post(const char* pszbuf);    
  31. extern void logx_postx(const char* pbuf, size_t sz);


  32. #endif

file: logx.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #include "logx.h"

  7. #ifndef null
  8. #define null NULL
  9. #endif

  10. static logx_t s_logx={0,0,0,0,0};

  11. extern void logx_do_signalx(const char* pbuf, size_t sz);

  12. static int __writex(struct logx_s *this, const char* pbuf, size_t sz)
  13. {
  14.     size_t cnts=0;
  15.     __assert(this!=null&&pbuf!=null&&sz>0);
  16.     if (this->fh) {
  17.         /* cnts = fprintf(this->fh, "%s", pbuf);*/
  18.         cnts = fwrite(pbuf,sizeof(pbuf[0]),sz,this->fh);
  19.         __assert(cnts==sz);
  20.         fflush(this->fh);
  21.     }
  22.     return 0;
  23. }

  24. static int __openx(struct logx_s *this, const char* psz_path)
  25. {
  26.     __assert(this!=null && psz_path!=null);

  27.     if (null == (this->fh = fopen(psz_path, "w+")))
  28.         return -1;
  29.     
  30.     return 0;
  31. }

  32. static int __clo***(struct logx_s *this)
  33. {
  34.     __assert(this!=null);
  35.     if(this->fh){
  36.         fclose(this->fh);
  37.         this->fh=0;
  38.     }
  39.     return 0;
  40. }

  41. static int __initx(struct logx_s *this, int mode)
  42. {
  43.     __assert(this!=null);
  44.     
  45.     if (mode==LOG_MUL_THREAD){
  46.         this->mode = mode;
  47.         signalx_init(&this->signalx, logx_do_signalx);         
  48.     }
  49.     return 0;
  50. }

  51. static int __exitx(struct logx_s *this)
  52. {
  53.     __assert(this!=null);
  54.     
  55.     if (this->mode==LOG_MUL_THREAD)
  56.         signalx_exit(&this->signalx);
  57.     return 0;
  58. }


  59. void logx_do_signalx(const char* pbuf, size_t sz)
  60. {
  61.     __assert(pbuf!=null&&sz>0);
  62.     if (s_logx.writex)
  63.         s_logx.writex(&s_logx, pbuf, sz);
  64. }


  65. void logx_init(const char* psz_path, int mode)
  66. {

  67.     __assert(psz_path!=null);
  68.     *(s_logx.writex) = __writex;
  69.     *(s_logx.openx) = __openx;
  70.     *(s_logx.clo***) = __clo***;
  71.     *(s_logx.initx) = __initx;
  72.     *(s_logx.exitx) = __exitx;
  73.     
  74.     s_logx.initx(&s_logx, mode);
  75.     s_logx.openx(&s_logx, psz_path);

  76. }

  77. void logx_exit()
  78. {
  79.     s_logx.clo***(&s_logx);
  80.     s_logx.exitx(&s_logx);
  81. }

  82. void logx_post(const char* pszbuf)
  83. {
  84.     __assert(pszbuf!=null);
  85.     if (s_logx.mode==LOG_MUL_THREAD)
  86.         signalx_post(s_logx.signalx,pszbuf);
  87.     else
  88.         s_logx.writex(&s_logx, pszbuf, strlen(pszbuf)+1);
  89. }
  90. void logx_postx(const char* pbuf, size_t sz)
  91. {
  92.     __assert(pbuf!=null&&sz>0);
  93.     
  94.     if (s_logx.mode==LOG_MUL_THREAD)
  95.         signalx_postx(s_logx.signalx,pbuf,sz);
  96.     else
  97.         s_logx.writex(&s_logx, pbuf, sz);
  98. }


  99. /** following part is only for debugx redirect the output to log file */
  100. #include "debugx.h"

  101. #if REPORTE==out2file
  102. int output2file(const char* pszbuf)
  103. {
  104.     logx_post(pszbuf);
  105.     return 0;
  106. }
  107. #endif

file: signalx.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #ifndef _SIGNALX_H_
  7. #define _SIGNALX_H_

  8. #include <stdio.h>


  9. #ifdef WIN32
  10. #    include "windows.h"
  11. #endif


  12. #ifndef MAX_PATH
  13. #define MAX_PATH 260
  14. #endif

  15. #ifndef MAX_POOL
  16. #define MAX_POOL 100
  17. #endif

  18. #define MOD_POOL_FIX 1
  19. #define MOD_POOL_DYN 2

  20. #define POOL_ITEM_LEN    100

  21. #define MOD_POOL MOD_POOL_DYN

  22. #ifndef __xmalloc
  23. #define __xmalloc malloc
  24. #endif

  25. #ifndef __xfree
  26. #define __xfree    free
  27. #endif

  28. #ifndef __assert
  29. #define __assert(x)
  30. #endif


  31. extern struct signalx_s;

  32. typedef void (*f_signalx_t)(const char* pbuf, size_t sz);

  33. typedef struct signalx_s{

  34.     void (*do_signalx)(const char* pbuf, size_t sz);

  35. #if MOD_POOL==MOD_POOL_FIX
  36.     char pool[MAX_POOL][POOL_ITEM_LEN];
  37. #elif MOD_POOL==MOD_POOL_DYN
  38.     char* pool[MAX_POOL];
  39. #endif
  40.     unsigned int index1; /* index 1 for the circular pool */
  41.     unsigned int index2; /* index 2 for the circular pool */
  42.     HANDLE hthread;    /* server thread for logging out */
  43.     HANDLE hevent_post; /* server thread will be hold except post event occur */
  44.     HANDLE hevent_exit; /* notify the server thread exit normally */
  45.     CRITICAL_SECTION cslock;

  46.     void (*post_msgx)(struct signalx_s *this, const char* fmt, ...);
  47.     void (*post_msg)(struct signalx_s *this, const char* pbuf, size_t sz);
  48.     int (*serv_init)(struct signalx_s *this, f_signalx_t pf_signalx);
  49.     int (*serv_exit)(struct signalx_s *this);
  50.     int (*serv_start)(struct signalx_s *this);
  51.     int (*serv_stop)(struct signalx_s *this);
  52.     
  53. }signalx_t;


  54. extern int signalx_init(signalx_t *psignalx, f_signalx_t pf_signalx);
  55. extern int signalx_exit(signalx_t *psignalx);

  56. #define signalx_post(signalx,pszbuf) ((signalx).post_msg(&(signalx),(pszbuf),strlen(pszbuf)+1))
  57. #define signalx_postx(signalx,pbuf,sz) ((signalx).post_msg(&(signalx),(pbuf),(sz)))




  58. #endif

file: signalx.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #include "signalx.h"

  7. #ifndef hnull
  8. #define hnull INVALID_HANDLE_VALUE
  9. #endif

  10. #ifndef null
  11. #define null NULL
  12. #endif

  13. #define __lockx() EnterCriticalSection(&this->cslock)
  14. #define __unlockx()    LeaveCriticalSection(&this->cslock)
  15. #define __lockx_init() InitializeCriticalSection(&this->cslock)
  16. #define __lockx_exit() DeleteCriticalSection(&this->cslock);

  17. DWORD WINAPI __thread_do_signalx(LPVOID lpThreadParameter)
  18. {
  19.     char *ptmp = NULL;
  20.     
  21.     signalx_t *this = (signalx_t*)lpThreadParameter;
  22.     __assert(this!=null);

  23.     while (1)
  24.     {
  25.         if (WaitForSingleObject((HANDLE)(this->hevent_post), INFINITE) == WAIT_OBJECT_0)
  26.         {
  27.             for (;;) /* write out the buffer */
  28.             {
  29.                 __lockx();
  30.                 
  31.                 ptmp = null;
  32.             
  33.                 /* get buffer pointer out of m_tcDataPool[] */
  34.                 if (MAX_POOL == this->index1)
  35.                     this->index1 = 0;
  36.                 if (NULL != this->pool[this->index1]) {
  37.                     ptmp = this->pool[this->index1];
  38.                     this->pool[this->index1] = null;
  39.                     this->index1++;
  40.                 }

  41.                 __unlockx();
  42.                 
  43.                 /* do signal */
  44.                 if (null != ptmp && null != this->do_signalx) {        
  45.                     this->do_signalx(ptmp, strlen(ptmp)+1);
  46.                     __xfree(ptmp);
  47.                 } else {
  48.                     if (hnull != this->hevent_post)
  49.                         ResetEvent(this->hevent_post);
  50.                     break;
  51.                 }        
  52.             } /* for(;;) */
  53.         }
  54.         if (WaitForSingleObject(this->hevent_exit, 0) == WAIT_OBJECT_0)
  55.             break;
  56.     } /* while(1) */
  57.     return 0;
  58. }

  59. static void __post_msgx(struct signalx_s *this, const char* fmt, ...)
  60. {
  61.     
  62. }

  63. static void __post_msg(struct signalx_s *this, const char* pbuf, size_t sz)
  64. {
  65.     char *pnew_buf=null;

  66.     __assert(this!=null&&pbuf!=null);

  67.     if (hnull==this->hthread) return;

  68.     pnew_buf = (char*)__xmalloc(sz * sizeof(char));
  69.     
  70.     if (pnew_buf) {
  71.         memcpy(pnew_buf, pbuf, sz);
  72.         
  73.         __lockx();
  74.         
  75.         /* put buffer pointer into pool[MAX_POOL] */
  76.         if (MAX_POOL == this->index2)
  77.             this->index2 = 0;
  78.         /* case: index2 == index1, so abandon the new data */
  79.         if (null == this->pool[this->index2])
  80.             this->pool[this->index2++] = pnew_buf;
  81.         else {
  82.             /* do NOT forget to free the new data when the pool was overflow */
  83.             __xfree (pnew_buf);
  84.             pnew_buf=null;
  85.         }
  86.         if (hnull != this->hevent_post)
  87.             SetEvent(this->hevent_post);
  88.         
  89.         __unlockx();    
  90.     }
  91. }

  92. static int __serv_init(struct signalx_s *this, f_signalx_t pf_signalx)
  93. {
  94.     __assert(this!=null && pf_signalx!=null);

  95.     this->hthread = hnull;
  96.     this->hevent_post = hnull;
  97.     this->hevent_exit = hnull;
  98.     this->index1 = 0;
  99.     this->index2 = 0;
  100.     /* NOTE: must initialize pool, else assert _CrtIsValidHeapPointer(pUserData) occur */
  101.     memset(this->pool, 0, sizeof(this->pool));

  102.     this->do_signalx = pf_signalx; /* register user custom signal function */

  103.     __lockx_init();
  104.     
  105.     this->hevent_post = CreateEvent(NULL, TRUE, FALSE, NULL);
  106.     this->hevent_exit = CreateEvent(NULL, TRUE, FALSE, NULL);
  107.     return 0;
  108. }

  109. static int __serv_exit(struct signalx_s *this)
  110. {
  111.     __assert(this!=null);
  112.     if (hnull != this->hevent_exit) SetEvent(this->hevent_exit);
  113.     if (hnull != this->hevent_post) SetEvent(this->hevent_post);
  114.     /* wait the thread exit */
  115.     if (hnull != this->hthread){
  116.         /* terminal the log server thread until 1 second over */
  117.         unsigned long state = WaitForSingleObject (this->hthread, 1000);
  118.         switch (state)
  119.         {
  120.             case WAIT_TIMEOUT:
  121.             {
  122.                 unsigned long exit_code = 0;
  123.                 if (0 != TerminateThread(this->hthread, exit_code))
  124.                     ; /* terminate the server thread */
  125.                 else
  126.                     ; /* terminate the LogSrv thread failed */
  127.                 break;
  128.             }
  129.             case WAIT_ABANDONED: break; /* the Thread abandoned */
  130.             case WAIT_OBJECT_0: break; /* exit the server thread */
  131.             default: break;
  132.         }
  133.         __lockx_exit();
  134.         CloseHandle(this->hthread);
  135.         this->hthread=hnull;
  136.     }
  137.     if (hnull != this->hevent_exit) CloseHandle(this->hevent_exit);
  138.     if (hnull != this->hevent_post) CloseHandle(this->hevent_post);
  139.     return 0;
  140. }

  141. static int __serv_start(struct signalx_s *this)
  142. {
  143.     unsigned long thread_id;
  144.     __assert(this!=null);
  145.     if (hnull == this->hthread) {
  146.         this->hthread = CreateThread(
  147.             NULL, /* default security attributes */
  148.             0, /* use default stack size */
  149.             __thread_do_signalx, /* thread function */
  150.             (LPVOID)this, /* argument to thread function */
  151.             0, /* use default creation flags */
  152.             &thread_id); /* returns the thread identifier */
  153.     }
  154.     return 0;
  155. }

  156. static int __serv_stop(signalx_t *this)
  157. {
  158.     return 0;
  159. }


  160. int signalx_init(signalx_t *this, f_signalx_t pf_signalx)
  161. {
  162.     __assert(this!=null&&pf_signalx!=null);

  163.     *(this->post_msgx) = __post_msgx;
  164.     *(this->post_msg) = __post_msg;
  165.     *(this->serv_init) = __serv_init;
  166.     *(this->serv_exit) = __serv_exit;
  167.     *(this->serv_start) = __serv_start;
  168.     *(this->serv_stop) = __serv_stop;

  169.     this->serv_init(this, pf_signalx);

  170.     this->serv_start(this);
  171.     return 0;
  172. }

  173. int signalx_exit(signalx_t *this)
  174. {
  175.     __assert(this!=null);
  176.     this->serv_exit(this);
  177.     return 0;
  178. }

file: thread_mgmt.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #ifndef _THREAD_MGMT_H_
  7. #define _THREAD_MGMT_H_

  8. #ifdef WIN32
  9. #    include "windows.h"
  10. #endif

  11. #ifndef __assert
  12. #define __assert(x)
  13. #endif

  14. #ifndef MAX_NAME
  15. #define MAX_NAME 100
  16. #endif

  17. #ifndef MAX_THREAD
  18. #define MAX_THREAD 10
  19. #endif

  20. typedef DWORD (WINAPI *f_thread_t)(LPVOID lpThreadParameter);

  21. typedef struct thread_info_s{
  22.     unsigned long id;    
  23.     char name[MAX_NAME];
  24.     HANDLE h;
  25.     f_thread_t f_thread;
  26. }thread_info_t;

  27. typedef struct thread_mgmt_s{
  28.     thread_info_t thread_info[MAX_THREAD];
  29.     int (*init)(struct thread_mgmt_s *this);    
  30.     int (*exit)(struct thread_mgmt_s *this);
  31.     int (*create_thread)(struct thread_mgmt_s *this, const char* psz_name, f_thread_t f_thread);
  32.     int (*delete_thread)(struct thread_mgmt_s *this, const char* psz_name);
  33. }thread_mgmt_t;

  34. void tm_init(thread_mgmt_t *ptm);

  35. void tm_exit(thread_mgmt_t *ptm);

  36. #define tm_create_thread(tm,nm,ft) ((tm).create_thread(&(tm),(nm),(ft)))
  37. #define tm_delete_thread(tm,nm)    ((tm).delete_thread(&(tm),(nm)))

  38. #endif


file: thread_mgmt.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #include "thread_mgmt.h"

  7. #ifndef hnull
  8. #define hnull INVALID_HANDLE_VALUE
  9. #endif

  10. #ifndef null
  11. #define null NULL
  12. #endif

  13. static int __init(struct thread_mgmt_s *this)
  14. {
  15.     int i = 0;

  16.     __assert(this!=null)
  17.     
  18.     for (;i<MAX_THREAD;i++)
  19.     {
  20.         this->thread_info[i].id = 0;
  21.         this->thread_info[i].h = hnull;
  22.         this->thread_info[i].f_thread=null;
  23.         this->thread_info[i].name[0]=0;
  24.     }
  25.     return 0;
  26. }
  27. static int __exit(struct thread_mgmt_s *this)
  28. {
  29.     int i = 0;
  30.     
  31.     __assert(this!=null);
  32.     
  33.     for (;i<MAX_THREAD;i++)
  34.     {
  35.         if(this->thread_info[i].h != hnull) {
  36.             /* terminal the log server thread until 1 second over */
  37.             unsigned long state = WaitForSingleObject (this->thread_info[i].h, 100);
  38.             switch (state)
  39.             {
  40.             case WAIT_TIMEOUT:
  41.                 {
  42.                     unsigned long exit_code = 0;
  43.                     if (0 != TerminateThread(this->thread_info[i].h, exit_code))
  44.                         ; /* terminate the server thread */
  45.                     else
  46.                         ; /* terminate the LogSrv thread failed */
  47.                     break;
  48.                 }
  49.             case WAIT_ABANDONED: break; /* the Thread abandoned */
  50.             case WAIT_OBJECT_0: break; /* exit the server thread */
  51.             default: break;
  52.             }
  53.             this->thread_info[i].h = hnull;
  54.             this->thread_info[i].name[0]=0;
  55.             this->thread_info[i].id=0;
  56.             this->thread_info[i].f_thread=0;
  57.         }
  58.         else if (this->thread_info[i].h == hnull) {
  59.             this->thread_info[i].h = hnull;
  60.             this->thread_info[i].name[0]=0;
  61.             this->thread_info[i].id=0;
  62.             this->thread_info[i].f_thread=0;
  63.         }
  64.     }
  65.     return 0;
  66. }
  67. static int __create_thread(struct thread_mgmt_s *this, const char* psz_name, f_thread_t f_thread)
  68. {
  69.     int i=0, len=0;

  70.     __assert(this!=null && psz_name!=null && f_thread!=null);

  71.     for (;i<MAX_THREAD;i++)
  72.     {
  73.         if(this->thread_info[i].h==hnull || this->thread_info[i].f_thread==null)
  74.             break;
  75.     }
  76.     if(i==MAX_THREAD) return -1;

  77.     this->thread_info[i].h = CreateThread(
  78.         null, // default security attributes
  79.         0, // use default stack size
  80.         f_thread,        // thread function
  81.         0, // argument to thread function
  82.         0, // use default creation flags
  83.         &(this->thread_info[i].id)); // returns the thread identifier

  84.     len=strlen(psz_name)+1;
  85.     if (MAX_NAME < len) {
  86.         memcpy(this->thread_info[i].name, psz_name, MAX_NAME-1);
  87.         this->thread_info[i].name[MAX_NAME-1]=0;
  88.     }
  89.     else
  90.         memcpy(this->thread_info[i].name, psz_name, len);
  91.     
  92.     this->thread_info[i].f_thread = f_thread;

  93.     return 0;
  94. }
  95. static int __delete_thread(struct thread_mgmt_s *this, const char* psz_name)
  96. {
  97.     int i = 0;

  98.     __assert(this!=null && psz_name!=null);

  99.     for (;i<MAX_THREAD;i++)
  100.     {
  101.         if(strcmp(this->thread_info[i].name, psz_name)==0
  102.             && this->thread_info[i].h != hnull)
  103.         {
  104.             /* terminal the log server thread until 1 second over */
  105.             unsigned long state = WaitForSingleObject (this->thread_info[i].h, 100);
  106.             switch (state)
  107.             {
  108.                 case WAIT_TIMEOUT:
  109.                 {
  110.                     unsigned long exit_code = 0;
  111.                     if (0 != TerminateThread(this->thread_info[i].h, exit_code))
  112.                         ; /* terminate the server thread */
  113.                     else
  114.                         ; /* terminate the LogSrv thread failed */
  115.                     break;
  116.                 }
  117.                 case WAIT_ABANDONED: break; /* the Thread abandoned */
  118.                 case WAIT_OBJECT_0: break; /* exit the server thread */
  119.                 default: break;
  120.             }
  121.             this->thread_info[i].h = hnull;
  122.             this->thread_info[i].name[0]=0;
  123.             this->thread_info[i].id=0;
  124.             this->thread_info[i].f_thread=0;
  125.         }
  126.         else if (this->thread_info[i].h == hnull)
  127.         {
  128.             this->thread_info[i].h = hnull;
  129.             this->thread_info[i].name[0]=0;
  130.             this->thread_info[i].id=0;
  131.             this->thread_info[i].f_thread=0;
  132.         }
  133.     }
  134.     return 0;
  135. }

  136. void tm_init(thread_mgmt_t *ptm)
  137. {
  138.     __assert(ptm!=null);

  139.     *(ptm->init) = __init;
  140.     *(ptm->exit) = __exit;
  141.     *(ptm->create_thread) = __create_thread;
  142.     *(ptm->delete_thread) = __delete_thread;

  143.     ptm->init(ptm);
  144. }

  145. void tm_exit(thread_mgmt_t *ptm)
  146. {
  147.     __assert(ptm!=null);

  148.     ptm->exit(ptm);
  149. }

file: main.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  */

  6. #include "debugx.h"

  7. #include "logx.h"

  8. #include "thread_mgmt.h"

  9. DWORD WINAPI f_thread1(LPVOID lpThreadParameter)
  10. {
  11.     DWORD id = GetCurrentThreadId();
  12.     while (1)
  13.     {
  14.         debugx(xinfo, "thread id(%d): this is %s!\n", id, "xinfo");
  15.         Sleep(10);
  16.     }
  17.     return 0;
  18. }

  19. DWORD WINAPI f_thread2(LPVOID lpThreadParameter)
  20. {
  21.     DWORD id = GetCurrentThreadId();
  22.     while (1)
  23.     {
  24.         debugx(xevent, "thread id(%d): this is %s!\n", id, "xevent");
  25.         Sleep(10);
  26.     }
  27.     return 0;
  28. }

  29. DWORD WINAPI f_thread3(LPVOID lpThreadParameter)
  30. {
  31.     DWORD id = GetCurrentThreadId();
  32.     while (1)
  33.     {
  34.         debugx(xerror, "thread id(%d): this is %s!\n", id, "xerror");
  35.         Sleep(10);
  36.     }
  37.     return 0;
  38. }


  39. int main(int argc, char* argv[])
  40. {    
  41.     int i = 1000;
  42.     DWORD id = 0;

  43. #if LOG_MOD==LOG_MUL_THREAD
  44.     thread_mgmt_t tm;
  45.     logx_init("D:/abc.txt", LOG_MUL_THREAD);
  46.     tm_init(&tm);
  47.     tm_create_thread(tm,"t1",f_thread1);
  48.     tm_create_thread(tm,"t2",f_thread2);
  49.     tm_create_thread(tm,"t3",f_thread3);
  50. #else
  51.     logx_init("D:/abc.txt", LOG_SIG_THREAD);
  52. #endif

  53.     debugx(xinfo, "this is %s!\n", "xinfo");
  54.     debugx(xdata, "this is %s!\n", "xdata");
  55.     debugx(xentry, "this is %s!\n", "xentry");
  56.     debugx(xevent, "this is %s!\n", "xevent");
  57.     debugx(xmsg, "this is %s!\n", "xmsg");
  58.     debugx(xwarn, "this is %s!\n", "xwarn");
  59.     debugx(xerror, "this is %s!\n", "xerror");
  60.     debugx(xfatal, "this is %s!\n", "xfatal");
  61.     debugx(xerror, "this is %s!\n", "xerror");

  62.     id = GetCurrentThreadId();
  63.     while (i--)
  64.     {
  65.         debugx(xfatal, "thread id(%d): this is %s!\n", id, "xfatal");
  66.         //logx_post("hello world!\n");
  67.         Sleep(10);
  68.     }

  69. #if LOG_MOD==LOG_MUL_THREAD    
  70.     tm_exit(&tm);
  71. #endif

  72.     logx_exit();

  73. //    Sleep(3000);
  74.     
  75.     return 0;
  76. }


附件:

 debugx_vc6_vs2005.rar  
阅读(1615) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~