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

全部博文(116)

文章存档

2013年(1)

2012年(17)

2011年(69)

2009年(29)

分类: LINUX

2011-09-20 13:59:17

http://vincent.blog.chinaunix.net

今天终于把linux平台也支持,不过我目前只是在cygwin平台上调试过,没做具体的详细的测试,简单的测试通过,目前支持VC6, VS2005和gcc编译器,下面是代码:

file: debugx.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #ifndef _DEBUGX_H_
  8. #define _DEBUGX_H_

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


  11. #define REPORTE out2screen

  12. #define MAX_OUTPUT 100

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

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


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

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

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

  50. extern unsigned int dbx;

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

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

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

  66. #endif

file: debugx.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #include "debugx.h"

  8. unsigned int dbx = debugx_level4;

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

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

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

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

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

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

  45. void debugx(unsigned int level,const char* fmt,...)
  46. {
  47.     switch (level)
  48.     {
  49.     case xinfo: if (dbx & xinfo) OUTPUT_MSG(info) break;
  50.     case xdata: if (dbx & xdata) OUTPUT_MSG(data) break;
  51.     case xentry: if (dbx & xentry) OUTPUT_MSG(entry) break;
  52.     case xevent: if (dbx & xevent) OUTPUT_MSG(event) break;
  53.     case xmsg: if (dbx & xmsg) OUTPUT_MSG(msg) break;
  54.     case xwarn: if (dbx & xwarn) OUTPUT_MSG(warn) break;
  55.     case xerror: if (dbx & xerror) OUTPUT_MSG(error) break;
  56.     case xfatal: if (dbx & xfatal) OUTPUT_MSG(fatal) break;
  57.     default: return;
  58.     }
  59. }
  60. #endif
file: logx.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #ifndef _LOGX_H_
  8. #define _LOGX_H_

  9. #include <stdio.h>

  10. #define LOG_MOD    LOG_MUL_THREAD

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

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

  16. #include "signalx.h"

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

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

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


  33. #endif
file: logx.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #include "logx.h"

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

  11. static logx_t s_logx= {
  12. #ifdef WIN32
  13. 0,0,0,0,0
  14. #else
  15. .writex = 0,
  16. .openx = 0,
  17. .clo*** = 0,
  18. .initx = 0,
  19. .exitx = 0,
  20. .mode = 0,
  21. .fh = 0,
  22. #endif
  23. };

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

  25. static int __writex(struct logx_s *this, const char* pbuf, size_t sz)
  26. {
  27.     size_t cnts=0;
  28.     __assert(this!=null&&pbuf!=null&&sz>0);
  29.     if (this->fh) {
  30.         /* cnts = fprintf(this->fh, "%s", pbuf);*/
  31.         cnts = fwrite(pbuf,sizeof(pbuf[0]),sz,this->fh);
  32.         __assert(cnts==sz);
  33.         fflush(this->fh);
  34.     }
  35.     return 0;
  36. }

  37. static int __openx(struct logx_s *this, const char* psz_path)
  38. {
  39.     __assert(this!=null && psz_path!=null);

  40.     if (null == (this->fh = fopen(psz_path, "w+")))
  41.         return -1;
  42.     
  43.     return 0;
  44. }

  45. static int __clo***(struct logx_s *this)
  46. {
  47.     __assert(this!=null);
  48.     if(this->fh){
  49.         fclose(this->fh);
  50.         this->fh=0;
  51.     }
  52.     return 0;
  53. }

  54. static int __initx(struct logx_s *this, int mode)
  55. {
  56.     __assert(this!=null);
  57.     
  58.     if (mode==LOG_MUL_THREAD){
  59.         this->mode = mode;
  60.         signalx_init(&this->signalx, logx_do_signalx);         
  61.     }
  62.     return 0;
  63. }

  64. static int __exitx(struct logx_s *this)
  65. {
  66.     __assert(this!=null);
  67.     
  68.     if (this->mode==LOG_MUL_THREAD)
  69.         signalx_exit(&this->signalx);
  70.     return 0;
  71. }


  72. void logx_do_signalx(const char* pbuf, size_t sz)
  73. {
  74.     __assert(pbuf!=null&&sz>0);
  75.     if (s_logx.writex)
  76.         s_logx.writex(&s_logx, pbuf, sz);
  77. }


  78. void logx_init(const char* psz_path, int mode)
  79. {

  80.     __assert(psz_path!=null);
  81.     *(&s_logx.writex) = &__writex;
  82.     *(&s_logx.openx) = &__openx;
  83.     *(&s_logx.clo***) = &__clo***;
  84.     *(&s_logx.initx) = &__initx;
  85.     *(&s_logx.exitx) = &__exitx;
  86.     
  87.     s_logx.initx(&s_logx, mode);
  88.     s_logx.openx(&s_logx, psz_path);

  89. }

  90. void logx_exit()
  91. {
  92.     s_logx.clo***(&s_logx);
  93.     s_logx.exitx(&s_logx);
  94. }

  95. void logx_post(const char* pszbuf)
  96. {
  97.     __assert(pszbuf!=null);
  98.     if (s_logx.mode==LOG_MUL_THREAD)
  99.         signalx_post(s_logx.signalx,pszbuf);
  100.     else
  101.         s_logx.writex(&s_logx, pszbuf, strlen(pszbuf));
  102. }
  103. void logx_postx(const char* pbuf, size_t sz)
  104. {
  105.     __assert(pbuf!=null&&sz>0);
  106.     
  107.     if (s_logx.mode==LOG_MUL_THREAD)
  108.         signalx_postx(s_logx.signalx,pbuf,sz);
  109.     else
  110.         s_logx.writex(&s_logx, pbuf, sz);
  111. }


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

  114. #if REPORTE==out2file
  115. int output2file(const char* pszbuf)
  116. {
  117.     logx_post(pszbuf);
  118.     return 0;
  119. }
  120. #endif

