Mostly commenting with a few bug fixes
r1543 | dcl | 2007-02-22 16:41:03 +1100 (Thu, 22 Feb 2007) | 2 lines
This commit is contained in:
123
nwatch.c
123
nwatch.c
@@ -22,19 +22,29 @@
|
||||
|
||||
#define NWMAGIC 51966
|
||||
|
||||
/* Net Watcher control structure */
|
||||
typedef struct __netwatcher_s {
|
||||
pNWContext cq_head;
|
||||
pNWContext cq_tail;
|
||||
pNWTimer tq_head;
|
||||
pNWTimer tq_tail;
|
||||
long lMagic;
|
||||
pNWContext cq_head; /* head of socket context queue */
|
||||
pNWContext cq_tail; /* tail of socket context queue */
|
||||
pNWTimer tq_head; /* head of timer context queue */
|
||||
pNWTimer tq_tail; /* tail of timer context queue */
|
||||
long lMagic; /* integrity check */
|
||||
} NetWatch, *pNetWatch;
|
||||
|
||||
/* Singleton pattern */
|
||||
static pNetWatch instance = NULL;
|
||||
|
||||
static int NetWatchTask(void* pData);
|
||||
|
||||
/**
|
||||
* \brief Initialises the Net Watcher singleton and starts the task
|
||||
*
|
||||
* \return 1=success, 0=failure
|
||||
*/
|
||||
int NetWatchInit(void) {
|
||||
/*
|
||||
* If the singleton has not yet been created, do so now
|
||||
*/
|
||||
if (instance == NULL) {
|
||||
instance = (pNetWatch) malloc(sizeof(NetWatch));
|
||||
if (instance == NULL)
|
||||
@@ -46,55 +56,78 @@ int NetWatchInit(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The timer context object private definition
|
||||
*/
|
||||
typedef struct __netwatchtimer {
|
||||
pNWTimer next;
|
||||
struct timeval tv;
|
||||
pNWCallback func;
|
||||
void* cntx;
|
||||
long vrfy;
|
||||
pNWTimer next; /* chain to next event */
|
||||
struct timeval tv; /* time when event is due */
|
||||
pNWCallback func; /* function to call */
|
||||
void* cntx; /* abstract context to pass to callback */
|
||||
long vrfy; /* integrity check */
|
||||
} NWTimer;
|
||||
|
||||
/*
|
||||
* \brief private function to insert an entry into the sorted timer queue.
|
||||
*
|
||||
* \param self singleton
|
||||
* \param handle new timer to insert
|
||||
*/
|
||||
static int NetWatchTimerInsQue(pNetWatch self, pNWTimer handle)
|
||||
{
|
||||
if (self->tq_head == NULL) /* empty */
|
||||
/* if the queue is empty, just stick new one in */
|
||||
if (self->tq_head == NULL) {
|
||||
self->tq_head = self->tq_tail = handle;
|
||||
else if (handle->tv.tv_sec > self->tq_tail->tv.tv_sec ||
|
||||
return 1;
|
||||
}
|
||||
/* if new one is later than latest one, insert after latest */
|
||||
if (handle->tv.tv_sec > self->tq_tail->tv.tv_sec ||
|
||||
(handle->tv.tv_sec == self->tq_tail->tv.tv_sec &&
|
||||
handle->tv.tv_usec >= self->tq_tail->tv.tv_usec)) {
|
||||
/* after last entry */
|
||||
self->tq_tail->next = handle;
|
||||
self->tq_tail = handle;
|
||||
} else if (handle->tv.tv_sec < self->tq_tail->tv.tv_sec ||
|
||||
(handle->tv.tv_sec == self->tq_tail->tv.tv_sec &&
|
||||
handle->tv.tv_usec <= self->tq_tail->tv.tv_usec)) {
|
||||
/* before first entry */
|
||||
return 1;
|
||||
}
|
||||
/* if new one is earlier than earliest one, insert before earliest */
|
||||
if (handle->tv.tv_sec < self->tq_head->tv.tv_sec ||
|
||||
(handle->tv.tv_sec == self->tq_head->tv.tv_sec &&
|
||||
handle->tv.tv_usec <= self->tq_head->tv.tv_usec)) {
|
||||
handle->next = self->tq_head;
|
||||
self->tq_head = handle;
|
||||
} else {
|
||||
/* start at the first entry */
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* must be in between two so start at the first entry */
|
||||
pNWTimer pNxt = self->tq_head;
|
||||
/* go until the one after is greater */
|
||||
/* follow chain until the one after this one is greater than new one */
|
||||
while (pNxt->next &&
|
||||
(handle->tv.tv_sec > pNxt->next->tv.tv_sec ||
|
||||
(handle->tv.tv_sec == pNxt->next->tv.tv_sec &&
|
||||
handle->tv.tv_usec > pNxt->next->tv.tv_usec)))
|
||||
pNxt = pNxt->next;
|
||||
/* slip it in */
|
||||
/* slip new one in between this one and the next one */
|
||||
handle = pNxt->next;
|
||||
pNxt->next = handle ;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief private function to remove an entry from the sorted timer queue.
|
||||
*
|
||||
* \param self singleton
|
||||
* \param handle existing timer to remove
|
||||
*/
|
||||
static int NetWatchTimerRemQue(pNetWatch self, pNWTimer handle)
|
||||
{
|
||||
if (handle == self->tq_head) { /* if first */
|
||||
self->tq_head = self->tq_head->next;
|
||||
if (handle == self->tq_tail) /* if also last */
|
||||
/* handle the case of first and possibly only */
|
||||
if (handle == self->tq_head) {
|
||||
self->tq_head = self->tq_head->next; /* may be NULL */
|
||||
if (handle == self->tq_tail)
|
||||
self->tq_tail = NULL;
|
||||
}
|
||||
else if (handle == self->tq_tail) /* if only last */
|
||||
self->tq_tail = NULL;
|
||||
/* handle general case */
|
||||
else {
|
||||
pNWTimer pNxt = self->tq_head;
|
||||
while (pNxt) {
|
||||
@@ -103,6 +136,9 @@ static int NetWatchTimerRemQue(pNetWatch self, pNWTimer handle)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* It it was the last entry, point tail to its predecessor */
|
||||
if (handle == self->tq_tail)
|
||||
self->tq_tail = pNxt;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -141,16 +177,23 @@ int NetWatchRemoveTimer(pNWTimer handle)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* private data */
|
||||
typedef struct __netwatchcontext {
|
||||
pNWContext next;
|
||||
int sock;
|
||||
int mode;
|
||||
int actn;
|
||||
pNWCallback func;
|
||||
void* cntx;
|
||||
long vrfy;
|
||||
pNWContext next; /* chain pointer */
|
||||
int sock; /* socket to watch */
|
||||
int mode; /* read or write */
|
||||
int actn; /* action being invoked on this pass */
|
||||
pNWCallback func; /* user supplied callback function */
|
||||
void* cntx; /* user supplied callback context */
|
||||
long vrfy; /* integrity check */
|
||||
} NWContext;
|
||||
|
||||
/**
|
||||
* \brief private function to insert entry into unsorted queue
|
||||
*
|
||||
* \param self singleton
|
||||
* \param handle entry to insert
|
||||
*/
|
||||
static int NetWatchContextInsQue(pNetWatch self, pNWContext handle)
|
||||
{
|
||||
if (self->cq_head == NULL) /* empty */
|
||||
@@ -162,6 +205,12 @@ static int NetWatchContextInsQue(pNetWatch self, pNWContext handle)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief private function to remove entry from unsorted queue
|
||||
*
|
||||
* \param self singleton
|
||||
* \param handle entry to insert
|
||||
*/
|
||||
static int NetWatchContextRemQue(pNetWatch self, pNWContext handle)
|
||||
{
|
||||
if (handle == self->cq_head) { /* if first */
|
||||
@@ -169,8 +218,6 @@ static int NetWatchContextRemQue(pNetWatch self, pNWContext handle)
|
||||
if (handle == self->cq_tail) /* if also last */
|
||||
self->cq_tail = NULL;
|
||||
}
|
||||
else if (handle == self->cq_tail) /* if only last */
|
||||
self->cq_tail = NULL;
|
||||
else {
|
||||
pNWContext pNxt = self->cq_head;
|
||||
while (pNxt) {
|
||||
@@ -179,6 +226,8 @@ static int NetWatchContextRemQue(pNetWatch self, pNWContext handle)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (handle == self->cq_tail) /* if last */
|
||||
self->cq_tail = pNxt;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -228,6 +277,9 @@ int NetWatchSetMode(pNWContext handle, int mode)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief the registered SICS Task to drive all this
|
||||
*/
|
||||
int NetWatchTask (void* pData)
|
||||
{
|
||||
pNetWatch self = NULL;
|
||||
@@ -239,6 +291,7 @@ int NetWatchTask (void* pData)
|
||||
int iCount;
|
||||
pNWContext action[FD_SETSIZE];
|
||||
|
||||
/* Check the singleton */
|
||||
self = (pNetWatch) instance;
|
||||
if(!self || self->lMagic != NWMAGIC)
|
||||
return 0;
|
||||
|
||||
65
nwatch.h
65
nwatch.h
@@ -10,24 +10,81 @@
|
||||
#ifndef SICSNETWATCHER
|
||||
#define SICSNETWATCHER
|
||||
|
||||
#define DFC_NWATCH 1
|
||||
#define nwatch_read 1
|
||||
#define nwatch_write 2
|
||||
/* the callback function */
|
||||
/**
|
||||
* \brief network or timer callback function
|
||||
*
|
||||
* \param context from the network/timer registration
|
||||
* \param mode
|
||||
* for network, nwatch_read or nwatch_write
|
||||
* for timer, zero, reserved for future use
|
||||
*
|
||||
* \return normally zero, for future use
|
||||
*/
|
||||
typedef int (*pNWCallback)(void* context, int mode);
|
||||
|
||||
/* the timer methods */
|
||||
/* the abstract timer object handle */
|
||||
typedef struct __netwatchtimer *pNWTimer;
|
||||
|
||||
/**
|
||||
* \brief register a one-shot timer event
|
||||
*
|
||||
* \param handle pointer to location to receive the timer object handle
|
||||
* \param mSec milliseconds after which the timer should expire
|
||||
* \param callback function when timer expires
|
||||
* \param context abstract context passed to callback function
|
||||
* \return success=1, failure=0
|
||||
*/
|
||||
int NetWatchRegisterTimer(pNWTimer* handle, int mSec,
|
||||
pNWCallback callback, void* context);
|
||||
|
||||
/**
|
||||
* \brief remove a registered timer event
|
||||
*
|
||||
* \param handle from the timer registration
|
||||
* \return success=1, failure=0
|
||||
*/
|
||||
int NetWatchRemoveTimer(pNWTimer handle);
|
||||
|
||||
/* the socket methods */
|
||||
/* the abstract socket object handle */
|
||||
typedef struct __netwatchcontext *pNWContext;
|
||||
|
||||
/**
|
||||
* \brief register a socket to be watched in read mode
|
||||
*
|
||||
* \param handle pointer to location to receive the socket object handle
|
||||
* \param iSocket file descriptor number of the socket to watch
|
||||
* \param callback function when socket readable/writeable
|
||||
* \param context abstract context passed to callback function
|
||||
* \return success=1, failure=0
|
||||
*/
|
||||
int NetWatchRegisterCallback(pNWContext* handle, int iSocket,
|
||||
pNWCallback callback, void* context);
|
||||
|
||||
/**
|
||||
* \brief remove a socket callback registration
|
||||
*
|
||||
* \param handle from the socket registration
|
||||
* \return success=1, failure=0
|
||||
*/
|
||||
int NetWatchRemoveCallback(pNWContext handle);
|
||||
|
||||
/**
|
||||
* \brief retrieve the mode of a socket callback registration
|
||||
*
|
||||
* \param handle from the socket registration
|
||||
* \return 0=failure else the mode (read and/or write)
|
||||
*/
|
||||
int NetWatchGetMode(pNWContext handle);
|
||||
|
||||
/**
|
||||
* \brief set the mode of a socket callback registration
|
||||
*
|
||||
* \param handle from the socket registration
|
||||
* \param mode read and/or write
|
||||
* \return 0=failure, 1=success
|
||||
*/
|
||||
int NetWatchSetMode(pNWContext handle, int mode);
|
||||
|
||||
#endif /* SICSNETWATCHER */
|
||||
|
||||
Reference in New Issue
Block a user