cleaned up locking - this is an old code written w/o consideration of SMP
thread safe locking issues
This commit is contained in:
133
src/db/dbEvent.c
133
src/db/dbEvent.c
@@ -90,10 +90,7 @@ struct event_user {
|
||||
epicsMutexId lock;
|
||||
epicsEventId ppendsem; /* Wait while empty */
|
||||
epicsEventId pflush_sem; /* wait for flush */
|
||||
|
||||
OVRFFUNC *overflow_sub; /* called when overflow detect */
|
||||
void *overflow_arg; /* parameter to above */
|
||||
|
||||
|
||||
EXTRALABORFUNC *extralabor_sub;/* off load to event task */
|
||||
void *extralabor_arg;/* parameter to above */
|
||||
|
||||
@@ -194,12 +191,6 @@ int epicsShareAPI dbel ( const char *pname, unsigned level )
|
||||
if ( level > 0 ) {
|
||||
printf ( "%4.4s", pdbFldDes->name );
|
||||
|
||||
/* they should never see this one */
|
||||
if ( pevent->ev_que->evUser->queovr ) {
|
||||
printf ( " !! event discard count=%d !!",
|
||||
pevent->ev_que->evUser->queovr );
|
||||
}
|
||||
|
||||
printf ( " { " );
|
||||
if ( pevent->select & DBE_VALUE ) printf( "VALUE " );
|
||||
if ( pevent->select & DBE_LOG ) printf( "LOG " );
|
||||
@@ -565,36 +556,22 @@ void epicsShareAPI db_cancel_event (dbEventSubscription es)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_ADD_OVERFLOW_EVENT()
|
||||
*
|
||||
* Specify a routine to be executed for event que overflow condition
|
||||
*/
|
||||
int epicsShareAPI db_add_overflow_event (
|
||||
dbEventCtx ctx, OVRFFUNC *overflow_sub, void *overflow_arg)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
|
||||
evUser->overflow_sub = overflow_sub;
|
||||
evUser->overflow_arg = overflow_arg;
|
||||
|
||||
return DB_EVENT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_FLUSH_EXTRA_LABOR_EVENT()
|
||||
*
|
||||
* waits for extra labor in progress to finish
|
||||
*/
|
||||
int epicsShareAPI db_flush_extra_labor_event (dbEventCtx ctx)
|
||||
void epicsShareAPI db_flush_extra_labor_event (dbEventCtx ctx)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
|
||||
while(evUser->extraLaborBusy){
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
while ( evUser->extraLaborBusy ) {
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
epicsThreadSleep(1.0);
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
}
|
||||
|
||||
return DB_EVENT_OK;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -625,19 +602,18 @@ int epicsShareAPI db_post_extra_labor (dbEventCtx ctx)
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
int doit;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
if ( ! evUser->extra_labor ) {
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
if ( ! evUser->extra_labor ) {
|
||||
evUser->extra_labor = TRUE;
|
||||
doit = TRUE;
|
||||
}
|
||||
else {
|
||||
doit = FALSE;
|
||||
}
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
if ( doit ) {
|
||||
epicsEventSignal(evUser->ppendsem);
|
||||
}
|
||||
evUser->extra_labor = TRUE;
|
||||
doit = TRUE;
|
||||
}
|
||||
else {
|
||||
doit = FALSE;
|
||||
}
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
if ( doit ) {
|
||||
epicsEventSignal(evUser->ppendsem);
|
||||
}
|
||||
|
||||
return DB_EVENT_OK;
|
||||
@@ -700,11 +676,11 @@ LOCAL void db_post_single_event_private (struct evSubscrip *event)
|
||||
firstEventFlag = 0;
|
||||
}
|
||||
/*
|
||||
* otherwise if the current entry is available then
|
||||
* fill it in and advance the ring buffer
|
||||
* Otherwise, the current entry must be available.
|
||||
* Fill it in and advance the ring buffer.
|
||||
*/
|
||||
else if ( ev_que->evque[ev_que->putix] == EVENTQEMPTY ) {
|
||||
|
||||
else {
|
||||
assert ( ev_que->evque[ev_que->putix] == EVENTQEMPTY );
|
||||
pLog = &ev_que->valque[ev_que->putix];
|
||||
ev_que->evque[ev_que->putix] = event;
|
||||
if (event->npend>0u) {
|
||||
@@ -723,14 +699,6 @@ LOCAL void db_post_single_event_private (struct evSubscrip *event)
|
||||
}
|
||||
ev_que->putix = RNGINC ( ev_que->putix );
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* this should never occur if this is bug free
|
||||
*/
|
||||
ev_que->evUser->queovr++;
|
||||
pLog = NULL;
|
||||
firstEventFlag = 0;
|
||||
}
|
||||
|
||||
if (pLog && event->valque) {
|
||||
struct dbCommon *precord = event->paddr->precord;
|
||||
@@ -948,50 +916,31 @@ LOCAL void event_task (void *pParm)
|
||||
* check to see if the caller has offloaded
|
||||
* labor to this task
|
||||
*/
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->extraLaborBusy = TRUE;
|
||||
if(evUser->extra_labor && evUser->extralabor_sub){
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
if(evUser->extra_labor && evUser->extralabor_sub){
|
||||
evUser->extra_labor = FALSE;
|
||||
pExtraLaborSub = evUser->extralabor_sub;
|
||||
pExtraLaborArg = evUser->extralabor_arg;
|
||||
}
|
||||
else {
|
||||
pExtraLaborSub = NULL;
|
||||
pExtraLaborArg = NULL;
|
||||
}
|
||||
if ( evUser->extra_labor && evUser->extralabor_sub ) {
|
||||
evUser->extra_labor = FALSE;
|
||||
pExtraLaborSub = evUser->extralabor_sub;
|
||||
pExtraLaborArg = evUser->extralabor_arg;
|
||||
}
|
||||
else {
|
||||
pExtraLaborSub = NULL;
|
||||
pExtraLaborArg = NULL;
|
||||
}
|
||||
if ( pExtraLaborSub ) {
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
if(pExtraLaborSub){
|
||||
(*pExtraLaborSub)(pExtraLaborArg);
|
||||
}
|
||||
(*pExtraLaborSub)(pExtraLaborArg);
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
}
|
||||
evUser->extraLaborBusy = FALSE;
|
||||
|
||||
if(evUser->extra_labor && evUser->extralabor_sub){
|
||||
evUser->extra_labor = FALSE;
|
||||
(*evUser->extralabor_sub)(evUser->extralabor_arg);
|
||||
}
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
for ( ev_que = &evUser->firstque; ev_que;
|
||||
ev_que = ev_que->nextque ) {
|
||||
event_read (ev_que);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following do not introduce event latency since they
|
||||
* are not between notification and posting events.
|
||||
*/
|
||||
if(evUser->queovr){
|
||||
if(evUser->overflow_sub)
|
||||
(*evUser->overflow_sub)(
|
||||
evUser->overflow_arg,
|
||||
evUser->queovr);
|
||||
else
|
||||
errlogPrintf("Events lost, discard count was %d\n",
|
||||
evUser->queovr);
|
||||
evUser->queovr = 0;
|
||||
}
|
||||
}while(!evUser->pendexit);
|
||||
} while( ! evUser->pendexit );
|
||||
|
||||
epicsMutexDestroy(evUser->firstque.writelock);
|
||||
|
||||
@@ -1027,14 +976,14 @@ int epicsShareAPI db_start_events (
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
|
||||
epicsMutexMustLock (evUser->firstque.writelock);
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
|
||||
/*
|
||||
* only one ca_pend_event thread may be
|
||||
* started for each evUser
|
||||
*/
|
||||
if (evUser->taskid) {
|
||||
epicsMutexUnlock (evUser->firstque.writelock);
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
return DB_EVENT_OK;
|
||||
}
|
||||
|
||||
@@ -1048,10 +997,10 @@ int epicsShareAPI db_start_events (
|
||||
taskname, osiPriority, epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
event_task, (void *)evUser);
|
||||
if (!evUser->taskid) {
|
||||
epicsMutexUnlock (evUser->firstque.writelock);
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
return DB_EVENT_ERROR;
|
||||
}
|
||||
epicsMutexUnlock (evUser->firstque.writelock);
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
return DB_EVENT_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ epicsShareFunc int epicsShareAPI db_post_events (
|
||||
|
||||
typedef void * dbEventCtx;
|
||||
|
||||
typedef void OVRFFUNC (void *overflow_arg, unsigned count);
|
||||
typedef void EXTRALABORFUNC (void *extralabor_arg);
|
||||
epicsShareFunc dbEventCtx epicsShareAPI db_init_events (void);
|
||||
epicsShareFunc int epicsShareAPI db_start_events (
|
||||
@@ -55,11 +54,9 @@ epicsShareFunc int epicsShareAPI db_start_events (
|
||||
epicsShareFunc void epicsShareAPI db_close_events (dbEventCtx ctx);
|
||||
epicsShareFunc void epicsShareAPI db_event_flow_ctrl_mode_on (dbEventCtx ctx);
|
||||
epicsShareFunc void epicsShareAPI db_event_flow_ctrl_mode_off (dbEventCtx ctx);
|
||||
epicsShareFunc int epicsShareAPI db_add_overflow_event (
|
||||
dbEventCtx ctx, OVRFFUNC *overflow_sub, void *overflow_arg);
|
||||
epicsShareFunc int epicsShareAPI db_add_extra_labor_event (
|
||||
dbEventCtx ctx, EXTRALABORFUNC *func, void *arg);
|
||||
epicsShareFunc int epicsShareAPI db_flush_extra_labor_event (dbEventCtx);
|
||||
epicsShareFunc void epicsShareAPI db_flush_extra_labor_event (dbEventCtx);
|
||||
epicsShareFunc int epicsShareAPI db_post_extra_labor (dbEventCtx ctx);
|
||||
epicsShareFunc void epicsShareAPI db_event_change_priority ( dbEventCtx ctx, unsigned epicsPriority );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user