Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1438289
  • 博文数量: 704
  • 博客积分: 10140
  • 博客等级: 上将
  • 技术积分: 6230
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-15 20:41
文章分类

全部博文(704)

文章存档

2013年(1)

2012年(16)

2011年(536)

2010年(151)

分类:

2011-11-07 22:10:35

原文地址:线程池实现 作者:vincent-cws

今天终于花了整个下午时间把这个线程池实现了,今后应该会经常用到这个模块代码,贴出来分享一下。。。

继续修改了一下,加入了notifier通知函数。。。


file: main.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * @2011-11-06: initial
  5.  * @2011-11-13: add the notifier to register
  6.  */

  7. #include "threadpool.h"
  8. #include "stdio.h"

  9. #ifdef WIN32
  10. #define __lockx(lock)            EnterCriticalSection(&(lock))
  11. #define __unlockx(lock)            LeaveCriticalSection(&(lock))
  12. #define __lockx_init(lock,attr) InitializeCriticalSection(&(lock))
  13. #define __lockx_exit(lock,attr) DeleteCriticalSection(&(lock))
  14. #endif

  15. static lock_t lock;

  16. void thrd_hook_1(void *pdata)
  17. {
  18.     __lockx(lock);
  19.     printf("thrd_hook_1 running ...\n");
  20.     fflush(stdout);
  21.     __unlockx(lock);
  22. }

  23. void thrd_hook_2(void *pdata)
  24. {
  25.     __lockx(lock);
  26.     printf("thrd_hook_2 running ...\n");
  27.     fflush(stdout);
  28.     __unlockx(lock);
  29. }

  30. void thrd_hook_3(void *pdata)
  31. {
  32.     __lockx(lock);
  33.     printf("thrd_hook_3 running ...\n");
  34.     fflush(stdout);
  35.     __unlockx(lock);
  36. }

  37. void thrd_hook_4(void *pdata)
  38. {
  39.     __lockx(lock);
  40.     printf("thrd_hook_4 running ...\n");
  41.     fflush(stdout);
  42.     __unlockx(lock);
  43. }

  44. static int notifierx_call_test1(struct notifierx_block *pnb, unsigned long nlen, const void *pdata)
  45. {
  46.     thrd_msg_t *pmsg=(thrd_msg_t*)pdata;
  47.     __lockx(lock);
  48.     printf("-- fun: %s, nlen: %d, handle:%08x, state: %s --\n",
  49.         "notifierx_call_test1", nlen, pmsg->h, pmsg->stat==stat_busy?"busy":"free");
  50.     fflush(stdout);
  51.     __unlockx(lock);    
  52.     return 0;
  53. }

  54. static int notifierx_call_test2(struct notifierx_block *pnb, unsigned long nlen, const void *pdata)
  55. {
  56.     thrd_msg_t *pmsg=(thrd_msg_t*)pdata;
  57.     __lockx(lock);
  58.     printf("-- fun: %s, nlen: %d, handle:%08x, state: %s --\n",
  59.         "notifierx_call_test2", nlen, pmsg->h, pmsg->stat==stat_busy?"busy":"free");
  60.     fflush(stdout);
  61.     __unlockx(lock);    
  62.     return 0;
  63. }

  64. static int notifierx_call_test3(struct notifierx_block *pnb, unsigned long nlen, const void *pdata)
  65. {
  66.     thrd_msg_t *pmsg=(thrd_msg_t*)pdata;
  67.     __lockx(lock);
  68.     printf("-- fun: %s, nlen: %d, handle:%08x, state: %s --\n",
  69.         "notifierx_call_test3", nlen, pmsg->h, pmsg->stat==stat_busy?"busy":"free");
  70.     fflush(stdout);
  71.     __unlockx(lock);    
  72.     return 0;
  73. }

  74. #define NB_INIT(nb,f) ((nb).notifierx_call=(f))

  75. void main()
  76. {
  77.     thrdpool_t* pthrdpool = thrdpool();
  78.     thrd_handle h1,h2,h3,h4;
  79.     notifierx_block_t nb1,nb2,nb3;

  80.     NB_INIT(nb1,notifierx_call_test1);
  81.     NB_INIT(nb2,notifierx_call_test2);
  82.     NB_INIT(nb3,notifierx_call_test3);

  83.     __lockx_init(lock,0);
  84.     
  85.     thrdpool_init(6);

  86.     pthrdpool->ops.reg_notifier(&nb1);
  87.     pthrdpool->ops.reg_notifier(&nb2);
  88.     pthrdpool->ops.reg_notifier(&nb3);
  89.     pthrdpool->ops.unreg_notifier(&nb1);
  90.     
  91.     pthrdpool->ops.query();

  92.     h1=pthrdpool->ops.thrd_alloc(thrd_hook_1, 0);
  93.     pthrdpool->ops.query();
  94.     h2=pthrdpool->ops.thrd_alloc(thrd_hook_2, 0);
  95.     pthrdpool->ops.query();
  96.     pthrdpool->ops.wakeup(h2);
  97.     h3=pthrdpool->ops.thrd_alloc(thrd_hook_3, 0);
  98.     pthrdpool->ops.query();
  99.     h4=pthrdpool->ops.thrd_alloc(thrd_hook_4, 0);
  100.     pthrdpool->ops.query();
  101.     pthrdpool->ops.wakeup(h2);
  102.     Sleep(1000);
  103.     pthrdpool->ops.thrd_free(h2);
  104.     pthrdpool->ops.thrd_del(h1);
  105.     pthrdpool->ops.query();
  106.     pthrdpool->ops.wakeup(h2);
  107.     pthrdpool->ops.wakeup(h4);
  108.     pthrdpool->ops.wakeup(h4);
  109.     pthrdpool->ops.wakeup(h3);
  110.     pthrdpool->ops.wakeup(h3);
  111.     pthrdpool->ops.thrd_del(h2);
  112.     pthrdpool->ops.thrd_del(h3);
  113.     pthrdpool->ops.thrd_del(h4);
  114.     Sleep(1000);
  115.     pthrdpool->ops.query();
  116.     pthrdpool->ops.thrd_add();
  117.     pthrdpool->ops.query();

  118.     thrdpool_exit();
  119.     __lockx_exit(lock,0);

  120. }

