Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions libs/libc/stdlib/lib_atexit.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ int atexit_register(int type, CODE void (*func)(void), FAR void *arg,
void atexit_call_exitfuncs(int status, bool quick)
{
FAR struct atexit_list_s *aehead;
FAR struct task_info_s *info = task_get_info();
CODE void (*func)(void);
FAR void *arg;
int idx;
Expand All @@ -119,17 +120,32 @@ void atexit_call_exitfuncs(int status, bool quick)

aehead = get_exitfuncs();

for (idx = aehead->nfuncs - 1; idx >= 0; idx--)
while (aehead->nfuncs > 0)
{
/* Remove the function to prevent recursive call to it */
/* Claim the newest entry under the lock. A handler may register
* further functions during exit processing; those land in the slot
* just freed here and are executed on the next iteration, i.e.
* before the older remaining ones, as documented in exit(3).
*/

type = aehead->funcs[idx].type;
if (nxmutex_lock(&info->ta_lock) < 0)
{
break;
}

idx = aehead->nfuncs - 1;

type = aehead->funcs[idx].type;
func = aehead->funcs[idx].func;
arg = aehead->funcs[idx].arg;

/* Remove the function to prevent recursive call to it */

aehead->funcs[idx].func = NULL;
aehead->funcs[idx].arg = NULL;
aehead->nfuncs--;

nxmutex_unlock(&info->ta_lock);

if (!func)
{
Expand Down
Loading