g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014 
<== Date ==> <== Thread ==>

Subject: [Merge] lp:~anj/epics-base/epicsEvent-api into lp:epics-base
From: Andrew Johnson <anj@aps.anl.gov>
To: mp+48992@code.launchpad.net
Date: Tue, 08 Feb 2011 21:40:14 -0000
Andrew Johnson has proposed merging lp:~anj/epics-base/epicsEvent-api into lp:epics-base.

Requested reviews:
  EPICS Core Developers (epics-core)

For more details, see:
https://code.launchpad.net/~anj/epics-base/epicsEvent-api/+merge/48992

This branch modifies the epicsEvent APIs for both C and C++ callers, but keeping full backwards compatibility.

The enum epicsEventWaitStatus is renamed to epicsEventStatus, with similar name changes for the choices except for epicsEventWaitTimeout which is unchanged.  Macros are provided to allow continued use of the old names.

It adds two new routines to the C API:
 + epicsEventTrigger(id) replaces epicsEventSignal(id) but returns an epicsEventStatus so it can flag any errors from the implementation routines.
 + epicsEventMustTrigger(id) calls epicsEventTrigger(id) and suspends the calling thread on error.

epicsEventSignal(id) is now a macro that calls epicsEventMustTrigger(id).

epicsEventWait() and epicsEventWaitWithTimeout() now report errors from the implementation on all architectures; previously some architectures would suspend the thread instead.

All the epicsEventMust...() routines are now implemented in the common epicsEvent.cpp source file, and properly call cantProceed() instead of mis-using assert() in the event of any errors.

The Posix implementation now provides a basic epicsEventShow() routine.

For the C++ API it adds an epicsEvent::trigger() method that will throw an epicsEvent::invalidSemaphore exception on receiving an error.

The epicsEvent::signal() method is now an inline call to epicsEvent::trigger(), although I wonder whether signal() should halt on error like it used to instead of throwing.

The epicsShareAPI decorations (used on Windows only) have all been removed.

-- 
https://code.launchpad.net/~anj/epics-base/epicsEvent-api/+merge/48992
Your team EPICS Core Developers is requested to review the proposed merge of lp:~anj/epics-base/epicsEvent-api into lp:epics-base.
=== modified file 'documentation/RELEASE_NOTES.html'
--- documentation/RELEASE_NOTES.html	2010-11-28 03:06:40 +0000
+++ documentation/RELEASE_NOTES.html	2011-02-08 21:39:58 +0000
@@ -13,6 +13,30 @@
 <h2 align="center">Changes between 3.14.x and 3.15.1</h2>
 <!-- Insert new items immediately below here ... -->
 
+<h3>
+Reworked the epicsEvent C &amp; C++ APIs</h3>
+
+<ul>
+  <li>Renamed the enum epicsEventWaitStatus to epicsEventStatus</li>
+  <li>Defined epicsEventWaitStatus as a macro for epicsEventStatus</li>
+  <li>Renamed epicsEventWaitOk to epicsEventOk</li>
+  <li>Renamed epicsEventWaitError to epicsEventError</li>
+  <li>Defined epicsEventWaitOK and epicsEventWaitError as macros</li>
+  <li>Added epicsEventTrigger(id) which triggers an event and returns OK or an
+    error status if the underlying OS primitives report an error</li>
+  <li>Added epicsEventMustTrigger(id) which halts on error</li>
+  <li>Defined epicsEventSignal(id) as a macro for epicsEventMustTrigger(id)</li>
+  <li>Added a new C++ method epicsEvent::trigger() which throws an
+    epicsEvent::invalidSemaphore in the event of an error</li>
+  <li>epicsEvent::signal() makes an inline call to epicsEvent::trigger()</li>
+  <li>epicsEventWait() and epicsEventWaitWithTimeout() now return an error
+    status if the underlying OS primitives report an error</li>
+  <li>All the epicsEventMust...() routines are now implemented in the common
+    libCom/osi/epicsEvent.cpp source file, and call cantProceed() instead of
+    mis-using assert()</li>
+  <li>Implemented epicsEventShow() on Posix</li>
+  <li>Win32: Removed all epicsShareAPI decorations</li>
+</ul>
 
 <h3>
 Moved src/RTEMS/base directory</h3>

=== modified file 'src/libCom/osi/epicsEvent.cpp'
--- src/libCom/osi/epicsEvent.cpp	2004-09-30 19:15:45 +0000
+++ src/libCom/osi/epicsEvent.cpp	2011-02-08 21:39:58 +0000
@@ -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 @@
     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"
+