file: threadpool.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * @2011-11-06: initial
  5.  * @2011-11-13: add the notifier to register
  6.  */

  7. #ifndef _THREADPOOL_H_
  8. #define _THREADPOOL_H_


  9. #include "list.h"

  10. #include "notifierx.h"

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


  16. #define null (void*)0
  17. #define NULL (void*)0



  18. #ifndef __assert
  19. #define __assert(x)
  20. #endif


  21. #ifdef WIN32
  22. #    define thrd_handle    HANDLE
  23. #    define event_t        HANDLE
  24. #    define lock_t        CRITICAL_SECTION
  25. #    define attr_t        void*
  26. #else
  27. #    define thrd_handle    pthread_t
  28. #    define event_t        pthread_cond_t
  29. #    define lock_t        pthread_mutex_t
  30. #    define attr_t        pthread_mutexattr_t
  31. #endif

  32. typedef void (*thrd_hook_t)(void *pdata);

  33. #define stat_busy    1
  34. #define stat_free    2

  35. typedef struct thrd_msg_s{
  36.     thrd_handle h;
  37.     int stat;
  38.     void* v;
  39. }thrd_msg_t;

  40. #define INIT_THRD_MSG(st,hdl) \
  41. {\
  42.     (st).h=(hdl); \
  43.     (st).stat=stat_free;\
  44. }
  45. #define SET_THRD_STAT(st,s) \
  46. {\
  47.     (st).stat=(s);\
  48. }
  49. #define ST_SIZE_AND_VAL(st) sizeof(st),&(st)

  50. #define call_chain(chain,st,s) \
  51. {    \
  52.     SET_THRD_STAT((st), (s)); \
  53.     notifierx_call_chain(&(chain), ST_SIZE_AND_VAL(st)); \
  54. }


  55. typedef struct thrd_desc_s{
  56.     thrd_handle h;
  57.     thrd_hook_t thrd_hook;
  58.     void *pthrd_data;
  59.     event_t hevent_go;
  60.     event_t hevent_exit;
  61.     lock_t cslock;
  62.     struct list_head list;
  63.     unsigned int ref_cnts;
  64.     attr_t attr;
  65. }thrd_desc_t;


  66. #ifdef WIN32
  67. #define INIT_EVENT(h) { h=CreateEvent(NULL, TRUE, FALSE, NULL); }
  68. #define EXIT_EVENT(h) { if (hnull != (h)) CloseHandle(h); }
  69. #define SET_EVENT(h) { if (hnull != (h)) SetEvent(h); }
  70. #define RESET_EVENT(h) {if (hnull != (h)) ResetEvent(h); }
  71. #else
  72. #define INIT_EVENT(h) { pthread_cond_init(&(h), null); }
  73. #define EXIT_EVENT(h) { pthread_cond_destroy(&(h); }
  74. #define SET_EVENT(h) { pthread_cond_signal(&(h)); }
  75. #endif

  76. #define INIT_THRD_DESC(td) \
  77. { \
  78.     (td).h = 0; \
  79.     (td).thrd_hook = (thrd_hook_t)0; \
  80.     (td).pthrd_data = 0; \
  81.     INIT_EVENT((td).hevent_go); \
  82.     INIT_EVENT((td).hevent_exit); \
  83.     (td).list.prev=&(td).list; \
  84.     (td).list.next=&(td).list; \
  85.     (td).ref_cnts=0; \
  86. }

  87. #define CLEAR_THRD_DESC(td) \
  88. { \
  89.     (td).thrd_hook = (thrd_hook_t)0; \
  90.     (td).pthrd_data = 0; \
  91. }

  92. #define SET_HANDLER_THRD_DESC(td,h,p) \
  93. { \
  94.     (td).thrd_hook = h; \
  95.     (td).pthrd_data = p; \
  96. }

  97. typedef struct thrdpool_ops{
  98.     thrd_handle (*thrd_alloc)(thrd_hook_t thrd_hook, void* pdata);
  99.     void (*thrd_free)(thrd_handle h);

  100.     int (*wakeup)(thrd_handle h);
  101.     
  102.     int (*thrd_add)();
  103.     int (*thrd_del)(thrd_handle h);
  104.     
  105.     int (*query)();

  106.     int (*reg_notifier)(struct notifierx_block *pnb);
  107.     int (*unreg_notifier)(struct notifierx_block *pnb);    
  108. }thrdpool_ops_t;

  109. typedef struct thrdpool_s{
  110.     struct thrdpool_ops ops;
  111.     struct list_head list;
  112.     struct notifierx_head thrdpool_chain;
  113.     lock_t cslock;
  114.     attr_t attr;
  115. }thrdpool_t;

  116. extern thrdpool_t* thrdpool();

  117. extern int thrdpool_init(int nthrds);
  118. extern int thrdpool_exit();

  119. #endif


file: threadpool.c
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * @2011-11-06: initial
  5.  * @2011-11-13: add the notifier to register
  6.  */


  7. #include "threadpool.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(lock)            EnterCriticalSection(&(lock))
  16. #define __unlockx(lock)            LeaveCriticalSection(&(lock))
  17. #define __lockx_init(lock,attr) InitializeCriticalSection(&(lock))
  18. #define __lockx_exit(lock,attr) DeleteCriticalSection(&(lock));

  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(lock)    pthread_mutex_lock(&(lock))
  27. #define __unlockx(lock) pthread_mutex_unlock(&(lock))
  28. #define __lockx_init(lock,attr) \
  29.     pthread_mutexattr_init(&(attr)); \
  30.     pthread_mutexattr_settype(&(attr),PTHREAD_MUTEX_RECURSIVE); \
  31.     pthread_mutex_init(&(lock),&(attr)); \

  32. #define __lockx_exit(attr,attr) \
  33.     pthread_mutex_destroy(&(lock)); \
  34.     pthread_mutexattr_destroy(&(attr)); \
  35.     
  36. #endif


  37. #ifdef WIN32
  38. static DWORD WINAPI thread_proc(LPVOID pvoid)
  39. #else
  40. static void *thread_proc(void *pvoid)
  41. #endif
  42. {
  43.     thrdpool_t* pthrdpool = thrdpool();
  44.     thrd_desc_t* pthrd_desc=(thrd_desc_t*)pvoid;

  45.     thrd_msg_t thrd_msg;

  46.     __assert(pthrd_desc&&pthrdpool);

  47.        INIT_THRD_MSG(thrd_msg, pthrd_desc->h);
  48.         
  49.     while (1)
  50.     {
  51. #        ifdef WIN32
  52.         if (WaitForSingleObject((HANDLE)(pthrd_desc->hevent_go), INFINITE) == WAIT_OBJECT_0)
  53. #        else
  54.         int ret=0;
  55.         __lockx(pthrd_desc->cslock);
  56.         ret = pthread_cond_wait(&pthrd_desc->hevent_go, &pthrd_desc->cslock);
  57.         __unlockx(pthrd_desc->cslock);
  58.         if (ret == 0)
  59. #        endif
  60.         {
  61.             call_chain(pthrdpool->thrdpool_chain,thrd_msg,stat_busy);
  62.             __lockx(pthrd_desc->cslock);
  63.             while(pthrd_desc->ref_cnts>0) {
  64.                 if (pthrd_desc->thrd_hook)
  65.                     pthrd_desc->thrd_hook(pthrd_desc->pthrd_data);
  66.                 pthrd_desc->ref_cnts--;
  67.             }
  68. #            ifdef WIN32
  69.                 RESET_EVENT(pthrd_desc->hevent_go);
  70. #            endif
  71.             __unlockx(pthrd_desc->cslock);

  72.         }
  73. #        ifdef WIN32
  74.         if (WaitForSingleObject(pthrd_desc->hevent_exit, 0) == WAIT_OBJECT_0)
  75.             break;
  76. #        endif
  77.         
  78.         call_chain(pthrdpool->thrdpool_chain,thrd_msg,stat_free);
  79.     } /* while(1) */
  80.     return 0;    
  81. }

  82. static thrd_handle __thrd_alloc(thrd_hook_t thrd_hook, void* pdata)
  83. {
  84.     struct list_head *list_p;
  85.     thrd_desc_t* pthrd_desc=null;
  86.     
  87.     thrdpool_t* pthrdpool = thrdpool();    
  88.     __assert(pthrdpool);
  89.     __lockx(pthrdpool->cslock);
  90.     list_for_each(list_p, &(pthrdpool->list))
  91.     {
  92.         pthrd_desc = list_entry(list_p, thrd_desc_t, list);
  93.         if (!pthrd_desc->thrd_hook)
  94.         {
  95.             __lockx(pthrd_desc->cslock);
  96.             SET_HANDLER_THRD_DESC(*pthrd_desc, thrd_hook, pdata);    
  97.             __unlockx(pthrd_desc->cslock);
  98.             __unlockx(pthrdpool->cslock);
  99.             return pthrd_desc->h;
  100.         }
  101.     }
  102.     __unlockx(pthrdpool->cslock);
  103.     return 0;
  104. }

  105. static void __thrd_free(thrd_handle h)
  106. {
  107.     struct list_head *list_p;
  108.     thrd_desc_t* pthrd_desc=null;
  109.     
  110.     thrdpool_t* pthrdpool = thrdpool();    
  111.     __assert(pthrdpool);
  112.     __lockx(pthrdpool->cslock);
  113.     list_for_each(list_p, &(pthrdpool->list))
  114.     {
  115.         pthrd_desc = list_entry(list_p, thrd_desc_t, list);
  116.         if (h == pthrd_desc->h) {
  117.             __lockx(pthrd_desc->cslock);
  118.             CLEAR_THRD_DESC(*pthrd_desc);    
  119.             __unlockx(pthrd_desc->cslock);
  120.         }
  121.     }    
  122.     __unlockx(pthrdpool->cslock);
  123. }
  124.     
  125. static int __wakeup(thrd_handle h)
  126. {
  127.     struct list_head *list_p;
  128.     thrd_desc_t* pthrd_desc=null;
  129.     
  130.     thrdpool_t* pthrdpool = thrdpool();    
  131.     __assert(pthrdpool);
  132.     __lockx(pthrdpool->cslock);
  133.     list_for_each(list_p, &(pthrdpool->list))
  134.     {
  135.         pthrd_desc = list_entry(list_p, thrd_desc_t, list);
  136.         if (h==pthrd_desc->h)
  137.         {
  138.             __lockx(pthrd_desc->cslock);
  139.             if (hnull != pthrd_desc->hevent_go)
  140.             {
  141.                 SET_EVENT(pthrd_desc->hevent_go);
  142.                 pthrd_desc->ref_cnts++;
  143.             }
  144.             __unlockx(pthrd_desc->cslock);
  145.             __unlockx(pthrdpool->cslock);
  146.             return 0;
  147.         }
  148.     }    
  149.     __unlockx(pthrdpool->cslock);
  150.     return -1;
  151. }
  152.     
  153. static int __thrd_add()
  154. {
  155.     thrdpool_t* pthrdpool = thrdpool();
  156.     thrd_desc_t* pthrd_desc=null;
  157.     __assert(pthrdpool);

  158.     pthrd_desc=(thrd_desc_t*)malloc(sizeof(thrd_desc_t));
  159.     __assert(pthrd_desc);
  160.     
  161.     INIT_THRD_DESC(*pthrd_desc);

  162.     __lockx_init(pthrd_desc->cslock,pthrd_desc->attr);

  163. #    ifdef WIN32    
  164.     pthrd_desc->h = CreateThread(
  165.         null, // default security attributes
  166.         0, // use default stack size
  167.         thread_proc,// thread function
  168.         pthrd_desc, // argument to thread function
  169.         0, // use default creation flags
  170.         0);
  171.     if(NULL == pthrd_desc->h)
  172.         goto __err;
  173. #    else
  174.     if(pthread_create(&pthrd_desc->h, null, thread_proc, null)!=0)
  175.         goto __err;
  176. #    endif
  177.     
  178.     __lockx(pthrdpool->cslock);
  179.     list_add(&pthrd_desc->list, &pthrdpool->list);
  180.     __unlockx(pthrdpool->cslock);
  181.     return 0;

  182. __err:
  183.     __lockx_exit(pthrd_desc->cslock, pthrd_desc->attr);
  184.     free(pthrd_desc);

  185.     return -1;
  186. }

  187. static int __thrd_del(thrd_handle h)
  188. {
  189.     struct list_head *list_p;
  190.     thrd_desc_t* pthrd_desc=null;
  191.     

  192.     thrdpool_t* pthrdpool = thrdpool();    
  193.     __assert(pthrdpool);
  194.     __lockx(pthrdpool->cslock);
  195.     list_for_each(list_p, &(pthrdpool->list))
  196.     {
  197.         pthrd_desc = list_entry(list_p, thrd_desc_t, list);
  198.         if (h==pthrd_desc->h) {
  199.             
  200. #            ifdef WIN32
  201.             SET_EVENT(pthrd_desc->hevent_exit);
  202.             SET_EVENT(pthrd_desc->hevent_go);
  203. #            else
  204.             SET_EVENT(pthrd_desc->hevent_go);
  205.             sleep(1);
  206.             pthread_cancel(pthrd_desc->h);
  207. #            endif
  208.             
  209.             /* wait the thread exit */
  210.             if (hnull != pthrd_desc->h)
  211.             {
  212. #                ifdef WIN32
  213.                 /* terminal the log server thread until 1 second over */
  214.                 unsigned long state = WaitForSingleObject (pthrd_desc->h, 2000);
  215.                 switch (state)
  216.                 {
  217.                 case WAIT_TIMEOUT:
  218.                     {
  219.                         unsigned long exit_code = 0;
  220.                         if (0 != TerminateThread(pthrd_desc->h, exit_code))
  221.                             ; /* terminate the server thread */
  222.                         else
  223.                             ; /* terminate the LogSrv thread failed */
  224.                         break;
  225.                     }
  226.                 case WAIT_ABANDONED: break; /* the Thread abandoned */
  227.                 case WAIT_OBJECT_0: break; /* exit the server thread */
  228.                 default: break;
  229.                 }
  230.                 CloseHandle(pthrd_desc->h);
  231. #                else
  232.                 int state = pthread_join(pthrd_desc->h, null);
  233. #                endif
  234.                 pthrd_desc->h=hnull;
  235.             }

  236.             __lockx_exit(pthrd_desc->cslock,pthrd_desc->attr);

  237. #            ifdef WIN32
  238.             EXIT_EVENT(pthrd_desc->hevent_exit);
  239. #            endif

  240.             EXIT_EVENT(pthrd_desc->hevent_go);

  241.             /* remove itself from the list */
  242.             list_del(&pthrd_desc->list);
  243.             /* free the memory from the malloc of the thread descript struct */
  244.             free(pthrd_desc);
  245.             
  246.             break;
  247.         } // if (h==pthrd_desc->h)
  248.     }    
  249.     __unlockx(pthrdpool->cslock);
  250.     return 0;
  251. }

  252. static void __display(const thrd_desc_t* pthrd_desc)
  253. {
  254.     __assert(pthrd_desc);
  255.     printf("handle:%08x, hook: %s\n",
  256.         pthrd_desc->h, pthrd_desc->thrd_hook ? "installed":"uninstalled");
  257. }
  258.     
  259. static int __query()
  260. {
  261.     struct list_head *list_p;
  262.     thrd_desc_t* pthrd_desc=null;
  263.     
  264.     thrdpool_t* pthrdpool = thrdpool();    
  265.     __assert(pthrdpool);
  266.     __lockx(pthrdpool->cslock);
  267.     list_for_each(list_p, &(pthrdpool->list))
  268.     {
  269.         pthrd_desc = list_entry(list_p, thrd_desc_t, list);
  270.         __display(pthrd_desc);
  271.     }    
  272.     printf("------------------------------\n");
  273.     __unlockx(pthrdpool->cslock);
  274.     return 0;
  275. }

  276. static int __reg_notifier(struct notifierx_block *pnb)
  277. {
  278.     thrdpool_t* pthrdpool = thrdpool();    
  279.     __assert(pthrdpool&&pnb);
  280.     return notifierx_chain_register(&pthrdpool->thrdpool_chain, pnb);
  281. }

  282. static int __unreg_notifier(struct notifierx_block *pnb)
  283. {
  284.     thrdpool_t* pthrdpool = thrdpool();    
  285.     __assert(pnb);
  286.     return notifierx_chain_unregister(&pthrdpool->thrdpool_chain, pnb);
  287. }

  288. thrdpool_t* thrdpool()
  289. {
  290.     static thrdpool_t s_thrdpool;
  291.     return &s_thrdpool;
  292. }

  293. int thrdpool_init(int nthrds)
  294. {
  295.     thrdpool_t* pthrdpool = thrdpool();
  296.     int ret=0, count=0;
  297.     __assert(pthrdpool);

  298.     INIT_NOTIFIERX_HEAD(pthrdpool->thrdpool_chain);
  299.     __lockx_init(pthrdpool->cslock,pthrdpool->attr);

  300.     pthrdpool->list.next=&pthrdpool->list;
  301.     pthrdpool->list.prev=&pthrdpool->list;

  302.     pthrdpool->ops.thrd_alloc    =__thrd_alloc;
  303.     pthrdpool->ops.thrd_free    =__thrd_free;
  304.     pthrdpool->ops.wakeup    =__wakeup;
  305.     pthrdpool->ops.thrd_add =__thrd_add;
  306.     pthrdpool->ops.thrd_del    =__thrd_del;
  307.     pthrdpool->ops.query    =__query;
  308.     pthrdpool->ops.reg_notifier = __reg_notifier;
  309.     pthrdpool->ops.unreg_notifier = __unreg_notifier;

  310.     while (count<nthrds) {
  311.         ret=__thrd_add();
  312.         __assert(-1!=ret);
  313.         count++;
  314.     }
  315.     return 0;
  316. }

  317. int thrdpool_exit()
  318. {
  319.     struct list_head *list_p;
  320.     thrd_desc_t* pthrd_desc=null;
  321.     thrd_desc_t* pthrd_temp=null;
  322.     thrdpool_t* pthrdpool = thrdpool();    
  323.     __assert(pthrdpool);

  324.     list_for_each_safe(list_p, pthrd_temp, &(pthrdpool->list))
  325.     {
  326.         pthrd_desc = list_entry(list_p, thrd_desc_t, list);
  327.         if (hnull!=pthrd_desc->h)
  328.             __thrd_del(pthrd_desc->h);
  329.     }
  330.     __lockx_exit(pthrdpool->cslock,pthrdpool->attr);
  331.     EXIT_NOTIFIERX_HEAD(pthrdpool->thrdpool_chain);

  332.     return 0;
  333. }

