From 1c95101ae1b1e4a65dfd7d1e6327a955e1f34cda Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 21 Aug 2009 17:32:13 +0000 Subject: [PATCH] Fixed Till's report of non-thread-safe lazy-init. --- src/libCom/osi/epicsInterrupt.h | 15 ++++---- src/libCom/osi/os/default/osdInterrupt.c | 46 +++++++++++++----------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/libCom/osi/epicsInterrupt.h b/src/libCom/osi/epicsInterrupt.h index b5cea5031..93b443810 100644 --- a/src/libCom/osi/epicsInterrupt.h +++ b/src/libCom/osi/epicsInterrupt.h @@ -1,27 +1,24 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2009 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 epicsInterrupth #define epicsInterrupth -/*THIS MAY BE A BIG PROBLEM */ - #ifdef __cplusplus extern "C" { #endif #include "shareLib.h" -epicsShareFunc int epicsShareAPI epicsInterruptLock(void); -epicsShareFunc void epicsShareAPI epicsInterruptUnlock(int key); -epicsShareFunc int epicsShareAPI epicsInterruptIsInterruptContext(void); -epicsShareFunc void epicsShareAPI epicsInterruptContextMessage(const char *message); +epicsShareFunc int epicsInterruptLock(void); +epicsShareFunc void epicsInterruptUnlock(int key); +epicsShareFunc int epicsInterruptIsInterruptContext(void); +epicsShareFunc void epicsInterruptContextMessage(const char *message); #ifdef __cplusplus } diff --git a/src/libCom/osi/os/default/osdInterrupt.c b/src/libCom/osi/os/default/osdInterrupt.c index 59407d962..91c5c5681 100644 --- a/src/libCom/osi/os/default/osdInterrupt.c +++ b/src/libCom/osi/os/default/osdInterrupt.c @@ -1,18 +1,15 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2009 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. \*************************************************************************/ /* osi/default/osdInterrupt.c */ /* Author: Marty Kraimer Date: 15JUL99 */ -/* This is a version that does not allow osi calls at interrupt level */ - #include #include #include @@ -21,34 +18,41 @@ #define epicsExportSharedSymbols #include "epicsMutex.h" +#include "epicsThread.h" #include "cantProceed.h" #include "errlog.h" #include "epicsInterrupt.h" -static epicsMutexId globalLock=0; -static int firstTime = 1; -epicsShareFunc int epicsShareAPI epicsInterruptLock() +static epicsMutexId globalLock = NULL; +static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; + +static void initOnce(void *junk) { - if(firstTime) { - globalLock = epicsMutexMustCreate(); - firstTime = 0; - } - epicsMutexMustLock(globalLock); - return(0); + globalLock = epicsMutexMustCreate(); } -epicsShareFunc void epicsShareAPI epicsInterruptUnlock(int key) +epicsShareFunc int epicsInterruptLock() { - if(firstTime) cantProceed( - "epicsInterruptUnlock called before epicsInterruptLock\n"); + epicsThreadOnce(&onceId, initOnce, NULL); + epicsMutexMustLock(globalLock); + return 0; +} + +epicsShareFunc void epicsInterruptUnlock(int key) +{ + if (!globalLock) + cantProceed("epicsInterruptUnlock called before epicsInterruptLock\n"); epicsMutexUnlock(globalLock); } -epicsShareFunc int epicsShareAPI epicsInterruptIsInterruptContext() { return(0);} - -epicsShareFunc void epicsShareAPI epicsInterruptContextMessage(const char *message) +epicsShareFunc int epicsInterruptIsInterruptContext() { - errlogPrintf("%s",message); + return 0; +} + +epicsShareFunc void epicsInterruptContextMessage(const char *message) +{ + errlogPrintf("%s", message); }