ptg10805159
828 Communicating with a Network Printer Chapter 21
482 /*
483 * Add a worker to the list of worker threads.
484 *
485 * LOCKING: acquires and releases workerlock.
486 */
487 void
488 add_worker(pthread_t tid, int sockfd)
489 {
490 struct worker_thread *wtp;
491 if ((wtp = malloc(sizeof(struct worker_thread))) == NULL) {
492 log_ret("add_worker: can’t malloc");
493 pthread_exit((void *)1);
494 }
495 wtp->tid=tid;
496 wtp->sockfd=sockfd;
497 pthread_mutex_lock(&workerlock);
498 wtp->prev=NULL;
499 wtp->next=workers;
500 if (workers == NULL)
501 workers=wtp;
502 else
503 workers->prev=wtp;
504 pthread_mutex_unlock(&workerlock);
505 }
506 /*
507 * Cancel (kill) all outstanding workers.
508 *
509 * LOCKING: acquires and releases workerlock.
510 */
511 void
512 kill_workers(void)
513 {
514 struct worker_thread *wtp;
515 pthread_mutex_lock(&workerlock);
516 for (wtp = workers; wtp != NULL; wtp = wtp->next)
517 pthread_cancel(wtp->tid);
518 pthread_mutex_unlock(&workerlock);
519 }
[482 – 505] add_workeradds aworker_threadstructure to the list of active threads.
We allocate memory for the structure, initialize it, lock theworkerlock
mutex, add the structure to the head of the list, and unlock the mutex.
[506 – 519] Thekill_workersfunction walks the list of worker threads and cancels
each one. We hold theworkerlockmutex while we walk the list. Recall
thatpthread_cancelmerely schedules a thread for cancellation; actual
cancellation happens when each thread reaches the next cancellation point.