Closing a file descriptor that is running

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");
    // comment out the next line to not forcefully interrupt
    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;

}
+3
source share
1 answer

For Linux, at least it seems risky. The manual page for closewarns:

It is probably unreasonable to close file descriptors while they may be in using system calls in other threads in the same process. Because the file descriptor can be reused, there are some obscure race conditions that can cause unintended side effects.

Linux, :

  • eventfd
  • eventfd ( ), fd
  • , eventfd, fd poll

signal errno == EINTR, poll. fd, .


Linux, epoll , poll.

+3

All Articles