Files
sics/messagepipe.c
Ferdi Franceschini 10d29d597c Cleaned up ANSTO code to merge with sinqdev.sics
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c
Conflicts:
	.gitignore
	SICSmain.c
	asynnet.c
	confvirtualmot.c
	counter.c
	devexec.c
	drive.c
	event.h
	exebuf.c
	exeman.c
	histmem.c
	interface.h
	motor.c
	motorlist.c
	motorsec.c
	multicounter.c
	napi.c
	napi.h
	napi4.c
	network.c
	nwatch.c
	nxscript.c
	nxxml.c
	nxxml.h
	ofac.c
	reflist.c
	scan.c
	sicshipadaba.c
	sicsobj.c
	site_ansto/docs/Copyright.txt
	site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl
	site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl
	statusfile.c
	tasdrive.c
	tasub.c
	tasub.h
	tasublib.c
	tasublib.h
2015-04-23 20:49:26 +10:00

119 lines
3.0 KiB
C

/**
* An implementation for a message pipe system as described in
*
* http://eventuallyconsistent.net/2013/08/14/messaging-as-a-programming-model-part-2/
*
* A message is passed through a series of filter routines which do things.
*
* Rather then loops I try using recursion here.
*
* copyright: GPL Copyleft
*
* Mark Koennecke, November 2013
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <messagepipe.h>
/*--------------------------------------------------------------------------------*/
typedef struct __MessagePipe {
void *userData;
mpUserKill killFunc;
mpFilterFunc filterFunc;
struct __MessagePipe *next;
struct __MessagePipe *previous;
} MessagePipe;
/*--------------------------------------------------------------------------------*/
static int EmptyFunc(void *message, void *userData)
{
return MPCONTINUE;
}
/*---------------------------------------------------------------------------------*/
pMP MakeMP()
{
pMP result = NULL;
result = malloc(sizeof(MessagePipe));
if(result != NULL){
memset(result,0,sizeof(MessagePipe));
result->filterFunc = EmptyFunc;
}
return result;
}
/*---------------------------------------------------------------------------------*/
void KillMP(pMP self)
{
if(self == NULL){
return;
}
pMP next = self->next;
if(self->userData != NULL && self->killFunc != NULL){
self->killFunc(self->userData);
}
free(self);
KillMP(next);
}
/*-----------------------------------------------------------------------------------*/
int AppendMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill)
{
assert(self != NULL);
assert(func != NULL);
if(self->next == NULL){
self->next = malloc(sizeof(MessagePipe));
if(self->next != NULL){
self->next->previous = self;
self->next->next = NULL;
self->next->userData = userData;
self->next->killFunc = usKill;
self->next->filterFunc = func;
return 0;
} else {
return 1;
}
} else {
return AppendMPFilter(self->next, func, userData, usKill);
}
}
/*-----------------------------------------------------------------------------------*/
pMP PrependMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill)
{
pMP result = NULL;
assert(func != NULL);
result = malloc(sizeof(MessagePipe));
if(result != NULL){
result->userData = userData;
result->killFunc = usKill;
result->filterFunc = func;
result->next = self;
result->previous = NULL;
return result;
} else {
/*
we are ignoring an error here.........
*/
return self;
}
}
/*-----------------------------------------------------------------------------------*/
int MPprocess(pMP self, void *message)
{
int status;
if(self == NULL || self->filterFunc == NULL){
return MPCONTINUE;
} else {
status = self->filterFunc(message, self->userData);
if(status == MPSTOP){
return status;
} else {
return MPprocess(self->next, message);
}
}
}