diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index b929e4d91..d2d921b35 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -15,6 +15,31 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
Changes between 3.14.x and 3.15.0.x
+
+Reworked the epicsEvent C & C++ APIs
+
+
+ - Renamed the enum epicsEventWaitStatus to epicsEventStatus
+ - Defined epicsEventWaitStatus as a macro for epicsEventStatus
+ - Renamed epicsEventWaitOk to epicsEventOk
+ - Renamed epicsEventWaitError to epicsEventError
+ - Defined epicsEventWaitOK and epicsEventWaitError as macros
+ - Added epicsEventTrigger(id) which triggers an event and returns OK or an
+ error status if the underlying OS primitives report an error
+ - Added epicsEventMustTrigger(id) which halts on error
+ - Defined epicsEventSignal(id) as a macro for epicsEventMustTrigger(id)
+ - Added a new C++ method epicsEvent::trigger() which throws an
+ epicsEvent::invalidSemaphore in the event of an error
+ - epicsEvent::signal() makes an inline call to epicsEvent::trigger()
+ - epicsEventWait() and epicsEventWaitWithTimeout() now return an error
+ status if the underlying OS primitives report an error
+ - All the epicsEventMust...() routines are now implemented in the common
+ libCom/osi/epicsEvent.cpp source file, and call cantProceed() instead of
+ mis-using assert()
+ - Implemented epicsEventShow() on Posix
+ - Win32: Removed all epicsShareAPI decorations
+
+
Enabled histogram record type
@@ -24,7 +49,8 @@ but has now been added along with its associated soft device support. The build
system now generates the list of all the record.dbd files in base automatically
in src/std/rec/Makefile.
-Reorganization of src/
+
+Reorganization of src/
Reorganization of subdirectories of src/ to better represent the relation
between different parts as described in the following table.
diff --git a/src/libCom/osi/epicsEvent.cpp b/src/libCom/osi/epicsEvent.cpp
index 4d3dd4492..04b4a08d0 100644
--- a/src/libCom/osi/epicsEvent.cpp
+++ b/src/libCom/osi/epicsEvent.cpp
@@ -1,10 +1,9 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
@@ -17,6 +16,7 @@
#define epicsExportSharedSymbols
#include "epicsEvent.h"
#include "epicsStdioRedirect.h"
+#include "cantProceed.h"
// vxWorks 5.4 gcc fails during compile when I use std::exception
using namespace std;
@@ -52,49 +52,81 @@ epicsEvent::~epicsEvent ()
epicsEventDestroy ( this->id );
}
-void epicsEvent::signal ()
+void epicsEvent::trigger ()
{
- epicsEventSignal ( this->id );
+ epicsEventStatus status = epicsEventTrigger (this->id);
+
+ if (status != epicsEventOK) {
+ throw invalidSemaphore ();
+ }
}
void epicsEvent::wait ()
{
- epicsEventWaitStatus status;
- status = epicsEventWait (this->id);
- if (status!=epicsEventWaitOK) {
+ epicsEventStatus status = epicsEventWait (this->id);
+
+ if (status != epicsEventOK) {
throw invalidSemaphore ();
}
}
bool epicsEvent::wait (double timeOut)
{
- epicsEventWaitStatus status;
- status = epicsEventWaitWithTimeout (this->id, timeOut);
- if (status==epicsEventWaitOK) {
+ epicsEventStatus status = epicsEventWaitWithTimeout (this->id, timeOut);
+
+ if (status == epicsEventOK) {
return true;
- } else if (status==epicsEventWaitTimeout) {
+ } else if (status == epicsEventWaitTimeout) {
return false;
- } else {
- throw invalidSemaphore ();
}
- return false;
+ throw invalidSemaphore ();
}
bool epicsEvent::tryWait ()
{
- epicsEventWaitStatus status;
- status = epicsEventTryWait (this->id);
- if (status==epicsEventWaitOK) {
+ epicsEventStatus status = epicsEventTryWait (this->id);
+
+ if (status == epicsEventOK) {
return true;
- } else if (status==epicsEventWaitTimeout) {
+ } else if (status == epicsEventWaitTimeout) {
return false;
- } else {
- throw invalidSemaphore ();
}
- return false;
+ throw invalidSemaphore ();
}
void epicsEvent::show ( unsigned level ) const
{
epicsEventShow ( this->id, level );
}
+
+
+// epicsEventMust... convenience routines for C code
+
+extern "C" {
+
+epicsShareFunc epicsEventId epicsEventMustCreate (
+ epicsEventInitialState initialState)
+{
+ epicsEventId id = epicsEventCreate (initialState);
+
+ if (!id)
+ cantProceed ("epicsEventMustCreate");
+ return id;
+}
+
+epicsShareFunc void epicsEventMustTrigger (epicsEventId id) {
+ epicsEventStatus status = epicsEventTrigger (id);
+
+ if (status != epicsEventOK)
+ cantProceed ("epicsEventMustTrigger");
+}
+
+epicsShareFunc void epicsEventMustWait (epicsEventId id) {
+ epicsEventStatus status = epicsEventWait (id);
+
+ if (status != epicsEventOK)
+ cantProceed ("epicsEventMustWait");
+}
+
+} // extern "C"
+
diff --git a/src/libCom/osi/epicsEvent.h b/src/libCom/osi/epicsEvent.h
index 1bc98a0fd..e77d9a5ce 100644
--- a/src/libCom/osi/epicsEvent.h
+++ b/src/libCom/osi/epicsEvent.h
@@ -1,25 +1,33 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#ifndef epicsEventh
#define epicsEventh
-#include "epicsAssert.h"
#include "shareLib.h"
typedef struct epicsEventOSD *epicsEventId;
typedef enum {
- epicsEventWaitOK,epicsEventWaitTimeout,epicsEventWaitError
-} epicsEventWaitStatus;
+ epicsEventOK = 0,
+ epicsEventWaitTimeout,
+ epicsEventError
+} epicsEventStatus;
-typedef enum {epicsEventEmpty,epicsEventFull} epicsEventInitialState;
+/* Backwards compatibility */
+#define epicsEventWaitStatus epicsEventStatus
+#define epicsEventWaitOK epicsEventOK
+#define epicsEventWaitError epicsEventError
+
+typedef enum {
+ epicsEventEmpty,
+ epicsEventFull
+} epicsEventInitialState;
#ifdef __cplusplus
@@ -27,42 +35,40 @@ class epicsShareClass epicsEvent {
public:
epicsEvent ( epicsEventInitialState initial = epicsEventEmpty );
~epicsEvent ();
- void signal ();
- void wait (); /* blocks until full */
- bool wait ( double timeOut ); /* false if empty at time out */
- bool tryWait (); /* false if empty */
+ void trigger ();
+ void signal () { this->trigger(); }
+ void wait (); /* blocks until full */
+ bool wait ( double timeOut ); /* false if still empty at time out */
+ bool tryWait (); /* false if empty */
void show ( unsigned level ) const;
- class invalidSemaphore; /* exception payload */
+ class invalidSemaphore; /* exception payload */
private:
epicsEvent ( const epicsEvent & );
epicsEvent & operator = ( const epicsEvent & );
epicsEventId id;
};
-#endif /*__cplusplus */
-
-#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus */
-epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate(
+epicsShareFunc epicsEventId epicsEventCreate(
epicsEventInitialState initialState);
-epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate (
+epicsShareFunc epicsEventId epicsEventMustCreate (
epicsEventInitialState initialState);
-epicsShareFunc void epicsShareAPI epicsEventDestroy(epicsEventId id);
-epicsShareFunc void epicsShareAPI epicsEventSignal(epicsEventId id);
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait(
+epicsShareFunc void epicsEventDestroy(epicsEventId id);
+epicsShareFunc epicsEventStatus epicsEventTrigger(
epicsEventId id);
-#define epicsEventMustWait(ID) { \
- epicsEventWaitStatus status = epicsEventWait(ID); \
- assert(status == epicsEventWaitOK); \
-}
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout(
+epicsShareFunc void epicsEventMustTrigger(epicsEventId id);
+#define epicsEventSignal(ID) epicsEventMustTrigger(ID)
+epicsShareFunc epicsEventStatus epicsEventWait(
+ epicsEventId id);
+epicsShareFunc void epicsEventMustWait(epicsEventId id);
+epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(
epicsEventId id, double timeOut);
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait(
+epicsShareFunc epicsEventStatus epicsEventTryWait(
epicsEventId id);
-epicsShareFunc void epicsShareAPI epicsEventShow(
+epicsShareFunc void epicsEventShow(
epicsEventId id, unsigned int level);
#ifdef __cplusplus
diff --git a/src/libCom/osi/os/RTEMS/osdEvent.c b/src/libCom/osi/os/RTEMS/osdEvent.c
index 12bbc4733..ce21506c7 100644
--- a/src/libCom/osi/os/RTEMS/osdEvent.c
+++ b/src/libCom/osi/os/RTEMS/osdEvent.c
@@ -1,7 +1,8 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
@@ -18,7 +19,6 @@
*/
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
-#include
#include
#include
#include
@@ -84,13 +84,6 @@ epicsEventCreate(epicsEventInitialState initialState)
return (epicsEventId)sid;
}
-epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
-{
- epicsEventId id = epicsEventCreate (initialState);
- assert (id);
- return id;
-}
-
void
epicsEventDestroy(epicsEventId id)
{
@@ -102,18 +95,20 @@ epicsEventDestroy(epicsEventId id)
errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc));
}
-void
-epicsEventSignal(epicsEventId id)
+epicsEventStatus
+epicsEventTrigger(epicsEventId id)
{
rtems_id sid = (rtems_id)id;
rtems_status_code sc;
sc = rtems_semaphore_release (sid);
- if (sc != RTEMS_SUCCESSFUL)
- errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc));
+ if (sc == RTEMS_SUCCESSFUL)
+ return epicsEventOK;
+ errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc));
+ return epicsEventError;
}
-epicsEventWaitStatus
+epicsEventStatus
epicsEventWait(epicsEventId id)
{
rtems_id sid = (rtems_id)id;
@@ -122,11 +117,11 @@ epicsEventWait(epicsEventId id)
SEMSTAT(0)
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
- return epicsEventWaitError;
- return epicsEventWaitOK;
+ return epicsEventError;
+ return epicsEventOK;
}
-epicsEventWaitStatus
+epicsEventStatus
epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
{
rtems_id sid = (rtems_id)id;
@@ -142,14 +137,14 @@ epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
delay++;
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay);
if (sc == RTEMS_SUCCESSFUL)
- return epicsEventWaitOK;
+ return epicsEventOK;
else if (sc == RTEMS_TIMEOUT)
return epicsEventWaitTimeout;
else
- return epicsEventWaitError;
+ return epicsEventError;
}
-epicsEventWaitStatus
+epicsEventStatus
epicsEventTryWait(epicsEventId id)
{
rtems_id sid = (rtems_id)id;
@@ -158,11 +153,11 @@ epicsEventTryWait(epicsEventId id)
SEMSTAT(2)
sc = rtems_semaphore_obtain (sid, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT);
if (sc == RTEMS_SUCCESSFUL)
- return epicsEventWaitOK;
+ return epicsEventOK;
else if (sc == RTEMS_UNSATISFIED)
return epicsEventWaitTimeout;
else
- return epicsEventWaitError;
+ return epicsEventError;
}
void
diff --git a/src/libCom/osi/os/WIN32/osdEvent.c b/src/libCom/osi/os/WIN32/osdEvent.c
index f7cafcf3e..a57d43608 100644
--- a/src/libCom/osi/os/WIN32/osdEvent.c
+++ b/src/libCom/osi/os/WIN32/osdEvent.c
@@ -1,10 +1,9 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* osdEvent.c */
@@ -27,7 +26,6 @@
#define epicsExportSharedSymbols
#include "shareLib.h"
#include "epicsEvent.h"
-#include "epicsAssert.h"
typedef struct epicsEventOSD {
HANDLE handle;
@@ -36,7 +34,7 @@ typedef struct epicsEventOSD {
/*
* epicsEventCreate ()
*/
-epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate (
+epicsShareFunc epicsEventId epicsEventCreate (
epicsEventInitialState initialState )
{
epicsEventOSD *pSem;
@@ -53,55 +51,44 @@ epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate (
return pSem;
}
-/*
- * epicsEventMustCreate ()
- */
-epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate (
- epicsEventInitialState initialState )
-{
- epicsEventId id = epicsEventCreate ( initialState );
- assert ( id );
- return id;
-}
-
/*
* epicsEventDestroy ()
*/
-epicsShareFunc void epicsShareAPI epicsEventDestroy ( epicsEventId pSem )
+epicsShareFunc void epicsEventDestroy ( epicsEventId pSem )
{
CloseHandle ( pSem->handle );
free ( pSem );
}
/*
- * epicsEventSignal ()
+ * epicsEventTrigger ()
*/
-epicsShareFunc void epicsShareAPI epicsEventSignal ( epicsEventId pSem )
+epicsShareFunc epicsEventStatus epicsEventTrigger ( epicsEventId pSem )
{
BOOL status;
status = SetEvent ( pSem->handle );
- assert ( status );
+ return status ? epicsEventOK : epicsEventError;
}
/*
* epicsEventWait ()
*/
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait ( epicsEventId pSem )
+epicsShareFunc epicsEventStatus epicsEventWait ( epicsEventId pSem )
{
DWORD status;
status = WaitForSingleObject (pSem->handle, INFINITE);
if ( status == WAIT_OBJECT_0 ) {
- return epicsEventWaitOK;
+ return epicsEventOK;
}
else {
- return epicsEventWaitError;
+ return epicsEventError;
}
}
/*
* epicsEventWaitWithTimeout ()
*/
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout (
+epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout (
epicsEventId pSem, double timeOut )
{
static const unsigned mSecPerSec = 1000;
@@ -122,38 +109,38 @@ epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout (
}
status = WaitForSingleObject ( pSem->handle, tmo );
if ( status == WAIT_OBJECT_0 ) {
- return epicsEventWaitOK;
+ return epicsEventOK;
}
else if ( status == WAIT_TIMEOUT ) {
return epicsEventWaitTimeout;
}
else {
- return epicsEventWaitError;
+ return epicsEventError;
}
}
/*
* epicsEventTryWait ()
*/
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait ( epicsEventId pSem )
+epicsShareFunc epicsEventStatus epicsEventTryWait ( epicsEventId pSem )
{
DWORD status;
status = WaitForSingleObject ( pSem->handle, 0 );
if ( status == WAIT_OBJECT_0 ) {
- return epicsEventWaitOK;
+ return epicsEventOK;
}
else if ( status == WAIT_TIMEOUT ) {
return epicsEventWaitTimeout;
}
else {
- return epicsEventWaitError;
+ return epicsEventError;
}
}
/*
* epicsEventShow ()
*/
-epicsShareFunc void epicsShareAPI epicsEventShow ( epicsEventId id, unsigned level )
+epicsShareFunc void epicsEventShow ( epicsEventId id, unsigned level )
{
}
diff --git a/src/libCom/osi/os/posix/osdEvent.c b/src/libCom/osi/os/posix/osdEvent.c
index dd3923c7d..cfd80aa67 100644
--- a/src/libCom/osi/os/posix/osdEvent.c
+++ b/src/libCom/osi/os/posix/osdEvent.c
@@ -1,5 +1,5 @@
/*************************************************************************\
-* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
@@ -21,155 +21,142 @@
#define epicsExportSharedSymbols
#include "epicsEvent.h"
-#include "cantProceed.h"
#include "epicsTime.h"
#include "errlog.h"
-#include "epicsAssert.h"
/* Until these can be demonstrated to work leave them undefined*/
#undef _POSIX_THREAD_PROCESS_SHARED
#undef _POSIX_THREAD_PRIO_INHERIT
-typedef struct epicsEventOSD {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int isFull;
-}epicsEventOSD;
-
-#define checkStatus(status,message) \
-if((status)) { \
- errlogPrintf("epicsEvent %s failed: error %s\n",(message),strerror((status)));}
+struct epicsEventOSD {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int isFull;
+};
-#define checkStatusQuit(status,message,method) \
-if(status) { \
- errlogPrintf("epicsEvent %s failed: error %s\n",(message),strerror((status))); \
- cantProceed((method)); \
-}
+#define printStatus(status, routine, func) \
+ errlogPrintf("%s: %s failed: %s\n", (func), (routine), strerror(status))
-static int mutexLock(pthread_mutex_t *id)
-{
- int status;
-
- while(1) {
- status = pthread_mutex_lock(id);
- if(status!=EINTR) return status;
- errlogPrintf("pthread_mutex_lock returned EINTR. Violates SUSv3\n");
+#define checkStatus(status, routine, func) \
+ if (status) { \
+ printStatus(status, routine, func); \
}
-}
-static int condTimedwait(pthread_cond_t *condId, pthread_mutex_t *mutexId,
- struct timespec *time)
-{
- int status;
- while(1) {
- status = pthread_cond_timedwait(condId,mutexId,time);
- if(status!=EINTR) return status;
- errlogPrintf("pthread_cond_timedwait returned EINTR. Violates SUSv3\n");
+#define checkStatusReturn(status, routine, func) \
+ if (status) { \
+ printStatus(status, routine, func); \
+ return epicsEventError; \
}
-}
-static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId)
+
+epicsShareFunc epicsEventId epicsEventCreate(epicsEventInitialState init)
{
- int status;
- while(1) {
- status = pthread_cond_wait(condId,mutexId);
- if(status!=EINTR) return status;
- errlogPrintf("pthread_cond_wait returned EINTR. Violates SUSv3\n");
+ epicsEventId pevent = malloc(sizeof(*pevent));
+
+ if (pevent) {
+ int status = pthread_mutex_init(&pevent->mutex, 0);
+
+ pevent->isFull = (init == epicsEventFull);
+ if (status) {
+ printStatus(status, "pthread_mutex_init", "epicsEventCreate");
+ } else {
+ status = pthread_cond_init(&pevent->cond, 0);
+ if (!status)
+ return pevent;
+ printStatus(status, "pthread_cond_init", "epicsEventCreate");
+ status = pthread_mutex_destroy(&pevent->mutex);
+ checkStatus(status, "pthread_mutex_destroy", "epicsEventCreate");
+ }
+ free(pevent);
}
-}
-
-epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate(epicsEventInitialState initialState)
-{
- epicsEventOSD *pevent;
- int status;
-
- pevent = callocMustSucceed(1,sizeof(*pevent),"epicsEventCreate");
- status = pthread_mutex_init(&pevent->mutex,0);
- checkStatusQuit(status,"pthread_mutex_init","epicsEventCreate");
- status = pthread_cond_init(&pevent->cond,0);
- checkStatusQuit(status,"pthread_cond_init","epicsEventCreate");
- if(initialState==epicsEventFull) pevent->isFull = 1;
- return((epicsEventId)pevent);
+ return NULL;
}
-epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate(epicsEventInitialState initialState)
+epicsShareFunc void epicsEventDestroy(epicsEventId pevent)
{
- epicsEventId id = epicsEventCreate (initialState);
- assert (id);
- return id;
-}
+ int status = pthread_mutex_destroy(&pevent->mutex);
-epicsShareFunc void epicsShareAPI epicsEventDestroy(epicsEventId pevent)
-{
- int status;
-
- status = pthread_mutex_destroy(&pevent->mutex);
- checkStatus(status,"pthread_mutex_destroy");
+ checkStatus(status, "pthread_mutex_destroy", "epicsEventDestroy");
status = pthread_cond_destroy(&pevent->cond);
- checkStatus(status,"pthread_cond_destroy");
+ checkStatus(status, "pthread_cond_destroy", "epicsEventDestroy");
free(pevent);
}
-epicsShareFunc void epicsShareAPI epicsEventSignal(epicsEventId pevent)
+epicsShareFunc epicsEventStatus epicsEventTrigger(epicsEventId pevent)
{
- int status;
+ int status = pthread_mutex_lock(&pevent->mutex);
- status = mutexLock(&pevent->mutex);
- checkStatusQuit(status,"pthread_mutex_lock","epicsEventSignal");
- if(!pevent->isFull) {
+ checkStatusReturn(status, "pthread_mutex_lock", "epicsEventTrigger");
+ if (!pevent->isFull) {
pevent->isFull = 1;
status = pthread_cond_signal(&pevent->cond);
- checkStatus(status,"pthread_cond_signal");
+ checkStatus(status, "pthread_cond_signal", "epicsEventTrigger");
}
status = pthread_mutex_unlock(&pevent->mutex);
- checkStatusQuit(status,"pthread_mutex_unlock","epicsEventSignal");
+ checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventTrigger");
+ return epicsEventOK;
}
-
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait(epicsEventId pevent)
-{
- int status;
- if(!pevent) return(epicsEventWaitError);
- status = mutexLock(&pevent->mutex);
- checkStatusQuit(status,"pthread_mutex_lock","epicsEventWait");
- /*no need for while since caller must be prepared for no work*/
- if(!pevent->isFull) {
- status = condWait(&pevent->cond,&pevent->mutex);
- checkStatusQuit(status,"pthread_cond_wait","epicsEventWait");
+epicsShareFunc epicsEventStatus epicsEventWait(epicsEventId pevent)
+{
+ epicsEventStatus result = epicsEventOK;
+ int status = pthread_mutex_lock(&pevent->mutex);
+
+ checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWait");
+ while (!pevent->isFull) {
+ status = pthread_cond_wait(&pevent->cond, &pevent->mutex);
+ if (status) {
+ printStatus(status, "pthread_cond_wait", "epicsEventWait");
+ result = epicsEventError;
+ goto release;
+ }
}
pevent->isFull = 0;
+ result = epicsEventOK;
+release:
status = pthread_mutex_unlock(&pevent->mutex);
- checkStatusQuit(status,"pthread_mutex_unlock","epicsEventWait");
- return(epicsEventWaitOK);
+ checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWait");
+ return result;
}
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout(epicsEventId pevent, double timeout)
+epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(epicsEventId pevent,
+ double timeout)
{
- struct timespec wakeTime;
- int status = 0;
- int unlockStatus;
+ epicsEventStatus result = epicsEventOK;
+ int status = pthread_mutex_lock(&pevent->mutex);
- status = mutexLock(&pevent->mutex);
- checkStatusQuit(status,"pthread_mutex_lock","epicsEventWaitWithTimeout");
- if(!pevent->isFull) {
- convertDoubleToWakeTime(timeout,&wakeTime);
- status = condTimedwait(
- &pevent->cond,&pevent->mutex,&wakeTime);
+ checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWaitWithTimeout");
+ if (!pevent->isFull) {
+ struct timespec wakeTime;
+
+ convertDoubleToWakeTime(timeout, &wakeTime);
+ while (!status && !pevent->isFull) {
+ status = pthread_cond_timedwait(&pevent->cond, &pevent->mutex,
+ &wakeTime);
+ }
+ if (status) {
+ result = (status == ETIMEDOUT) ?
+ epicsEventWaitTimeout : epicsEventError;
+ goto release;
+ }
}
- if(status==0) pevent->isFull = 0;
- unlockStatus = pthread_mutex_unlock(&pevent->mutex);
- checkStatusQuit(unlockStatus,"pthread_mutex_unlock","epicsEventWaitWithTimeout");
- if(status==0) return(epicsEventWaitOK);
- if(status==ETIMEDOUT) return(epicsEventWaitTimeout);
- checkStatus(status,"pthread_cond_timedwait");
- return(epicsEventWaitError);
+ pevent->isFull = 0;
+release:
+ status = pthread_mutex_unlock(&pevent->mutex);
+ checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWaitWithTimeout");
+ return result;
}
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait(epicsEventId id)
+epicsShareFunc epicsEventStatus epicsEventTryWait(epicsEventId id)
{
- return(epicsEventWaitWithTimeout(id,0.0));
+ return epicsEventWaitWithTimeout(id, 0.0);
}
-epicsShareFunc void epicsShareAPI epicsEventShow(epicsEventId id,unsigned int level)
+epicsShareFunc void epicsEventShow(epicsEventId pevent, unsigned int level)
{
+ printf("epicsEvent %p: %s\n", pevent,
+ pevent->isFull ? "full" : "empty");
+ if (level > 0)
+ printf(" pthread_mutex = %p, pthread_cond = %p\n",
+ &pevent->mutex, &pevent->cond);
}
diff --git a/src/libCom/osi/os/vxWorks/osdEvent.c b/src/libCom/osi/os/vxWorks/osdEvent.c
index 692d6f63f..875d4e6f6 100644
--- a/src/libCom/osi/os/vxWorks/osdEvent.c
+++ b/src/libCom/osi/os/vxWorks/osdEvent.c
@@ -1,10 +1,9 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* os/vxWorks/osdEvent.c */
@@ -29,19 +28,12 @@ epicsEventId epicsEventCreate(epicsEventInitialState initialState)
(initialState == epicsEventEmpty) ? SEM_EMPTY : SEM_FULL);
}
-epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
-{
- epicsEventId id = epicsEventCreate(initialState);
- assert(id);
- return id;
-}
-
void epicsEventDestroy(epicsEventId id)
{
semDelete((SEM_ID)id);
}
-epicsEventWaitStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
+epicsEventStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
{
int rate = sysClkRateGet();
int status;
@@ -58,22 +50,22 @@ epicsEventWaitStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
}
status = semTake((SEM_ID)id, ticks);
if (status == OK)
- return epicsEventWaitOK;
+ return epicsEventOK;
if (errno == S_objLib_OBJ_TIMEOUT ||
(errno == S_objLib_OBJ_UNAVAILABLE && ticks == 0))
return epicsEventWaitTimeout;
- return epicsEventWaitError;
+ return epicsEventError;
}
-epicsEventWaitStatus epicsEventTryWait(epicsEventId id)
+epicsEventStatus epicsEventTryWait(epicsEventId id)
{
int status = semTake((SEM_ID)id, NO_WAIT);
if (status == OK)
- return epicsEventWaitOK;
+ return epicsEventOK;
if (errno == S_objLib_OBJ_UNAVAILABLE)
return epicsEventWaitTimeout;
- return epicsEventWaitError;
+ return epicsEventError;
}
void epicsEventShow(epicsEventId id, unsigned int level)
diff --git a/src/libCom/osi/os/vxWorks/osdEvent.h b/src/libCom/osi/os/vxWorks/osdEvent.h
index 450f8eac6..b08b4d98f 100644
--- a/src/libCom/osi/os/vxWorks/osdEvent.h
+++ b/src/libCom/osi/os/vxWorks/osdEvent.h
@@ -1,10 +1,9 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* os/vxWorks/osdEvent.h */
@@ -14,12 +13,8 @@
#include
#include
-/* If the macro is replaced by inline it is necessary to say
- static __inline__
- but then a warning message appears everywhere osdEvent.h is included
-*/
-
-#define epicsEventSignal(ID) semGive((SEM_ID)(ID))
+#define epicsEventTrigger(ID) \
+ (semGive((SEM_ID)(ID)) == OK ? epicsEventOK : epicsEventError)
#define epicsEventWait(ID) \
-(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? epicsEventWaitOK : epicsEventWaitError)
+ (semTake((SEM_ID)(ID), WAIT_FOREVER) == OK ? epicsEventOK : epicsEventError)
diff --git a/src/libCom/test/epicsEventTest.cpp b/src/libCom/test/epicsEventTest.cpp
index 31da6208b..b0d79613f 100644
--- a/src/libCom/test/epicsEventTest.cpp
+++ b/src/libCom/test/epicsEventTest.cpp
@@ -47,8 +47,8 @@ static void consumer(void *arg)
testDiag("consumer: starting");
while (!pinfo->quit) {
- epicsEventWaitStatus status = epicsEventWait(pinfo->event);
- if (status != epicsEventWaitOK) {
+ epicsEventStatus status = epicsEventWait(pinfo->event);
+ if (status != epicsEventOK) {
testDiag("consumer: epicsEventWait returned %d", status);
errors++;
}
@@ -101,7 +101,7 @@ static void producer(void *arg)
}
epicsMutexUnlock(pinfo->lockRing);
epicsThreadSleep(1.0);
- epicsEventSignal(pinfo->event);
+ epicsEventMustTrigger(pinfo->event);
}
testOk(errors == 0, "%s: errors = %d", name, errors);
}
@@ -140,7 +140,7 @@ static void eventWakeupTest(void)
epicsMutexUnlock(wp->countMutex);
testOk(c == 0, "all threads still sleeping");
for (i = 1 ; i <= SLEEPERCOUNT ; i++) {
- epicsEventSignal(wp->event);
+ epicsEventMustTrigger(wp->event);
epicsThreadSleep(0.5);
epicsMutexLock(wp->countMutex);
c = wp->count;
@@ -190,7 +190,7 @@ MAIN(epicsEventTest)
epicsEventId event;
int status;
- testPlan(12+SLEEPERCOUNT);
+ testPlan(13+SLEEPERCOUNT);
event = epicsEventMustCreate(epicsEventEmpty);
@@ -206,19 +206,21 @@ MAIN(epicsEventTest)
testOk(status == epicsEventWaitTimeout,
"epicsEventTryWait(event) = %d", status);
- epicsEventSignal(event);
+ status = epicsEventTrigger(event);
+ testOk(status == epicsEventOK,
+ "epicsEventTrigger(event) = %d", status);
status = epicsEventWaitWithTimeout(event, 1.0);
- testOk(status == epicsEventWaitOK,
+ testOk(status == epicsEventOK,
"epicsEventWaitWithTimeout(event, 1.0) = %d", status);
- epicsEventSignal(event);
+ epicsEventMustTrigger(event);
status = epicsEventWaitWithTimeout(event,DBL_MAX);
- testOk(status == epicsEventWaitOK,
+ testOk(status == epicsEventOK,
"epicsEventWaitWithTimeout(event, DBL_MAX) = %d", status);
- epicsEventSignal(event);
+ epicsEventMustTrigger(event);
status = epicsEventTryWait(event);
- testOk(status == epicsEventWaitOK,
+ testOk(status == epicsEventOK,
"epicsEventTryWait(event) = %d", status);
info *pinfo = (info *)calloc(1,sizeof(info));
@@ -242,7 +244,7 @@ MAIN(epicsEventTest)
pinfo->quit = 1;
epicsThreadSleep(2.0);
- epicsEventSignal(pinfo->event);
+ epicsEventMustTrigger(pinfo->event);
epicsThreadSleep(1.0);
eventWaitTest();