file: signalx.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #ifndef _SIGNALX_H_
  8. #define _SIGNALX_H_

  9. #include <stdio.h>


  10. #ifdef WIN32
  11. #    include "windows.h"
  12. #else
  13. # include <pthread.h>
  14. #endif


  15. #ifndef MAX_PATH
  16. #define MAX_PATH 260
  17. #endif

  18. #ifndef MAX_POOL
  19. #define MAX_POOL 100
  20. #endif

  21. #define MOD_POOL_FIX 1
  22. #define MOD_POOL_DYN 2

  23. #define POOL_ITEM_LEN    100

  24. #define MOD_POOL MOD_POOL_DYN

  25. #ifndef __xmalloc
  26. #define __xmalloc malloc
  27. #endif

  28. #ifndef __xfree
  29. #define __xfree    free
  30. #endif

  31. #ifndef __assert
  32. #define __assert(x)
  33. #endif


  34. extern struct signalx_s;

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

  36. typedef struct signalx_s{
  37.     
  38.     void (*do_signalx)(const char* pbuf, size_t sz);
  39.     
  40. #if MOD_POOL==MOD_POOL_FIX
  41.     char pool[MAX_POOL][POOL_ITEM_LEN];
  42. #elif MOD_POOL==MOD_POOL_DYN
  43.     char* pool[MAX_POOL];
  44. #endif
  45.     unsigned int index1; /* index 1 for the circular pool */
  46.     unsigned int index2; /* index 2 for the circular pool */
  47. #ifdef WIN32
  48.     HANDLE hthread;    /* server thread for logging out */
  49.     HANDLE hevent_post; /* server thread will be hold except post event occur */
  50.     HANDLE hevent_exit; /* notify the server thread exit normally */
  51.     CRITICAL_SECTION cslock;
  52. #else
  53.     pthread_t hthread;
  54.     pthread_cond_t hevent_post;
  55.   /*    pthread_cond_t hevent_exit; */
  56.     pthread_mutex_t cslock;
  57.     pthread_mutexattr_t attr;
  58. #endif
  59.     void (*post_msgx)(struct signalx_s *this, const char* fmt, ...);
  60.     void (*post_msg)(struct signalx_s *this, const char* pbuf, size_t sz);
  61.     int (*serv_init)(struct signalx_s *this, f_signalx_t pf_signalx);
  62.     int (*serv_exit)(struct signalx_s *this);
  63.     int (*serv_start)(struct signalx_s *this);
  64.     int (*serv_stop)(struct signalx_s *this);
  65.     
  66. }signalx_t;


  67. extern int signalx_init(signalx_t *psignalx, f_signalx_t pf_signalx);
  68. extern int signalx_exit(signalx_t *psignalx);

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

  71. #endif
file: signalx.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #include "signalx.h"

  8. #ifdef WIN32

  9. #ifndef hnull
  10. #define hnull INVALID_HANDLE_VALUE
  11. #endif
  12. #ifndef null
  13. #define null NULL
  14. #endif
  15. #define __lockx() EnterCriticalSection(&this->cslock)
  16. #define __unlockx()    LeaveCriticalSection(&this->cslock)
  17. #define __lockx_init() InitializeCriticalSection(&this->cslock)
  18. #define __lockx_exit() DeleteCriticalSection(&this->cslock);

  19. #else

  20. #ifndef hnull
  21. #define hnull (void*)0
  22. #endif
  23. #ifndef null
  24. #define null (void*)0
  25. #endif
  26. #define __lockx() pthread_mutex_lock(&this->cslock)
  27. #define __unlockx()    pthread_mutex_unlock(&this->cslock)
  28. #define __lockx_init() \
  29.     pthread_mutexattr_init(&this->attr); \
  30.     pthread_mutexattr_settype(&this->attr,PTHREAD_MUTEX_RECURSIVE); \
  31.     pthread_mutex_init(&this->cslock,&this->attr); \

  32. #define __lockx_exit() \
  33.     pthread_mutex_destroy(&this->cslock); \
  34.     pthread_mutexattr_destroy(&this->attr); \
  35.     
  36. #endif

  37. #ifdef WIN32
  38. DWORD WINAPI __thread_do_signalx(LPVOID lpThreadParameter)
  39. #else
  40. void __thread_do_signalx(void* lpThreadParameter)
  41. #endif
  42. {
  43.     char *ptmp = null;
  44.     
  45.     signalx_t *this = (signalx_t*)lpThreadParameter;
  46.     __assert(this!=null);
  47.     
  48.     while (1)
  49.     {
  50. #ifdef WIN32
  51.         if (WaitForSingleObject((HANDLE)(this->hevent_post), INFINITE) == WAIT_OBJECT_0)
  52. #else
  53.         int ret=0;
  54.         __lockx();
  55.         ret = pthread_cond_wait(&this->hevent_post, &this->cslock);
  56.         __unlockx();
  57.         if (ret == 0)
  58. #endif
  59.         {
  60.             for (;;) /* write out the buffer */
  61.             {
  62.                 __lockx();
  63.                 
  64.                 ptmp = null;
  65.                 
  66.                 /* get buffer pointer out of m_tcDataPool[] */
  67.                 if (MAX_POOL == this->index1)
  68.                     this->index1 = 0;
  69.                 if (NULL != this->pool[this->index1]) {
  70.                     ptmp = this->pool[this->index1];
  71.                     this->pool[this->index1] = null;
  72.                     this->index1++;
  73.                 }
  74.                 
  75.                 __unlockx();
  76.                 
  77.                 /* do signal */
  78.                 if (null != ptmp && null != this->do_signalx) {        
  79.                     this->do_signalx(ptmp, strlen(ptmp));
  80.                     __xfree(ptmp);
  81.                 } else {
  82. #ifdef WIN32
  83.                     if (hnull != this->hevent_post)
  84.                         ResetEvent(this->hevent_post);
  85. #endif
  86.                     break;
  87.                 }        
  88.             } /* for(;;) */
  89.         }
  90. #ifdef WIN32
  91.         if (WaitForSingleObject(this->hevent_exit, 0) == WAIT_OBJECT_0)
  92.             break;
  93. #endif
  94.     } /* while(1) */
  95.     return 0;
  96. }

  97. static void __post_msgx(struct signalx_s *this, const char* fmt, ...)
  98. {
  99.     
  100. }

  101. static void __post_msg(struct signalx_s *this, const char* pbuf, size_t sz)
  102. {
  103.     char *pnew_buf=null;
  104.     
  105.     __assert(this!=null&&pbuf!=null);
  106.     
  107.     if (hnull==this->hthread) return;
  108.     
  109.     pnew_buf = (char*)__xmalloc(sz * sizeof(char));
  110.     
  111.     if (pnew_buf) {
  112.         memcpy(pnew_buf, pbuf, sz);
  113.         
  114.         __lockx();
  115.         
  116.         /* put buffer pointer into pool[MAX_POOL] */
  117.         if (MAX_POOL == this->index2)
  118.             this->index2 = 0;
  119.         /* case: index2 == index1, so abandon the new data */
  120.         if (null == this->pool[this->index2])
  121.             this->pool[this->index2++] = pnew_buf;
  122.         else {
  123.             /* do NOT forget to free the new data when the pool was overflow */
  124.             __xfree (pnew_buf);
  125.             pnew_buf=null;
  126.         }
  127.         if (hnull != this->hevent_post)
  128.         {
  129. #ifdef WIN32
  130.             SetEvent(this->hevent_post);
  131. #else
  132.             pthread_cond_signal(&this->hevent_post);
  133. #endif        
  134.         }
  135.         __unlockx();    
  136.     }
  137. }

  138. static int __serv_init(struct signalx_s *this, f_signalx_t pf_signalx)
  139. {
  140.     __assert(this!=null && pf_signalx!=null);
  141.     
  142.     this->hthread = hnull;
  143.     this->hevent_post = hnull;
  144. #ifdef WIN32
  145.     this->hevent_exit = hnull;
  146. #endif
  147.     this->index1 = 0;
  148.     this->index2 = 0;
  149.     /* NOTE: must initialize pool, else assert _CrtIsValidHeapPointer(pUserData) occur */
  150.     memset(this->pool, 0, sizeof(this->pool));
  151.     
  152.     this->do_signalx = pf_signalx; /* register user custom signal function */
  153.     
  154.     __lockx_init();
  155. #ifdef WIN32    
  156.     this->hevent_post = CreateEvent(NULL, TRUE, FALSE, NULL);
  157.     this->hevent_exit = CreateEvent(NULL, TRUE, FALSE, NULL);
  158. #else
  159.     pthread_cond_init(&this->hevent_post,null);
  160.     /* pthread_cond_init(&this->hevent_exit,null); */
  161. #endif
  162.     return 0;
  163. }

  164. static int __serv_exit(struct signalx_s *this)
  165. {
  166.     __assert(this!=null);

  167. #ifdef WIN32
  168.     if (hnull != this->hevent_exit) SetEvent(this->hevent_exit);
  169.     if (hnull != this->hevent_post) SetEvent(this->hevent_post);
  170. #else
  171.     pthread_cond_signal(&this->hevent_post);
  172.     sleep(1);
  173.     pthread_cancel(this->hthread);
  174. #endif
  175.     
  176.     /* wait the thread exit */
  177.     if (hnull != this->hthread)
  178.     {
  179. #ifdef WIN32
  180.         /* terminal the log server thread until 1 second over */
  181.         unsigned long state = WaitForSingleObject (this->hthread, 1000);
  182.         switch (state)
  183.         {
  184.         case WAIT_TIMEOUT:
  185.             {
  186.                 unsigned long exit_code = 0;
  187.                 if (0 != TerminateThread(this->hthread, exit_code))
  188.                     ; /* terminate the server thread */
  189.                 else
  190.                     ; /* terminate the LogSrv thread failed */
  191.                 break;
  192.             }
  193.         case WAIT_ABANDONED: break; /* the Thread abandoned */
  194.         case WAIT_OBJECT_0: break; /* exit the server thread */
  195.         default: break;
  196.         }
  197.         CloseHandle(this->hthread);
  198. #else
  199.         int state = pthread_join(this->hthread, null);
  200. #endif
  201.         this->hthread=hnull;
  202.     }
  203.     
  204.     __lockx_exit();
  205.     
  206. #ifdef WIN32
  207.     if (hnull != this->hevent_exit) CloseHandle(this->hevent_exit);
  208.     if (hnull != this->hevent_post) CloseHandle(this->hevent_post);
  209. #else
  210.     /* pthread_cond_destroy(&this->hevent_exit);*/
  211.     pthread_cond_destroy(&this->hevent_post);
  212. #endif
  213.     return 0;
  214. }

  215. static int __serv_start(struct signalx_s *this)
  216. {
  217.     unsigned long thread_id;
  218.     __assert(this!=null);
  219.     if (hnull == this->hthread) {
  220. #ifdef WIN32
  221.         this->hthread = CreateThread(
  222.             NULL, /* default security attributes */
  223.             0, /* use default stack size */
  224.             __thread_do_signalx, /* thread function */
  225.             (LPVOID)this, /* argument to thread function */
  226.             0, /* use default creation flags */
  227.             &thread_id); /* returns the thread identifier */
  228. #else
  229.         if(pthread_create(&this->hthread, null, __thread_do_signalx, (void*)this)!=0)
  230.             return -1;
  231. #endif
  232.     }
  233.     return 0;
  234. }

  235. static int __serv_stop(signalx_t *this)
  236. {
  237.     return 0;
  238. }


  239. int signalx_init(signalx_t *this, f_signalx_t pf_signalx)
  240. {
  241.     __assert(this!=null&&pf_signalx!=null);
  242.     
  243.     *(&this->post_msgx) = &__post_msgx;
  244.     *(&this->post_msg) = &__post_msg;
  245.     *(&this->serv_init) = &__serv_init;
  246.     *(&this->serv_exit) = &__serv_exit;
  247.     *(&this->serv_start) = &__serv_start;
  248.     *(&this->serv_stop) = &__serv_stop;
  249.     
  250.     this->serv_init(this, pf_signalx);
  251.     
  252.     this->serv_start(this);
  253.     return 0;
  254. }

  255. int signalx_exit(signalx_t *this)
  256. {
  257.     __assert(this!=null);
  258.     this->serv_exit(this);
  259.     return 0;
  260. }
