If I have two threads (Linux, NPTL), and I have one thread that processes one or more file descriptors and the other closes one of them, is this a sensible action? Am I doing what I should not do in the MT environment?
The main reason I think this is because I donβt necessarily want to talk to the polling stream, interrupt it, etc., instead, I would just close the descriptor for some reason, and when the polling stream I I wake up, I expect that the revents will contain POLLNVAL, which will be evidence that the file descriptor should just be thrown away by the thread before the next poll.
I put together a simple test that shows that POLLNVAL is exactly what will happen. However, in this case, POLLNVAL is set only after the timeout expires, closing the socket does not seem to return poll (). If this happens, I can kill the thread to return to poll ().
#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <poll.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
static pthread_t main_thread;
void * close_some(void*a) {
printf("thread #2 (%d) is sleeping\n", getpid());
sleep(2);
close(0);
printf("socket closed\n");
pthread_kill(main_thread, SIGUSR1);
return 0;
}
void on_sig(int s) {
printf("signal recieved\n");
}
int main(int argc, char ** argv) {
pthread_t two;
struct pollfd pfd;
int rc;
struct sigaction act;
act.sa_handler = on_sig;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGUSR1, &act, 0);
main_thread = pthread_self();
pthread_create(&two, 0, close_some, 0);
pfd.fd = 0;
pfd.events = POLLIN | POLLRDHUP;
printf("thread 0 (%d) polling\n", getpid());
rc = poll(&pfd, 1, 7000);
if (rc < 0) {
printf("error : %s\n", strerror(errno));
} else if (!rc) {
printf("time out!\n");
} else {
printf("revents = %x\n", pfd.revents);
}
return 0;
}
source
share