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-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.
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*\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