#include #include #include #include #include #include "sockettome.h" /* I've made this #define so that you can test it on smaller intervals. */ #define TIME (3600) /* Global variables: The buffer and the mutex. */ char BUFFER[501]; pthread_mutex_t lock; /* The sigpipe handler simply re-registers itself as a signal handler, and then ignores SIGPIPE. The standard I/O library will catch closed socket connections. */ void sigpipe_handler(int dummy) { signal(SIGPIPE, sigpipe_handler); return; } /* The idea thread opens MBI.txt, and then reads a line from it using fgets every TIME seconds. It protects the fgets call with a mutex so that there are no race conditions. It exits when MBI.txt has nothing else to read. */ void *idea(void *arg) { FILE *f; f = fopen("MBI.txt", "r"); if (f == NULL) { perror("MBI.txt"); exit(1); } while (1) { pthread_mutex_lock(&lock); if (fgets(BUFFER, 500, f) == NULL) { pthread_mutex_unlock(&lock); return NULL; } pthread_mutex_unlock(&lock); sleep(TIME); } } /* The connection thread assumes that it is passed a FILE *, which has been created by the main thread using fdopen() on a socket connection. Every TIME seconds it copies BUFFER to a local buffer, and then tries to write it to the socket connection. If either fputs() or fflush() report an error, then the thread exits gracefully. Each thread uses its own buffer so that it is not holding the mutex during the write to the socket. */ void *connection(void *arg) { FILE *f; char buffer[501]; f = (FILE *) arg; while (1) { pthread_mutex_lock(&lock); strcpy(buffer, BUFFER); pthread_mutex_unlock(&lock); if (fputs(buffer, f) == EOF) { fclose(f); return NULL; } if (fflush(f) == EOF) { fclose(f); return NULL; } sleep(TIME); } } /* Finally, the main thread sets up the socket and the mutex, and it creates the idea thread. Then it accepts socket connections, creating FILE *'s for each connection using fdopen(), and then creating a thread to handle the connection. It calls pthread_detach() so that when a thread dies, its state is cleaned up. */ int main() { int s, fd; FILE *f; pthread_t tid; signal(SIGPIPE, sigpipe_handler); s = serve_socket(30602); pthread_mutex_init(&lock, NULL); pthread_create(&tid, NULL, idea, NULL); pthread_detach(tid); while (1) { fd = accept_connection(s); f = fdopen(fd, "w"); pthread_create(&tid, NULL, connection, (void *) f); pthread_detach(tid); } }