OSDN Git Service

Enable to track git://github.com/monaka/binutils.git
[pf3gnuchains/pf3gnuchains3x.git] / winsup / testsuite / winsup.api / pthread / cancel5.c
diff --git a/winsup/testsuite/winsup.api/pthread/cancel5.c b/winsup/testsuite/winsup.api/pthread/cancel5.c
new file mode 100644 (file)
index 0000000..9dd5795
--- /dev/null
@@ -0,0 +1,165 @@
+/*\r
+ * File: cancel5.c\r
+ *\r
+ * Test Synopsis: Test calling pthread_cancel from the main thread\r
+ *                without calling pthread_self() in main.\r
+ *\r
+ * Test Method (Validation or Falsification):\r
+ * - \r
+ *\r
+ * Requirements Tested:\r
+ * -\r
+ *\r
+ * Features Tested:\r
+ * - \r
+ *\r
+ * Cases Tested:\r
+ * - \r
+ *\r
+ * Description:\r
+ * - \r
+ *\r
+ * Environment:\r
+ * - \r
+ *\r
+ * Input:\r
+ * - None.\r
+ *\r
+ * Output:\r
+ * - File name, Line number, and failed expression on failure.\r
+ * - No output on success.\r
+ *\r
+ * Assumptions:\r
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock\r
+ *   pthread_testcancel, pthread_cancel, pthread_join\r
+ *\r
+ * Pass Criteria:\r
+ * - Process returns zero exit status.\r
+ *\r
+ * Fail Criteria:\r
+ * - Process returns non-zero exit status.\r
+ */\r
+\r
+#include "test.h"\r
+\r
+/*\r
+ * Create NUMTHREADS threads in addition to the Main thread.\r
+ */\r
+enum {\r
+  NUMTHREADS = 10\r
+};\r
+\r
+typedef struct bag_t_ bag_t;\r
+struct bag_t_ {\r
+  int threadnum;\r
+  int started;\r
+  /* Add more per-thread state variables here */\r
+  int count;\r
+};\r
+\r
+static bag_t threadbag[NUMTHREADS + 1];\r
+\r
+void *\r
+mythread(void * arg)\r
+{\r
+  int result = ((int)PTHREAD_CANCELED + 1);\r
+  bag_t * bag = (bag_t *) arg;\r
+\r
+  assert(bag == &threadbag[bag->threadnum]);\r
+  assert(bag->started == 0);\r
+  bag->started = 1;\r
+\r
+  /* Set to known state and type */\r
+\r
+  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);\r
+\r
+  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);\r
+\r
+  /*\r
+   * We wait up to 10 seconds, waking every 0.1 seconds,\r
+   * for a cancelation to be applied to us.\r
+   */\r
+  for (bag->count = 0; bag->count < 100; bag->count++)\r
+    Sleep(100);\r
+\r
+  return (void *) result;\r
+}\r
+\r
+int\r
+main()\r
+{\r
+  int failed = 0;\r
+  int i;\r
+  pthread_t t[NUMTHREADS + 1];\r
+\r
+  for (i = 1; i <= NUMTHREADS; i++)\r
+    {\r
+      threadbag[i].started = 0;\r
+      threadbag[i].threadnum = i;\r
+      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);\r
+    }\r
+\r
+  /*\r
+   * Code to control or munipulate child threads should probably go here.\r
+   */\r
+  Sleep(500);\r
+\r
+  for (i = 1; i <= NUMTHREADS; i++)\r
+    {\r
+      assert(pthread_cancel(t[i]) == 0);\r
+    }\r
+\r
+  /*\r
+   * Give threads time to run.\r
+   */\r
+  Sleep(NUMTHREADS * 100);\r
+\r
+  /*\r
+   * Standard check that all threads started.\r
+   */\r
+  for (i = 1; i <= NUMTHREADS; i++)\r
+    { \r
+      if (!threadbag[i].started)\r
+       {\r
+         failed |= !threadbag[i].started;\r
+         fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);\r
+       }\r
+    }\r
+\r
+  assert(!failed);\r
+\r
+  /*\r
+   * Check any results here. Set "failed" and only print output on failure.\r
+   */\r
+  failed = 0;\r
+  for (i = 1; i <= NUMTHREADS; i++)\r
+    {\r
+      int fail = 0;\r
+      int result = 0;\r
+\r
+      /*\r
+       * The thread does not contain any cancelation points, so\r
+       * a return value of PTHREAD_CANCELED confirms that async\r
+       * cancelation succeeded.\r
+       */\r
+      assert(pthread_join(t[i], (void **) &result) == 0);\r
+\r
+      fail = (result != (int) PTHREAD_CANCELED);\r
+\r
+      if (fail)\r
+       {\r
+         fprintf(stderr, "Thread %d: started %d: count %d\n",\r
+                 i,\r
+                 threadbag[i].started,\r
+                 threadbag[i].count);\r
+       }\r
+      failed = (failed || fail);\r
+    }\r
+\r
+  assert(!failed);\r
+\r
+  /*\r
+   * Success.\r
+   */\r
+  return 0;\r
+}\r