Merge lp:~anj/epics-base/epicsEvent-api into lp:~epics-core/epics-base/3.15

Proposed by Andrew Johnson on 2011-02-08
Status: Merged
Merged at revision: 12238
Proposed branch: lp:~anj/epics-base/epicsEvent-api
Merge into: lp:~epics-core/epics-base/3.15
Diff against target: 911 lines (+287/-269)
8 files modified
documentation/RELEASE_NOTES.html (+24/-0)
src/libCom/osi/epicsEvent.cpp (+54/-22)
src/libCom/osi/epicsEvent.h (+37/-31)
src/libCom/osi/os/RTEMS/osdEvent.c (+18/-23)
src/libCom/osi/os/WIN32/osdEvent.c (+17/-30)
src/libCom/osi/os/posix/osdEvent.c (+124/-137)
src/libCom/osi/os/vxWorks/osdEvent.c (+8/-16)
src/libCom/osi/os/vxWorks/osdEvent.h (+5/-10)
To merge this branch: bzr merge lp:~anj/epics-base/epicsEvent-api
Reviewer Review Type Date Requested Status
EPICS Core Developers 2011-02-08 Pending
Review via email: mp+48992@code.launchpad.net

Description of the change

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.

To post a comment you must log in.
Andrew Johnson (anj) wrote :

