VirtualBox

Changeset 20903 in vbox for trunk


Ignore:
Timestamp:
Jun 24, 2009 7:32:12 PM (16 years ago)
Author:
vboxsync
Message:

SUP: Added a testcase to make sure threads exit when the process exits.

Location:
trunk/src/VBox/HostDrivers/Support/testcase
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/testcase/Makefile.kmk

    r19892 r20903  
    4646        tstGIP-2 \
    4747        tstGetPagingMode \
    48         tstSupSem
     48        tstSupSem \
     49        tstSupSem-Zombie
    4950endif # VBOX_WITH_TESTCASES
    5051
     
    8990tstSupSem_SOURCES     = tstSupSem.cpp
    9091
     92tstSupSem-Zombie_TEMPLATE = VBOXR3TSTEXE
     93tstSupSem-Zombie_SOURCES  = tstSupSem-Zombie.cpp
     94
    9195include $(KBUILD_PATH)/subfooter.kmk
    9296
  • trunk/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp

    r20902 r20903  
    11/* $Id$ */
    22/** @file
    3  * Support Library Testcase - Ring-3 Semaphore interface.
     3 * Support Library Testcase - Ring-3 Semaphore interface - Zombie bugs.
    44 */
    55
     
    3636
    3737#include <VBox/param.h>
     38#include <iprt/env.h>
    3839#include <iprt/err.h>
    3940#include <iprt/initterm.h>
     41#include <iprt/process.h>
    4042#include <iprt/stream.h>
    4143#include <iprt/test.h>
     44#include <iprt/time.h>
    4245#include <iprt/thread.h>
    4346
     
    4851static PSUPDRVSESSION   g_pSession;
    4952static RTTEST           g_hTest;
    50 static uint32_t         g_cMillies; /* Used by the interruptible tests. */
    51 
    52 
    53 
    54 static DECLCALLBACK(int) tstSupSemInterruptibleSRE(RTTHREAD hSelf, void *pvUser)
     53
     54
     55
     56static DECLCALLBACK(int) tstSupSemSRETimed(RTTHREAD hSelf, void *pvUser)
    5557{
    5658    SUPSEMEVENT hEvent = (SUPSEMEVENT)pvUser;
    5759    RTThreadUserSignal(hSelf);
    58     return SUPSemEventWaitNoResume(g_pSession, hEvent, g_cMillies);
    59 }
    60 
    61 
    62 static DECLCALLBACK(int) tstSupSemInterruptibleMRE(RTTHREAD hSelf, void *pvUser)
     60    return SUPSemEventWaitNoResume(g_pSession, hEvent, 120*1000);
     61}
     62
     63
     64static DECLCALLBACK(int) tstSupSemMRETimed(RTTHREAD hSelf, void *pvUser)
    6365{
    6466    SUPSEMEVENTMULTI hEventMulti = (SUPSEMEVENTMULTI)pvUser;
    6567    RTThreadUserSignal(hSelf);
    66     return SUPSemEventMultiWaitNoResume(g_pSession, hEventMulti, g_cMillies);
    67 }
    68 
    69 
    70 int main(int argc, char **argv)
     68    return SUPSemEventMultiWaitNoResume(g_pSession, hEventMulti, 120*1000);
     69}
     70
     71
     72static DECLCALLBACK(int) tstSupSemSREInf(RTTHREAD hSelf, void *pvUser)
     73{
     74    SUPSEMEVENT hEvent = (SUPSEMEVENT)pvUser;
     75    RTThreadUserSignal(hSelf);
     76    return SUPSemEventWaitNoResume(g_pSession, hEvent, RT_INDEFINITE_WAIT);
     77}
     78
     79
     80static DECLCALLBACK(int) tstSupSemMREInf(RTTHREAD hSelf, void *pvUser)
     81{
     82    SUPSEMEVENTMULTI hEventMulti = (SUPSEMEVENTMULTI)pvUser;
     83    RTThreadUserSignal(hSelf);
     84    return SUPSemEventMultiWaitNoResume(g_pSession, hEventMulti, RT_INDEFINITE_WAIT);
     85}
     86
     87static int mainChild(void)
    7188{
    7289    /*
     
    7693    if (RT_FAILURE(rc))
    7794    {
    78         RTPrintf("tstSupSem: fatal error: RTR3InitAndSUPLib failed with rc=%Rrc\n", rc);
     95        RTPrintf("tstSupSem-Zombie-Child: fatal error: RTR3InitAndSUPLib failed with rc=%Rrc\n", rc);
    7996        return 1;
    8097    }
    8198
    8299    RTTEST hTest;
    83     rc = RTTestCreate("tstSupSem", &hTest);
     100    rc = RTTestCreate("tstSupSem-Zombie-Child", &hTest);
    84101    if (RT_FAILURE(rc))
    85102    {
    86         RTPrintf("tstSupSem: fatal error: RTTestCreate failed with rc=%Rrc\n", rc);
     103        RTPrintf("tstSupSem-Zombie-Child: fatal error: RTTestCreate failed with rc=%Rrc\n", rc);
    87104        return 1;
    88105    }
     
    98115    g_pSession = pSession;
    99116
     117    /*
     118     * A semaphore of each kind and throw a bunch of threads on them.
     119     */
     120    SUPSEMEVENT hEvent = NIL_SUPSEMEVENT;
     121    RTTESTI_CHECK_RC(rc = SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
     122    if (RT_SUCCESS(rc))
     123    {
     124        SUPSEMEVENTMULTI hEventMulti = NIL_SUPSEMEVENT;
     125        RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS);
     126        if (RT_SUCCESS(rc))
     127        {
     128            for (uint32_t cThreads = 0; cThreads < 5; cThreads++)
     129            {
     130                RTTHREAD hThread;
     131                RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemSRETimed, (void *)hEvent,      0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntSRE"), VINF_SUCCESS);
     132                RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemMRETimed, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntMRE"), VINF_SUCCESS);
     133                RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemSREInf,   (void *)hEvent,      0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntSRE"), VINF_SUCCESS);
     134                RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemMREInf,   (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntMRE"), VINF_SUCCESS);
     135                RTThreadSleep(2);
     136            }
     137            RTThreadSleep(50);
     138
     139            /*
     140             * This is where the test really starts...
     141             */
     142            return 0;
     143        }
     144    }
     145
     146    return RTTestSummaryAndDestroy(hTest);
     147}
     148
     149
     150/**
     151 * The parent main routine.
     152 * @param   argv0       The executable name (or whatever).
     153 */
     154static int mainParent(const char *argv0)
     155{
    100156    /*
    101      * Basic API checks.
    102      */
    103     RTTestSub(hTest, "Single Release Event (SRE) API");
    104     SUPSEMEVENT hEvent = NIL_SUPSEMEVENT;
    105     RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent),          VINF_SUCCESS);
    106     RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VERR_TIMEOUT);
    107     RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20),  VERR_TIMEOUT);
    108     RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    109     RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VINF_SUCCESS);
    110     RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    111     RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20),  VINF_SUCCESS);
    112     RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    113     RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    114     RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VINF_SUCCESS);
    115     RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VERR_TIMEOUT);
    116     RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20),  VERR_TIMEOUT);
    117     RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent),            VINF_OBJECT_DESTROYED);
    118     RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent),            VERR_INVALID_HANDLE);
    119     RTTESTI_CHECK_RC(SUPSemEventClose(pSession, NIL_SUPSEMEVENT),   VINF_SUCCESS);
    120 
    121     RTTestSub(hTest, "Multiple Release Event (MRE) API");
    122     SUPSEMEVENTMULTI hEventMulti = NIL_SUPSEMEVENT;
    123     RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti),            VINF_SUCCESS);
    124     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VERR_TIMEOUT);
    125     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20),    VERR_TIMEOUT);
    126     RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    127     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    128     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    129     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    130     RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    131     RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    132     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    133     RTTESTI_CHECK_RC(SUPSemEventMultiReset(pSession, hEventMulti),              VINF_SUCCESS);
    134     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VERR_TIMEOUT);
    135     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20),    VERR_TIMEOUT);
    136     RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    137     RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    138     RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti),              VINF_OBJECT_DESTROYED);
    139     RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti),              VERR_INVALID_HANDLE);
    140     RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, NIL_SUPSEMEVENTMULTI),     VINF_SUCCESS);
    141 
    142 #if !defined(RT_OS_OS2) && !defined(RT_OS_WINDOWS)
    143     RTTestSub(hTest, "SRE Interruptibility");
    144     RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
    145     g_cMillies = RT_INDEFINITE_WAIT;
    146     RTTHREAD hThread = NIL_RTTHREAD;
    147     RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleSRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS);
    148     RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS);
    149     RTThreadSleep(120);
    150     RTThreadPoke(hThread);
    151     int rcThread = VINF_SUCCESS;
    152     RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS);
    153     RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED);
    154     RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
    155 
    156     RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
    157     g_cMillies = 120*1000;
    158     hThread = NIL_RTTHREAD;
    159     RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleSRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS);
    160     RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS);
    161     RTThreadSleep(120);
    162     RTThreadPoke(hThread);
    163     rcThread = VINF_SUCCESS;
    164     RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS);
    165     RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED);
    166     RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
    167 
    168 
    169     RTTestSub(hTest, "MRE Interruptibility");
    170     RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS);
    171     g_cMillies = RT_INDEFINITE_WAIT;
    172     hThread = NIL_RTTHREAD;
    173     RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleMRE, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntMRE"), VINF_SUCCESS);
    174     RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS);
    175     RTThreadSleep(120);
    176     RTThreadPoke(hThread);
    177     rcThread = VINF_SUCCESS;
    178     RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS);
    179     RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED);
    180     RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VINF_OBJECT_DESTROYED);
    181 
    182     RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS);
    183     g_cMillies = 120*1000;
    184     hThread = NIL_RTTHREAD;
    185     RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleMRE, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntMRE"), VINF_SUCCESS);
    186     RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS);
    187     RTThreadSleep(120);
    188     RTThreadPoke(hThread);
    189     rcThread = VINF_SUCCESS;
    190     RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS);
    191     RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED);
    192     RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VINF_OBJECT_DESTROYED);
    193 #endif /* !OS2 && !WINDOWS */
     157     * Init.
     158     */
     159    RTTEST hTest;
     160    int rc = RTTestInitAndCreate("tstSupSem-Zombie", &hTest);
     161    if (rc)
     162        return rc;
     163    RTTestBanner(hTest);
    194164
    195165    /*
    196      * Done.
    197      */
     166     * Spin of the child process which may or may not turn into a zombie
     167     */
     168    for (uint32_t iPass = 0; iPass < 32; iPass++)
     169    {
     170        RTTestSubF(hTest, "Pass %u", iPass);
     171
     172        RTPROCESS hProcess;
     173        const char *apszArgs[3] = { argv0, "--child", NULL };
     174        RTTESTI_CHECK_RC_OK(rc = RTProcCreate(argv0, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hProcess));
     175        if (RT_SUCCESS(rc))
     176        {
     177            /*
     178             * Wait for 60 seconds then give up.
     179             */
     180            RTPROCSTATUS    Status;
     181            uint64_t        StartTS = RTTimeMilliTS();
     182            for (;;)
     183            {
     184                rc = RTProcWait(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &Status);
     185                if (RT_SUCCESS(rc))
     186                    break;
     187                uint64_t cElapsed = RTTimeMilliTS() - StartTS;
     188                if (cElapsed > 60*1000)
     189                    break;
     190                RTThreadSleep(cElapsed < 60 ? 30 : cElapsed < 200 ? 10 : 100);
     191            }
     192            RTTESTI_CHECK_RC_OK(rc);
     193            if (    RT_SUCCESS(rc)
     194                &&  (   Status.enmReason != RTPROCEXITREASON_NORMAL
     195                     || Status.iStatus != 0))
     196            {   
     197                RTTestIFailed("child %u (%d) reason %d\n", Status.iStatus, Status.iStatus, Status.enmReason);
     198                rc = VERR_PERMISSION_DENIED;
     199            }
     200        }
     201        /* one zombie process is enough. */
     202        if (RT_FAILURE(rc))
     203            break;                     
     204    }
     205
    198206    return RTTestSummaryAndDestroy(hTest);
    199207}
    200208
     209
     210int main(int argc, char **argv)
     211{
     212    if (    argc == 2
     213        &&  !strcmp(argv[1], "--child"))
     214        return mainChild();
     215    return mainParent(argv[0]);
     216}
     217
  • trunk/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp

    r19923 r20903  
    9797    }
    9898    g_pSession = pSession;
     99    RTTestBanner(hTest);
    99100
    100101    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette