2020-01-20 19:52:46 -06:00
// 10 april 2019
# include "test.h"
2020-01-21 13:19:52 -06:00
# include "thread.h"
2020-05-09 01:04:51 -05:00
# include "../common/testhooks.h"
2020-01-20 19:52:46 -06:00
2020-05-09 19:03:51 -05:00
static void testImplInitFailureFull ( const char * file , long line )
2020-05-09 01:04:51 -05:00
{
uiInitError err ;
2020-05-09 01:33:18 -05:00
void * ctx ;
2020-05-09 01:04:51 -05:00
2020-05-09 01:33:18 -05:00
ctx = beginCheckProgrammerError ( NULL ) ;
2020-05-09 01:04:51 -05:00
uiprivTestHookSetInitShouldFailArtificially ( true ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
if ( uiInit ( NULL , & err ) )
2020-05-09 19:03:51 -05:00
TestErrorfFull ( file , line , " uiInit() succeeded; expected failure " ) ;
2020-05-09 01:04:51 -05:00
else if ( strcmp ( err . Message , " general failure " ) ! = 0 )
2020-05-09 19:03:51 -05:00
TestErrorfFull ( file , line , " uiInit() failed with wrong message: " diff ( " %s " ) ,
2020-05-09 01:04:51 -05:00
err . Message , " general failure " ) ;
2020-05-09 01:33:18 -05:00
endCheckProgrammerError ( ctx ) ;
2020-05-09 01:04:51 -05:00
}
2020-05-09 19:03:51 -05:00
# define testImplInitFailure() testImplInitFailureFull(__FILE__, __LINE__)
2020-05-09 15:35:01 -05:00
TestNoInit ( InitFailure )
{
testImplInitFailure ( ) ;
}
2020-05-09 19:03:51 -05:00
static void testImplNonNullOptionsFull ( const char * file , long line )
2020-05-09 00:45:09 -05:00
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiInit(): invalid uiInitOptions passed " ) ;
if ( uiInit ( ctx , NULL ) )
2020-05-09 19:03:51 -05:00
TestErrorfFull ( file , line , " uiInit() with non-NULL options succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-01-20 19:52:46 -06:00
2020-05-09 19:03:51 -05:00
# define testImplNonNullOptions() testImplNonNullOptionsFull(__FILE__, __LINE__)
2020-05-09 15:35:01 -05:00
TestNoInit ( InitWithNonNullOptionsIsProgrammerError )
{
testImplNonNullOptions ( ) ;
}
2020-05-09 00:45:09 -05:00
TestNoInit ( InitWithNullErrorIsProgrammerError )
2020-01-20 19:52:46 -06:00
{
2020-05-09 00:45:09 -05:00
void * ctx ;
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): invalid null pointer for uiInitError " ) ;
2020-01-20 19:52:46 -06:00
if ( uiInit ( NULL , NULL ) )
TestErrorf ( " uiInit() with NULL error succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
TestNoInit ( InitWithWrongErrorSizeIsProgrammerError )
{
uiInitError err ;
void * ctx ;
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): wrong size 2 for uiInitError " ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
2020-01-20 19:52:46 -06:00
err . Size = 2 ;
if ( uiInit ( NULL , & err ) )
TestErrorf ( " uiInit() with error with invalid size succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
Test ( InitCorrectlyAfterInitializedSuccessfully )
{
uiInitError err ;
void * ctx ;
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
2020-01-20 19:52:46 -06:00
err . Size = sizeof ( uiInitError ) ;
2020-05-09 00:45:09 -05:00
if ( uiInit ( NULL , & err ) )
TestFatalf ( " uiInit() after a previous successful call succeeded; expected failure " ) ;
endCheckProgrammerError ( ctx ) ;
}
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
Test ( InitIncorrectlyAfterInitializedSuccessfully )
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
if ( uiInit ( NULL , NULL ) )
TestFatalf ( " bad uiInit() after a previous successful call succeeded; expected failure " ) ;
endCheckProgrammerError ( ctx ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 01:38:07 -05:00
TestNoInit ( InitCorrectlyAfterFailureToInitialize )
{
uiInitError err ;
void * ctx ;
2020-05-09 15:35:01 -05:00
testImplInitFailure ( ) ;
2020-05-09 01:38:07 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
if ( uiInit ( NULL , & err ) )
2020-05-09 15:35:01 -05:00
TestFatalf ( " uiInit() after a previous failed call succeeded; expected failure " ) ;
2020-05-09 01:38:07 -05:00
endCheckProgrammerError ( ctx ) ;
}
TestNoInit ( InitIncorrectlyAfterFailureToInitialize )
{
void * ctx ;
2020-05-09 15:35:01 -05:00
testImplInitFailure ( ) ;
2020-05-09 01:38:07 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
if ( uiInit ( NULL , NULL ) )
2020-05-09 15:35:01 -05:00
TestFatalf ( " bad uiInit() after a previous failed call succeeded; expected failure " ) ;
2020-05-09 01:38:07 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-05-09 00:45:09 -05:00
TestNoInit ( InitCorrectlyAfterIncorrectInitialization )
2020-01-20 19:52:46 -06:00
{
uiInitError err ;
2020-05-09 00:45:09 -05:00
void * ctx ;
2020-01-20 19:52:46 -06:00
2020-05-09 15:35:01 -05:00
testImplNonNullOptions ( ) ;
2020-05-09 00:45:09 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
2020-01-20 19:52:46 -06:00
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
if ( uiInit ( NULL , & err ) )
2020-05-09 15:35:01 -05:00
TestFatalf ( " uiInit() after a previous erroneous call succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 00:45:09 -05:00
TestNoInit ( InitIncorrectlyAfterIncorrectInitialization )
{
void * ctx ;
2020-05-09 15:35:01 -05:00
testImplNonNullOptions ( ) ;
2020-05-09 00:45:09 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
if ( uiInit ( NULL , NULL ) )
2020-05-09 15:35:01 -05:00
TestFatalf ( " bad uiInit() after a previous erroneous call succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-05-09 21:34:42 -05:00
static void done ( void * data )
{
uiQuit ( ) ;
}
Test ( MainCalledTwiceIsProgrammerError )
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiMain(): attempt to call more than once " ) ;
uiQueueMain ( done , NULL ) ;
uiMain ( ) ;
uiMain ( ) ;
endCheckProgrammerError ( ctx ) ;
}
static void mainAndQuit ( void * data )
{
uiMain ( ) ;
uiQuit ( ) ;
}
Test ( MainCalledRecursivelyIsProgrammerError )
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiMain(): attempt to call more than once " ) ;
uiQueueMain ( mainAndQuit , NULL ) ;
uiMain ( ) ;
uiMain ( ) ;
endCheckProgrammerError ( ctx ) ;
}
// largely redundant due to InitCorrectlyAfterInitializedSuccessfully, but include it anyway just to be safe
Test ( InitAfterMainIsProgrammerError )
{
uiInitError err ;
void * ctx ;
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
uiQueueMain ( done , NULL ) ;
uiMain ( ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
if ( uiInit ( NULL , & err ) )
TestFatalf ( " uiInit() after a previous successful call succeeded; expected failure " ) ;
endCheckProgrammerError ( ctx ) ;
}
Test ( QuitBeforeMainIsProgrammerError )
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiQuit(): attempt to call before uiMain() " ) ;
uiQuit ( ) ;
endCheckProgrammerError ( ctx ) ;
}
static void quitTwice ( void * data )
{
uiQuit ( ) ;
uiQuit ( ) ;
}
Test ( QuitCalledTwiceIsProgrammerError )
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiQuit(): attempt to call more than once " ) ;
uiQueueMain ( quitTwice , NULL ) ;
uiMain ( ) ;
endCheckProgrammerError ( ctx ) ;
}
Test ( QuitAfterMainIsProgrammerError )
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiQuit(): attempt to call more than once " ) ;
uiQueueMain ( done , NULL ) ;
uiMain ( ) ;
uiQuit ( ) ;
endCheckProgrammerError ( ctx ) ;
}
2020-05-09 21:14:03 -05:00
struct simpleTestParams {
2020-05-09 15:54:18 -05:00
unsigned int n ;
2020-05-09 22:10:58 -05:00
threadThread * thread ;
threadSysError createErr ;
threadSysError sleepErr ;
2020-01-20 19:52:46 -06:00
} ;
2020-05-09 22:10:58 -05:00
static void queueSimple ( void * data )
2020-01-20 19:52:46 -06:00
{
2020-05-09 21:14:03 -05:00
struct simpleTestParams * p = ( struct simpleTestParams * ) data ;
2020-01-20 19:52:46 -06:00
2020-05-09 15:54:18 -05:00
p - > n + + ;
if ( p - > n > 2 )
p - > n = 2 ;
2020-01-20 19:52:46 -06:00
uiQuit ( ) ;
}
2020-01-21 13:19:52 -06:00
Test ( QueueMain )
2020-01-20 19:52:46 -06:00
{
2020-05-09 21:14:03 -05:00
struct simpleTestParams p ;
2020-01-20 19:52:46 -06:00
2020-05-09 21:14:03 -05:00
memset ( & p , 0 , sizeof ( struct simpleTestParams ) ) ;
2020-05-09 15:54:18 -05:00
p . n = 0 ;
2020-05-09 22:10:58 -05:00
uiQueueMain ( queueSimple , & p ) ;
2020-01-21 13:19:52 -06:00
uiMain ( ) ;
2020-05-09 15:54:18 -05:00
switch ( p . n ) {
case 0 :
TestErrorf ( " uiQueueMain() function was not called " ) ;
break ;
case 1 :
// do nothing; this is the expected case
break ;
default :
TestErrorf ( " uiQueueMain() called more than once " ) ;
}
2020-01-20 19:52:46 -06:00
}
2020-05-09 19:03:51 -05:00
struct queuedOrder {
int calls [ 4 ] ;
int i ;
unsigned int extraCalls ;
} ;
2020-05-09 15:54:18 -05:00
2020-05-09 19:03:51 -05:00
static void queueOrder ( struct queuedOrder * q , int n )
{
if ( q - > i < 4 ) {
q - > calls [ q - > i ] = n ;
q - > i + + ;
return ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 19:03:51 -05:00
q - > extraCalls + + ;
if ( q - > extraCalls > 9 )
q - > extraCalls = 9 ;
}
2020-05-09 20:54:26 -05:00
static void queueCheckOrderFull ( const char * file , long line , struct queuedOrder * got , int wantI , int wantA , int wantB , int wantC , int wantD )
2020-01-20 19:52:46 -06:00
{
2020-05-09 20:54:26 -05:00
int wantarr [ 4 ] ;
int i ;
if ( got - > i ! = wantI | | got - > extraCalls ! = 0 ) {
const char * orMore ;
orMore = " " ;
if ( got - > extraCalls > = 9 )
orMore = " or more " ;
TestErrorfFull ( file , line , " wrong number of queued function calls: " diff ( " %d%s " ) ,
got - > i + got - > extraCalls , orMore ,
wantI , " " ) ;
}
wantarr [ 0 ] = wantA ;
wantarr [ 1 ] = wantB ;
wantarr [ 2 ] = wantC ;
wantarr [ 3 ] = wantD ;
for ( i = 0 ; i < 4 ; i + + )
if ( got - > calls [ i ] ! = wantarr [ i ] )
TestErrorfFull ( file , line , " wrong value for call %d in sequence: " diff ( " %d " ) ,
i + 1 , got - > calls [ i ] , wantarr [ i ] ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 20:54:26 -05:00
# define queueCheckOrder(got, i, a, b, c, d) queueCheckOrderFull(__FILE__, __LINE__, got, i, a, b, c, d)
struct queueTestParams {
struct queuedOrder order1 ;
struct queuedOrder order2 ;
2020-05-10 10:50:05 -05:00
unsigned int n ;
2020-05-09 22:10:58 -05:00
threadThread * thread ;
threadSysError createErr ;
2020-05-10 10:50:05 -05:00
threadSysError sleepErr1 ;
threadSysError sleepErr2 ;
2020-01-20 19:52:46 -06:00
} ;
2020-05-09 20:54:26 -05:00
# define queueStep(name, type, field, n) \
static void name ( void * data ) \
{ \
type * p = ( type * ) data ; \
queueOrder ( & ( p - > field ) , n ) ; \
}
queueStep ( step11 , struct queueTestParams , order1 , 1 )
queueStep ( step12 , struct queueTestParams , order1 , 2 )
queueStep ( step13 , struct queueTestParams , order1 , 3 )
queueStep ( step14 , struct queueTestParams , order1 , 4 )
queueStep ( step21 , struct queueTestParams , order2 , 1 )
queueStep ( step22 , struct queueTestParams , order2 , 2 )
queueStep ( step23 , struct queueTestParams , order2 , 3 )
queueStep ( step24 , struct queueTestParams , order2 , 4 )
static void queueOrder1 ( struct queueTestParams * p )
2020-01-20 19:52:46 -06:00
{
2020-05-09 20:54:26 -05:00
uiQueueMain ( step11 , p ) ;
uiQueueMain ( step12 , p ) ;
uiQueueMain ( step13 , p ) ;
uiQueueMain ( step14 , p ) ;
uiQueueMain ( done , NULL ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 20:54:26 -05:00
Test ( QueueMain_Sequence )
2020-01-20 19:52:46 -06:00
{
2020-05-09 20:54:26 -05:00
struct queueTestParams p ;
2020-01-20 19:52:46 -06:00
2020-05-09 20:54:26 -05:00
memset ( & p , 0 , sizeof ( struct queueTestParams ) ) ;
queueOrder1 ( & p ) ;
2020-01-21 13:19:52 -06:00
uiMain ( ) ;
2020-05-09 20:54:26 -05:00
queueCheckOrder ( & ( p . order1 ) , 4 , 1 , 2 , 3 , 4 ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 22:10:58 -05:00
static void queueOrder1ExceptStep2 ( void * data )
{
struct queueTestParams * p = ( struct queueTestParams * ) data ;
uiQueueMain ( step11 , p ) ;
uiQueueMain ( step13 , p ) ;
uiQueueMain ( step14 , p ) ;
uiQueueMain ( done , NULL ) ;
}
Test ( QueueMain_SequenceWorksEvenWithFunctionsAlreadyQueued )
2020-05-09 21:14:03 -05:00
{
struct queueTestParams p ;
memset ( & p , 0 , sizeof ( struct queueTestParams ) ) ;
2020-05-09 22:10:58 -05:00
uiQueueMain ( queueOrder1ExceptStep2 , & p ) ;
uiQueueMain ( step12 , & p ) ;
2020-05-09 21:14:03 -05:00
uiMain ( ) ;
queueCheckOrder ( & ( p . order1 ) , 4 , 2 , 1 , 3 , 4 ) ;
}
2020-01-21 13:19:52 -06:00
2020-01-20 19:52:46 -06:00
static void queueThread ( void * data )
{
2020-05-09 21:14:03 -05:00
struct simpleTestParams * p = ( struct simpleTestParams * ) data ;
2020-01-20 19:52:46 -06:00
2020-05-09 22:10:58 -05:00
p - > sleepErr = threadSleep ( 1250 * threadMillisecond ) ;
uiQueueMain ( queueSimple , p ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 21:14:03 -05:00
Test ( QueueMain_DifferentThread )
2020-01-20 19:52:46 -06:00
{
threadThread * thread ;
threadSysError err ;
2020-05-09 21:14:03 -05:00
struct simpleTestParams p ;
2020-01-20 19:52:46 -06:00
2020-05-09 21:14:03 -05:00
memset ( & p , 0 , sizeof ( struct simpleTestParams ) ) ;
p . n = 0 ;
2020-01-20 19:52:46 -06:00
err = threadNewThread ( queueThread , & p , & thread ) ;
if ( err ! = 0 )
2020-01-21 13:19:52 -06:00
TestFatalf ( " error creating thread: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
uiMain ( ) ;
2020-01-20 19:52:46 -06:00
err = threadThreadWaitAndFree ( thread ) ;
if ( err ! = 0 )
2020-01-21 13:19:52 -06:00
TestFatalf ( " error waiting for thread to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
2020-05-09 22:10:58 -05:00
if ( p . sleepErr ! = 0 )
TestErrorf ( " error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt , threadSysErrorFmtArg ( p . sleepErr ) ) ;
switch ( p . n ) {
case 0 :
TestErrorf ( " uiQueueMain() function was not called " ) ;
break ;
case 1 :
// do nothing; this is the expected case
break ;
default :
TestErrorf ( " uiQueueMain() called more than once " ) ;
}
}
static void queueCreateThread ( void * data )
{
struct simpleTestParams * p = ( struct simpleTestParams * ) data ;
p - > createErr = threadNewThread ( queueThread , p , & ( p - > thread ) ) ;
if ( p - > createErr ! = 0 )
uiQuit ( ) ;
}
Test ( QueueMain_DifferentThreadStartedByQueuedFunction )
{
threadSysError err ;
struct simpleTestParams p ;
memset ( & p , 0 , sizeof ( struct simpleTestParams ) ) ;
p . n = 0 ;
uiQueueMain ( queueCreateThread , & p ) ;
uiMain ( ) ;
if ( p . createErr ! = 0 )
TestFatalf ( " error creating thread: " threadSysErrorFmt , threadSysErrorFmtArg ( p . createErr ) ) ;
err = threadThreadWaitAndFree ( p . thread ) ;
if ( err ! = 0 )
TestFatalf ( " error waiting for thread to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
if ( p . sleepErr ! = 0 )
TestErrorf ( " error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt , threadSysErrorFmtArg ( p . sleepErr ) ) ;
2020-05-09 21:14:03 -05:00
switch ( p . n ) {
case 0 :
TestErrorf ( " uiQueueMain() function was not called " ) ;
break ;
case 1 :
// do nothing; this is the expected case
break ;
default :
TestErrorf ( " uiQueueMain() called more than once " ) ;
}
}
static void queueOrder2 ( struct queueTestParams * p )
{
uiQueueMain ( step23 , p ) ;
uiQueueMain ( step22 , p ) ;
uiQueueMain ( step24 , p ) ;
uiQueueMain ( step21 , p ) ;
uiQueueMain ( done , NULL ) ;
2020-01-20 19:52:46 -06:00
}
static void queueOrderThread ( void * data )
{
2020-05-09 21:14:03 -05:00
struct queueTestParams * p = ( struct queueTestParams * ) data ;
2020-01-20 19:52:46 -06:00
2020-05-10 10:50:05 -05:00
p - > sleepErr1 = threadSleep ( 1250 * threadMillisecond ) ;
2020-05-09 21:14:03 -05:00
queueOrder2 ( p ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 21:14:03 -05:00
Test ( QueueMain_DifferentThreadSequence )
2020-01-20 19:52:46 -06:00
{
threadThread * thread ;
threadSysError err ;
2020-05-09 21:14:03 -05:00
struct queueTestParams p ;
2020-01-20 19:52:46 -06:00
2020-05-09 21:14:03 -05:00
memset ( & p , 0 , sizeof ( struct queueTestParams ) ) ;
2020-01-20 19:52:46 -06:00
err = threadNewThread ( queueOrderThread , & p , & thread ) ;
if ( err ! = 0 )
2020-01-21 13:19:52 -06:00
TestFatalf ( " error creating thread: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
uiMain ( ) ;
2020-01-20 19:52:46 -06:00
err = threadThreadWaitAndFree ( thread ) ;
if ( err ! = 0 )
2020-01-21 13:19:52 -06:00
TestFatalf ( " error waiting for thread to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
2020-05-10 10:50:05 -05:00
if ( p . sleepErr1 ! = 0 )
TestErrorf ( " error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt , threadSysErrorFmtArg ( p . sleepErr1 ) ) ;
2020-05-09 22:10:58 -05:00
queueCheckOrder ( & ( p . order2 ) , 4 , 3 , 2 , 4 , 1 ) ;
}
2020-05-10 10:50:05 -05:00
static void doneInterleaved ( void * data )
{
struct queueTestParams * p = ( struct queueTestParams * ) data ;
p - > n + + ;
if ( p - > n = = 2 )
uiQuit ( ) ;
}
static void queueOrder1Interleaved ( struct queueTestParams * p )
{
uiQueueMain ( step13 , p ) ;
uiQueueMain ( step11 , p ) ;
uiQueueMain ( step12 , p ) ;
uiQueueMain ( step14 , p ) ;
uiQueueMain ( doneInterleaved , p ) ;
}
static void queueOrder2Interleaved ( struct queueTestParams * p )
{
uiQueueMain ( step24 , p ) ;
uiQueueMain ( step22 , p ) ;
uiQueueMain ( step21 , p ) ;
uiQueueMain ( step23 , p ) ;
uiQueueMain ( doneInterleaved , p ) ;
}
static void queueOrderThread1Interleaved ( void * data )
{
struct queueTestParams * p = ( struct queueTestParams * ) data ;
p - > sleepErr1 = threadSleep ( 1250 * threadMillisecond ) ;
queueOrder1Interleaved ( p ) ;
}
static void queueOrderThread2Interleaved ( void * data )
{
struct queueTestParams * p = ( struct queueTestParams * ) data ;
p - > sleepErr2 = threadSleep ( 1250 * threadMillisecond ) ;
queueOrder2Interleaved ( p ) ;
}
Test ( QueueMain_DifferentThreadSequenceInterleaved )
{
threadThread * thread1 , * thread2 ;
threadSysError err ;
struct queueTestParams p ;
memset ( & p , 0 , sizeof ( struct queueTestParams ) ) ;
err = threadNewThread ( queueOrderThread1Interleaved , & p , & thread1 ) ;
if ( err ! = 0 )
TestFatalf ( " error creating thread 1: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
err = threadNewThread ( queueOrderThread2Interleaved , & p , & thread2 ) ;
if ( err ! = 0 )
TestFatalf ( " error creating thread 2: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
uiMain ( ) ;
err = threadThreadWaitAndFree ( thread1 ) ;
if ( err ! = 0 )
TestFatalf ( " error waiting for thread 1 to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
if ( p . sleepErr1 ! = 0 )
TestErrorf ( " error sleeping in thread 1 to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt , threadSysErrorFmtArg ( p . sleepErr1 ) ) ;
err = threadThreadWaitAndFree ( thread2 ) ;
if ( err ! = 0 )
TestFatalf ( " error waiting for thread 2 to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
if ( p . sleepErr2 ! = 0 )
TestErrorf ( " error sleeping in thread 2 to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt , threadSysErrorFmtArg ( p . sleepErr2 ) ) ;
queueCheckOrder ( & ( p . order1 ) , 4 , 3 , 1 , 2 , 4 ) ;
queueCheckOrder ( & ( p . order2 ) , 4 , 4 , 2 , 1 , 3 ) ;
}
2020-05-09 22:10:58 -05:00
static void queueCreateQueueThread ( void * data )
{
struct queueTestParams * p = ( struct queueTestParams * ) data ;
p - > createErr = threadNewThread ( queueOrderThread , p , & ( p - > thread ) ) ;
if ( p - > createErr ! = 0 )
uiQuit ( ) ;
}
// TODO make a version of this where functions are queued by both the main thread and a secondary thread (which is why there are two queues)
Test ( QueueMain_DifferentThreadSequenceStartedByQueuedFunction )
{
threadSysError err ;
struct queueTestParams p ;
memset ( & p , 0 , sizeof ( struct queueTestParams ) ) ;
uiQueueMain ( queueCreateQueueThread , & p ) ;
uiMain ( ) ;
if ( p . createErr ! = 0 )
TestFatalf ( " error creating thread: " threadSysErrorFmt , threadSysErrorFmtArg ( p . createErr ) ) ;
err = threadThreadWaitAndFree ( p . thread ) ;
if ( err ! = 0 )
TestFatalf ( " error waiting for thread to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
2020-05-10 10:50:05 -05:00
if ( p . sleepErr1 ! = 0 )
TestErrorf ( " error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt , threadSysErrorFmtArg ( p . sleepErr1 ) ) ;
2020-05-09 21:14:03 -05:00
queueCheckOrder ( & ( p . order2 ) , 4 , 3 , 2 , 4 , 1 ) ;
2020-01-20 19:52:46 -06:00
}
2020-01-21 13:19:52 -06:00
#if 0
2020-01-20 19:52:46 -06:00
static void timer ( void * data )
{
int * n = ( int * ) data ;
// TODO return stop if n == 5, continue otherwise
* n + + ;
}
testingTest ( Timer )
{
}
# endif