If nobody has any comments on this branch it will be merged into 3.15 at the Codeathon next week.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'documentation/RELEASE_NOTES.html'
2--- documentation/RELEASE_NOTES.html 2010-11-28 03:06:40 +0000
3+++ documentation/RELEASE_NOTES.html 2011-02-08 21:39:58 +0000
4@@ -13,6 +13,30 @@
5 <h2 align="center">Changes between 3.14.x and 3.15.1</h2>
6 <!-- Insert new items immediately below here ... -->
7
8+<h3>
9+Reworked the epicsEvent C &amp; C++ APIs</h3>
10+
11+<ul>
12+ <li>Renamed the enum epicsEventWaitStatus to epicsEventStatus</li>
13+ <li>Defined epicsEventWaitStatus as a macro for epicsEventStatus</li>
14+ <li>Renamed epicsEventWaitOk to epicsEventOk</li>
15+ <li>Renamed epicsEventWaitError to epicsEventError</li>
16+ <li>Defined epicsEventWaitOK and epicsEventWaitError as macros</li>
17+ <li>Added epicsEventTrigger(id) which triggers an event and returns OK or an
18+ error status if the underlying OS primitives report an error</li>
19+ <li>Added epicsEventMustTrigger(id) which halts on error</li>
20+ <li>Defined epicsEventSignal(id) as a macro for epicsEventMustTrigger(id)</li>
21+ <li>Added a new C++ method epicsEvent::trigger() which throws an
22+ epicsEvent::invalidSemaphore in the event of an error</li>
23+ <li>epicsEvent::signal() makes an inline call to epicsEvent::trigger()</li>
24+ <li>epicsEventWait() and epicsEventWaitWithTimeout() now return an error
25+ status if the underlying OS primitives report an error</li>
26+ <li>All the epicsEventMust...() routines are now implemented in the common
27+ libCom/osi/epicsEvent.cpp source file, and call cantProceed() instead of
28+ mis-using assert()</li>
29+ <li>Implemented epicsEventShow() on Posix</li>
30+ <li>Win32: Removed all epicsShareAPI decorations</li>
31+</ul>
32
33 <h3>
34 Moved src/RTEMS/base directory</h3>
35
36=== modified file 'src/libCom/osi/epicsEvent.cpp'
37--- src/libCom/osi/epicsEvent.cpp 2004-09-30 19:15:45 +0000
38+++ src/libCom/osi/epicsEvent.cpp 2011-02-08 21:39:58 +0000
39@@ -1,10 +1,9 @@
40 /*************************************************************************\
41-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
42+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
43 * National Laboratory.
44 * Copyright (c) 2002 The Regents of the University of California, as
45 * Operator of Los Alamos National Laboratory.
46-* EPICS BASE Versions 3.13.7
47-* and higher are distributed subject to a Software License Agreement found
48+* EPICS BASE is distributed subject to a Software License Agreement found
49 * in file LICENSE that is included with this distribution.
50 \*************************************************************************/
51
52@@ -17,6 +16,7 @@
53 #define epicsExportSharedSymbols
54 #include "epicsEvent.h"
55 #include "epicsStdioRedirect.h"
56+#include "cantProceed.h"
57
58 // vxWorks 5.4 gcc fails during compile when I use std::exception
59 using namespace std;
60@@ -52,49 +52,81 @@
61 epicsEventDestroy ( this->id );
62 }
63
64-void epicsEvent::signal ()
65+void epicsEvent::trigger ()
66 {
67- epicsEventSignal ( this->id );
68+ epicsEventStatus status = epicsEventTrigger (this->id);
69+
70+ if (status != epicsEventOK) {
71+ throw invalidSemaphore ();
72+ }
73 }
74
75 void epicsEvent::wait ()
76 {
77- epicsEventWaitStatus status;
78- status = epicsEventWait (this->id);
79- if (status!=epicsEventWaitOK) {
80+ epicsEventStatus status = epicsEventWait (this->id);
81+
82+ if (status != epicsEventOK) {
83 throw invalidSemaphore ();
84 }
85 }
86
87 bool epicsEvent::wait (double timeOut)
88 {
89- epicsEventWaitStatus status;
90- status = epicsEventWaitWithTimeout (this->id, timeOut);
91- if (status==epicsEventWaitOK) {
92+ epicsEventStatus status = epicsEventWaitWithTimeout (this->id, timeOut);
93+
94+ if (status == epicsEventOK) {
95 return true;
96- } else if (status==epicsEventWaitTimeout) {
97+ } else if (status == epicsEventWaitTimeout) {
98 return false;
99- } else {
100- throw invalidSemaphore ();
101 }
102- return false;
103+ throw invalidSemaphore ();
104 }
105
106 bool epicsEvent::tryWait ()
107 {
108- epicsEventWaitStatus status;
109- status = epicsEventTryWait (this->id);
110- if (status==epicsEventWaitOK) {
111+ epicsEventStatus status = epicsEventTryWait (this->id);
112+
113+ if (status == epicsEventOK) {
114 return true;
115- } else if (status==epicsEventWaitTimeout) {
116+ } else if (status == epicsEventWaitTimeout) {
117 return false;
118- } else {
119- throw invalidSemaphore ();
120 }
121- return false;
122+ throw invalidSemaphore ();
123 }
124
125 void epicsEvent::show ( unsigned level ) const
126 {
127 epicsEventShow ( this->id, level );
128 }
129+
130+
131+// epicsEventMust... convenience routines for C code
132+
133+extern "C" {
134+
135+epicsShareFunc epicsEventId epicsEventMustCreate (
136+ epicsEventInitialState initialState)
137+{
138+ epicsEventId id = epicsEventCreate (initialState);
139+
140+ if (!id)
141+ cantProceed ("epicsEventMustCreate");
142+ return id;
143+}
144+
145+epicsShareFunc void epicsEventMustTrigger (epicsEventId id) {
146+ epicsEventStatus status = epicsEventTrigger (id);
147+
148+ if (status != epicsEventOK)
149+ cantProceed ("epicsEventMustTrigger");
150+}
151+
152+epicsShareFunc void epicsEventMustWait (epicsEventId id) {
153+ epicsEventStatus status = epicsEventWait (id);
154+
155+ if (status != epicsEventOK)
156+ cantProceed ("epicsEventMustWait");
157+}
158+
159+} // extern "C"
160+
161
162=== modified file 'src/libCom/osi/epicsEvent.h'
163--- src/libCom/osi/epicsEvent.h 2009-01-06 17:07:56 +0000
164+++ src/libCom/osi/epicsEvent.h 2011-02-08 21:39:58 +0000
165@@ -1,25 +1,33 @@
166 /*************************************************************************\
167-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
168+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
169 * National Laboratory.
170 * Copyright (c) 2002 The Regents of the University of California, as
171 * Operator of Los Alamos National Laboratory.
172-* EPICS BASE Versions 3.13.7
173-* and higher are distributed subject to a Software License Agreement found
174+* EPICS BASE is distributed subject to a Software License Agreement found
175 * in file LICENSE that is included with this distribution.
176 \*************************************************************************/
177 #ifndef epicsEventh
178 #define epicsEventh
179
180-#include "epicsAssert.h"
181 #include "shareLib.h"
182
183 typedef struct epicsEventOSD *epicsEventId;
184
185 typedef enum {
186- epicsEventWaitOK,epicsEventWaitTimeout,epicsEventWaitError
187-} epicsEventWaitStatus;
188-
189-typedef enum {epicsEventEmpty,epicsEventFull} epicsEventInitialState;
190+ epicsEventOK = 0,
191+ epicsEventWaitTimeout,
192+ epicsEventError
193+} epicsEventStatus;
194+
195+/* Backwards compatibility */
196+#define epicsEventWaitStatus epicsEventStatus
197+#define epicsEventWaitOK epicsEventOK
198+#define epicsEventWaitError epicsEventError
199+
200+typedef enum {
201+ epicsEventEmpty,
202+ epicsEventFull
203+} epicsEventInitialState;
204
205 #ifdef __cplusplus
206
207@@ -27,42 +35,40 @@
208 public:
209 epicsEvent ( epicsEventInitialState initial = epicsEventEmpty );
210 ~epicsEvent ();
211- void signal ();
212- void wait (); /* blocks until full */
213- bool wait ( double timeOut ); /* false if empty at time out */
214- bool tryWait (); /* false if empty */
215+ void trigger ();
216+ void signal () { this->trigger(); }
217+ void wait (); /* blocks until full */
218+ bool wait ( double timeOut ); /* false if still empty at time out */
219+ bool tryWait (); /* false if empty */
220 void show ( unsigned level ) const;
221
222- class invalidSemaphore; /* exception payload */
223+ class invalidSemaphore; /* exception payload */
224 private:
225 epicsEvent ( const epicsEvent & );
226 epicsEvent & operator = ( const epicsEvent & );
227 epicsEventId id;
228 };
229
230-#endif /*__cplusplus */
231-
232-#ifdef __cplusplus
233 extern "C" {
234 #endif /*__cplusplus */
235
236-epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate(
237- epicsEventInitialState initialState);
238-epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate (
239- epicsEventInitialState initialState);
240-epicsShareFunc void epicsShareAPI epicsEventDestroy(epicsEventId id);
241-epicsShareFunc void epicsShareAPI epicsEventSignal(epicsEventId id);
242-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait(
243- epicsEventId id);
244-#define epicsEventMustWait(ID) { \
245- epicsEventWaitStatus status = epicsEventWait(ID); \
246- assert(status == epicsEventWaitOK); \
247-}
248-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout(
249+epicsShareFunc epicsEventId epicsEventCreate(
250+ epicsEventInitialState initialState);
251+epicsShareFunc epicsEventId epicsEventMustCreate (
252+ epicsEventInitialState initialState);
253+epicsShareFunc void epicsEventDestroy(epicsEventId id);
254+epicsShareFunc epicsEventStatus epicsEventTrigger(
255+ epicsEventId id);
256+epicsShareFunc void epicsEventMustTrigger(epicsEventId id);
257+#define epicsEventSignal(ID) epicsEventMustTrigger(ID)
258+epicsShareFunc epicsEventStatus epicsEventWait(
259+ epicsEventId id);
260+epicsShareFunc void epicsEventMustWait(epicsEventId id);
261+epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(
262 epicsEventId id, double timeOut);
263-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait(
264+epicsShareFunc epicsEventStatus epicsEventTryWait(
265 epicsEventId id);
266-epicsShareFunc void epicsShareAPI epicsEventShow(
267+epicsShareFunc void epicsEventShow(
268 epicsEventId id, unsigned int level);
269
270 #ifdef __cplusplus
271
272=== modified file 'src/libCom/osi/os/RTEMS/osdEvent.c'
273--- src/libCom/osi/os/RTEMS/osdEvent.c 2010-10-05 19:27:37 +0000
274+++ src/libCom/osi/os/RTEMS/osdEvent.c 2011-02-08 21:39:58 +0000
275@@ -1,7 +1,8 @@
276 /*************************************************************************\
277 * Copyright (c) 2002 The University of Saskatchewan
278-* EPICS BASE Versions 3.13.7
279-* and higher are distributed subject to a Software License Agreement found
280+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
281+* National Laboratory.
282+* EPICS BASE is distributed subject to a Software License Agreement found
283 * in file LICENSE that is included with this distribution.
284 \*************************************************************************/
285 /*
286@@ -18,7 +19,6 @@
287 */
288 #define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
289
290-#include <assert.h>
291 #include <stdio.h>
292 #include <rtems.h>
293 #include <rtems/error.h>
294@@ -84,13 +84,6 @@
295 return (epicsEventId)sid;
296 }
297
298-epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
299-{
300- epicsEventId id = epicsEventCreate (initialState);
301- assert (id);
302- return id;
303-}
304-
305 void
306 epicsEventDestroy(epicsEventId id)
307 {
308@@ -102,18 +95,20 @@
309 errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc));
310 }
311
312-void
313-epicsEventSignal(epicsEventId id)
314+epicsEventStatus
315+epicsEventTrigger(epicsEventId id)
316 {
317 rtems_id sid = (rtems_id)id;
318 rtems_status_code sc;
319
320 sc = rtems_semaphore_release (sid);
321- if (sc != RTEMS_SUCCESSFUL)
322- errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc));
323+ if (sc == RTEMS_SUCCESSFUL)
324+ return epicsEventOK;
325+ errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc));
326+ return epicsEventError;
327 }
328
329-epicsEventWaitStatus
330+epicsEventStatus
331 epicsEventWait(epicsEventId id)
332 {
333 rtems_id sid = (rtems_id)id;
334@@ -122,11 +117,11 @@
335 SEMSTAT(0)
336 sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
337 if (sc != RTEMS_SUCCESSFUL)
338- return epicsEventWaitError;
339- return epicsEventWaitOK;
340+ return epicsEventError;
341+ return epicsEventOK;
342 }
343
344-epicsEventWaitStatus
345+epicsEventStatus
346 epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
347 {
348 rtems_id sid = (rtems_id)id;
349@@ -142,14 +137,14 @@
350 delay++;
351 sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay);
352 if (sc == RTEMS_SUCCESSFUL)
353- return epicsEventWaitOK;
354+ return epicsEventOK;
355 else if (sc == RTEMS_TIMEOUT)
356 return epicsEventWaitTimeout;
357 else
358- return epicsEventWaitError;
359+ return epicsEventError;
360 }
361
362-epicsEventWaitStatus
363+epicsEventStatus
364 epicsEventTryWait(epicsEventId id)
365 {
366 rtems_id sid = (rtems_id)id;
367@@ -158,11 +153,11 @@
368 SEMSTAT(2)
369 sc = rtems_semaphore_obtain (sid, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT);
370 if (sc == RTEMS_SUCCESSFUL)
371- return epicsEventWaitOK;
372+ return epicsEventOK;
373 else if (sc == RTEMS_UNSATISFIED)
374 return epicsEventWaitTimeout;
375 else
376- return epicsEventWaitError;
377+ return epicsEventError;
378 }
379
380 void
381
382=== modified file 'src/libCom/osi/os/WIN32/osdEvent.c'
383--- src/libCom/osi/os/WIN32/osdEvent.c 2010-10-05 19:27:37 +0000
384+++ src/libCom/osi/os/WIN32/osdEvent.c 2011-02-08 21:39:58 +0000
385@@ -1,10 +1,9 @@
386 /*************************************************************************\
387-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
388+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
389 * National Laboratory.
390 * Copyright (c) 2002 The Regents of the University of California, as
391 * Operator of Los Alamos National Laboratory.
392-* EPICS BASE Versions 3.13.7
393-* and higher are distributed subject to a Software License Agreement found
394+* EPICS BASE is distributed subject to a Software License Agreement found
395 * in file LICENSE that is included with this distribution.
396 \*************************************************************************/
397 /* osdEvent.c */
398@@ -27,7 +26,6 @@
399 #define epicsExportSharedSymbols
400 #include "shareLib.h"
401 #include "epicsEvent.h"
402-#include "epicsAssert.h"
403
404 typedef struct epicsEventOSD {
405 HANDLE handle;
406@@ -36,7 +34,7 @@
407 /*
408 * epicsEventCreate ()
409 */
410-epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate (
411+epicsShareFunc epicsEventId epicsEventCreate (
412 epicsEventInitialState initialState )
413 {
414 epicsEventOSD *pSem;
415@@ -54,54 +52,43 @@
416 }
417
418 /*
419- * epicsEventMustCreate ()
420- */
421-epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate (
422- epicsEventInitialState initialState )
423-{
424- epicsEventId id = epicsEventCreate ( initialState );
425- assert ( id );
426- return id;
427-}
428-
429-/*
430 * epicsEventDestroy ()
431 */
432-epicsShareFunc void epicsShareAPI epicsEventDestroy ( epicsEventId pSem )
433+epicsShareFunc void epicsEventDestroy ( epicsEventId pSem )
434 {
435 CloseHandle ( pSem->handle );
436 free ( pSem );
437 }
438
439 /*
440- * epicsEventSignal ()
441+ * epicsEventTrigger ()
442 */
443-epicsShareFunc void epicsShareAPI epicsEventSignal ( epicsEventId pSem )
444+epicsShareFunc epicsEventStatus epicsEventTrigger ( epicsEventId pSem )
445 {
446 BOOL status;
447 status = SetEvent ( pSem->handle );
448- assert ( status );
449+ return status ? epicsEventOK : epicsEventError;
450 }
451
452 /*
453 * epicsEventWait ()
454 */
455-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait ( epicsEventId pSem )
456+epicsShareFunc epicsEventStatus epicsEventWait ( epicsEventId pSem )
457 {
458 DWORD status;
459 status = WaitForSingleObject (pSem->handle, INFINITE);
460 if ( status == WAIT_OBJECT_0 ) {
461- return epicsEventWaitOK;
462+ return epicsEventOK;
463 }
464 else {
465- return epicsEventWaitError;
466+ return epicsEventError;
467 }
468 }
469
470 /*
471 * epicsEventWaitWithTimeout ()
472 */
473-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout (
474+epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout (
475 epicsEventId pSem, double timeOut )
476 {
477 static const unsigned mSecPerSec = 1000;
478@@ -122,38 +109,38 @@
479 }
480 status = WaitForSingleObject ( pSem->handle, tmo );
481 if ( status == WAIT_OBJECT_0 ) {
482- return epicsEventWaitOK;
483+ return epicsEventOK;
484 }
485 else if ( status == WAIT_TIMEOUT ) {
486 return epicsEventWaitTimeout;
487 }
488 else {
489- return epicsEventWaitError;
490+ return epicsEventError;
491 }
492 }
493
494 /*
495 * epicsEventTryWait ()
496 */
497-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait ( epicsEventId pSem )
498+epicsShareFunc epicsEventStatus epicsEventTryWait ( epicsEventId pSem )
499 {
500 DWORD status;
501
502 status = WaitForSingleObject ( pSem->handle, 0 );
503 if ( status == WAIT_OBJECT_0 ) {
504- return epicsEventWaitOK;
505+ return epicsEventOK;
506 }
507 else if ( status == WAIT_TIMEOUT ) {
508 return epicsEventWaitTimeout;
509 }
510 else {
511- return epicsEventWaitError;
512+ return epicsEventError;
513 }
514 }
515
516 /*
517 * epicsEventShow ()
518 */
519-epicsShareFunc void epicsShareAPI epicsEventShow ( epicsEventId id, unsigned level )
520+epicsShareFunc void epicsEventShow ( epicsEventId id, unsigned level )
521 {
522 }
523
524=== modified file 'src/libCom/osi/os/posix/osdEvent.c'
525--- src/libCom/osi/os/posix/osdEvent.c 2009-04-23 18:49:40 +0000
526+++ src/libCom/osi/os/posix/osdEvent.c 2011-02-08 21:39:58 +0000
527@@ -1,5 +1,5 @@
528 /*************************************************************************\
529-* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
530+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
531 * National Laboratory.
532 * Copyright (c) 2002 The Regents of the University of California, as
533 * Operator of Los Alamos National Laboratory.
534@@ -21,155 +21,142 @@
535
536 #define epicsExportSharedSymbols
537 #include "epicsEvent.h"
538-#include "cantProceed.h"
539 #include "epicsTime.h"
540 #include "errlog.h"
541-#include "epicsAssert.h"
542
543 /* Until these can be demonstrated to work leave them undefined*/
544 #undef _POSIX_THREAD_PROCESS_SHARED
545 #undef _POSIX_THREAD_PRIO_INHERIT
546
547-typedef struct epicsEventOSD {
548- pthread_mutex_t mutex;
549- pthread_cond_t cond;
550- int isFull;
551-}epicsEventOSD;
552-
553
554-#define checkStatus(status,message) \
555-if((status)) { \
556- errlogPrintf("epicsEvent %s failed: error %s\n",(message),strerror((status)));}
557-
558-#define checkStatusQuit(status,message,method) \
559-if(status) { \
560- errlogPrintf("epicsEvent %s failed: error %s\n",(message),strerror((status))); \
561- cantProceed((method)); \
562-}
563-
564-static int mutexLock(pthread_mutex_t *id)
565-{
566- int status;
567-
568- while(1) {
569- status = pthread_mutex_lock(id);
570- if(status!=EINTR) return status;
571- errlogPrintf("pthread_mutex_lock returned EINTR. Violates SUSv3\n");
572- }
573-}
574-
575-static int condTimedwait(pthread_cond_t *condId, pthread_mutex_t *mutexId,
576- struct timespec *time)
577-{
578- int status;
579- while(1) {
580- status = pthread_cond_timedwait(condId,mutexId,time);
581- if(status!=EINTR) return status;
582- errlogPrintf("pthread_cond_timedwait returned EINTR. Violates SUSv3\n");
583- }
584-}
585-
586-static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId)
587-{
588- int status;
589- while(1) {
590- status = pthread_cond_wait(condId,mutexId);
591- if(status!=EINTR) return status;
592- errlogPrintf("pthread_cond_wait returned EINTR. Violates SUSv3\n");
593- }
594-}
595-
596
597-epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate(epicsEventInitialState initialState)
598-{
599- epicsEventOSD *pevent;
600- int status;
601-
602- pevent = callocMustSucceed(1,sizeof(*pevent),"epicsEventCreate");
603- status = pthread_mutex_init(&pevent->mutex,0);
604- checkStatusQuit(status,"pthread_mutex_init","epicsEventCreate");
605- status = pthread_cond_init(&pevent->cond,0);
606- checkStatusQuit(status,"pthread_cond_init","epicsEventCreate");
607- if(initialState==epicsEventFull) pevent->isFull = 1;
608- return((epicsEventId)pevent);
609-}
610-
611-epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate(epicsEventInitialState initialState)
612-{
613- epicsEventId id = epicsEventCreate (initialState);
614- assert (id);
615- return id;
616-}
617-
618-epicsShareFunc void epicsShareAPI epicsEventDestroy(epicsEventId pevent)
619-{
620- int status;
621-
622- status = pthread_mutex_destroy(&pevent->mutex);
623- checkStatus(status,"pthread_mutex_destroy");
624+struct epicsEventOSD {
625+ pthread_mutex_t mutex;
626+ pthread_cond_t cond;
627+ int isFull;
628+};
629+
630+#define printStatus(status, routine, func) \
631+ errlogPrintf("%s: %s failed: %s\n", (func), (routine), strerror(status))
632+
633+#define checkStatus(status, routine, func) \
634+ if (status) { \
635+ printStatus(status, routine, func); \
636+ }
637+
638+#define checkStatusReturn(status, routine, func) \
639+ if (status) { \
640+ printStatus(status, routine, func); \
641+ return epicsEventError; \
642+ }
643+
644+
645+epicsShareFunc epicsEventId epicsEventCreate(epicsEventInitialState init)
646+{
647+ epicsEventId pevent = malloc(sizeof(*pevent));
648+
649+ if (pevent) {
650+ int status = pthread_mutex_init(&pevent->mutex, 0);
651+
652+ pevent->isFull = (init == epicsEventFull);
653+ if (status) {
654+ printStatus(status, "pthread_mutex_init", "epicsEventCreate");
655+ } else {
656+ status = pthread_cond_init(&pevent->cond, 0);
657+ if (!status)
658+ return pevent;
659+ printStatus(status, "pthread_cond_init", "epicsEventCreate");
660+ status = pthread_mutex_destroy(&pevent->mutex);
661+ checkStatus(status, "pthread_mutex_destroy", "epicsEventCreate");
662+ }
663+ free(pevent);
664+ }
665+ return NULL;
666+}
667+
668+epicsShareFunc void epicsEventDestroy(epicsEventId pevent)
669+{
670+ int status = pthread_mutex_destroy(&pevent->mutex);
671+
672+ checkStatus(status, "pthread_mutex_destroy", "epicsEventDestroy");
673 status = pthread_cond_destroy(&pevent->cond);
674- checkStatus(status,"pthread_cond_destroy");
675+ checkStatus(status, "pthread_cond_destroy", "epicsEventDestroy");
676 free(pevent);
677 }
678
679-epicsShareFunc void epicsShareAPI epicsEventSignal(epicsEventId pevent)
680+epicsShareFunc epicsEventStatus epicsEventTrigger(epicsEventId pevent)
681 {
682- int status;
683+ int status = pthread_mutex_lock(&pevent->mutex);
684
685- status = mutexLock(&pevent->mutex);
686- checkStatusQuit(status,"pthread_mutex_lock","epicsEventSignal");
687- if(!pevent->isFull) {
688+ checkStatusReturn(status, "pthread_mutex_lock", "epicsEventTrigger");
689+ if (!pevent->isFull) {
690 pevent->isFull = 1;
691 status = pthread_cond_signal(&pevent->cond);
692- checkStatus(status,"pthread_cond_signal");
693- }
694- status = pthread_mutex_unlock(&pevent->mutex);
695- checkStatusQuit(status,"pthread_mutex_unlock","epicsEventSignal");
696-}
697-
698
699-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait(epicsEventId pevent)
700-{
701- int status;
702-
703- if(!pevent) return(epicsEventWaitError);
704- status = mutexLock(&pevent->mutex);
705- checkStatusQuit(status,"pthread_mutex_lock","epicsEventWait");
706- /*no need for while since caller must be prepared for no work*/
707- if(!pevent->isFull) {
708- status = condWait(&pevent->cond,&pevent->mutex);
709- checkStatusQuit(status,"pthread_cond_wait","epicsEventWait");
710- }
711- pevent->isFull = 0;
712- status = pthread_mutex_unlock(&pevent->mutex);
713- checkStatusQuit(status,"pthread_mutex_unlock","epicsEventWait");
714- return(epicsEventWaitOK);
715-}
716-
717-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout(epicsEventId pevent, double timeout)
718-{
719- struct timespec wakeTime;
720- int status = 0;
721- int unlockStatus;
722-
723- status = mutexLock(&pevent->mutex);
724- checkStatusQuit(status,"pthread_mutex_lock","epicsEventWaitWithTimeout");
725- if(!pevent->isFull) {
726- convertDoubleToWakeTime(timeout,&wakeTime);
727- status = condTimedwait(
728- &pevent->cond,&pevent->mutex,&wakeTime);
729- }
730- if(status==0) pevent->isFull = 0;
731- unlockStatus = pthread_mutex_unlock(&pevent->mutex);
732- checkStatusQuit(unlockStatus,"pthread_mutex_unlock","epicsEventWaitWithTimeout");
733- if(status==0) return(epicsEventWaitOK);
734- if(status==ETIMEDOUT) return(epicsEventWaitTimeout);
735- checkStatus(status,"pthread_cond_timedwait");
736- return(epicsEventWaitError);
737-}
738-
739-epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait(epicsEventId id)
740-{
741- return(epicsEventWaitWithTimeout(id,0.0));
742-}
743-
744-epicsShareFunc void epicsShareAPI epicsEventShow(epicsEventId id,unsigned int level)
745-{
746+ checkStatus(status, "pthread_cond_signal", "epicsEventTrigger");
747+ }
748+ status = pthread_mutex_unlock(&pevent->mutex);
749+ checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventTrigger");
750+ return epicsEventOK;
751+}
752+
753+epicsShareFunc epicsEventStatus epicsEventWait(epicsEventId pevent)
754+{
755+ epicsEventStatus result = epicsEventOK;
756+ int status = pthread_mutex_lock(&pevent->mutex);
757+
758+ checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWait");
759+ while (!pevent->isFull) {
760+ status = pthread_cond_wait(&pevent->cond, &pevent->mutex);
761+ if (status) {
762+ printStatus(status, "pthread_cond_wait", "epicsEventWait");
763+ result = epicsEventError;
764+ goto release;
765+ }
766+ }
767+ pevent->isFull = 0;
768+ result = epicsEventOK;
769+release:
770+ status = pthread_mutex_unlock(&pevent->mutex);
771+ checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWait");
772+ return result;
773+}
774+
775+epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(epicsEventId pevent,
776+ double timeout)
777+{
778+ epicsEventStatus result = epicsEventOK;
779+ int status = pthread_mutex_lock(&pevent->mutex);
780+
781+ checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWaitWithTimeout");
782+ if (!pevent->isFull) {
783+ struct timespec wakeTime;
784+
785+ convertDoubleToWakeTime(timeout, &wakeTime);
786+ while (!status && !pevent->isFull) {
787+ status = pthread_cond_timedwait(&pevent->cond, &pevent->mutex,
788+ &wakeTime);
789+ }
790+ if (status) {
791+ result = (status == ETIMEDOUT) ?
792+ epicsEventWaitTimeout : epicsEventError;
793+ goto release;
794+ }
795+ }
796+ pevent->isFull = 0;
797+release:
798+ status = pthread_mutex_unlock(&pevent->mutex);
799+ checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWaitWithTimeout");
800+ return result;
801+}
802+
803+epicsShareFunc epicsEventStatus epicsEventTryWait(epicsEventId id)
804+{
805+ return epicsEventWaitWithTimeout(id, 0.0);
806+}
807+
808+epicsShareFunc void epicsEventShow(epicsEventId pevent, unsigned int level)
809+{
810+ printf("epicsEvent %p: %s\n", pevent,
811+ pevent->isFull ? "full" : "empty");
812+ if (level > 0)
813+ printf(" pthread_mutex = %p, pthread_cond = %p\n",
814+ &pevent->mutex, &pevent->cond);
815 }
816
817=== modified file 'src/libCom/osi/os/vxWorks/osdEvent.c'
818--- src/libCom/osi/os/vxWorks/osdEvent.c 2008-09-24 19:24:59 +0000
819+++ src/libCom/osi/os/vxWorks/osdEvent.c 2011-02-08 21:39:58 +0000
820@@ -1,10 +1,9 @@
821 /*************************************************************************\
822-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
823+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
824 * National Laboratory.
825 * Copyright (c) 2002 The Regents of the University of California, as
826 * Operator of Los Alamos National Laboratory.
827-* EPICS BASE Versions 3.13.7
828-* and higher are distributed subject to a Software License Agreement found
829+* EPICS BASE is distributed subject to a Software License Agreement found
830 * in file LICENSE that is included with this distribution.
831 \*************************************************************************/
832 /* os/vxWorks/osdEvent.c */
833@@ -29,19 +28,12 @@
834 (initialState == epicsEventEmpty) ? SEM_EMPTY : SEM_FULL);
835 }
836
837-epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
838-{
839- epicsEventId id = epicsEventCreate(initialState);
840- assert(id);
841- return id;
842-}
843-
844 void epicsEventDestroy(epicsEventId id)
845 {
846 semDelete((SEM_ID)id);
847 }
848
849-epicsEventWaitStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
850+epicsEventStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
851 {
852 int rate = sysClkRateGet();
853 int status;
854@@ -58,22 +50,22 @@
855 }
856 status = semTake((SEM_ID)id, ticks);
857 if (status == OK)
858- return epicsEventWaitOK;
859+ return epicsEventOK;
860 if (errno == S_objLib_OBJ_TIMEOUT ||
861 (errno == S_objLib_OBJ_UNAVAILABLE && ticks == 0))
862 return epicsEventWaitTimeout;
863- return epicsEventWaitError;
864+ return epicsEventError;
865 }
866
867-epicsEventWaitStatus epicsEventTryWait(epicsEventId id)
868+epicsEventStatus epicsEventTryWait(epicsEventId id)
869 {
870 int status = semTake((SEM_ID)id, NO_WAIT);
871
872 if (status == OK)
873- return epicsEventWaitOK;
874+ return epicsEventOK;
875 if (errno == S_objLib_OBJ_UNAVAILABLE)
876 return epicsEventWaitTimeout;
877- return epicsEventWaitError;
878+ return epicsEventError;
879 }
880
881 void epicsEventShow(epicsEventId id, unsigned int level)
882
883=== modified file 'src/libCom/osi/os/vxWorks/osdEvent.h'
884--- src/libCom/osi/os/vxWorks/osdEvent.h 2002-07-12 21:35:43 +0000
885+++ src/libCom/osi/os/vxWorks/osdEvent.h 2011-02-08 21:39:58 +0000
886@@ -1,10 +1,9 @@
887 /*************************************************************************\
888-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
889+* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
890 * National Laboratory.
891 * Copyright (c) 2002 The Regents of the University of California, as
892 * Operator of Los Alamos National Laboratory.
893-* EPICS BASE Versions 3.13.7
894-* and higher are distributed subject to a Software License Agreement found
895+* EPICS BASE is distributed subject to a Software License Agreement found
896 * in file LICENSE that is included with this distribution.
897 \*************************************************************************/
898 /* os/vxWorks/osdEvent.h */
899@@ -14,12 +13,8 @@
900 #include <vxWorks.h>
901 #include <semLib.h>
902
903-/* If the macro is replaced by inline it is necessary to say
904- static __inline__
905- but then a warning message appears everywhere osdEvent.h is included
906-*/
907-
908-#define epicsEventSignal(ID) semGive((SEM_ID)(ID))
909+#define epicsEventTrigger(ID) \
910+ (semGive((SEM_ID)(ID)) == OK ? epicsEventOK : epicsEventError)
911
912 #define epicsEventWait(ID) \
913-(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? epicsEventWaitOK : epicsEventWaitError)
914+ (semTake((SEM_ID)(ID), WAIT_FOREVER) == OK ? epicsEventOK : epicsEventError)

Subscribers

People subscribed via source and target branches