assert(out->tv_nsec < 1000000000);
}
+static int gettid(void) {
+ return (int)syscall(SYS_gettid);
+}
+
static void warn_time(const char* desc,
const struct timespec* restrict start,
const struct timespec* restrict end) {
if (diff.tv_sec > 0 || diff.tv_nsec > SLOW_NSEC) {
char buf[128];
extern char *__progname; // This is where glibc stashes argv[0].
- snprintf(buf, sizeof(buf), "%d: %s: %s took %d.%09d secs\n",
- (int)getpid(), __progname, desc,
- (int)diff.tv_sec, (int)diff.tv_nsec);
+ snprintf(buf, sizeof(buf), "%s:tid %d: %s took %d.%09d secs\n",
+ __progname, gettid(), desc, (int)diff.tv_sec, (int)diff.tv_nsec);
// Best effort write to a non-blocking stderr.
(void)write(STDERR_FILENO, buf, strlen(buf));
}
return (int)write_ret;
}
-static int max(const int a, const int b) { return (a > b) ? a : b; }
-
static void wait_until_readable(const int fd) {
- int select_ret;
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
- if ((select_ret = select(fd + 1, &read_fds, NULL, NULL, NULL)) == -1)
+ int select_ret = select(fd + 1, &read_fds, NULL, NULL, NULL);
+ if (select_ret == -1) {
+ if (errno == EINTR) {
+ assert(stopping); // that should have been SIGTERM
+ return;
+ }
err(1, "select() failed");
+ }
if (!FD_ISSET(fd, &read_fds))
errx(1, "select() did not return readable fd = %d", fd);
}
static void* writer_routine(void *arg) {
struct writer_thread* my = arg;
+ struct buf* buf = NULL;
+ lock(&shared_queue_mutex);
for (;;) {
- // FIXME: less locking
- struct buf* buf = NULL;
-
- lock(&shared_queue_mutex);
while (!stopping && STAILQ_EMPTY(&my->queue)) {
// Sleep.
pthread_cond_wait(&shared_wakeup_cond, &shared_queue_mutex);
// Unreference buffer, freeing it if we have to.
lock(&shared_queue_mutex);
unref_buf(buf);
- unlock(&shared_queue_mutex);
}
warnx("thread exiting cleanly");
return NULL;