上の回答例で「実はCでも出来んことはない」と書いた以上Cでも書いてみる。
jobmgr.h
#ifndef jobmgr_h #define jobmgr_h typedef struct JOBHDR { struct JOBHDR * prev; struct JOBHDR * next; struct JOBHDR * rmv_next; int (*func_watch)(void *); int (*func_exec)(void *); void (*func_destroy)(void *); } JOBHDR; void job_init(); void * job_regist(size_t szWork, int (*func_watch)(void *), int (*func_exec)(void *), void (*func_destroy)(void *)); int job_remove(void * pWork); void job_exec(void); #endif /* jobmgr_h */
jobmgr.c
#include <stdio.h> #include <stdlib.h> #include "jobmgr.h" typedef struct { JOBHDR * begin; JOBHDR * end; JOBHDR * remove; } JOBLIST; static JOBLIST jobList; void * job_regist(size_t szWork, int (*func_watch)(void *), int (*func_exec)(void *), void (*func_destroy)(void *)) { JOBHDR * pWork; if(szWork < sizeof(JOBHDR)) return NULL; if(NULL == (pWork = malloc(szWork))) return NULL; pWork->func_watch = func_watch; pWork->func_exec = func_exec; pWork->func_destroy = func_destroy; pWork->next = NULL; if(NULL != (pWork->prev = jobList.end)) { jobList.end->next = pWork; } else { jobList.begin = pWork; } jobList.end = pWork; pWork->rmv_next = NULL; return pWork; } int job_remove(void * pWork) { JOBHDR * jWork = (JOBHDR *)pWork; jWork->rmv_next = jobList.remove; jobList.remove = jWork; return 1; } void job_exec(void) { JOBHDR * pJob; JOBHDR * pNxt; jobList.remove = NULL; for(pJob = jobList.begin; pJob; pJob = pJob->next) { if(pJob->func_watch(pJob)) pJob->func_exec(pJob); } /* 破棄予約分の破棄 */ pJob = jobList.remove; while(pJob) { pNxt = pJob->rmv_next; if(pJob->prev) { pJob->prev->next = pJob->next; } else { jobList.begin = pJob->next; } if(pJob->next) { pJob->next->prev = pJob->prev; } else { jobList.end = pJob->prev; } pJob->func_destroy(pJob); free(pJob); pJob = pNxt; } } void job_init(void) { jobList.begin = jobList.end = jobList.remove = NULL; }
count_job.c (上記を使ったJobの作例)
#include <stdio.h> #include <stdlib.h> #include "jobmgr.h" typedef struct { JOBHDR header; int count; } WORK; static int my_watch(void * vpWork) { WORK * pWork = vpWork; pWork->count++; if(pWork->count > 100) return 1; return 0; } static int my_exec(void * vpWork) { WORK * pWork = vpWork; pWork->count = 0; printf("count 100\n"); return 1; } static void my_destroy(void * vpWork) { WORK * pWork = vpWork; /* 特にやることないな */ } void count_init(void) { WORK * pWork; pWork = job_regist(sizeof(WORK), my_watch, my_exec, my_destroy); pWork->count = 0; }