3c99391d93
In some cases the license-identification header was missing, so I added that as well. Replaced the remaining headers that specifically identified "Versions 3.13.7 and higher". Makefiles and the build system were deliberately excluded.
109 lines
2.9 KiB
C
109 lines
2.9 KiB
C
/*************************************************************************\
|
|
* Copyright (c) 2006 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.
|
|
* SPDX-License-Identifier: EPICS
|
|
* EPICS BASE is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
/* epicsExitTest.cpp */
|
|
|
|
/* Author: Marty Kraimer Date: 09JUL2004*/
|
|
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
|
|
#include "epicsThread.h"
|
|
#include "epicsAssert.h"
|
|
#include "epicsEvent.h"
|
|
#include "epicsExit.h"
|
|
#include "epicsUnitTest.h"
|
|
#include "testMain.h"
|
|
|
|
|
|
typedef struct info {
|
|
char name[64];
|
|
epicsEventId terminate;
|
|
epicsEventId terminated;
|
|
}info;
|
|
|
|
static void atExit(void *pvt)
|
|
{
|
|
info *pinfo = (info *)pvt;
|
|
testPass("%s reached atExit", pinfo->name);
|
|
epicsEventSignal(pinfo->terminate);
|
|
/*Now wait for thread to terminate*/
|
|
epicsEventMustWait(pinfo->terminated);
|
|
testPass("%s destroying pinfo", pinfo->name);
|
|
epicsEventDestroy(pinfo->terminate);
|
|
epicsEventDestroy(pinfo->terminated);
|
|
free(pinfo);
|
|
}
|
|
|
|
static void atThreadExit(void *pvt)
|
|
{
|
|
info *pinfo = (info *)pvt;
|
|
testPass("%s terminating", pinfo->name);
|
|
epicsEventSignal(pinfo->terminated);
|
|
}
|
|
|
|
static void thread(void *arg)
|
|
{
|
|
info *pinfo = (info *)arg;
|
|
|
|
strcpy(pinfo->name, epicsThreadGetNameSelf());
|
|
testDiag("%s starting", pinfo->name);
|
|
pinfo->terminate = epicsEventMustCreate(epicsEventEmpty);
|
|
pinfo->terminated = epicsEventMustCreate(epicsEventEmpty);
|
|
testOk(!epicsAtExit(atExit, pinfo), "Registered atExit(%p)", pinfo);
|
|
testOk(!epicsAtThreadExit(atThreadExit, pinfo),
|
|
"Registered atThreadExit(%p)", pinfo);
|
|
testDiag("%s waiting for atExit", pinfo->name);
|
|
epicsEventMustWait(pinfo->terminate);
|
|
}
|
|
|
|
int count;
|
|
|
|
static void counter(void *pvt)
|
|
{
|
|
count++;
|
|
}
|
|
|
|
static void mainExit(void *pvt)
|
|
{
|
|
testPass("Reached mainExit");
|
|
testDone();
|
|
}
|
|
|
|
MAIN(epicsExitTest)
|
|
{
|
|
unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
|
info *pinfoA = (info *)calloc(1, sizeof(info));
|
|
info *pinfoB = (info *)calloc(1, sizeof(info));
|
|
|
|
testPlan(15);
|
|
|
|
testOk(!epicsAtExit(counter, NULL), "Registered counter()");
|
|
count = 0;
|
|
epicsExitCallAtExits();
|
|
testOk(count == 1, "counter() called once");
|
|
epicsExitCallAtExits();
|
|
testOk(count == 1, "unregistered counter() not called");
|
|
|
|
testOk(!epicsAtExit(mainExit, NULL), "Registered mainExit()");
|
|
|
|
epicsThreadCreate("threadA", 50, stackSize, thread, pinfoA);
|
|
epicsThreadSleep(0.1);
|
|
epicsThreadCreate("threadB", 50, stackSize, thread, pinfoB);
|
|
epicsThreadSleep(1.0);
|
|
|
|
testDiag("Calling epicsExit");
|
|
epicsExit(0);
|
|
return 0;
|
|
}
|