file: thread_mgmt.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #ifndef _THREAD_MGMT_H_
  8. #define _THREAD_MGMT_H_

  9. #include <stdio.h>

  10. #ifdef WIN32
  11. #include <windows.h>
  12. #else
  13. #include <pthread.h>
  14. #endif
  15. #ifndef __assert
  16. #define __assert(x)
  17. #endif

  18. #ifndef MAX_NAME
  19. #define MAX_NAME 100
  20. #endif

  21. #ifndef MAX_THREAD
  22. #define MAX_THREAD 10
  23. #endif

  24. #ifdef WIN32
  25. typedef DWORD (WINAPI *f_thread_t)(LPVOID lpThreadParameter);
  26. #else
  27. typedef void* (*f_thread_t)(void *pvoid);
  28. #endif

  29. typedef struct thread_info_s
  30. {
  31.     unsigned long id;
  32.     char name[MAX_NAME];
  33. #ifdef WIN32
  34.     HANDLE h;
  35. #else
  36.     pthread_t h;
  37. #endif
  38.     f_thread_t f_thread;
  39. }thread_info_t;

  40. typedef struct thread_mgmt_s
  41. {
  42.     thread_info_t thread_info[MAX_THREAD];

  43.     int (*init)(struct thread_mgmt_s *this);
  44.     int (*exit)(struct thread_mgmt_s *this);
  45.     int (*create_thread)(struct thread_mgmt_s *this, const char* psz_name, f_thread_t f_thread);
  46.     int (*delete_thread)(struct thread_mgmt_s *this, const char* psz_name);
  47.     
  48. }thread_mgmt_t;

  49. void tm_init(thread_mgmt_t *ptm);

  50. void tm_exit(thread_mgmt_t *ptm);

  51. #define tm_create_thread(tm,nm,ft) ((tm).create_thread(&(tm),(nm),(ft)))
  52. #define tm_delete_thread(tm,nm)((tm).delete_thread(&(tm),(nm)))

  53. #endif
