33 while (crew->work_count == 0) {
34 status = pthread_cond_wait (&crew->go, &crew->mutex);
35 if (status != 0)
36 err_abort (status, "Wait for go");
37 }
38
39 status = pthread_mutex_unlock (&crew->mutex);
40 if (status != 0)
41 err_abort (status, "Unlock mutex");
42
43 DPRINTF (("Crew %d starting\n", mine->index));
44
45 /*
46 * Now, as long as there's work, keep doing it.
47 */
48 while (1) {
49 /*
50 * Wait while there is nothing to do, and
51 * the hope of something coming along later. If
52 * crew->first is NULL, there's no work. But if
53 * crew->work_count goes to zero, we're done.
54 */
55 status = pthread_mutex_lock (&crew->mutex);
56 if (status != 0)
57 err_abort (status, "Lock crew mutex");
58
59 DPRINTF (("Crew %d top: first is %#lx, count is %d\n",
60 mine->index, crew->first, crew->work_count));
61 while (crew->first == NULL) {
62 status = pthread_cond_wait (&crew->go, &crew->mutex);
63 if (status != 0)
64 err_abort (status, "Wait for work");
65 }
66
67 DPRINTF (("Crew %d woke: %#lx, %d\n",
68 mine->index, crew->first, crew->work_count));
69
70 /*
71 * Remove and process a work item.
72 */
73 work = crew->first;
74 crew->first = work->next;
75 if (crew->first == NULL)
76 crew->last = NULL;
77
78 DPRINTF (("Crew %d took %#lx, leaves first %#lx, last %#lx\n",
79 mine->index, work, crew->first, crew->last));
80
81 status = pthread_mutex_unlock (&crew->mutex);
82 if (status != 0)
83 err_abort (status, "Unlock mutex");
84
85 /*
86 * We have a work item. Process it, which may involve
87 * queuing new work items.
88 */
89 status = lstat (work->path, &filestat);
90
91 if (S_ISLNK (filestat.st_mode))
92 printf (
93 "Thread %d: %s is a link, skipping.\n",
94 mine->index,
95 work->path);
96 else if (S_ISDIR (filestat.st_mode)) {
97 DIR *directory;
98 struct dirent *result;
99
100 /*
101 * If the file is a directory, search it and place
102 * all files onto the queue as new work items.
103 */
104 directory = opendir (work->path);
105 if (directory == NULL) {
106 fprintf (
107 stderr, "Unable to open directory %s: %d (%s)\n",
108 work->path,
109 errno, strerror (errno));
110 continue;
111 }
112
113 while (1) {
114 status = readdir_r (directory, entry, &result);
115 if (status != 0) {
116 fprintf (
117 stderr,
118 "Unable to read directory %s: %d (%s)\n",
119 work->path,
120 status, strerror (status));
121 break;
122 }
123 if (result == NULL)
124 break; /* End of directory */
125
126 /*
127 * Ignore "." and entries.
128 */