#プログラム大喜利 内容不定Job実行系(わざわざCで書いてみる編)

Twitter. It's what's happening.

上の回答例で「実は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;
}