file: thread_mgmt.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #include "thread_mgmt.h"

  8. #ifdef WIN32

  9. #ifndef hnull
  10. #define hnull INVALID_HANDLE_VALUE
  11. #endif
  12. #ifndef null
  13. #define null NULL
  14. #endif

  15. #else

  16. #ifndef hnull
  17. #define hnull (void*)0
  18. #endif
  19. #ifndef null
  20. #define null (void*)0
  21. #endif

  22. #endif


  23. static int __init(struct thread_mgmt_s *this)
  24. {
  25.     int i = 0;
  26.     __assert(this!=null)
  27.     for (;i<MAX_THREAD;i++)
  28.     {
  29.         this->thread_info[i].id = 0;
  30.         this->thread_info[i].h = hnull;
  31.         this->thread_info[i].f_thread=null;
  32.         this->thread_info[i].name[0]=0;
  33.     }
  34.     return 0;
  35. }

  36. static int __exit(struct thread_mgmt_s *this)
  37. {
  38.     int i = 0;
  39.     __assert(this!=null);
  40.     for (;i<MAX_THREAD;i++)
  41.     {
  42.         if(this->thread_info[i].h != hnull)
  43.         {
  44. #ifdef WIN32
  45.             /* terminal the log server thread until 1 second over */
  46.             unsigned long state = WaitForSingleObject (this->thread_info[i].h, 100);
  47.             switch (state)
  48.             {
  49.             case WAIT_TIMEOUT:
  50.                 {
  51.                     unsigned long exit_code = 0;
  52.                     if (0 != TerminateThread(this->thread_info[i].h, exit_code))
  53.                         ;
  54.                     /* terminate the server thread */
  55.                     else
  56.                         ;
  57.                     /* terminate the LogSrv thread failed */
  58.                     break;
  59.                 }
  60.             case WAIT_ABANDONED: break;
  61.                 /* the Thread abandoned */
  62.             case WAIT_OBJECT_0: break;
  63.                 /* exit the server thread */
  64.             default: break;
  65.             }
  66. #else
  67.             if(pthread_cancel(this->thread_info[i].h)!=0)
  68.                 ;/* go on to terminal others, althought error occur nowing */
  69. #endif
  70.             this->thread_info[i].h = hnull;
  71.             this->thread_info[i].name[0]=0;
  72.             this->thread_info[i].id=0;
  73.             this->thread_info[i].f_thread=0;
  74.         }
  75.         else if (this->thread_info[i].h == hnull)
  76.         {
  77.             this->thread_info[i].h = hnull;
  78.             this->thread_info[i].name[0]=0;
  79.             this->thread_info[i].id=0;
  80.             this->thread_info[i].f_thread=0;
  81.         }
  82.     }
  83.     return 0;
  84. }


  85. static int __create_thread(struct thread_mgmt_s *this, const char* psz_name, f_thread_t f_thread)
  86. {
  87.     int i=0, len=0;
  88.     __assert(this!=null && psz_name!=null && f_thread!=null);
  89.     for (;i<MAX_THREAD;i++)
  90.     {
  91.         if(this->thread_info[i].h==hnull || this->thread_info[i].f_thread==null)
  92.             break;
  93.     }
  94.     if(i==MAX_THREAD) return -1;
  95. #ifdef WIN32
  96.     this->thread_info[i].h = CreateThread(
  97.         null, // default security attributes
  98.         0, // use default stack size
  99.         f_thread,// thread function
  100.         0, // argument to thread function
  101.         0, // use default creation flags
  102.         &(this->thread_info[i].id));
  103. #else
  104.     if(pthread_create(&this->thread_info[i].h, null, f_thread, null)!=0)
  105.         return -1;
  106. #endif
  107.     len=strlen(psz_name)+1;
  108.     if (MAX_NAME < len)
  109.     {
  110.         memcpy(this->thread_info[i].name, psz_name, MAX_NAME-1);
  111.         this->thread_info[i].name[MAX_NAME-1]=0;
  112.     }
  113.     else
  114.         memcpy(this->thread_info[i].name, psz_name, len);
  115.     
  116.     this->thread_info[i].f_thread = f_thread;
  117.     
  118.     return 0;
  119. }


  120. static int __delete_thread(struct thread_mgmt_s *this, const char* psz_name)
  121. {
  122.     int i = 0;
  123.     __assert(this!=null && psz_name!=null);
  124.     for (;i<MAX_THREAD;i++)
  125.     {
  126.         if(strcmp(this->thread_info[i].name, psz_name)==0
  127.             && this->thread_info[i].h != hnull)
  128.         {
  129.             /* terminal the log server thread until 1 second over */
  130. #ifdef WIN32
  131.             unsigned long state = WaitForSingleObject (this->thread_info[i].h, 100);
  132.             switch (state)
  133.             {
  134.             case WAIT_TIMEOUT:
  135.                 {
  136.                     unsigned long exit_code = 0;
  137.                     
  138.                     if (0 != TerminateThread(this->thread_info[i].h, exit_code))
  139.                         ;
  140.                     /* terminate the server thread */
  141.                     else
  142.                         ;
  143.                     /* terminate the LogSrv thread failed */
  144.                     break;
  145.                 }
  146.             case WAIT_ABANDONED: break;
  147.                 /* the Thread abandoned */
  148.             case WAIT_OBJECT_0: break;
  149.                 /* exit the server thread */
  150.             default: break;
  151.             }
  152. #else
  153.             if(pthread_cancel(this->thread_info[i].h)!=0)
  154.                 return -1;
  155. #endif
  156.             this->thread_info[i].h = hnull;
  157.             this->thread_info[i].name[0]=0;
  158.             this->thread_info[i].id=0;
  159.             this->thread_info[i].f_thread=0;
  160.         }
  161.         else if (this->thread_info[i].h == hnull)
  162.         {
  163.             this->thread_info[i].h = hnull;
  164.             this->thread_info[i].name[0]=0;
  165.             this->thread_info[i].id=0;
  166.             this->thread_info[i].f_thread=0;
  167.         }
  168.     }
  169.     return 0;
  170. }

  171. void tm_init(thread_mgmt_t *ptm)
  172. {
  173.     __assert(ptm!=null);
  174.     *(&ptm->init) = &__init;
  175.     *(&ptm->exit) = &__exit;
  176.     *(&ptm->create_thread) = &__create_thread;
  177.     *(&ptm->delete_thread) = &__delete_thread;
  178.     ptm->init(ptm);
  179. }

  180. void tm_exit(thread_mgmt_t *ptm)
  181. {
  182.     __assert(ptm!=null);
  183.     ptm->exit(ptm);
  184. }