=== modified file 'src/libCom/osi/epicsEvent.h'
--- src/libCom/osi/epicsEvent.h	2009-01-06 17:07:56 +0000
+++ src/libCom/osi/epicsEvent.h	2011-02-08 21:39:58 +0000
@@ -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;
-
-typedef enum {epicsEventEmpty,epicsEventFull} epicsEventInitialState;
+    epicsEventOK = 0,
+    epicsEventWaitTimeout,
+    epicsEventError
+} epicsEventStatus;
+
+/* Backwards compatibility */
+#define epicsEventWaitStatus epicsEventStatus
+#define epicsEventWaitOK epicsEventOK
+#define epicsEventWaitError epicsEventError
+
+typedef enum {
+    epicsEventEmpty,
+    epicsEventFull
+} epicsEventInitialState;
 
 #ifdef __cplusplus
 
@@ -27,42 +35,40 @@
 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(
-    epicsEventInitialState initialState);
-epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate (
-    epicsEventInitialState initialState);
-epicsShareFunc void epicsShareAPI epicsEventDestroy(epicsEventId id);
-epicsShareFunc void epicsShareAPI epicsEventSignal(epicsEventId id);
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait(
-    epicsEventId id);
-#define epicsEventMustWait(ID) {                        \
-    epicsEventWaitStatus status = epicsEventWait(ID);   \
-    assert(status == epicsEventWaitOK);                 \
-}
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout(
+epicsShareFunc epicsEventId epicsEventCreate(
+    epicsEventInitialState initialState);
+epicsShareFunc epicsEventId epicsEventMustCreate (
+    epicsEventInitialState initialState);
+epicsShareFunc void epicsEventDestroy(epicsEventId id);
+epicsShareFunc epicsEventStatus epicsEventTrigger(
+    epicsEventId id);
+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

=== modified file 'src/libCom/osi/os/RTEMS/osdEvent.c'
--- src/libCom/osi/os/RTEMS/osdEvent.c	2010-10-05 19:27:37 +0000
+++ src/libCom/osi/os/RTEMS/osdEvent.c	2011-02-08 21:39:58 +0000
@@ -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 <assert.h>
 #include <stdio.h>
 #include <rtems.h>
 #include <rtems/error.h>
@@ -84,13 +84,6 @@
     return (epicsEventId)sid;
 }
 
-epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
-{
-    epicsEventId id = epicsEventCreate (initialState);
-    assert (id);
-    return id;
-}
-
 void
 epicsEventDestroy(epicsEventId id)
 {
@@ -102,18 +95,20 @@
         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 @@
     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 @@
         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 @@
     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

=== modified file 'src/libCom/osi/os/WIN32/osdEvent.c'
--- src/libCom/osi/os/WIN32/osdEvent.c	2010-10-05 19:27:37 +0000
+++ src/libCom/osi/os/WIN32/osdEvent.c	2011-02-08 21:39:58 +0000
@@ -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 @@
 /*
  * epicsEventCreate ()
  */
-epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate (
+epicsShareFunc epicsEventId epicsEventCreate (
     epicsEventInitialState initialState ) 
 {
     epicsEventOSD *pSem;
@@ -54,54 +52,43 @@
 }
 
 /*
- * 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 @@
     }
     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 ) 
 { 
 }

=== modified file 'src/libCom/osi/os/posix/osdEvent.c'
--- src/libCom/osi/os/posix/osdEvent.c	2009-04-23 18:49:40 +0000
+++ src/libCom/osi/os/posix/osdEvent.c	2011-02-08 21:39:58 +0000
@@ -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)));}
-
-#define checkStatusQuit(status,message,method) \
-if(status) { \
-    errlogPrintf("epicsEvent %s failed: error %s\n",(message),strerror((status))); \
-    cantProceed((method)); \
-}
-
-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");
-    }
-}
-
-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");
-    }
-}
-
-static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId)
-{
-    int status;
-    while(1) {
-        status = pthread_cond_wait(condId,mutexId);
-        if(status!=EINTR) return status;
-        errlogPrintf("pthread_cond_wait returned EINTR. Violates SUSv3\n");
-    }
-}
-
-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);
-}
-
-epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate(epicsEventInitialState initialState)
-{
-    epicsEventId id = epicsEventCreate (initialState);
-    assert (id);
-    return id;
-}
-
-epicsShareFunc void epicsShareAPI epicsEventDestroy(epicsEventId pevent)
-{
-    int   status;
-
-    status = pthread_mutex_destroy(&pevent->mutex);
-    checkStatus(status,"pthread_mutex_destroy");
+struct epicsEventOSD {
+    pthread_mutex_t mutex;
+    pthread_cond_t  cond;
+    int             isFull;
+};
+
+#define printStatus(status, routine, func) \
+    errlogPrintf("%s: %s failed: %s\n", (func), (routine), strerror(status))
+
+#define checkStatus(status, routine, func) \
+    if (status) { \
+        printStatus(status, routine, func); \
+    }
+
+#define checkStatusReturn(status, routine, func) \
+    if (status) { \
+        printStatus(status, routine, func); \
+        return epicsEventError; \
+    }
+
+
+epicsShareFunc epicsEventId epicsEventCreate(epicsEventInitialState init)
+{
+    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);
+    }
+    return NULL;
+}
+
+epicsShareFunc void epicsEventDestroy(epicsEventId pevent)
+{
+    int status = pthread_mutex_destroy(&pevent->mutex);
+
+    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");
-    }
-    status = pthread_mutex_unlock(&pevent->mutex);
-    checkStatusQuit(status,"pthread_mutex_unlock","epicsEventSignal");
-}
-
-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");
-    }
-    pevent->isFull = 0;
-    status = pthread_mutex_unlock(&pevent->mutex);
-    checkStatusQuit(status,"pthread_mutex_unlock","epicsEventWait");
-    return(epicsEventWaitOK);
-}
-
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout(epicsEventId pevent, double timeout)
-{
-    struct timespec wakeTime;
-    int   status = 0;
-    int   unlockStatus;
-
-    status = mutexLock(&pevent->mutex);
-    checkStatusQuit(status,"pthread_mutex_lock","epicsEventWaitWithTimeout");
-    if(!pevent->isFull) {
-        convertDoubleToWakeTime(timeout,&wakeTime);
-        status = condTimedwait(
-            &pevent->cond,&pevent->mutex,&wakeTime);
-    }
-    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);
-}
-
-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait(epicsEventId id)
-{
-    return(epicsEventWaitWithTimeout(id,0.0));
-}
-
-epicsShareFunc void epicsShareAPI epicsEventShow(epicsEventId id,unsigned int level)
-{
+        checkStatus(status, "pthread_cond_signal", "epicsEventTrigger");
+    }
+    status = pthread_mutex_unlock(&pevent->mutex);
+    checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventTrigger");
+    return epicsEventOK;
+}
+
+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);
+    checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWait");
+    return result;
+}
+
+epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(epicsEventId pevent,
+    double timeout)
+{
+    epicsEventStatus result = epicsEventOK;
+    int status = pthread_mutex_lock(&pevent->mutex);
+
+    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;
+        }
+    }
+    pevent->isFull = 0;
+release:
+    status = pthread_mutex_unlock(&pevent->mutex);
+    checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWaitWithTimeout");
+    return result;
+}
+
+epicsShareFunc epicsEventStatus epicsEventTryWait(epicsEventId id)
+{
+    return epicsEventWaitWithTimeout(id, 0.0);
+}
+
+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);
 }

=== modified file 'src/libCom/osi/os/vxWorks/osdEvent.c'
--- src/libCom/osi/os/vxWorks/osdEvent.c	2008-09-24 19:24:59 +0000
+++ src/libCom/osi/os/vxWorks/osdEvent.c	2011-02-08 21:39:58 +0000
@@ -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 @@
         (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 @@
     }
     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)

=== modified file 'src/libCom/osi/os/vxWorks/osdEvent.h'
--- src/libCom/osi/os/vxWorks/osdEvent.h	2002-07-12 21:35:43 +0000
+++ src/libCom/osi/os/vxWorks/osdEvent.h	2011-02-08 21:39:58 +0000
@@ -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 <vxWorks.h>
 #include <semLib.h>
 
-/* 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)


Replies:
Re: [Merge] lp:~anj/epics-base/epicsEvent-api into lp:epics-base Andrew Johnson
Re: [Merge] lp:~anj/epics-base/epicsEvent-api into lp:epics-base Andrew Johnson
[Merge] lp:~anj/epics-base/epicsEvent-api into lp:epics-base noreply

Navigate by Date:
Prev: Project ideas for the Codeathon Andrew Johnson
Next: Re: [Merge] lp:~anj/epics-base/epicsEvent-api into lp:epics-base Andrew Johnson
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014 
Navigate by Thread:
Prev: Project ideas for the Codeathon Andrew Johnson
Next: Re: [Merge] lp:~anj/epics-base/epicsEvent-api into lp:epics-base Andrew Johnson
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·