file: notifierx.h
  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-11-13
  5.  */

  6. #ifndef _NOTIFIERX_H_
  7. #define _NOTIFIERX_H_

  8. #include "list.h"

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

  14. #define null (void*)0
  15. #define NULL (void*)0

  16. #ifndef __assert
  17. #define __assert(x)
  18. #endif

  19. #ifdef WIN32
  20. #    define thrd_handle    HANDLE
  21. #    define event_t        HANDLE
  22. #    define lock_t        CRITICAL_SECTION
  23. #    define attr_t        void*
  24. #else
  25. #    define thrd_handle    pthread_t
  26. #    define event_t        pthread_cond_t
  27. #    define lock_t        pthread_mutex_t
  28. #    define attr_t        pthread_mutexattr_t
  29. #endif


  30. typedef struct notifierx_block {
  31.     int (*notifierx_call)(struct notifierx_block *pnb, unsigned long nlen, const void *pdata);
  32.     struct list_head list;
  33. }notifierx_block_t;

  34. struct notifierx_head {
  35.     lock_t cslock;
  36.     attr_t attr;
  37.     struct list_head head;
  38. };

  39. #define INIT_NOTIFIERX_HEAD(name) do {                \
  40.         __lockx_init((name).cslock,(name).attr);    \
  41.         INIT_LIST_HEAD(&(name).head);                \
  42.     } while (0)
  43.         

  44. #define EXIT_NOTIFIERX_HEAD(name) do {                    \
  45.         notifierx_chain_all_unregister(&(name));    \
  46.         __lockx_exit((name).cslock, (name).attr);        \
  47.     } while (0)
  48. //            

  49. extern int notifierx_chain_register(struct notifierx_head *pnh, struct notifierx_block *pnb);
  50. extern int notifierx_chain_all_unregister(struct notifierx_head *pnh);
  51. extern int notifierx_chain_unregister(struct notifierx_head *pnh, struct notifierx_block *pnb);
  52. extern int notifierx_call_chain(struct notifierx_head *pnh, unsigned long nlen, void *pdata);

  53. #endif



