http://vincent.blog.chinaunix.net今天终于把linux平台也支持,不过我目前只是在cygwin平台上调试过,没做具体的详细的测试,简单的测试通过,目前支持VC6, VS2005和gcc编译器,下面是代码:
file: debugx.h
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #ifndef _DEBUGX_H_
- #define _DEBUGX_H_
- #include <stdio.h>
- #include <stdarg.h>
- #define REPORTE out2screen
- #define MAX_OUTPUT 100
- /* where to output */
- #define out2screen 1
- #define out2file 2
- #if defined(WIN32)&&(_MSC_VER < 1300) /* if lower or equal to VC6 under win32 */
- # define __func__ "?"
- # if REPORTE!=out2screen && REPORTE!=out2file
- void outputx(const char* fmt,...){}
- # else
- extern void outputx(const char* fmt,...);
- # endif
- #else
- # define __func__ __FUNCTION__
- # if REPORTE!=out2screen && REPORTE!=out2file
- # define outputx(fmt,...)
- # else
- extern void outputx(const char* fmt,...);
- # endif
- #endif
- #define __bit(x) ((unsigned)1<<(x))
- /** generic data dump */
- #define xinfo __bit(0)
- #define xdata __bit(1)
- /** function invoke */
- #define xentry __bit(2)
- /** interruption signal */
- #define xevent __bit(3)
- #define xmsg __bit(4)
- /** warning level */
- #define xwarn __bit(5)
- #define xerror __bit(6)
- #define xfatal __bit(7)
- /** debug level */
- #define debugx_level0 (0)
- #define debugx_level1 (xinfo|xdata|xentry)
- #define debugx_level2 (xevent|xmsg)
- #define debugx_level3 (xwarn|xerror|xfatal)
- #define debugx_level4 (debugx_level1|debugx_level2|debugx_level3)
- extern unsigned int dbx;
- #define DBX(x) "debug(" #x ",%s,%d): "
- #define INFO __func__, __LINE__ /** function name and line information */
- #if defined(WIN32)&&(_MSC_VER < 1300) /* if lower or equal to VC6 under win32 */
- extern void debugx(unsigned int level,const char* fmt,...);
- #else
- # define debugx_xinfo(fmt,...) do {if (dbx & xinfo) outputx(DBX(info) fmt, INFO, __VA_ARGS__);} while(0)
- # define debugx_xdata(fmt,...) do {if (dbx & xdata) outputx(DBX(data) fmt, INFO, __VA_ARGS__);} while(0)
- # define debugx_xentry(fmt,...) do {if (dbx & xentry) outputx(DBX(entry) fmt,INFO, __VA_ARGS__);} while(0)
- # define debugx_xevent(fmt,...) do {if (dbx & xevent) outputx(DBX(event) fmt,INFO, __VA_ARGS__);} while(0)
- # define debugx_xmsg(fmt,...) do {if (dbx & xmsg) outputx(DBX(msg) fmt, INFO, __VA_ARGS__);} while(0)
- # define debugx_xwarn(fmt,...) do {if (dbx & xwarn) outputx(DBX(warn) fmt,INFO, __VA_ARGS__);} while(0)
- # define debugx_xerror(fmt,...) do {if (dbx & xerror) outputx(DBX(error) fmt,INFO, __VA_ARGS__);} while(0)
- # define debugx_xfatal(fmt,...) do {if (dbx & xfatal) outputx(DBX(fatal) fmt,INFO, __VA_ARGS__);} while(0)
- # define debugx(level,fmt,...) debugx_##level(fmt, __VA_ARGS__)
- #endif
- #endif
file: debugx.c
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #include "debugx.h"
- unsigned int dbx = debugx_level4;
- #ifdef WIN32
- # define vsnprintf _vsnprintf
- #endif
- /** you should define your output2file by yourself */
- extern int output2file(const char* pszbuf);
- /** */
- #if REPORTE==out2screen
- # define xprintf printf
- #else
- # define xprintf output2file
- #endif
- #if REPORTE==out2screen || REPORTE==out2file
- void outputx(const char* fmt,...)
- {
- int ret;
- char buf[MAX_OUTPUT]="";
- va_list args;
- va_start(args, fmt);
- ret = vsnprintf(buf, sizeof(buf), fmt, args);
- if(ret<0) buf[MAX_OUTPUT-1]=0; /** output has been truncated */
- xprintf(buf);
- va_end(args);
- }
- #endif
- #if defined(WIN32)&&(_MSC_VER < 1300) /* if lower or equal to VC6 under win32 */
- #define OUTPUT_MSG(lv) \
- {\
- int ret;\
- char buf[MAX_OUTPUT]="";\
- va_list args;\
- va_start(args, fmt);\
- ret = vsnprintf(buf, sizeof(buf), fmt, args);\
- if(ret<0) buf[MAX_OUTPUT-1]=0;\
- xprintf(buf);\
- va_end(args);\
- }
- void debugx(unsigned int level,const char* fmt,...)
- {
- switch (level)
- {
- case xinfo: if (dbx & xinfo) OUTPUT_MSG(info) break;
- case xdata: if (dbx & xdata) OUTPUT_MSG(data) break;
- case xentry: if (dbx & xentry) OUTPUT_MSG(entry) break;
- case xevent: if (dbx & xevent) OUTPUT_MSG(event) break;
- case xmsg: if (dbx & xmsg) OUTPUT_MSG(msg) break;
- case xwarn: if (dbx & xwarn) OUTPUT_MSG(warn) break;
- case xerror: if (dbx & xerror) OUTPUT_MSG(error) break;
- case xfatal: if (dbx & xfatal) OUTPUT_MSG(fatal) break;
- default: return;
- }
- }
- #endif
file: logx.h
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #ifndef _LOGX_H_
- #define _LOGX_H_
- #include <stdio.h>
- #define LOG_MOD LOG_MUL_THREAD
- #define LOG_MUL_THREAD 1
- #define LOG_SIG_THREAD 2
- #ifndef __assert
- #define __assert(x)
- #endif
- #include "signalx.h"
- typedef struct logx_s{
-
- int (*writex)(struct logx_s *this, const char* pbuf, size_t sz);
- int (*openx)(struct logx_s *this, const char* psz_path);
- int (*clo***)(struct logx_s *this);
- int (*initx)(struct logx_s *this, int mode);
- int (*exitx)(struct logx_s *this);
-
- int mode;
- FILE *fh;
- signalx_t signalx;
- }logx_t;
- extern void logx_init(const char* psz_path, int mode);
- extern void logx_exit();
- extern void logx_post(const char* pszbuf);
- extern void logx_postx(const char* pbuf, size_t sz);
- #endif
file: logx.h
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #include "logx.h"
- #ifndef null
- #define null NULL
- #endif
- static logx_t s_logx= {
- #ifdef WIN32
- 0,0,0,0,0
- #else
- .writex = 0,
- .openx = 0,
- .clo*** = 0,
- .initx = 0,
- .exitx = 0,
- .mode = 0,
- .fh = 0,
- #endif
- };
- extern void logx_do_signalx(const char* pbuf, size_t sz);
- static int __writex(struct logx_s *this, const char* pbuf, size_t sz)
- {
- size_t cnts=0;
- __assert(this!=null&&pbuf!=null&&sz>0);
- if (this->fh) {
- /* cnts = fprintf(this->fh, "%s", pbuf);*/
- cnts = fwrite(pbuf,sizeof(pbuf[0]),sz,this->fh);
- __assert(cnts==sz);
- fflush(this->fh);
- }
- return 0;
- }
- static int __openx(struct logx_s *this, const char* psz_path)
- {
- __assert(this!=null && psz_path!=null);
- if (null == (this->fh = fopen(psz_path, "w+")))
- return -1;
-
- return 0;
- }
- static int __clo***(struct logx_s *this)
- {
- __assert(this!=null);
- if(this->fh){
- fclose(this->fh);
- this->fh=0;
- }
- return 0;
- }
- static int __initx(struct logx_s *this, int mode)
- {
- __assert(this!=null);
-
- if (mode==LOG_MUL_THREAD){
- this->mode = mode;
- signalx_init(&this->signalx, logx_do_signalx);
- }
- return 0;
- }
- static int __exitx(struct logx_s *this)
- {
- __assert(this!=null);
-
- if (this->mode==LOG_MUL_THREAD)
- signalx_exit(&this->signalx);
- return 0;
- }
- void logx_do_signalx(const char* pbuf, size_t sz)
- {
- __assert(pbuf!=null&&sz>0);
- if (s_logx.writex)
- s_logx.writex(&s_logx, pbuf, sz);
- }
- void logx_init(const char* psz_path, int mode)
- {
- __assert(psz_path!=null);
- *(&s_logx.writex) = &__writex;
- *(&s_logx.openx) = &__openx;
- *(&s_logx.clo***) = &__clo***;
- *(&s_logx.initx) = &__initx;
- *(&s_logx.exitx) = &__exitx;
-
- s_logx.initx(&s_logx, mode);
- s_logx.openx(&s_logx, psz_path);
- }
- void logx_exit()
- {
- s_logx.clo***(&s_logx);
- s_logx.exitx(&s_logx);
- }
- void logx_post(const char* pszbuf)
- {
- __assert(pszbuf!=null);
- if (s_logx.mode==LOG_MUL_THREAD)
- signalx_post(s_logx.signalx,pszbuf);
- else
- s_logx.writex(&s_logx, pszbuf, strlen(pszbuf));
- }
- void logx_postx(const char* pbuf, size_t sz)
- {
- __assert(pbuf!=null&&sz>0);
-
- if (s_logx.mode==LOG_MUL_THREAD)
- signalx_postx(s_logx.signalx,pbuf,sz);
- else
- s_logx.writex(&s_logx, pbuf, sz);
- }
- /** following part is only for debugx redirect the output to log file */
- #include "debugx.h"
- #if REPORTE==out2file
- int output2file(const char* pszbuf)
- {
- logx_post(pszbuf);
- return 0;
- }
- #endif
file: signalx.h
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #ifndef _SIGNALX_H_
- #define _SIGNALX_H_
- #include <stdio.h>
- #ifdef WIN32
- # include "windows.h"
- #else
- # include <pthread.h>
- #endif
- #ifndef MAX_PATH
- #define MAX_PATH 260
- #endif
- #ifndef MAX_POOL
- #define MAX_POOL 100
- #endif
- #define MOD_POOL_FIX 1
- #define MOD_POOL_DYN 2
- #define POOL_ITEM_LEN 100
- #define MOD_POOL MOD_POOL_DYN
- #ifndef __xmalloc
- #define __xmalloc malloc
- #endif
- #ifndef __xfree
- #define __xfree free
- #endif
- #ifndef __assert
- #define __assert(x)
- #endif
- extern struct signalx_s;
- typedef void (*f_signalx_t)(const char* pbuf, size_t sz);
- typedef struct signalx_s{
-
- void (*do_signalx)(const char* pbuf, size_t sz);
-
- #if MOD_POOL==MOD_POOL_FIX
- char pool[MAX_POOL][POOL_ITEM_LEN];
- #elif MOD_POOL==MOD_POOL_DYN
- char* pool[MAX_POOL];
- #endif
- unsigned int index1; /* index 1 for the circular pool */
- unsigned int index2; /* index 2 for the circular pool */
- #ifdef WIN32
- HANDLE hthread; /* server thread for logging out */
- HANDLE hevent_post; /* server thread will be hold except post event occur */
- HANDLE hevent_exit; /* notify the server thread exit normally */
- CRITICAL_SECTION cslock;
- #else
- pthread_t hthread;
- pthread_cond_t hevent_post;
- /* pthread_cond_t hevent_exit; */
- pthread_mutex_t cslock;
- pthread_mutexattr_t attr;
- #endif
- void (*post_msgx)(struct signalx_s *this, const char* fmt, ...);
- void (*post_msg)(struct signalx_s *this, const char* pbuf, size_t sz);
- int (*serv_init)(struct signalx_s *this, f_signalx_t pf_signalx);
- int (*serv_exit)(struct signalx_s *this);
- int (*serv_start)(struct signalx_s *this);
- int (*serv_stop)(struct signalx_s *this);
-
- }signalx_t;
- extern int signalx_init(signalx_t *psignalx, f_signalx_t pf_signalx);
- extern int signalx_exit(signalx_t *psignalx);
- #define signalx_post(signalx,pszbuf) ((signalx).post_msg(&(signalx),(pszbuf),strlen(pszbuf)+1))
- #define signalx_postx(signalx,pbuf,sz) ((signalx).post_msg(&(signalx),(pbuf),(sz)))
- #endif
file: signalx.c
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #include "signalx.h"
- #ifdef WIN32
- #ifndef hnull
- #define hnull INVALID_HANDLE_VALUE
- #endif
- #ifndef null
- #define null NULL
- #endif
- #define __lockx() EnterCriticalSection(&this->cslock)
- #define __unlockx() LeaveCriticalSection(&this->cslock)
- #define __lockx_init() InitializeCriticalSection(&this->cslock)
- #define __lockx_exit() DeleteCriticalSection(&this->cslock);
- #else
- #ifndef hnull
- #define hnull (void*)0
- #endif
- #ifndef null
- #define null (void*)0
- #endif
- #define __lockx() pthread_mutex_lock(&this->cslock)
- #define __unlockx() pthread_mutex_unlock(&this->cslock)
- #define __lockx_init() \
- pthread_mutexattr_init(&this->attr); \
- pthread_mutexattr_settype(&this->attr,PTHREAD_MUTEX_RECURSIVE); \
- pthread_mutex_init(&this->cslock,&this->attr); \
- #define __lockx_exit() \
- pthread_mutex_destroy(&this->cslock); \
- pthread_mutexattr_destroy(&this->attr); \
-
- #endif
- #ifdef WIN32
- DWORD WINAPI __thread_do_signalx(LPVOID lpThreadParameter)
- #else
- void __thread_do_signalx(void* lpThreadParameter)
- #endif
- {
- char *ptmp = null;
-
- signalx_t *this = (signalx_t*)lpThreadParameter;
- __assert(this!=null);
-
- while (1)
- {
- #ifdef WIN32
- if (WaitForSingleObject((HANDLE)(this->hevent_post), INFINITE) == WAIT_OBJECT_0)
- #else
- int ret=0;
- __lockx();
- ret = pthread_cond_wait(&this->hevent_post, &this->cslock);
- __unlockx();
- if (ret == 0)
- #endif
- {
- for (;;) /* write out the buffer */
- {
- __lockx();
-
- ptmp = null;
-
- /* get buffer pointer out of m_tcDataPool[] */
- if (MAX_POOL == this->index1)
- this->index1 = 0;
- if (NULL != this->pool[this->index1]) {
- ptmp = this->pool[this->index1];
- this->pool[this->index1] = null;
- this->index1++;
- }
-
- __unlockx();
-
- /* do signal */
- if (null != ptmp && null != this->do_signalx) {
- this->do_signalx(ptmp, strlen(ptmp));
- __xfree(ptmp);
- } else {
- #ifdef WIN32
- if (hnull != this->hevent_post)
- ResetEvent(this->hevent_post);
- #endif
- break;
- }
- } /* for(;;) */
- }
- #ifdef WIN32
- if (WaitForSingleObject(this->hevent_exit, 0) == WAIT_OBJECT_0)
- break;
- #endif
- } /* while(1) */
- return 0;
- }
- static void __post_msgx(struct signalx_s *this, const char* fmt, ...)
- {
-
- }
- static void __post_msg(struct signalx_s *this, const char* pbuf, size_t sz)
- {
- char *pnew_buf=null;
-
- __assert(this!=null&&pbuf!=null);
-
- if (hnull==this->hthread) return;
-
- pnew_buf = (char*)__xmalloc(sz * sizeof(char));
-
- if (pnew_buf) {
- memcpy(pnew_buf, pbuf, sz);
-
- __lockx();
-
- /* put buffer pointer into pool[MAX_POOL] */
- if (MAX_POOL == this->index2)
- this->index2 = 0;
- /* case: index2 == index1, so abandon the new data */
- if (null == this->pool[this->index2])
- this->pool[this->index2++] = pnew_buf;
- else {
- /* do NOT forget to free the new data when the pool was overflow */
- __xfree (pnew_buf);
- pnew_buf=null;
- }
- if (hnull != this->hevent_post)
- {
- #ifdef WIN32
- SetEvent(this->hevent_post);
- #else
- pthread_cond_signal(&this->hevent_post);
- #endif
- }
- __unlockx();
- }
- }
- static int __serv_init(struct signalx_s *this, f_signalx_t pf_signalx)
- {
- __assert(this!=null && pf_signalx!=null);
-
- this->hthread = hnull;
- this->hevent_post = hnull;
- #ifdef WIN32
- this->hevent_exit = hnull;
- #endif
- this->index1 = 0;
- this->index2 = 0;
- /* NOTE: must initialize pool, else assert _CrtIsValidHeapPointer(pUserData) occur */
- memset(this->pool, 0, sizeof(this->pool));
-
- this->do_signalx = pf_signalx; /* register user custom signal function */
-
- __lockx_init();
- #ifdef WIN32
- this->hevent_post = CreateEvent(NULL, TRUE, FALSE, NULL);
- this->hevent_exit = CreateEvent(NULL, TRUE, FALSE, NULL);
- #else
- pthread_cond_init(&this->hevent_post,null);
- /* pthread_cond_init(&this->hevent_exit,null); */
- #endif
- return 0;
- }
- static int __serv_exit(struct signalx_s *this)
- {
- __assert(this!=null);
- #ifdef WIN32
- if (hnull != this->hevent_exit) SetEvent(this->hevent_exit);
- if (hnull != this->hevent_post) SetEvent(this->hevent_post);
- #else
- pthread_cond_signal(&this->hevent_post);
- sleep(1);
- pthread_cancel(this->hthread);
- #endif
-
- /* wait the thread exit */
- if (hnull != this->hthread)
- {
- #ifdef WIN32
- /* terminal the log server thread until 1 second over */
- unsigned long state = WaitForSingleObject (this->hthread, 1000);
- switch (state)
- {
- case WAIT_TIMEOUT:
- {
- unsigned long exit_code = 0;
- if (0 != TerminateThread(this->hthread, exit_code))
- ; /* terminate the server thread */
- else
- ; /* terminate the LogSrv thread failed */
- break;
- }
- case WAIT_ABANDONED: break; /* the Thread abandoned */
- case WAIT_OBJECT_0: break; /* exit the server thread */
- default: break;
- }
- CloseHandle(this->hthread);
- #else
- int state = pthread_join(this->hthread, null);
- #endif
- this->hthread=hnull;
- }
-
- __lockx_exit();
-
- #ifdef WIN32
- if (hnull != this->hevent_exit) CloseHandle(this->hevent_exit);
- if (hnull != this->hevent_post) CloseHandle(this->hevent_post);
- #else
- /* pthread_cond_destroy(&this->hevent_exit);*/
- pthread_cond_destroy(&this->hevent_post);
- #endif
- return 0;
- }
- static int __serv_start(struct signalx_s *this)
- {
- unsigned long thread_id;
- __assert(this!=null);
- if (hnull == this->hthread) {
- #ifdef WIN32
- this->hthread = CreateThread(
- NULL, /* default security attributes */
- 0, /* use default stack size */
- __thread_do_signalx, /* thread function */
- (LPVOID)this, /* argument to thread function */
- 0, /* use default creation flags */
- &thread_id); /* returns the thread identifier */
- #else
- if(pthread_create(&this->hthread, null, __thread_do_signalx, (void*)this)!=0)
- return -1;
- #endif
- }
- return 0;
- }
- static int __serv_stop(signalx_t *this)
- {
- return 0;
- }
- int signalx_init(signalx_t *this, f_signalx_t pf_signalx)
- {
- __assert(this!=null&&pf_signalx!=null);
-
- *(&this->post_msgx) = &__post_msgx;
- *(&this->post_msg) = &__post_msg;
- *(&this->serv_init) = &__serv_init;
- *(&this->serv_exit) = &__serv_exit;
- *(&this->serv_start) = &__serv_start;
- *(&this->serv_stop) = &__serv_stop;
-
- this->serv_init(this, pf_signalx);
-
- this->serv_start(this);
- return 0;
- }
- int signalx_exit(signalx_t *this)
- {
- __assert(this!=null);
- this->serv_exit(this);
- return 0;
- }
file: thread_mgmt.h
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #ifndef _THREAD_MGMT_H_
- #define _THREAD_MGMT_H_
- #include <stdio.h>
- #ifdef WIN32
- #include <windows.h>
- #else
- #include <pthread.h>
- #endif
- #ifndef __assert
- #define __assert(x)
- #endif
- #ifndef MAX_NAME
- #define MAX_NAME 100
- #endif
- #ifndef MAX_THREAD
- #define MAX_THREAD 10
- #endif
- #ifdef WIN32
- typedef DWORD (WINAPI *f_thread_t)(LPVOID lpThreadParameter);
- #else
- typedef void* (*f_thread_t)(void *pvoid);
- #endif
- typedef struct thread_info_s
- {
- unsigned long id;
- char name[MAX_NAME];
- #ifdef WIN32
- HANDLE h;
- #else
- pthread_t h;
- #endif
- f_thread_t f_thread;
- }thread_info_t;
- typedef struct thread_mgmt_s
- {
- thread_info_t thread_info[MAX_THREAD];
- int (*init)(struct thread_mgmt_s *this);
- int (*exit)(struct thread_mgmt_s *this);
- int (*create_thread)(struct thread_mgmt_s *this, const char* psz_name, f_thread_t f_thread);
- int (*delete_thread)(struct thread_mgmt_s *this, const char* psz_name);
-
- }thread_mgmt_t;
- void tm_init(thread_mgmt_t *ptm);
- void tm_exit(thread_mgmt_t *ptm);
- #define tm_create_thread(tm,nm,ft) ((tm).create_thread(&(tm),(nm),(ft)))
- #define tm_delete_thread(tm,nm)((tm).delete_thread(&(tm),(nm)))
- #endif
file: thread_mgmt.c
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #include "thread_mgmt.h"
- #ifdef WIN32
- #ifndef hnull
- #define hnull INVALID_HANDLE_VALUE
- #endif
- #ifndef null
- #define null NULL
- #endif
- #else
- #ifndef hnull
- #define hnull (void*)0
- #endif
- #ifndef null
- #define null (void*)0
- #endif
- #endif
- static int __init(struct thread_mgmt_s *this)
- {
- int i = 0;
- __assert(this!=null)
- for (;i<MAX_THREAD;i++)
- {
- this->thread_info[i].id = 0;
- this->thread_info[i].h = hnull;
- this->thread_info[i].f_thread=null;
- this->thread_info[i].name[0]=0;
- }
- return 0;
- }
- static int __exit(struct thread_mgmt_s *this)
- {
- int i = 0;
- __assert(this!=null);
- for (;i<MAX_THREAD;i++)
- {
- if(this->thread_info[i].h != hnull)
- {
- #ifdef WIN32
- /* terminal the log server thread until 1 second over */
- unsigned long state = WaitForSingleObject (this->thread_info[i].h, 100);
- switch (state)
- {
- case WAIT_TIMEOUT:
- {
- unsigned long exit_code = 0;
- if (0 != TerminateThread(this->thread_info[i].h, exit_code))
- ;
- /* terminate the server thread */
- else
- ;
- /* terminate the LogSrv thread failed */
- break;
- }
- case WAIT_ABANDONED: break;
- /* the Thread abandoned */
- case WAIT_OBJECT_0: break;
- /* exit the server thread */
- default: break;
- }
- #else
- if(pthread_cancel(this->thread_info[i].h)!=0)
- ;/* go on to terminal others, althought error occur nowing */
- #endif
- this->thread_info[i].h = hnull;
- this->thread_info[i].name[0]=0;
- this->thread_info[i].id=0;
- this->thread_info[i].f_thread=0;
- }
- else if (this->thread_info[i].h == hnull)
- {
- this->thread_info[i].h = hnull;
- this->thread_info[i].name[0]=0;
- this->thread_info[i].id=0;
- this->thread_info[i].f_thread=0;
- }
- }
- return 0;
- }
- static int __create_thread(struct thread_mgmt_s *this, const char* psz_name, f_thread_t f_thread)
- {
- int i=0, len=0;
- __assert(this!=null && psz_name!=null && f_thread!=null);
- for (;i<MAX_THREAD;i++)
- {
- if(this->thread_info[i].h==hnull || this->thread_info[i].f_thread==null)
- break;
- }
- if(i==MAX_THREAD) return -1;
- #ifdef WIN32
- this->thread_info[i].h = CreateThread(
- null, // default security attributes
- 0, // use default stack size
- f_thread,// thread function
- 0, // argument to thread function
- 0, // use default creation flags
- &(this->thread_info[i].id));
- #else
- if(pthread_create(&this->thread_info[i].h, null, f_thread, null)!=0)
- return -1;
- #endif
- len=strlen(psz_name)+1;
- if (MAX_NAME < len)
- {
- memcpy(this->thread_info[i].name, psz_name, MAX_NAME-1);
- this->thread_info[i].name[MAX_NAME-1]=0;
- }
- else
- memcpy(this->thread_info[i].name, psz_name, len);
-
- this->thread_info[i].f_thread = f_thread;
-
- return 0;
- }
- static int __delete_thread(struct thread_mgmt_s *this, const char* psz_name)
- {
- int i = 0;
- __assert(this!=null && psz_name!=null);
- for (;i<MAX_THREAD;i++)
- {
- if(strcmp(this->thread_info[i].name, psz_name)==0
- && this->thread_info[i].h != hnull)
- {
- /* terminal the log server thread until 1 second over */
- #ifdef WIN32
- unsigned long state = WaitForSingleObject (this->thread_info[i].h, 100);
- switch (state)
- {
- case WAIT_TIMEOUT:
- {
- unsigned long exit_code = 0;
-
- if (0 != TerminateThread(this->thread_info[i].h, exit_code))
- ;
- /* terminate the server thread */
- else
- ;
- /* terminate the LogSrv thread failed */
- break;
- }
- case WAIT_ABANDONED: break;
- /* the Thread abandoned */
- case WAIT_OBJECT_0: break;
- /* exit the server thread */
- default: break;
- }
- #else
- if(pthread_cancel(this->thread_info[i].h)!=0)
- return -1;
- #endif
- this->thread_info[i].h = hnull;
- this->thread_info[i].name[0]=0;
- this->thread_info[i].id=0;
- this->thread_info[i].f_thread=0;
- }
- else if (this->thread_info[i].h == hnull)
- {
- this->thread_info[i].h = hnull;
- this->thread_info[i].name[0]=0;
- this->thread_info[i].id=0;
- this->thread_info[i].f_thread=0;
- }
- }
- return 0;
- }
- void tm_init(thread_mgmt_t *ptm)
- {
- __assert(ptm!=null);
- *(&ptm->init) = &__init;
- *(&ptm->exit) = &__exit;
- *(&ptm->create_thread) = &__create_thread;
- *(&ptm->delete_thread) = &__delete_thread;
- ptm->init(ptm);
- }
- void tm_exit(thread_mgmt_t *ptm)
- {
- __assert(ptm!=null);
- ptm->exit(ptm);
- }
file: main.c
- /**
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2011-09-18
- * porting to linux(cygwin) @ 2011-09-20
- */
- #include "debugx.h"
- #include "logx.h"
- #include "thread_mgmt.h"
- #ifdef WIN32
- #define val_time 10
- #define sleep Sleep
- #define gettidx() GetCurrentThreadId()
- #else
- #define val_time 1
- #define gettidx() pthread_self()
- #endif
- #ifdef WIN32
- DWORD WINAPI f_thread1(LPVOID pvoid)
- #else
- void *f_thread1(void *pvoid)
- #endif
- {
- int i = 10;
- unsigned long id = gettidx();
- while (i--)
- {
- debugx(xinfo, "thread id(%lu): this is %s!\n", id, "xinfo");
- sleep(val_time);
- }
- }
- #ifdef WIN32
- DWORD WINAPI f_thread2(LPVOID pvoid)
- #else
- void *f_thread2(void *pvoid)
- #endif
- {
- int i = 10;
- unsigned long id = gettidx();
- while (i--)
- {
- debugx(xevent, "thread id(%lu): this is %s!\n", id, "xevent");
- sleep(val_time);
- }
- }
- #ifdef WIN32
- DWORD WINAPI f_thread3(LPVOID pvoid)
- #else
- void *f_thread3(void *pvoid)
- #endif
- {
- int i = 10;
- unsigned long id = gettidx();
- while (i--)
- {
- debugx(xerror, "thread id(%lu): this is %s!\n", id, "xerror");
- sleep(val_time);
- }
- }
- int main()
- {
- int i = 10;
- unsigned long id = 0;
- #if LOG_MOD==LOG_MUL_THREAD
- thread_mgmt_t tm;
- logx_init("D:/abc.txt", LOG_MUL_THREAD);
- tm_init(&tm);
- tm_create_thread(tm,"t1",f_thread1);
- tm_create_thread(tm,"t2",f_thread2);
- tm_create_thread(tm,"t3",f_thread3);
- #else
- logx_init("D:/abc.txt", LOG_SIG_THREAD);
- #endif
- debugx(xinfo, "this is %s!\n", "xinfo");
- debugx(xdata, "this is %s!\n", "xdata");
- debugx(xentry, "this is %s!\n", "xentry");
- debugx(xevent, "this is %s!\n", "xevent");
- debugx(xmsg, "this is %s!\n", "xmsg");
- debugx(xwarn, "this is %s!\n", "xwarn");
- debugx(xerror, "this is %s!\n", "xerror");
- debugx(xfatal, "this is %s!\n", "xfatal");
- debugx(xerror, "this is %s!\n", "xerror");
- id = gettidx();
- while (i--)
- {
- debugx(xfatal, "thread id(%d): this is %s!\n", id, "xfatal");
- sleep(val_time);
- }
- #if LOG_MOD==LOG_MUL_THREAD
- tm_exit(&tm);
- #endif
- logx_exit();
- return 0;
- }
附件:
debugx__.rar
阅读(1722) | 评论(0) | 转发(0) |