From c94735ecdde19c4de652efd144faeec1a729b1e0 Mon Sep 17 00:00:00 2001 From: rpj Date: Thu, 28 Dec 2000 05:32:07 +0000 Subject: ./ChangeLog: 2000-12-28 Ross Johnson * private.c (ptw32_threadStart): Unhandled exceptions are now passed through to the system to deal with. This is consistent with normal Windows behaviour. C++ applications may use set_terminate() to override the default behaviour which is to call ptw32_terminate(). Ptw32_terminate() cleans up some POSIX thread stuff before calling the system default function which calls abort(). The users termination function should conform to standard C++ semantics which is to not return. It should exit the thread (call pthread_exit()) or exit the application. * private.c (ptw32_terminate): Added as the default set_terminate() function. It calls the system default function after cleaning up some POSIX thread stuff. * implement.h (ptw32_try_enter_critical_section): Move declaration. * global.c (ptw32_try_enter_critical_section): Moved from dll.c. * dll.c: Move process and thread attach/detach code into functions in nonportable.c. * nonportable.c (pthread_win32_process_attach_np): Process attach code from dll.c is now available to static linked applications. * nonportable.c (pthread_win32_process_detach_np): Likewise. * nonportable.c (pthread_win32_thread_attach_np): Likewise. * nonportable.c (pthread_win32_thread_detach_np): Likewise. * pthread.h: Add new non-portable prototypes for static linked applications. * GNUmakefile (OPT): Increase optimisation flag and remove debug info flag. * pthread.def: Add new non-portable exports for static linked applications. 2000-12-11 Ross Johnson * FAQ: Update Answer 6 re getting a fully working Mingw32 built library. 2000-09-09 Ross Johnson * pthread.h (ctime_r): Fix arg. ./tests/ChangeLog: 2000-12-28 Ross Johnson * eyal1.c: Increase thread work loads. * exception2.c: New test. * exception3.c: New test. * Makefile: Add new tests exception2.c and exception3.c. * GNUmakefile: Likewise. 2000-12-11 Ross Johnson * cleanup3.c: Remove unused variable. * cleanup2.c: Likewise. * exception1.c: Throw an exception rather than use a deliberate zero divide so that catch(...) will handle it under Mingw32. Mingw32 now builds the library correctly to pass all tests - see Thomas Pfaff's detailed instructions re needed changes to Mingw32 in the Pthreads-Win32 FAQ. --- tests/exception1.c | 453 +++++++++++++++++++++++++++-------------------------- 1 file changed, 229 insertions(+), 224 deletions(-) (limited to 'tests/exception1.c') diff --git a/tests/exception1.c b/tests/exception1.c index 609e5ed..1452d1a 100644 --- a/tests/exception1.c +++ b/tests/exception1.c @@ -1,224 +1,229 @@ -/* - * File: exception1.c - * - * Test Synopsis: Test passing of exceptions back to the application. - * - * Test Method (Validation or Falsification): - * - - * - * Requirements Tested: - * - - * - * Features Tested: - * - - * - * Cases Tested: - * - - * - * Description: - * - - * - * Environment: - * - - * - * Input: - * - None. - * - * Output: - * - File name, Line number, and failed expression on failure. - * - No output on success. - * - * Assumptions: - * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock - * pthread_testcancel, pthread_cancel, pthread_join - * - * Pass Criteria: - * - Process returns zero exit status. - * - * Fail Criteria: - * - Process returns non-zero exit status. - */ - -#if defined(_MSC_VER) || defined(__cplusplus) - -#include "test.h" - -/* - * Create NUMTHREADS threads in addition to the Main thread. - */ -enum { - NUMTHREADS = 4 -}; - -void * -exceptionedThread(void * arg) -{ - int result = ((int)PTHREAD_CANCELED + 1); - int one = 1; - int zero = 0; - int dummy = 0; - - /* Set to async cancelable */ - - assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); - - assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); - - Sleep(100); - -#if defined(_MSC_VER) && !defined(__cplusplus) - __try - { - /* Avoid being optimised out */ - if (dummy == one/zero) - Sleep(0); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - /* Should get into here. */ - result = ((int)PTHREAD_CANCELED + 2); - } -#elif defined(__cplusplus) - try - { - /* Avoid being optimised out */ - if (dummy == one/zero) - Sleep(0); - } -#if defined(PtW32CatchAll) - PtW32CatchAll -#else - catch (...) -#endif - { - /* Should get into here. */ - result = ((int)PTHREAD_CANCELED + 2); - } -#endif - - return (void *) result; -} - -void * -canceledThread(void * arg) -{ - int result = ((int)PTHREAD_CANCELED + 1); - int count; - - /* Set to async cancelable */ - - assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); - - assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); - -#if defined(_MSC_VER) && !defined(__cplusplus) - __try - { - /* - * We wait up to 10 seconds, waking every 0.1 seconds, - * for a cancelation to be applied to us. - */ - for (count = 0; count < 100; count++) - Sleep(100); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - /* Should NOT get into here. */ - result = ((int)PTHREAD_CANCELED + 2); - } -#elif defined(__cplusplus) - try - { - /* - * We wait up to 10 seconds, waking every 0.1 seconds, - * for a cancelation to be applied to us. - */ - for (count = 0; count < 100; count++) - Sleep(100); - } -#if defined(PtW32CatchAll) - PtW32CatchAll -#else - catch (...) -#endif - { - /* Should NOT get into here. */ - result = ((int)PTHREAD_CANCELED + 2); - } -#endif - - return (void *) result; -} - -int -main() -{ - int failed = 0; - int i; - pthread_t mt; - pthread_t et[NUMTHREADS]; - pthread_t ct[NUMTHREADS]; - - assert((mt = pthread_self()) != NULL); - - for (i = 0; i < NUMTHREADS; i++) - { - assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0); - assert(pthread_create(&ct[i], NULL, canceledThread, NULL) == 0); - } - - /* - * Code to control or munipulate child threads should probably go here. - */ - Sleep(500); - - for (i = 0; i < NUMTHREADS; i++) - { - assert(pthread_cancel(ct[i]) == 0); - } - - /* - * Give threads time to run. - */ - Sleep(NUMTHREADS * 100); - - /* - * Check any results here. Set "failed" and only print output on failure. - */ - failed = 0; - for (i = 0; i < NUMTHREADS; i++) - { - int fail = 0; - int result = 0; - - /* Canceled thread */ - assert(pthread_join(ct[i], (void **) &result) == 0); - fail = (result != (int) PTHREAD_CANCELED); - - failed = (failed || fail); - - /* Exception thread */ - assert(pthread_join(et[i], (void **) &result) == 0); - fail = (result != ((int) PTHREAD_CANCELED + 2)); - - failed = (failed || fail); - } - - assert(!failed); - - /* - * Success. - */ - return 0; -} - -#else /* defined(_MSC_VER) || defined(__cplusplus) */ - -int -main() -{ - fprintf(stderr, "Test N/A for this compiler environment.\n"); - return 0; -} - -#endif /* defined(_MSC_VER) || defined(__cplusplus) */ +/* + * File: exception1.c + * + * Test Synopsis: Test passing of exceptions back to the application. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#if defined(_MSC_VER) || defined(__cplusplus) + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +void * +exceptionedThread(void * arg) +{ + int dummy = 0; + int result = ((int)PTHREAD_CANCELED + 1); + /* Set to async cancelable */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + Sleep(100); + +#if defined(_MSC_VER) && !defined(__cplusplus) + __try + { + int zero = 0; + int one = 1; + /* + * The deliberate exception condition (zero devide) is + * in an "if" to avoid being optimised out. + */ + if (dummy == one/zero) + Sleep(0); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + /* Should get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } +#elif defined(__cplusplus) + try + { + /* + * I had a zero divide exception here but it + * wasn't being caught by the catch(...) + * below under Mingw32. That could be a problem. + */ + throw dummy; + } +#if defined(PtW32CatchAll) + PtW32CatchAll +#else + catch (...) +#endif + { + /* Should get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } +#endif + + return (void *) result; +} + +void * +canceledThread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + int count; + + /* Set to async cancelable */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + +#if defined(_MSC_VER) && !defined(__cplusplus) + __try + { + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (count = 0; count < 100; count++) + Sleep(100); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + /* Should NOT get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } +#elif defined(__cplusplus) + try + { + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (count = 0; count < 100; count++) + Sleep(100); + } +#if defined(PtW32CatchAll) + PtW32CatchAll +#else + catch (...) +#endif + { + /* Should NOT get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } +#endif + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t mt; + pthread_t et[NUMTHREADS]; + pthread_t ct[NUMTHREADS]; + + assert((mt = pthread_self()) != NULL); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0); + assert(pthread_create(&ct[i], NULL, canceledThread, NULL) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(1000); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_cancel(ct[i]) == 0); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 1000); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 0; i < NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* Canceled thread */ + assert(pthread_join(ct[i], (void **) &result) == 0); + assert(!(fail = (result != (int) PTHREAD_CANCELED))); + + failed = (failed || fail); + + /* Exceptioned thread */ + assert(pthread_join(et[i], (void **) &result) == 0); + assert(!(fail = (result != ((int) PTHREAD_CANCELED + 2)))); + + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + +#else /* defined(_MSC_VER) || defined(__cplusplus) */ + +int +main() +{ + fprintf(stderr, "Test N/A for this compiler environment.\n"); + return 0; +} + +#endif /* defined(_MSC_VER) || defined(__cplusplus) */ -- cgit v1.2.3