* winsup.api/pthread/cancel1.c: New test. Port from pthreads-win32
project. * winsup.api/pthread/cancel2.c: Ditto. * winsup.api/pthread/cancel3.c: Ditto. * winsup.api/pthread/cancel4.c: Ditto. * winsup.api/pthread/cancel5.c: Ditto.
This commit is contained in:
		| @@ -1,3 +1,12 @@ | |||||||
|  | 2002-07-04  Egor Duda  <deo@logos-m.ru> | ||||||
|  |  | ||||||
|  | 	* winsup.api/pthread/cancel1.c: New test. Port from pthreads-win32  | ||||||
|  | 	project. | ||||||
|  | 	* winsup.api/pthread/cancel2.c: Ditto. | ||||||
|  | 	* winsup.api/pthread/cancel3.c: Ditto. | ||||||
|  | 	* winsup.api/pthread/cancel4.c: Ditto. | ||||||
|  | 	* winsup.api/pthread/cancel5.c: Ditto. | ||||||
|  |  | ||||||
| 2002-07-03  Christopher Faylor  <cgf@redhat.com> | 2002-07-03  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
| 	* Makefile.in: Eliminate unneeded Makefile recreation rule. | 	* Makefile.in: Eliminate unneeded Makefile recreation rule. | ||||||
|   | |||||||
							
								
								
									
										147
									
								
								winsup/testsuite/winsup.api/pthread/cancel1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								winsup/testsuite/winsup.api/pthread/cancel1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | |||||||