file: notifierx.c

  1. /**
  2.  * author: vincent.cws2008@gmail.com
  3.  * history:
  4.  * initial @ 2011-11-13
  5.  */


  6. #include "notifierx.h"

  7. #ifdef WIN32

  8. #ifndef hnull
  9. #define hnull INVALID_HANDLE_VALUE
  10. #endif
  11. #ifndef null
  12. #define null NULL
  13. #endif
  14. #define __lockx(lock)            EnterCriticalSection(&(lock))
  15. #define __unlockx(lock)            LeaveCriticalSection(&(lock))
  16. #define __lockx_init(lock,attr) InitializeCriticalSection(&(lock))
  17. #define __lockx_exit(lock,attr) DeleteCriticalSection(&(lock))

  18. #else

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

  31. #define __lockx_exit(attr,attr) \
  32.     pthread_mutex_destroy(&(lock)); \
  33.     pthread_mutexattr_destroy(&(attr)); \
  34.     
  35. #endif


  36. int notifierx_chain_register(struct notifierx_head *pnh,
  37.         struct notifierx_block *pnb)
  38. {
  39.     __assert(pnh&&pnb);
  40.     __lockx(pnh->cslock);
  41.     list_add(&pnb->list, &pnh->head);
  42.     __unlockx(pnh->cslock);    
  43.     return 0;
  44. }

  45. int notifierx_chain_all_unregister(struct notifierx_head *pnh)
  46. {
  47.     struct list_head *list_p;
  48.     notifierx_block_t* pnb_it=null;
  49.     notifierx_block_t* pnb_temp=null;
  50.     __assert(pnh);

  51.     __lockx(pnh->cslock);
  52.     list_for_each_safe(list_p, pnb_temp, &(pnh->head))
  53.     {
  54.         pnb_it = list_entry(list_p, notifierx_block_t, list);
  55.         list_del(&pnb_it->list);
  56.     }
  57.     
  58.     __unlockx(pnh->cslock);

  59.     return 0;
  60. }

  61. int notifierx_chain_unregister(struct notifierx_head *pnh,
  62.         struct notifierx_block *pnb)
  63. {
  64.     struct list_head *list_p;
  65.     struct notifierx_block *pnb_it;
  66.     __assert(pnh&&pnb);
  67.     
  68.     __lockx(pnh->cslock);
  69.     list_for_each(list_p, &(pnh->head))
  70.     {
  71.         pnb_it = list_entry(list_p, notifierx_block_t, list);
  72.         if (pnb_it->notifierx_call == pnb->notifierx_call)
  73.         {
  74.             list_del(&pnb_it->list);
  75.             __unlockx(pnh->cslock);
  76.             return 0;
  77.         }
  78.     }
  79.     __unlockx(pnh->cslock);    
  80.     return -1;
  81. }

  82. int notifierx_call_chain(struct notifierx_head *pnh, unsigned long nlen, void *pdata)
  83. {
  84.     struct list_head *list_p;
  85.     notifierx_block_t* pnb_it=null;

  86.     __assert(pnh);
  87.     
  88.     __lockx(pnh->cslock);
  89.     list_for_each(list_p, &(pnh->head))
  90.     {
  91.         pnb_it = list_entry(list_p, notifierx_block_t, list);
  92.         pnb_it->notifierx_call(pnb_it, nlen, pdata);
  93.     }    
  94.     __unlockx(pnh->cslock);

  95.     return 0;
  96. }



attached:

 threadpool.rar  


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