* 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> | ||||
|  | ||||
| 	* 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