typedef struct
{
struct list_head list;
int optionType;
int (*chOption)(void *param);
int (*kickoutOption)(void *param);
void *param;
}chTOption;
typedef struct
{
int chId;
struct list_head optionList;
pthread_mutex_t listMutex;
}chThreadSession;
chThreadSession *g_chThreadSession[CHANNEL_NUM];
int initChannelThreads()
{
int i = 0;
for(i = 0; i < CHANNEL_NUM; i++)
{
g_chThreadSession[i] = kitMemMalloc(sizeof(chThreadSession));
if(g_chThreadSession[i] == NULL)
{
CHT_DBG4("initChannelThreads: get mem fail, i = %d\n", i);
goto EXIT;
}
g_chThreadSession[i]->chId = i;
INIT_LIST_HEAD(&g_chThreadSession[i]->optionList);
pthread_mutex_init(&(g_chThreadSession[i]->listMutex), NULL);
}
return APP_OK;
EXIT:
return APP_FAIL;
}
static void* chToptionFunc(chThreadSession * session)
{
struct list_head *pos, *tmp;
chTOption *options = NULL;
CHT_DBG2("chToptionFunc: session %p, ch %d\n", session, session->chId);
pthread_mutex_lock(&session->listMutex);
list_for_each_safe(pos, tmp, &(session->optionList)){
options = ( chTOption*)pos;
CHT_DBG2("chToptionFunc: options %p, chOption %p\n", options, options->chOption);
options->chOption(options->param);
list_del(options);
kitMemFree(options);
}
pthread_mutex_unlock(&session->listMutex);
int chTAddOption(int ch, int type, void* chOption, void* para, void *kickoutOption)
{
int ret = APP_OK;
char inPool = 0;
chTOption *option = NULL;
if(ch < 0 || ch > CHANNEL_NUM)
{
return APP_FAIL;
}
pthread_mutex_lock(&g_chThreadSession[ch]->listMutex);
if(list_empty(&g_chThreadSession[ch]->optionList) == 0)
{
inPool = 1;
}
/** todo: kickout rules */
option = kitMemMalloc(sizeof(chTOption));
if(option == NULL)
{
CHT_DBG4("chTAddOption: get mem fail, ch = %d, type %d\n", ch, type);
ret = APP_FAIL;
goto EXIT;
}
option->optionType = type;
option->chOption = chOption;
option->param = para;
option->kickoutOption = kickoutOption;
CHT_DBG2("chTAddOption:option %p, chOption\n", option, option->chOption);
if(inPool)
{
list_add_tail(option, &(g_chThreadSession[ch]->optionList));
}
else
{
list_add_tail(option, &(g_chThreadSession[ch]->optionList));
ret = kThreadPoolPush(chToptionFunc, (void *)g_chThreadSession[ch]);
if (ret != NVR_THPL_ENOERR)
{
dbgPrintfl(FATAL, "chTAddOption call kThreadPoolPush() failed, ch = %d\n", ch);
ret = APP_FAIL;
assert(0);
goto EXIT;
}
}
EXIT:
pthread_mutex_unlock(&g_chThreadSession[ch]->listMutex);
return ret;
}
对外使用接口实例:
chTAddOption(pIn->channel, type, AddFollowUpProcLogin,pAddParam,NULL);
chTAddOption(pIn->channel, type, DelFollowUpProcLogin,pDelParam,NULL);