|  | /* | ||||||
|  |  * File: cancel1.c | ||||||
|  |  * | ||||||
|  |  * Test Synopsis: Test setting cancel state and cancel type. | ||||||
|  |  * -  | ||||||
|  |  * | ||||||
|  |  * Test Method (Validation or Falsification): | ||||||
|  |  * -  | ||||||
|  |  * | ||||||
|  |  * Requirements Tested: | ||||||
|  |  * - pthread_setcancelstate function | ||||||
|  |  * - pthread_setcanceltype function | ||||||
|  |  * | ||||||
|  |  * Features Tested: | ||||||
|  |  * -  | ||||||
|  |  * | ||||||
|  |  * Cases Tested: | ||||||
|  |  * -  | ||||||
|  |  * | ||||||
|  |  * Description: | ||||||
|  |  * -  | ||||||
|  |  * | ||||||
|  |  * Environment: | ||||||
|  |  * -  | ||||||
|  |  * | ||||||
|  |  * Input: | ||||||
|  |  * - None. | ||||||
|  |  * | ||||||
|  |  * Output: | ||||||
|  |  * - File name, Line number, and failed expression on failure. | ||||||
|  |  * - No output on success. | ||||||
|  |  * | ||||||
|  |  * Assumptions: | ||||||
|  |  * - pthread_create, pthread_self work. | ||||||
|  |  * | ||||||
|  |  * Pass Criteria: | ||||||
|  |  * - Process returns zero exit status. | ||||||
|  |  * | ||||||
|  |  * Fail Criteria: | ||||||
|  |  * - Process returns non-zero exit status. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "test.h" | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Create NUMTHREADS threads in addition to the Main thread. | ||||||
|  |  */ | ||||||
|  | enum { | ||||||
|  |   NUMTHREADS = 10 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef struct bag_t_ bag_t; | ||||||
|  | struct bag_t_ { | ||||||
|  |   int threadnum; | ||||||
|  |   int started; | ||||||
|  |   /* Add more per-thread state variables here */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static bag_t threadbag[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  | void * | ||||||
|  | mythread(void * arg) | ||||||
|  | { | ||||||
|  |   bag_t * bag = (bag_t *) arg; | ||||||
|  |  | ||||||
|  |   assert(bag == &threadbag[bag->threadnum]); | ||||||
|  |   assert(bag->started == 0); | ||||||
|  |   bag->started = 1; | ||||||
|  |  | ||||||
|  |   /* ... */ | ||||||
|  |   { | ||||||
|  |     int oldstate; | ||||||
|  |     int oldtype; | ||||||
|  |  | ||||||
|  |     assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) == 0); | ||||||
|  |     assert(oldstate == PTHREAD_CANCEL_ENABLE); /* Check default */ | ||||||
|  |     assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); | ||||||
|  |     assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) == 0); | ||||||
|  |     assert(pthread_setcancelstate(oldstate, &oldstate) == 0); | ||||||
|  |     assert(oldstate == PTHREAD_CANCEL_DISABLE); /* Check setting */ | ||||||
|  |  | ||||||
|  |     assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype) == 0); | ||||||
|  |     assert(oldtype == PTHREAD_CANCEL_DEFERRED); /* Check default */ | ||||||
|  |     assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); | ||||||
|  |     assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); | ||||||
|  |     assert(pthread_setcanceltype(oldtype, &oldtype) == 0); | ||||||
|  |     assert(oldtype == PTHREAD_CANCEL_ASYNCHRONOUS); /* Check setting */ | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | main() | ||||||
|  | { | ||||||
|  |   int failed = 0; | ||||||
|  |   int i; | ||||||
|  |   pthread_t t[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  |   assert((t[0] = pthread_self()) != NULL); | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       threadbag[i].started = 0; | ||||||
|  |       threadbag[i].threadnum = i; | ||||||
|  |       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Code to control or munipulate child threads should probably go here. | ||||||
|  |    */ | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Give threads time to run. | ||||||
|  |    */ | ||||||
|  |   Sleep(NUMTHREADS * 1000); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Standard check that all threads started. | ||||||
|  |    */ | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     {  | ||||||
|  |       failed = !threadbag[i].started; | ||||||
|  |  | ||||||
|  |       if (failed) | ||||||
|  | 	{ | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Check any results here. Set "failed" and only print ouput on failure. | ||||||
|  |    */ | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     {  | ||||||
|  |       /* ... */ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Success. | ||||||
|  |    */ | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
							
								
								
									
										181
									
								
								winsup/testsuite/winsup.api/pthread/cancel2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								winsup/testsuite/winsup.api/pthread/cancel2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | |||||||
|  | /* | ||||||
|  |  * File: cancel2.c | ||||||
|  |  * | ||||||
|  |  * Test Synopsis: Test SEH or C++ cancel exception handling within | ||||||
|  |  * application exception blocks. | ||||||
|  |  * | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "test.h" | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Create NUMTHREADS threads in addition to the Main thread. | ||||||
|  |  */ | ||||||
|  | enum { | ||||||
|  |   NUMTHREADS = 10 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef struct bag_t_ bag_t; | ||||||
|  | struct bag_t_ { | ||||||
|  |   int threadnum; | ||||||
|  |   int started; | ||||||
|  |   /* Add more per-thread state variables here */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static bag_t threadbag[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  | static pthread_mutex_t waitLock = PTHREAD_MUTEX_INITIALIZER; | ||||||
|  |  | ||||||
|  | void * | ||||||
|  | mythread(void * arg) | ||||||
|  | { | ||||||
|  |   int result = 0; | ||||||
|  |   bag_t * bag = (bag_t *) arg; | ||||||
|  |  | ||||||
|  |   assert(bag == &threadbag[bag->threadnum]); | ||||||
|  |   assert(bag->started == 0); | ||||||
|  |   bag->started = 1; | ||||||
|  |  | ||||||
|  |   /* Set to known state and type */ | ||||||
|  |  | ||||||
|  |   assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); | ||||||
|  |  | ||||||
|  |   switch (bag->threadnum % 2) | ||||||
|  |     { | ||||||
|  |     case 0: | ||||||
|  |       assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); | ||||||
|  |       result = 0; | ||||||
|  |       break; | ||||||
|  |     case 1: | ||||||
|  |       assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); | ||||||
|  |       result = 1; | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* Wait for go from main */ | ||||||
|  |   assert(pthread_mutex_lock(&waitLock) == 0); | ||||||
|  |   assert(pthread_mutex_unlock(&waitLock) == 0); | ||||||
|  |   sched_yield(); | ||||||
|  |  | ||||||
|  |   for (;;) | ||||||
|  |     {	   | ||||||
|  |       pthread_testcancel(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   return (void *) result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | main() | ||||||
|  | { | ||||||
|  |   int failed = 0; | ||||||
|  |   int i; | ||||||
|  |   pthread_t t[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  |   assert((t[0] = pthread_self()) != NULL); | ||||||
|  |   assert(pthread_mutex_lock(&waitLock) == 0); | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       threadbag[i].started = 0; | ||||||
|  |       threadbag[i].threadnum = i; | ||||||
|  |       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Code to control or munipulate child threads should probably go here. | ||||||
|  |    */ | ||||||
|  |   Sleep(500); | ||||||
|  |  | ||||||
|  |   assert(pthread_mutex_unlock(&waitLock) == 0); | ||||||
|  |  | ||||||
|  |   Sleep(500); | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       assert(pthread_cancel(t[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Give threads time to run. | ||||||
|  |    */ | ||||||
|  |   Sleep(NUMTHREADS * 100); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Standard check that all threads started. | ||||||
|  |    */ | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     {  | ||||||
|  |       if (!threadbag[i].started) | ||||||
|  | 	{ | ||||||
|  | 	  failed |= !threadbag[i].started; | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Check any results here. Set "failed" and only print output on failure. | ||||||
|  |    */ | ||||||
|  |   failed = 0; | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       int fail = 0; | ||||||
|  |       int result = 0; | ||||||
|  |  | ||||||
|  |       assert(pthread_join(t[i], (void **) &result) == 0); | ||||||
|  |       fail = (result != (int) PTHREAD_CANCELED); | ||||||
|  |       if (fail) | ||||||
|  | 	{ | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d: location %d: cancel type %s\n", | ||||||
|  | 		  i, | ||||||
|  | 		  threadbag[i].started, | ||||||
|  | 		  result, | ||||||
|  | 		  ((result % 2) == 0) ? "ASYNCHRONOUS" : "DEFERRED"); | ||||||
|  | 	} | ||||||
|  |       failed |= fail; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Success. | ||||||
|  |    */ | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										166
									
								
								winsup/testsuite/winsup.api/pthread/cancel3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								winsup/testsuite/winsup.api/pthread/cancel3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | |||||||
|  | /* | ||||||
|  |  * File: cancel3.c | ||||||
|  |  * | ||||||
|  |  * Test Synopsis: Test asynchronous cancelation. | ||||||
|  |  * | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "test.h" | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Create NUMTHREADS threads in addition to the Main thread. | ||||||
|  |  */ | ||||||
|  | enum { | ||||||
|  |   NUMTHREADS = 10 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef struct bag_t_ bag_t; | ||||||
|  | struct bag_t_ { | ||||||
|  |   int threadnum; | ||||||
|  |   int started; | ||||||
|  |   /* Add more per-thread state variables here */ | ||||||
|  |   int count; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static bag_t threadbag[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  | void * | ||||||
|  | mythread(void * arg) | ||||||
|  | { | ||||||
|  |   int result = ((int)PTHREAD_CANCELED + 1); | ||||||
|  |   bag_t * bag = (bag_t *) arg; | ||||||
|  |  | ||||||
|  |   assert(bag == &threadbag[bag->threadnum]); | ||||||
|  |   assert(bag->started == 0); | ||||||
|  |   bag->started = 1; | ||||||
|  |  | ||||||
|  |   /* Set to known state and type */ | ||||||
|  |  | ||||||
|  |   assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); | ||||||
|  |  | ||||||
|  |   assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * We wait up to 10 seconds, waking every 0.1 seconds, | ||||||
|  |    * for a cancelation to be applied to us. | ||||||
|  |    */ | ||||||
|  |   for (bag->count = 0; bag->count < 100; bag->count++) | ||||||
|  |     Sleep(100); | ||||||
|  |  | ||||||
|  |   return (void *) result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | main() | ||||||
|  | { | ||||||
|  |   int failed = 0; | ||||||
|  |   int i; | ||||||
|  |   pthread_t t[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  |   assert((t[0] = pthread_self()) != NULL); | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       threadbag[i].started = 0; | ||||||
|  |       threadbag[i].threadnum = i; | ||||||
|  |       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Code to control or munipulate child threads should probably go here. | ||||||
|  |    */ | ||||||
|  |   Sleep(500); | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       assert(pthread_cancel(t[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Give threads time to run. | ||||||
|  |    */ | ||||||
|  |   Sleep(NUMTHREADS * 100); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Standard check that all threads started. | ||||||
|  |    */ | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     {  | ||||||
|  |       if (!threadbag[i].started) | ||||||
|  | 	{ | ||||||
|  | 	  failed |= !threadbag[i].started; | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Check any results here. Set "failed" and only print output on failure. | ||||||
|  |    */ | ||||||
|  |   failed = 0; | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       int fail = 0; | ||||||
|  |       int result = 0; | ||||||
|  |  | ||||||
|  |       /* | ||||||
|  |        * The thread does not contain any cancelation points, so | ||||||
|  |        * a return value of PTHREAD_CANCELED confirms that async | ||||||
|  |        * cancelation succeeded. | ||||||
|  |        */ | ||||||
|  |       assert(pthread_join(t[i], (void **) &result) == 0); | ||||||
|  |  | ||||||
|  |       fail = (result != (int) PTHREAD_CANCELED); | ||||||
|  |  | ||||||
|  |       if (fail) | ||||||
|  | 	{ | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d: count %d\n", | ||||||
|  | 		  i, | ||||||
|  | 		  threadbag[i].started, | ||||||
|  | 		  threadbag[i].count); | ||||||
|  | 	} | ||||||
|  |       failed = (failed || fail); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Success. | ||||||
|  |    */ | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
							
								
								
									
										172
									
								
								winsup/testsuite/winsup.api/pthread/cancel4.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								winsup/testsuite/winsup.api/pthread/cancel4.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | |||||||
|  | /* | ||||||
|  |  * File: cancel4.c | ||||||
|  |  * | ||||||
|  |  * Test Synopsis: Test cancelation does not occur in deferred | ||||||
|  |  *                cancelation threads with no cancelation points. | ||||||
|  |  * | ||||||
|  |  * 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: | ||||||
|  |  * - pthread_create | ||||||
|  |  *   pthread_self | ||||||
|  |  *   pthread_cancel | ||||||
|  |  *   pthread_join | ||||||
|  |  *   pthread_setcancelstate | ||||||
|  |  *   pthread_setcanceltype | ||||||
|  |  * | ||||||
|  |  * Pass Criteria: | ||||||
|  |  * - Process returns zero exit status. | ||||||
|  |  * | ||||||
|  |  * Fail Criteria: | ||||||
|  |  * - Process returns non-zero exit status. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "test.h" | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Create NUMTHREADS threads in addition to the Main thread. | ||||||
|  |  */ | ||||||
|  | enum { | ||||||
|  |   NUMTHREADS = 10 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef struct bag_t_ bag_t; | ||||||
|  | struct bag_t_ { | ||||||
|  |   int threadnum; | ||||||
|  |   int started; | ||||||
|  |   /* Add more per-thread state variables here */ | ||||||
|  |   int count; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static bag_t threadbag[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  | void * | ||||||
|  | mythread(void * arg) | ||||||
|  | { | ||||||
|  |   int result = ((int)PTHREAD_CANCELED + 1); | ||||||
|  |   bag_t * bag = (bag_t *) arg; | ||||||
|  |  | ||||||
|  |   assert(bag == &threadbag[bag->threadnum]); | ||||||
|  |   assert(bag->started == 0); | ||||||
|  |   bag->started = 1; | ||||||
|  |  | ||||||
|  |   /* Set to known state and type */ | ||||||
|  |  | ||||||
|  |   assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); | ||||||
|  |  | ||||||
|  |   assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * We wait up to 10 seconds, waking every 0.1 seconds, | ||||||
|  |    * for a cancelation to be applied to us. | ||||||
|  |    */ | ||||||
|  |   for (bag->count = 0; bag->count < 100; bag->count++) | ||||||
|  |     Sleep(100); | ||||||
|  |  | ||||||
|  |   return (void *) result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | main() | ||||||
|  | { | ||||||
|  |   int failed = 0; | ||||||
|  |   int i; | ||||||
|  |   pthread_t t[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  |   assert((t[0] = pthread_self()) != NULL); | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       threadbag[i].started = 0; | ||||||
|  |       threadbag[i].threadnum = i; | ||||||
|  |       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Code to control or munipulate child threads should probably go here. | ||||||
|  |    */ | ||||||
|  |   Sleep(500); | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       assert(pthread_cancel(t[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Give threads time to run. | ||||||
|  |    */ | ||||||
|  |   Sleep(NUMTHREADS * 100); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Standard check that all threads started. | ||||||
|  |    */ | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     {  | ||||||
|  |       if (!threadbag[i].started) | ||||||
|  | 	{ | ||||||
|  | 	  failed |= !threadbag[i].started; | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Check any results here. Set "failed" and only print output on failure. | ||||||
|  |    */ | ||||||
|  |   failed = 0; | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       int fail = 0; | ||||||
|  |       int result = 0; | ||||||
|  |  | ||||||
|  |       /* | ||||||
|  |        * The thread does not contain any cancelation points, so | ||||||
|  |        * a return value of PTHREAD_CANCELED indicates that async | ||||||
|  |        * cancelation occurred. | ||||||
|  |        */ | ||||||
|  |       assert(pthread_join(t[i], (void **) &result) == 0); | ||||||
|  |  | ||||||
|  |       fail = (result == (int) PTHREAD_CANCELED); | ||||||
|  |  | ||||||
|  |       if (fail) | ||||||
|  | 	{ | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d: count %d\n", | ||||||
|  | 		  i, | ||||||
|  | 		  threadbag[i].started, | ||||||
|  | 		  threadbag[i].count); | ||||||
|  | 	} | ||||||
|  |       failed = (failed || fail); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Success. | ||||||
|  |    */ | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										165
									
								
								winsup/testsuite/winsup.api/pthread/cancel5.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								winsup/testsuite/winsup.api/pthread/cancel5.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | |||||||
|  | /* | ||||||
|  |  * File: cancel5.c | ||||||
|  |  * | ||||||
|  |  * Test Synopsis: Test calling pthread_cancel from the main thread | ||||||
|  |  *                without calling pthread_self() in main. | ||||||
|  |  * | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "test.h" | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Create NUMTHREADS threads in addition to the Main thread. | ||||||
|  |  */ | ||||||
|  | enum { | ||||||
|  |   NUMTHREADS = 10 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef struct bag_t_ bag_t; | ||||||
|  | struct bag_t_ { | ||||||
|  |   int threadnum; | ||||||
|  |   int started; | ||||||
|  |   /* Add more per-thread state variables here */ | ||||||
|  |   int count; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static bag_t threadbag[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  | void * | ||||||
|  | mythread(void * arg) | ||||||
|  | { | ||||||
|  |   int result = ((int)PTHREAD_CANCELED + 1); | ||||||
|  |   bag_t * bag = (bag_t *) arg; | ||||||
|  |  | ||||||
|  |   assert(bag == &threadbag[bag->threadnum]); | ||||||
|  |   assert(bag->started == 0); | ||||||
|  |   bag->started = 1; | ||||||
|  |  | ||||||
|  |   /* Set to known state and type */ | ||||||
|  |  | ||||||
|  |   assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); | ||||||
|  |  | ||||||
|  |   assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * We wait up to 10 seconds, waking every 0.1 seconds, | ||||||
|  |    * for a cancelation to be applied to us. | ||||||
|  |    */ | ||||||
|  |   for (bag->count = 0; bag->count < 100; bag->count++) | ||||||
|  |     Sleep(100); | ||||||
|  |  | ||||||
|  |   return (void *) result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | main() | ||||||
|  | { | ||||||
|  |   int failed = 0; | ||||||
|  |   int i; | ||||||
|  |   pthread_t t[NUMTHREADS + 1]; | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       threadbag[i].started = 0; | ||||||
|  |       threadbag[i].threadnum = i; | ||||||
|  |       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Code to control or munipulate child threads should probably go here. | ||||||
|  |    */ | ||||||
|  |   Sleep(500); | ||||||
|  |  | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       assert(pthread_cancel(t[i]) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Give threads time to run. | ||||||
|  |    */ | ||||||
|  |   Sleep(NUMTHREADS * 100); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Standard check that all threads started. | ||||||
|  |    */ | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     {  | ||||||
|  |       if (!threadbag[i].started) | ||||||
|  | 	{ | ||||||
|  | 	  failed |= !threadbag[i].started; | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Check any results here. Set "failed" and only print output on failure. | ||||||
|  |    */ | ||||||
|  |   failed = 0; | ||||||
|  |   for (i = 1; i <= NUMTHREADS; i++) | ||||||
|  |     { | ||||||
|  |       int fail = 0; | ||||||
|  |       int result = 0; | ||||||
|  |  | ||||||
|  |       /* | ||||||
|  |        * The thread does not contain any cancelation points, so | ||||||
|  |        * a return value of PTHREAD_CANCELED confirms that async | ||||||
|  |        * cancelation succeeded. | ||||||
|  |        */ | ||||||
|  |       assert(pthread_join(t[i], (void **) &result) == 0); | ||||||
|  |  | ||||||
|  |       fail = (result != (int) PTHREAD_CANCELED); | ||||||
|  |  | ||||||
|  |       if (fail) | ||||||
|  | 	{ | ||||||
|  | 	  fprintf(stderr, "Thread %d: started %d: count %d\n", | ||||||
|  | 		  i, | ||||||
|  | 		  threadbag[i].started, | ||||||
|  | 		  threadbag[i].count); | ||||||
|  | 	} | ||||||
|  |       failed = (failed || fail); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   assert(!failed); | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Success. | ||||||
|  |    */ | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user