18 void *worker_routine (void *arg)
19 {
20 int counter;
21
22 for (counter = 0; ; counter++)
23 if ((counter % 1000) == 0)
24 pthread_testcancel ();
25 }
26
27 /*
28 * Cancellation cleanup handler for the contractor thread. It
29 * will cancel and detach each worker in the team.
30 */
31 void cleanup (void *arg)
32 {
33 team_t *team = (team_t *)arg;
34 int count, status;
35
36 for (count = team->join_i; count < THREADS; count++) {
37 status = pthread_cancel (team->workers[count]);
38 if (status != 0)
39 err_abort (status, "Cancel worker");
40
41 status = pthread_detach(team->workers[count]);
42 if (status != 0)
43 err_abort (status, "Detach worker");
44 printf ("Cleanup: canceled %d\n", count);
45 }
46 }
47
48 /*
49 * Thread start routine for the contractor. It creates a team of
50 * worker threads, and then joins with them. When canceled, the
51 * cleanup handler will cancel and detach the remaining threads.
52 */
53 void *thread_routine (void *arg)
54 {
53 team_t team; /* team info */
56 int count;
57 void *result; /* Return status */
58 int status;
59
60 for (count = 0; count < THREADS; count++) {
61 status = pthread_create (
62 &team.workers[count], NULL, worker_routine, NULL);
63 if (status != 0)
64 err_abort (status, "Create worker");
55 }
66 pthread_cleanup_push (cleanup, (void*)&team);
67
68 for (team.join_i = 0; team.join_i < THREADS; team.join_i++) {
69 status = pthread_join (team.workers[team.join_i], &result);
70 if (status != 0)
71 err_abort (status, "Join worker");
72 }
73
74 pthread_cleanup_pop (0);
75 return NULL;
76 }
77
78 int main (int argc, char *argv[])
79 {
80 pthread_t thread_id;
81 int status;
82
83 #ifdef sun
84 /*
85 * On Solaris 2.5, threads are not timesliced. To ensure
86 * that our threads can run concurrently, we need to
87 * increase the concurrency level to at least 2 plus THREADS
88 * (the number of workers).
89 */
90 DPRINTF (("Setting concurrency level to %d\n", THREADS+2));
91 thr_setconcurrency (THREADS+2);
92 #endif
93 status = pthread_create (&thread_id, NULL, thread_routine, NULL);
94 if (status != 0)
95 err_abort (status, "Create team");
96 sleep (5);
97 printf ("Cancelling...\n");
98 status = pthread_cancel (thread_id);
99 if (status != 0)
100 err_abort (status, "Cancel team");
101 status = pthread_join (thread_id, NULL);
102 if (status != 0)
103 err_abort (status, "Join team");
104 }
5.4 Thread-specific data