0

My question is I have this chunk of code my timeout works fine so I haven't mentioned all its things. When I call stop() I should get out of the start function. Right now I am getting stuck at my select till my timeout. How should i write to the filedesc from my stop function.

static int filedesc = STDIN_FILENO;
start()
{ fd_set set;
  FD_ZERO(&set);
  FD_SET(filedesc, &set);

  while(something)
  {
      select(FD_SETSIZE, &set, NULL, NULL, timeout);
  } 
  pthread_exit(NULL);
}

stop()
{
    something = FALSE;
    pthread_join(start, NULL);
}
Pyou
  • 13
  • 2
  • Assuming `int something;` or even `atomic bool something`, `something = FALSE;` is not guaranteed to stop `while(something)` from continuing to loop. The compiler can assume that `something` doesn't change value while the loop is running. And [changing to `volatile something` will not make the code correct](https://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming). – Andrew Henle Jul 22 '19 at 21:45
  • Hi Andrew, the something is static global here and it is working as expected as the start() is a pthread and stop is just a normal function. The stop is working for exiting the thread but since the select is not released yet it stalls first then go to while check the something which is false now and then release it. Is there any way to set the value for the descriptor in set so that it doesn't stall there – Pyou Jul 22 '19 at 21:57
  • 2
    Use a pipe to wake up `select()`. Write to one end of the pipe and have `select()` wait on the other end. You can have `select()` wait on your `filedesc` and the pipe at the same time, just put them both into the same `fd_set` – Remy Lebeau Jul 22 '19 at 22:33
  • oh that sounds promising. I haven't used pipe before though. But I can research and try this out. Thanks will let you know soon – Pyou Jul 22 '19 at 23:07
  • 1
    I guess you could can `raise()` some signal. Your select() (any select, sleep, usleep etc. in all threads!) will be interrupted and return with errno EINTR. You can handle that and act accordingly. – KamilCuk Jul 23 '19 at 00:43
  • *it is working as expected* That is not an indicator of correctness. That just means you haven't observed it failing. – Andrew Henle Jul 23 '19 at 16:40

1 Answers1

0

I tried using pipe for my select and I am not sure what I am doing wrong. Since I want to write from another function I am opening a pipe as a global. This is not serving the purpose. Am I using the pipe right?

This is the right code. It works:

 static char* msg1 = "exit";
    static int p[2];

    start()
    { fd_set set;
      pipe(p);
      FD_ZERO(&set);
      FD_SET(p[0], &set);

      while(something)
      {
          select(FD_SETSIZE, &set, NULL, NULL, timeout);
          FD_SET(p[0],&set)
      } 
      pthread_exit(NULL);
    }

    stop()
    {
        something = FALSE;
        write(p[1]),msg1,16);
        pthread_join(start, NULL);
    }
Pyou
  • 13
  • 2
  • You should `write()` to `p[1]` and `FD_SET()/select()` on `p[0]`. Currently both threads are trying to use the same "end" of the pipe, which won't do what you want. – Jeremy Friesner Jul 23 '19 at 20:35
  • Also, put your calls to `FD_ZERO()`, `FD_SET()`, and the setting of the contents of the `timeout` struct inside your `while`-loop, at the top of the loop. They need to be re-initialized before each call to `select()`, since `select()` will modify their contents. – Jeremy Friesner Jul 23 '19 at 20:36
  • Thanks for the feedback Jeremy the p[0] and p[1] was a typing mistake and I got your point for select. I have never used select apart from the timeout. I will try that. – Pyou Jul 23 '19 at 20:45
  • It worked I just had to set the descriptor again within the loop. Thanks guys – Pyou Jul 25 '19 at 22:43