/* * Demo program that shows how to implement a timeout for a * blocking read call. This could be used to detect idle * persistent HTTP connections and close them. * * One thread is blocked in a call to read() on a file descriptor * (here, for example purpose, file descriptor 0 aka stdin. * It could be a socket as well. * * When the timeout occurs (here after the main thread sleeps for * 1 second), the main thread closes the stdin file descriptor * and signals the thread. Subsequently, the signal handler * will be executed by the thread that's blocked in read(). * Since SA_RESTART isn't set, this thread will then return * from read() with EINTR. We detect this condition and let * the thread return. * * Written by Godmar Back for CS 3214 Fall 2010 */ #include #include #include #include #include #include static void * thread_func(void *fd) { char buf[128]; printf("now reading...\n"); int rc = read(0, buf, 128); if (rc == -1 && errno == EINTR) { printf("reading thread was interrupted\n"); } else { printf("read returned %d\n", rc); } return NULL; } /* a signal handler is required */ static void ignore_this_signal(int s) { } int main() { struct sigaction sa = { .sa_handler = ignore_this_signal // do not set SA_RESTART, causing thread to return with EINTR }; int rc = sigaction(SIGUSR1, &sa, NULL); if (rc == -1) perror("sigaction"); pthread_t t; pthread_create(&t, NULL, thread_func, NULL); sleep (1); printf("now closing file descriptor\n"); rc = close(0); if (rc == -1) perror("close"); printf("now signaling thread\n"); rc = pthread_kill(t, SIGUSR1); if (rc == -1) perror("pthread_kill"); printf("signaled thread\n"); rc = pthread_join(t, NULL); if (rc == -1) perror("pthread_join"); return 0; }