From 012139638d6a212ba347c11cbedaedaf8875ab6f Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 11 Jun 2024 12:23:52 -0700 Subject: [PATCH] posix: epicsThreadCreateOpt() avoid leak of joinable on EPERM On a system where RT priorities have been probed. When creating a joinable thread, but still fails with EPERM, the first epicsThreadOSD was leaked. --- modules/libcom/src/osi/os/posix/osdThread.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/libcom/src/osi/os/posix/osdThread.c b/modules/libcom/src/osi/os/posix/osdThread.c index 6142e73c5..17dfacbc8 100644 --- a/modules/libcom/src/osi/os/posix/osdThread.c +++ b/modules/libcom/src/osi/os/posix/osdThread.c @@ -615,6 +615,10 @@ epicsThreadCreateOpt(const char * name, start_routine, pthreadInfo); if (status==EPERM) { /* Try again without SCHED_FIFO*/ + if (pthreadInfo->joinable) { + int cnt = epicsAtomicDecrIntT(&pthreadInfo->refcnt); + assert(cnt==1); + } free_threadInfo(pthreadInfo); pthreadInfo = init_threadInfo(name, opts->priority, stackSize, @@ -630,12 +634,15 @@ epicsThreadCreateOpt(const char * name, if (status) { if (pthreadInfo->joinable) { /* release extra ref which would have been for epicsThreadMustJoin() */ - epicsAtomicDecrIntT(&pthreadInfo->refcnt); + int cnt = epicsAtomicDecrIntT(&pthreadInfo->refcnt); + assert(cnt==1); } - free_threadInfo(pthreadInfo); return 0; } + /* New thread starting and is now responsible for one free_threadInfo(). + * If joinable, then caller responsible for arranging one epicsThreadMustJoin() + */ status = pthread_sigmask(SIG_SETMASK, &oldSig, NULL); checkStatusOnce(status, "pthread_sigmask");