Merge commit 'refs/merge-requests/1' of ssh://gitorious.psi.ch/sinqdev/sics into merge-requests/1
First merge with ANSTO which compiles Conflicts: SICSmain.c asynnet.c confvirtualmot.c counter.c devexec.c drive.c exebuf.c hipadaba.c interface.h make_gen motor.c nserver.c nwatch.c ofac.c protocol.c sicshipadaba.c
This commit is contained in:
114
nwatch.c
114
nwatch.c
@@ -18,8 +18,8 @@
|
||||
#include <sys/time.h>
|
||||
#include "fortify.h"
|
||||
#include "nwatch.h"
|
||||
#include "sics.h"
|
||||
#include "uselect.h"
|
||||
#include "sics.h"
|
||||
|
||||
#define NWMAGIC 51966
|
||||
|
||||
@@ -36,14 +36,12 @@ typedef struct __netwatcher_s {
|
||||
/* 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)
|
||||
static pNetWatch NetWatchGetInstance(void)
|
||||
{
|
||||
/*
|
||||
* If the singleton has not yet been created, do so now
|
||||
@@ -54,9 +52,8 @@ int NetWatchInit(void)
|
||||
return 0;
|
||||
memset(instance, 0, sizeof(NetWatch));
|
||||
instance->lMagic = NWMAGIC;
|
||||
TaskRegisterN(pServ->pTasker,"nwatch", NetWatchTask, NULL, NULL, NULL, 1);
|
||||
}
|
||||
return 1;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -67,10 +64,13 @@ typedef struct __netwatchtimer {
|
||||
struct timeval tv; /* time when event is due */
|
||||
pNWCallback func; /* function to call */
|
||||
void *cntx; /* abstract context to pass to callback */
|
||||
long int tick; /* millisecond repeat rate */
|
||||
int msec; /* millisecond delay time */
|
||||
int tick; /* millisecond repeat rate */
|
||||
long int vrfy; /* integrity check */
|
||||
} NWTimer;
|
||||
|
||||
static pNWTimer activeTimer = NULL;
|
||||
|
||||
/*
|
||||
* \brief private function to insert an entry into the sorted timer queue.
|
||||
*
|
||||
@@ -83,6 +83,7 @@ static int NetWatchTimerInsQue(pNetWatch self, pNWTimer handle)
|
||||
if (self->tq_head == NULL) {
|
||||
self->tq_head = self->tq_tail = handle;
|
||||
handle->next = NULL;
|
||||
handle->vrfy = NWMAGIC;
|
||||
return 1;
|
||||
}
|
||||
/* if new one is not earlier than latest one, insert after latest */
|
||||
@@ -92,6 +93,7 @@ static int NetWatchTimerInsQue(pNetWatch self, pNWTimer handle)
|
||||
self->tq_tail->next = handle;
|
||||
self->tq_tail = handle;
|
||||
handle->next = NULL;
|
||||
handle->vrfy = NWMAGIC;
|
||||
return 1;
|
||||
}
|
||||
/* if new one is not later than earliest one, insert before earliest */
|
||||
@@ -100,6 +102,7 @@ static int NetWatchTimerInsQue(pNetWatch self, pNWTimer handle)
|
||||
handle->tv.tv_usec <= self->tq_head->tv.tv_usec)) {
|
||||
handle->next = self->tq_head;
|
||||
self->tq_head = handle;
|
||||
handle->vrfy = NWMAGIC;
|
||||
return 1;
|
||||
} else {
|
||||
/* must be in between two so start at the first entry */
|
||||
@@ -113,8 +116,10 @@ static int NetWatchTimerInsQue(pNetWatch self, pNWTimer handle)
|
||||
/* slip new one in between this one and the next one */
|
||||
handle->next = pNxt->next;
|
||||
pNxt->next = handle;
|
||||
handle->vrfy = NWMAGIC;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -125,6 +130,7 @@ static int NetWatchTimerInsQue(pNetWatch self, pNWTimer handle)
|
||||
*/
|
||||
static int NetWatchTimerRemQue(pNetWatch self, pNWTimer handle)
|
||||
{
|
||||
assert(handle->vrfy == NWMAGIC);
|
||||
/* handle the case of first and possibly only */
|
||||
if (handle == self->tq_head) {
|
||||
self->tq_head = self->tq_head->next; /* may be NULL */
|
||||
@@ -145,13 +151,15 @@ static int NetWatchTimerRemQue(pNetWatch self, pNWTimer handle)
|
||||
if (handle == self->tq_tail)
|
||||
self->tq_tail = pNxt;
|
||||
}
|
||||
handle->vrfy = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int NetWatchRegisterTimer(pNWTimer * handle, int mSec,
|
||||
pNWCallback callback, void *context)
|
||||
{
|
||||
pNetWatch self = instance;
|
||||
assert(callback);
|
||||
pNetWatch self = NetWatchGetInstance();
|
||||
if (!self || self->lMagic != NWMAGIC)
|
||||
return 0;
|
||||
pNWTimer pNew = (pNWTimer) malloc(sizeof(NWTimer));
|
||||
@@ -165,10 +173,10 @@ int NetWatchRegisterTimer(pNWTimer * handle, int mSec,
|
||||
pNew->tv.tv_sec++;
|
||||
pNew->tv.tv_usec -= 1000000;
|
||||
}
|
||||
pNew->msec = mSec;
|
||||
pNew->tick = 0;
|
||||
pNew->func = callback;
|
||||
pNew->cntx = context;
|
||||
pNew->vrfy = NWMAGIC;
|
||||
NetWatchTimerInsQue(self, pNew);
|
||||
*handle = pNew;
|
||||
return 1;
|
||||
@@ -178,6 +186,7 @@ int NetWatchRegisterTimerPeriodic(pNWTimer * handle, int mSecInitial,
|
||||
int mSecPeriod, pNWCallback callback,
|
||||
void *context)
|
||||
{
|
||||
assert(callback);
|
||||
if (NetWatchRegisterTimer(handle, mSecInitial, callback, context)) {
|
||||
pNWTimer pNew = *handle;
|
||||
if (pNew == NULL)
|
||||
@@ -189,16 +198,36 @@ int NetWatchRegisterTimerPeriodic(pNWTimer * handle, int mSecInitial,
|
||||
return 0;
|
||||
}
|
||||
|
||||
pNWTimer NetWatchGetActiveTimer(void)
|
||||
{
|
||||
return activeTimer;
|
||||
}
|
||||
|
||||
int NetWatchGetTimerInitial(pNWTimer handle)
|
||||
{
|
||||
if (handle == NULL
|
||||
|| (handle->vrfy != NWMAGIC && handle->vrfy != ~NWMAGIC))
|
||||
return 0;
|
||||
return handle->msec;
|
||||
}
|
||||
|
||||
int NetWatchGetTimerDelay(pNWTimer handle)
|
||||
{
|
||||
return NetWatchGetTimerInitial(handle);
|
||||
}
|
||||
|
||||
int NetWatchGetTimerPeriod(pNWTimer handle)
|
||||
{
|
||||
if (handle == NULL || handle->vrfy != NWMAGIC)
|
||||
if (handle == NULL
|
||||
|| (handle->vrfy != NWMAGIC && handle->vrfy != ~NWMAGIC))
|
||||
return 0;
|
||||
return handle->tick;
|
||||
}
|
||||
|
||||
int NetWatchSetTimerPeriod(pNWTimer handle, int mSecPeriod)
|
||||
{
|
||||
if (handle == NULL || handle->vrfy != NWMAGIC)
|
||||
if (handle == NULL
|
||||
|| (handle->vrfy != NWMAGIC && handle->vrfy != ~NWMAGIC))
|
||||
return 0;
|
||||
handle->tick = mSecPeriod;
|
||||
return 1;
|
||||
@@ -206,9 +235,11 @@ int NetWatchSetTimerPeriod(pNWTimer handle, int mSecPeriod)
|
||||
|
||||
int NetWatchRemoveTimer(pNWTimer handle)
|
||||
{
|
||||
pNetWatch self = instance;
|
||||
pNetWatch self = NetWatchGetInstance();
|
||||
if (!self || self->lMagic != NWMAGIC)
|
||||
return 0;
|
||||
if (handle == NULL || handle->vrfy != NWMAGIC)
|
||||
return 0;
|
||||
NetWatchTimerRemQue(self, handle);
|
||||
handle->vrfy = 0;
|
||||
free(handle);
|
||||
@@ -239,35 +270,10 @@ static int NetWatchContextInsQue(pNetWatch self, pNWContext handle)
|
||||
self->cq_tail->next = handle;
|
||||
self->cq_tail = handle;
|
||||
}
|
||||
handle->vrfy = NWMAGIC;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief private function to remove entry from unsorted queue
|
||||
*
|
||||
* \param self singleton
|
||||
* \param handle entry to insert
|
||||
*/
|
||||
static void NetWatchContextRemQue(pNetWatch self, pNWContext handle)
|
||||
{
|
||||
if (handle == self->cq_head) { /* if first */
|
||||
self->cq_head = self->cq_head->next;
|
||||
if (handle == self->cq_tail) /* if also last */
|
||||
self->cq_tail = NULL;
|
||||
} else {
|
||||
pNWContext pNxt = self->cq_head;
|
||||
while (pNxt) {
|
||||
if (handle == pNxt->next) {
|
||||
pNxt->next = pNxt->next->next;
|
||||
break;
|
||||
}
|
||||
pNxt = pNxt->next;
|
||||
}
|
||||
if (handle == self->cq_tail) /* if last */
|
||||
self->cq_tail = pNxt;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief private function to purge invalid entries
|
||||
@@ -286,19 +292,19 @@ static void NetWatchContextPrgQue(pNetWatch self)
|
||||
free(tmp);
|
||||
}
|
||||
pNxt = self->cq_head;
|
||||
while (pNxt) {
|
||||
if (pNxt->next && pNxt->next->sock < 0) {
|
||||
while (pNxt && pNxt->next) {
|
||||
if (pNxt->next->sock < 0) {
|
||||
pNWContext tmp = NULL;
|
||||
tmp = pNxt->next;
|
||||
pNxt->next = pNxt->next->next;
|
||||
tmp->vrfy = 0;
|
||||
free(tmp);
|
||||
continue;
|
||||
}
|
||||
pNxt = pNxt->next;
|
||||
}
|
||||
/* if the queue is empty clear the tail */
|
||||
if (self->cq_head == NULL)
|
||||
self->cq_tail = pNxt;
|
||||
/* if the queue is empty then pNxt is NULL else pNxt points to the tail */
|
||||
self->cq_tail = pNxt;
|
||||
self->nInvalid = 0;
|
||||
return;
|
||||
}
|
||||
@@ -306,8 +312,9 @@ static void NetWatchContextPrgQue(pNetWatch self)
|
||||
int NetWatchRegisterCallback(pNWContext * handle, int iSocket,
|
||||
pNWCallback callback, void *context)
|
||||
{
|
||||
assert(callback);
|
||||
pNWContext pNew = NULL;
|
||||
pNetWatch self = instance;
|
||||
pNetWatch self = NetWatchGetInstance();
|
||||
if (!self || self->lMagic != NWMAGIC)
|
||||
return 0;
|
||||
if (iSocket < 0 || iSocket > 65535)
|
||||
@@ -320,7 +327,6 @@ int NetWatchRegisterCallback(pNWContext * handle, int iSocket,
|
||||
pNew->mode = nwatch_read;
|
||||
pNew->func = callback;
|
||||
pNew->cntx = context;
|
||||
pNew->vrfy = NWMAGIC;
|
||||
*handle = pNew;
|
||||
NetWatchContextInsQue(self, pNew);
|
||||
return 1;
|
||||
@@ -328,13 +334,16 @@ int NetWatchRegisterCallback(pNWContext * handle, int iSocket,
|
||||
|
||||
int NetWatchRemoveCallback(pNWContext handle)
|
||||
{
|
||||
pNetWatch self = instance;
|
||||
pNetWatch self = NetWatchGetInstance();
|
||||
if (handle == NULL || handle->vrfy != NWMAGIC)
|
||||
return 0;
|
||||
if (!self || self->lMagic != NWMAGIC)
|
||||
return 0;
|
||||
/* mark as invalid */
|
||||
handle->sock = -1;
|
||||
/* increment count of invalid */
|
||||
self->nInvalid++;
|
||||
/* leave for garbage collection */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -354,7 +363,8 @@ int NetWatchSetMode(pNWContext handle, int mode)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief the registered SICS Task to drive all this
|
||||
* \brief the task to drive all this
|
||||
* Should be called periodically
|
||||
*/
|
||||
int NetWatchTask(void *pData)
|
||||
{
|
||||
@@ -367,7 +377,7 @@ int NetWatchTask(void *pData)
|
||||
int iCount;
|
||||
|
||||
/* Check the singleton */
|
||||
self = (pNetWatch) instance;
|
||||
self = NetWatchGetInstance();
|
||||
if (!self || self->lMagic != NWMAGIC)
|
||||
return 0;
|
||||
|
||||
@@ -375,7 +385,7 @@ int NetWatchTask(void *pData)
|
||||
if (self->nInvalid > 0)
|
||||
NetWatchContextPrgQue(self);
|
||||
|
||||
/* build the select mask */
|
||||
/* build the select mask */
|
||||
FD_ZERO(&rMask);
|
||||
FD_ZERO(&wMask);
|
||||
pNWC = self->cq_head;
|
||||
@@ -430,7 +440,11 @@ int NetWatchTask(void *pData)
|
||||
break;
|
||||
}
|
||||
NetWatchTimerRemQue(self, pNew);
|
||||
activeTimer = pNew;
|
||||
activeTimer->vrfy = ~NWMAGIC;
|
||||
iStatus = pNew->func(pNew->cntx, 0);
|
||||
activeTimer->vrfy = 0;
|
||||
activeTimer = NULL;
|
||||
/*
|
||||
* If this is a recurrent timer and the function
|
||||
* indicates to keep it going, put it back in
|
||||
|
||||
Reference in New Issue
Block a user