今天终于花了整个下午时间把这个线程池实现了,今后应该会经常用到这个模块代码,贴出来分享一下。。。
继续修改了一下,加入了notifier通知函数。。。
file: main.c
- /**
-
* author: vincent.cws2008@gmail.com
-
* history:
-
* @2011-11-06: initial
-
* @2011-11-13: add the notifier to register
-
*/
-
-
#include "threadpool.h"
-
#include "stdio.h"
-
-
#ifdef WIN32
-
#define __lockx(lock) EnterCriticalSection(&(lock))
-
#define __unlockx(lock) LeaveCriticalSection(&(lock))
-
#define __lockx_init(lock,attr) InitializeCriticalSection(&(lock))
-
#define __lockx_exit(lock,attr) DeleteCriticalSection(&(lock))
-
#endif
-
-
static lock_t lock;
-
-
void thrd_hook_1(void *pdata)
-
{
-
__lockx(lock);
-
printf("thrd_hook_1 running ...\n");
-
fflush(stdout);
-
__unlockx(lock);
-
}
-
-
void thrd_hook_2(void *pdata)
-
{
-
__lockx(lock);
-
printf("thrd_hook_2 running ...\n");
-
fflush(stdout);
-
__unlockx(lock);
-
}
-
-
void thrd_hook_3(void *pdata)
-
{
-
__lockx(lock);
-
printf("thrd_hook_3 running ...\n");
-
fflush(stdout);
-
__unlockx(lock);
-
}
-
-
void thrd_hook_4(void *pdata)
-
{
-
__lockx(lock);
-
printf("thrd_hook_4 running ...\n");
-
fflush(stdout);
-
__unlockx(lock);
-
}
-
-
static int notifierx_call_test1(struct notifierx_block *pnb, unsigned long nlen, const void *pdata)
-
{
-
thrd_msg_t *pmsg=(thrd_msg_t*)pdata;
-
__lockx(lock);
-
printf("-- fun: %s, nlen: %d, handle:%08x, state: %s --\n",
-
"notifierx_call_test1", nlen, pmsg->h, pmsg->stat==stat_busy?"busy":"free");
-
fflush(stdout);
-
__unlockx(lock);
-
return 0;
-
}
-
-
static int notifierx_call_test2(struct notifierx_block *pnb, unsigned long nlen, const void *pdata)
-
{
-
thrd_msg_t *pmsg=(thrd_msg_t*)pdata;
-
__lockx(lock);
-
printf("-- fun: %s, nlen: %d, handle:%08x, state: %s --\n",
-
"notifierx_call_test2", nlen, pmsg->h, pmsg->stat==stat_busy?"busy":"free");
-
fflush(stdout);
-
__unlockx(lock);
-
return 0;
-
}
-
-
static int notifierx_call_test3(struct notifierx_block *pnb, unsigned long nlen, const void *pdata)
-
{
-
thrd_msg_t *pmsg=(thrd_msg_t*)pdata;
-
__lockx(lock);
-
printf("-- fun: %s, nlen: %d, handle:%08x, state: %s --\n",
-
"notifierx_call_test3", nlen, pmsg->h, pmsg->stat==stat_busy?"busy":"free");
-
fflush(stdout);
-
__unlockx(lock);
-
return 0;
-
}
-
-
#define NB_INIT(nb,f) ((nb).notifierx_call=(f))
-
-
void main()
-
{
-
thrdpool_t* pthrdpool = thrdpool();
-
thrd_handle h1,h2,h3,h4;
-
notifierx_block_t nb1,nb2,nb3;
-
-
NB_INIT(nb1,notifierx_call_test1);
-
NB_INIT(nb2,notifierx_call_test2);
-
NB_INIT(nb3,notifierx_call_test3);
-
-
__lockx_init(lock,0);
-
-
thrdpool_init(6);
-
-
pthrdpool->ops.reg_notifier(&nb1);
-
pthrdpool->ops.reg_notifier(&nb2);
-
pthrdpool->ops.reg_notifier(&nb3);
-
pthrdpool->ops.unreg_notifier(&nb1);
-
-
pthrdpool->ops.query();
-
-
h1=pthrdpool->ops.thrd_alloc(thrd_hook_1, 0);
-
pthrdpool->ops.query();
-
h2=pthrdpool->ops.thrd_alloc(thrd_hook_2, 0);
-
pthrdpool->ops.query();
-
pthrdpool->ops.wakeup(h2);
-
h3=pthrdpool->ops.thrd_alloc(thrd_hook_3, 0);
-
pthrdpool->ops.query();
-
h4=pthrdpool->ops.thrd_alloc(thrd_hook_4, 0);
-
pthrdpool->ops.query();
-
pthrdpool->ops.wakeup(h2);
-
Sleep(1000);
-
pthrdpool->ops.thrd_free(h2);
-
pthrdpool->ops.thrd_del(h1);
-
pthrdpool->ops.query();
-
pthrdpool->ops.wakeup(h2);
-
pthrdpool->ops.wakeup(h4);
-
pthrdpool->ops.wakeup(h4);
-
pthrdpool->ops.wakeup(h3);
-
pthrdpool->ops.wakeup(h3);
-
pthrdpool->ops.thrd_del(h2);
-
pthrdpool->ops.thrd_del(h3);
-
pthrdpool->ops.thrd_del(h4);
-
Sleep(1000);
-
pthrdpool->ops.query();
-
pthrdpool->ops.thrd_add();
-
pthrdpool->ops.query();
-
-
thrdpool_exit();
-
__lockx_exit(lock,0);
-
-
}
file: threadpool.h
- /**
-
* author: vincent.cws2008@gmail.com
-
* history:
-
* @2011-11-06: initial
-
* @2011-11-13: add the notifier to register
-
*/
-
-
#ifndef _THREADPOOL_H_
-
#define _THREADPOOL_H_
-
-
-
#include "list.h"
-
-
#include "notifierx.h"
-
-
#ifdef WIN32
-
# include "windows.h"
-
#else
-
# include <pthread.h>
-
#endif
-
-
-
#define null (void*)0
-
#define NULL (void*)0
-
-
-
-
#ifndef __assert
-
#define __assert(x)
-
#endif
-
-
-
#ifdef WIN32
-
# define thrd_handle HANDLE
-
# define event_t HANDLE
-
# define lock_t CRITICAL_SECTION
-
# define attr_t void*
-
#else
-
# define thrd_handle pthread_t
-
# define event_t pthread_cond_t
-
# define lock_t pthread_mutex_t
-
# define attr_t pthread_mutexattr_t
-
#endif
-
-
typedef void (*thrd_hook_t)(void *pdata);
-
-
#define stat_busy 1
-
#define stat_free 2
-
-
typedef struct thrd_msg_s{
-
thrd_handle h;
-
int stat;
-
void* v;
-
}thrd_msg_t;
-
-
#define INIT_THRD_MSG(st,hdl) \
-
{\
-
(st).h=(hdl); \
-
(st).stat=stat_free;\
-
}
-
#define SET_THRD_STAT(st,s) \
-
{\
-
(st).stat=(s);\
-
}
-
#define ST_SIZE_AND_VAL(st) sizeof(st),&(st)
-
-
#define call_chain(chain,st,s) \
-
{ \
-
SET_THRD_STAT((st), (s)); \
-
notifierx_call_chain(&(chain), ST_SIZE_AND_VAL(st)); \
-
}
-
-
-
typedef struct thrd_desc_s{
-
thrd_handle h;
-
thrd_hook_t thrd_hook;
-
void *pthrd_data;
-
event_t hevent_go;
-
event_t hevent_exit;
-
lock_t cslock;
-
struct list_head list;
-
unsigned int ref_cnts;
-
attr_t attr;
-
}thrd_desc_t;
-
-
-
#ifdef WIN32
-
#define INIT_EVENT(h) { h=CreateEvent(NULL, TRUE, FALSE, NULL); }
-
#define EXIT_EVENT(h) { if (hnull != (h)) CloseHandle(h); }
-
#define SET_EVENT(h) { if (hnull != (h)) SetEvent(h); }
-
#define RESET_EVENT(h) {if (hnull != (h)) ResetEvent(h); }
-
#else
-
#define INIT_EVENT(h) { pthread_cond_init(&(h), null); }
-
#define EXIT_EVENT(h) { pthread_cond_destroy(&(h); }
-
#define SET_EVENT(h) { pthread_cond_signal(&(h)); }
-
#endif
-
-
#define INIT_THRD_DESC(td) \
-
{ \
-
(td).h = 0; \
-
(td).thrd_hook = (thrd_hook_t)0; \
-
(td).pthrd_data = 0; \
-
INIT_EVENT((td).hevent_go); \
-
INIT_EVENT((td).hevent_exit); \
-
(td).list.prev=&(td).list; \
-
(td).list.next=&(td).list; \
-
(td).ref_cnts=0; \
-
}
-
-
#define CLEAR_THRD_DESC(td) \
-
{ \
-
(td).thrd_hook = (thrd_hook_t)0; \
-
(td).pthrd_data = 0; \
-
}
-
-
#define SET_HANDLER_THRD_DESC(td,h,p) \
-
{ \
-
(td).thrd_hook = h; \
-
(td).pthrd_data = p; \
-
}
-
-
typedef struct thrdpool_ops{
-
thrd_handle (*thrd_alloc)(thrd_hook_t thrd_hook, void* pdata);
-
void (*thrd_free)(thrd_handle h);
-
-
int (*wakeup)(thrd_handle h);
-
-
int (*thrd_add)();
-
int (*thrd_del)(thrd_handle h);
-
-
int (*query)();
-
-
int (*reg_notifier)(struct notifierx_block *pnb);
-
int (*unreg_notifier)(struct notifierx_block *pnb);
-
}thrdpool_ops_t;
-
-
typedef struct thrdpool_s{
-
struct thrdpool_ops ops;
-
struct list_head list;
-
struct notifierx_head thrdpool_chain;
-
lock_t cslock;
-
attr_t attr;
-
}thrdpool_t;
-
-
extern thrdpool_t* thrdpool();
-
-
extern int thrdpool_init(int nthrds);
-
extern int thrdpool_exit();
-
-
#endif
file: threadpool.c
- /**
-
* author: vincent.cws2008@gmail.com
-
* history:
-
* @2011-11-06: initial
-
* @2011-11-13: add the notifier to register
-
*/
-
-
-
#include "threadpool.h"
-
-
#ifdef WIN32
-
-
#ifndef hnull
-
#define hnull INVALID_HANDLE_VALUE
-
#endif
-
#ifndef null
-
#define null NULL
-
#endif
-
#define __lockx(lock) EnterCriticalSection(&(lock))
-
#define __unlockx(lock) LeaveCriticalSection(&(lock))
-
#define __lockx_init(lock,attr) InitializeCriticalSection(&(lock))
-
#define __lockx_exit(lock,attr) DeleteCriticalSection(&(lock));
-
-
#else
-
-
#ifndef hnull
-
#define hnull (void*)0
-
#endif
-
#ifndef null
-
#define null (void*)0
-
#endif
-
#define __lockx(lock) pthread_mutex_lock(&(lock))
-
#define __unlockx(lock) pthread_mutex_unlock(&(lock))
-
#define __lockx_init(lock,attr) \
-
pthread_mutexattr_init(&(attr)); \
-
pthread_mutexattr_settype(&(attr),PTHREAD_MUTEX_RECURSIVE); \
-
pthread_mutex_init(&(lock),&(attr)); \
-
-
#define __lockx_exit(attr,attr) \
-
pthread_mutex_destroy(&(lock)); \
-
pthread_mutexattr_destroy(&(attr)); \
-
-
#endif
-
-
-
#ifdef WIN32
-
static DWORD WINAPI thread_proc(LPVOID pvoid)
-
#else
-
static void *thread_proc(void *pvoid)
-
#endif
-
{
-
thrdpool_t* pthrdpool = thrdpool();
-
thrd_desc_t* pthrd_desc=(thrd_desc_t*)pvoid;
-
-
thrd_msg_t thrd_msg;
-
-
__assert(pthrd_desc&&pthrdpool);
-
-
INIT_THRD_MSG(thrd_msg, pthrd_desc->h);
-
-
while (1)
-
{
-
# ifdef WIN32
-
if (WaitForSingleObject((HANDLE)(pthrd_desc->hevent_go), INFINITE) == WAIT_OBJECT_0)
-
# else
-
int ret=0;
-
__lockx(pthrd_desc->cslock);
-
ret = pthread_cond_wait(&pthrd_desc->hevent_go, &pthrd_desc->cslock);
-
__unlockx(pthrd_desc->cslock);
-
if (ret == 0)
-
# endif
-
{
-
call_chain(pthrdpool->thrdpool_chain,thrd_msg,stat_busy);
-
__lockx(pthrd_desc->cslock);
-
while(pthrd_desc->ref_cnts>0) {
-
if (pthrd_desc->thrd_hook)
-
pthrd_desc->thrd_hook(pthrd_desc->pthrd_data);
-
pthrd_desc->ref_cnts--;
-
}
-
# ifdef WIN32
-
RESET_EVENT(pthrd_desc->hevent_go);
-
# endif
-
__unlockx(pthrd_desc->cslock);
-
-
}
-
# ifdef WIN32
-
if (WaitForSingleObject(pthrd_desc->hevent_exit, 0) == WAIT_OBJECT_0)
-
break;
-
# endif
-
-
call_chain(pthrdpool->thrdpool_chain,thrd_msg,stat_free);
-
} /* while(1) */
-
return 0;
-
}
-
-
static thrd_handle __thrd_alloc(thrd_hook_t thrd_hook, void* pdata)
-
{
-
struct list_head *list_p;
-
thrd_desc_t* pthrd_desc=null;
-
-
thrdpool_t* pthrdpool = thrdpool();
-
__assert(pthrdpool);
-
__lockx(pthrdpool->cslock);
-
list_for_each(list_p, &(pthrdpool->list))
-
{
-
pthrd_desc = list_entry(list_p, thrd_desc_t, list);
-
if (!pthrd_desc->thrd_hook)
-
{
-
__lockx(pthrd_desc->cslock);
-
SET_HANDLER_THRD_DESC(*pthrd_desc, thrd_hook, pdata);
-
__unlockx(pthrd_desc->cslock);
- __unlockx(pthrdpool->cslock);
-
return pthrd_desc->h;
-
}
-
}
-
__unlockx(pthrdpool->cslock);
-
return 0;
-
}
-
-
static void __thrd_free(thrd_handle h)
-
{
-
struct list_head *list_p;
-
thrd_desc_t* pthrd_desc=null;
-
-
thrdpool_t* pthrdpool = thrdpool();
-
__assert(pthrdpool);
-
__lockx(pthrdpool->cslock);
-
list_for_each(list_p, &(pthrdpool->list))
-
{
-
pthrd_desc = list_entry(list_p, thrd_desc_t, list);
-
if (h == pthrd_desc->h) {
-
__lockx(pthrd_desc->cslock);
-
CLEAR_THRD_DESC(*pthrd_desc);
-
__unlockx(pthrd_desc->cslock);
-
}
-
}
-
__unlockx(pthrdpool->cslock);
-
}
-
-
static int __wakeup(thrd_handle h)
-
{
-
struct list_head *list_p;
-
thrd_desc_t* pthrd_desc=null;
-
-
thrdpool_t* pthrdpool = thrdpool();
-
__assert(pthrdpool);
-
__lockx(pthrdpool->cslock);
-
list_for_each(list_p, &(pthrdpool->list))
-
{
-
pthrd_desc = list_entry(list_p, thrd_desc_t, list);
-
if (h==pthrd_desc->h)
-
{
-
__lockx(pthrd_desc->cslock);
-
if (hnull != pthrd_desc->hevent_go)
-
{
-
SET_EVENT(pthrd_desc->hevent_go);
-
pthrd_desc->ref_cnts++;
-
}
-
__unlockx(pthrd_desc->cslock);
- __unlockx(pthrdpool->cslock);
-
return 0;
-
}
-
}
-
__unlockx(pthrdpool->cslock);
-
return -1;
-
}
-
-
static int __thrd_add()
-
{
-
thrdpool_t* pthrdpool = thrdpool();
-
thrd_desc_t* pthrd_desc=null;
-
__assert(pthrdpool);
-
-
pthrd_desc=(thrd_desc_t*)malloc(sizeof(thrd_desc_t));
-
__assert(pthrd_desc);
-
-
INIT_THRD_DESC(*pthrd_desc);
-
-
__lockx_init(pthrd_desc->cslock,pthrd_desc->attr);
-
-
# ifdef WIN32
-
pthrd_desc->h = CreateThread(
-
null, // default security attributes
-
0, // use default stack size
-
thread_proc,// thread function
-
pthrd_desc, // argument to thread function
-
0, // use default creation flags
-
0);
-
if(NULL == pthrd_desc->h)
-
goto __err;
-
# else
-
if(pthread_create(&pthrd_desc->h, null, thread_proc, null)!=0)
-
goto __err;
-
# endif
-
-
__lockx(pthrdpool->cslock);
-
list_add(&pthrd_desc->list, &pthrdpool->list);
-
__unlockx(pthrdpool->cslock);
-
return 0;
-
-
__err:
-
__lockx_exit(pthrd_desc->cslock, pthrd_desc->attr);
-
free(pthrd_desc);
-
-
return -1;
-
}
-
-
static int __thrd_del(thrd_handle h)
-
{
-
struct list_head *list_p;
-
thrd_desc_t* pthrd_desc=null;
-
-
-
thrdpool_t* pthrdpool = thrdpool();
-
__assert(pthrdpool);
-
__lockx(pthrdpool->cslock);
-
list_for_each(list_p, &(pthrdpool->list))
-
{
-
pthrd_desc = list_entry(list_p, thrd_desc_t, list);
-
if (h==pthrd_desc->h) {
-
-
# ifdef WIN32
-
SET_EVENT(pthrd_desc->hevent_exit);
-
SET_EVENT(pthrd_desc->hevent_go);
-
# else
-
SET_EVENT(pthrd_desc->hevent_go);
-
sleep(1);
-
pthread_cancel(pthrd_desc->h);
-
# endif
-
-
/* wait the thread exit */
-
if (hnull != pthrd_desc->h)
-
{
-
# ifdef WIN32
-
/* terminal the log server thread until 1 second over */
-
unsigned long state = WaitForSingleObject (pthrd_desc->h, 2000);
-
switch (state)
-
{
-
case WAIT_TIMEOUT:
-
{
-
unsigned long exit_code = 0;
-
if (0 != TerminateThread(pthrd_desc->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;
-
}
-
CloseHandle(pthrd_desc->h);
-
# else
-
int state = pthread_join(pthrd_desc->h, null);
-
# endif
-
pthrd_desc->h=hnull;
-
}
-
-
__lockx_exit(pthrd_desc->cslock,pthrd_desc->attr);
-
-
# ifdef WIN32
-
EXIT_EVENT(pthrd_desc->hevent_exit);
-
# endif
-
-
EXIT_EVENT(pthrd_desc->hevent_go);
-
-
/* remove itself from the list */
-
list_del(&pthrd_desc->list);
-
/* free the memory from the malloc of the thread descript struct */
-
free(pthrd_desc);
-
-
break;
-
} // if (h==pthrd_desc->h)
-
}
-
__unlockx(pthrdpool->cslock);
-
return 0;
-
}
-
-
static void __display(const thrd_desc_t* pthrd_desc)
-
{
-
__assert(pthrd_desc);
-
printf("handle:%08x, hook: %s\n",
-
pthrd_desc->h, pthrd_desc->thrd_hook ? "installed":"uninstalled");
-
}
-
-
static int __query()
-
{
-
struct list_head *list_p;
-
thrd_desc_t* pthrd_desc=null;
-
-
thrdpool_t* pthrdpool = thrdpool();
-
__assert(pthrdpool);
-
__lockx(pthrdpool->cslock);
-
list_for_each(list_p, &(pthrdpool->list))
-
{
-
pthrd_desc = list_entry(list_p, thrd_desc_t, list);
-
__display(pthrd_desc);
-
}
-
printf("------------------------------\n");
-
__unlockx(pthrdpool->cslock);
-
return 0;
-
}
-
-
static int __reg_notifier(struct notifierx_block *pnb)
-
{
-
thrdpool_t* pthrdpool = thrdpool();
-
__assert(pthrdpool&&pnb);
-
return notifierx_chain_register(&pthrdpool->thrdpool_chain, pnb);
-
}
-
-
static int __unreg_notifier(struct notifierx_block *pnb)
-
{
-
thrdpool_t* pthrdpool = thrdpool();
-
__assert(pnb);
-
return notifierx_chain_unregister(&pthrdpool->thrdpool_chain, pnb);
-
}
-
-
thrdpool_t* thrdpool()
-
{
-
static thrdpool_t s_thrdpool;
-
return &s_thrdpool;
-
}
-
-
int thrdpool_init(int nthrds)
-
{
-
thrdpool_t* pthrdpool = thrdpool();
-
int ret=0, count=0;
-
__assert(pthrdpool);
-
-
INIT_NOTIFIERX_HEAD(pthrdpool->thrdpool_chain);
-
__lockx_init(pthrdpool->cslock,pthrdpool->attr);
-
-
pthrdpool->list.next=&pthrdpool->list;
-
pthrdpool->list.prev=&pthrdpool->list;
-
-
pthrdpool->ops.thrd_alloc =__thrd_alloc;
-
pthrdpool->ops.thrd_free =__thrd_free;
-
pthrdpool->ops.wakeup =__wakeup;
-
pthrdpool->ops.thrd_add =__thrd_add;
-
pthrdpool->ops.thrd_del =__thrd_del;
-
pthrdpool->ops.query =__query;
-
pthrdpool->ops.reg_notifier = __reg_notifier;
-
pthrdpool->ops.unreg_notifier = __unreg_notifier;
-
-
while (count<nthrds) {
-
ret=__thrd_add();
-
__assert(-1!=ret);
-
count++;
-
}
-
return 0;
-
}
-
-
int thrdpool_exit()
-
{
-
struct list_head *list_p;
-
thrd_desc_t* pthrd_desc=null;
-
thrd_desc_t* pthrd_temp=null;
-
thrdpool_t* pthrdpool = thrdpool();
-
__assert(pthrdpool);
-
-
list_for_each_safe(list_p, pthrd_temp, &(pthrdpool->list))
-
{
-
pthrd_desc = list_entry(list_p, thrd_desc_t, list);
-
if (hnull!=pthrd_desc->h)
-
__thrd_del(pthrd_desc->h);
-
}
-
__lockx_exit(pthrdpool->cslock,pthrdpool->attr);
-
EXIT_NOTIFIERX_HEAD(pthrdpool->thrdpool_chain);
-
-
return 0;
-
}
file: notifierx.h
- /**
-
* author: vincent.cws2008@gmail.com
-
* history:
-
* initial @ 2011-11-13
-
*/
-
-
#ifndef _NOTIFIERX_H_
-
#define _NOTIFIERX_H_
-
-
#include "list.h"
-
-
#ifdef WIN32
-
# include "windows.h"
-
#else
-
# include <pthread.h>
-
#endif
-
-
#define null (void*)0
-
#define NULL (void*)0
-
-
#ifndef __assert
-
#define __assert(x)
-
#endif
-
-
#ifdef WIN32
-
# define thrd_handle HANDLE
-
# define event_t HANDLE
-
# define lock_t CRITICAL_SECTION
-
# define attr_t void*
-
#else
-
# define thrd_handle pthread_t
-
# define event_t pthread_cond_t
-
# define lock_t pthread_mutex_t
-
# define attr_t pthread_mutexattr_t
-
#endif
-
-
-
typedef struct notifierx_block {
-
int (*notifierx_call)(struct notifierx_block *pnb, unsigned long nlen, const void *pdata);
-
struct list_head list;
-
}notifierx_block_t;
-
-
struct notifierx_head {
-
lock_t cslock;
-
attr_t attr;
-
struct list_head head;
-
};
-
-
#define INIT_NOTIFIERX_HEAD(name) do { \
-
__lockx_init((name).cslock,(name).attr); \
-
INIT_LIST_HEAD(&(name).head); \
-
} while (0)
-
-
-
#define EXIT_NOTIFIERX_HEAD(name) do { \
-
notifierx_chain_all_unregister(&(name)); \
-
__lockx_exit((name).cslock, (name).attr); \
-
} while (0)
-
//
-
-
extern int notifierx_chain_register(struct notifierx_head *pnh, struct notifierx_block *pnb);
-
extern int notifierx_chain_all_unregister(struct notifierx_head *pnh);
-
extern int notifierx_chain_unregister(struct notifierx_head *pnh, struct notifierx_block *pnb);
-
extern int notifierx_call_chain(struct notifierx_head *pnh, unsigned long nlen, void *pdata);
-
-
#endif
file: notifierx.c
- /**
-
* author: vincent.cws2008@gmail.com
-
* history:
-
* initial @ 2011-11-13
-
*/
-
-
-
#include "notifierx.h"
-
-
#ifdef WIN32
-
-
#ifndef hnull
-
#define hnull INVALID_HANDLE_VALUE
-
#endif
-
#ifndef null
-
#define null NULL
-
#endif
-
#define __lockx(lock) EnterCriticalSection(&(lock))
-
#define __unlockx(lock) LeaveCriticalSection(&(lock))
-
#define __lockx_init(lock,attr) InitializeCriticalSection(&(lock))
-
#define __lockx_exit(lock,attr) DeleteCriticalSection(&(lock))
-
-
#else
-
-
#ifndef hnull
-
#define hnull (void*)0
-
#endif
-
#ifndef null
-
#define null (void*)0
-
#endif
-
#define __lockx(lock) pthread_mutex_lock(&(lock))
-
#define __unlockx(lock) pthread_mutex_unlock(&(lock))
-
#define __lockx_init(lock,attr) \
-
pthread_mutexattr_init(&(attr)); \
-
pthread_mutexattr_settype(&(attr),PTHREAD_MUTEX_RECURSIVE); \
-
pthread_mutex_init(&(lock),&(attr)); \
-
-
#define __lockx_exit(attr,attr) \
-
pthread_mutex_destroy(&(lock)); \
-
pthread_mutexattr_destroy(&(attr)); \
-
-
#endif
-
-
-
int notifierx_chain_register(struct notifierx_head *pnh,
-
struct notifierx_block *pnb)
-
{
-
__assert(pnh&&pnb);
-
__lockx(pnh->cslock);
-
list_add(&pnb->list, &pnh->head);
-
__unlockx(pnh->cslock);
-
return 0;
-
}
-
-
int notifierx_chain_all_unregister(struct notifierx_head *pnh)
-
{
-
struct list_head *list_p;
-
notifierx_block_t* pnb_it=null;
-
notifierx_block_t* pnb_temp=null;
-
__assert(pnh);
-
-
__lockx(pnh->cslock);
-
list_for_each_safe(list_p, pnb_temp, &(pnh->head))
-
{
-
pnb_it = list_entry(list_p, notifierx_block_t, list);
-
list_del(&pnb_it->list);
-
}
-
-
__unlockx(pnh->cslock);
-
-
return 0;
-
}
-
-
int notifierx_chain_unregister(struct notifierx_head *pnh,
-
struct notifierx_block *pnb)
-
{
-
struct list_head *list_p;
-
struct notifierx_block *pnb_it;
-
__assert(pnh&&pnb);
-
-
__lockx(pnh->cslock);
-
list_for_each(list_p, &(pnh->head))
-
{
-
pnb_it = list_entry(list_p, notifierx_block_t, list);
-
if (pnb_it->notifierx_call == pnb->notifierx_call)
-
{
-
list_del(&pnb_it->list);
-
__unlockx(pnh->cslock);
-
return 0;
-
}
-
}
-
__unlockx(pnh->cslock);
-
return -1;
-
}
-
-
int notifierx_call_chain(struct notifierx_head *pnh, unsigned long nlen, void *pdata)
-
{
-
struct list_head *list_p;
-
notifierx_block_t* pnb_it=null;
-
-
__assert(pnh);
-
-
__lockx(pnh->cslock);
-
list_for_each(list_p, &(pnh->head))
-
{
-
pnb_it = list_entry(list_p, notifierx_block_t, list);
-
pnb_it->notifierx_call(pnb_it, nlen, pdata);
-
}
-
__unlockx(pnh->cslock);
-
-
return 0;
-
}
attached:
threadpool.rar
阅读(407) | 评论(0) | 转发(0) |