file: main.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-09-18
  5.  * porting to linux(cygwin) @ 2011-09-20
  6.  */

  7. #include "debugx.h"
  8. #include "logx.h"
  9. #include "thread_mgmt.h"

  10. #ifdef WIN32
  11. #define val_time 10
  12. #define sleep Sleep
  13. #define gettidx() GetCurrentThreadId()
  14. #else
  15. #define val_time 1
  16. #define gettidx() pthread_self()
  17. #endif

  18. #ifdef WIN32
  19. DWORD WINAPI f_thread1(LPVOID pvoid)
  20. #else
  21. void *f_thread1(void *pvoid)
  22. #endif
  23. {
  24.     int i = 10;
  25.     unsigned long id = gettidx();

  26.     while (i--)
  27.     {
  28.         debugx(xinfo, "thread id(%lu): this is %s!\n", id, "xinfo");
  29.         sleep(val_time);
  30.     }
  31. }

  32. #ifdef WIN32
  33. DWORD WINAPI f_thread2(LPVOID pvoid)
  34. #else
  35. void *f_thread2(void *pvoid)
  36. #endif
  37. {
  38.     int i = 10;
  39.     unsigned long id = gettidx();

  40.     while (i--)
  41.     {
  42.         debugx(xevent, "thread id(%lu): this is %s!\n", id, "xevent");
  43.         sleep(val_time);
  44.     }
  45. }

  46. #ifdef WIN32
  47. DWORD WINAPI f_thread3(LPVOID pvoid)
  48. #else
  49. void *f_thread3(void *pvoid)
  50. #endif
  51. {
  52.     int i = 10;
  53.     unsigned long id = gettidx();
  54.     while (i--)
  55.     {
  56.         debugx(xerror, "thread id(%lu): this is %s!\n", id, "xerror");
  57.         sleep(val_time);
  58.     }
  59. }

  60. int main()
  61. {
  62.     int i = 10;
  63.     unsigned long id = 0;
  64. #if LOG_MOD==LOG_MUL_THREAD
  65.     thread_mgmt_t tm;
  66.     logx_init("D:/abc.txt", LOG_MUL_THREAD);
  67.     tm_init(&tm);
  68.     tm_create_thread(tm,"t1",f_thread1);
  69.     tm_create_thread(tm,"t2",f_thread2);
  70.     tm_create_thread(tm,"t3",f_thread3);
  71. #else
  72.     logx_init("D:/abc.txt", LOG_SIG_THREAD);
  73. #endif

  74.     debugx(xinfo, "this is %s!\n", "xinfo");
  75.     debugx(xdata, "this is %s!\n", "xdata");
  76.     debugx(xentry, "this is %s!\n", "xentry");
  77.     debugx(xevent, "this is %s!\n", "xevent");
  78.     debugx(xmsg, "this is %s!\n", "xmsg");
  79.     debugx(xwarn, "this is %s!\n", "xwarn");
  80.     debugx(xerror, "this is %s!\n", "xerror");
  81.     debugx(xfatal, "this is %s!\n", "xfatal");
  82.     debugx(xerror, "this is %s!\n", "xerror");

  83.     id = gettidx();

  84.     while (i--)
  85.     {
  86.         debugx(xfatal, "thread id(%d): this is %s!\n", id, "xfatal");
  87.         sleep(val_time);
  88.     }

  89. #if LOG_MOD==LOG_MUL_THREAD
  90.     tm_exit(&tm);
  91. #endif
  92.     logx_exit();

  93.     return 0;
  94. }

附件:
 debugx__.rar  
阅读(1722) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~