diff --git a/modules/libcom/src/iocsh/initHooks.c b/modules/libcom/src/iocsh/initHooks.c index 90b1de2c5..2def0e2d4 100644 --- a/modules/libcom/src/iocsh/initHooks.c +++ b/modules/libcom/src/iocsh/initHooks.c @@ -21,6 +21,7 @@ #include "ellLib.h" #include "epicsMutex.h" #include "epicsThread.h" +#include "cantProceed.h" #include "initHooks.h" @@ -52,19 +53,26 @@ static void initHookInit(void) int initHookRegister(initHookFunction func) { initHookLink *newHook; + ELLNODE *cur; if (!func) return 0; initHookInit(); - newHook = (initHookLink *)malloc(sizeof(initHookLink)); - if (!newHook) { - printf("Cannot malloc a new initHookLink\n"); - return -1; + epicsMutexMustLock(listLock); + + for(cur = ellFirst(&functionList); cur; cur = ellNext(cur)) { + const initHookLink *fn = CONTAINER(cur, initHookLink, node); + if(fn->func==func) { + /* silently ignore duplicate */ + epicsMutexUnlock(listLock); + return 0; + } } + + newHook = (initHookLink *)mallocMustSucceed(sizeof(initHookLink), "initHookRegister"); newHook->func = func; - epicsMutexMustLock(listLock); ellAdd(&functionList, &newHook->node); epicsMutexUnlock(listLock); return 0; diff --git a/modules/libcom/src/iocsh/initHooks.h b/modules/libcom/src/iocsh/initHooks.h index 573817f6b..57a1cc1fc 100644 --- a/modules/libcom/src/iocsh/initHooks.h +++ b/modules/libcom/src/iocsh/initHooks.h @@ -163,7 +163,11 @@ typedef void (*initHookFunction)(initHookState state); * * Registers \p func for initHook notifications * \param func Pointer to application's notification function. - * \return 0 if Ok, -1 on error (memory allocation failure). + * \return Always zero. (before UNRELEASED could return -1 on allocation failure) + * + * \since UNRELEASED initHookRegister is idempotent. + * Previously, repeated registrations would result + * in duplicate calls to the hook function. */ LIBCOM_API int initHookRegister(initHookFunction func);