From 34a4b00f91bcb11e9a81e69f2efa20b3236ec598 Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Fri, 27 Aug 2004 16:00:33 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'B3.14'. --- src/libCom/misc/epicsExit.c | 94 +++++++++++++++++++++++++++++++++++++ src/libCom/misc/epicsExit.h | 28 +++++++++++ 2 files changed, 122 insertions(+) create mode 100644 src/libCom/misc/epicsExit.c create mode 100644 src/libCom/misc/epicsExit.h diff --git a/src/libCom/misc/epicsExit.c b/src/libCom/misc/epicsExit.c new file mode 100644 index 000000000..63bfaeb9a --- /dev/null +++ b/src/libCom/misc/epicsExit.c @@ -0,0 +1,94 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, 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 +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/*epicsExit.c*/ +/* Author: Marty Kraimer */ +/* Date: 23AUG2004 */ + +#include +#include + +#include "ellLib.h" +#include "epicsThread.h" +#include "epicsMutex.h" +#include "cantProceed.h" +#define epicsExportSharedSymbols +#include "epicsExit.h" + +typedef void (*epicsExitFunc)(void *arg); + +typedef struct exitNode { + ELLNODE node; + epicsExitFunc func; + void *arg; +}exitNode; + +typedef struct exitPvt { + ELLLIST list; + epicsMutexId lock; + int epicsExitNcalls; +}exitPvt; +static exitPvt exitPvtInstance; +static exitPvt *pexitPvt = &exitPvtInstance; +static epicsThreadOnceId createOnce = EPICS_THREAD_ONCE_INIT; + +static void atExit(void) {epicsExit(0);} + +static void createExitPvt(void) +{ + pexitPvt->lock = epicsMutexMustCreate(); + ellInit(&pexitPvt->list); + atexit(atExit); +} + +epicsShareFunc void epicsShareAPI epicsExitCallAtExits(void) +{ + exitNode *pexitNode; + + epicsThreadOnce(&createOnce,(EPICSTHREADFUNC)createExitPvt,0); + epicsMutexMustLock(pexitPvt->lock); + if(pexitPvt->epicsExitNcalls++>0) { + epicsMutexUnlock(pexitPvt->lock); + return; + } + epicsMutexUnlock(pexitPvt->lock); + /* remove exitNodes in reverse order that they were added*/ + while((pexitNode = (exitNode *)ellLast(&pexitPvt->list))) { + ellDelete(&pexitPvt->list,&pexitNode->node); + pexitNode->func(pexitNode->arg); + free(pexitNode); + } + /* epicsMutexDestroy is not called because of possible race conditions*/ + /*epicsMutexDestroy(pexitPvt->lock);*/ +} + +epicsShareFunc void epicsShareAPI epicsExit(int status) +{ + epicsExitCallAtExits(); + exit(status); +} + +epicsShareFunc int epicsShareAPI epicsAtExit(epicsExitFunc func, void *arg) +{ + exitNode *pexitNode; + + epicsThreadOnce(&createOnce,(EPICSTHREADFUNC)createExitPvt,0); + pexitNode = callocMustSucceed(1,sizeof(exitNode),"epicsAtExit"); + pexitNode->func = func; + pexitNode->arg = arg; + epicsMutexMustLock(pexitPvt->lock); + if(pexitPvt->epicsExitNcalls>0) { + epicsMutexUnlock(pexitPvt->lock); + free(pexitNode); + return -1; + } + ellAdd(&pexitPvt->list,&pexitNode->node); + epicsMutexUnlock(pexitPvt->lock); + return 0; +} diff --git a/src/libCom/misc/epicsExit.h b/src/libCom/misc/epicsExit.h new file mode 100644 index 000000000..b0ea48361 --- /dev/null +++ b/src/libCom/misc/epicsExit.h @@ -0,0 +1,28 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, 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 +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/*epicsExit.h*/ +#ifndef epicsExith +#define epicsExith +#include + +#ifdef __cplusplus +extern "C" { +#endif + +epicsShareFunc void epicsShareAPI epicsExit(int status); +epicsShareFunc void epicsShareAPI epicsExitCallAtExits(void); +epicsShareFunc int epicsShareAPI epicsAtExit( + void (*epicsExitFunc)(void *arg),void *arg); + +#ifdef __cplusplus +} +#endif + +#endif /*epicsExith*/