title: Linux Socket file descriptor with threads
body: <p>consider following situation: One thread (lets call it A) initialises, sets socket state with <code>listen()</code> and then wait with <code>accept()</code>. Connection arrives to A socket, <code>accept()</code> returns valid fd. New thread (B) is created (using <code>std::thread</code>), and acquired fd is passed to a callable object witch runs in thread B. Reading (using <code>read()</code>) for fd fails and <code>errno</code> is set to <code>9 EBADFD</code>. Thread A calls <code>join()</code> on B. When B is not spawned and fd is used (still via same callable object) read completes without failure. Why? Below is some code to illustrate this situation.</p>
  
  <pre><code>BaseFun::BaseFun(char* bufferAdr, int socket):
      socket_fd(socket)
      buffer(bufferAdr)
  {}
  
  BaseFun::~BaseFun()
  {
      close(socket_fd);
  }
  
  char* BaseFun::buffer_read()
  {
      if(read(socket_fd, buffer, BUFF_SIZE-1) &lt; 0) {
          std::cout&lt;&lt;"ERROR while READ\n"&lt;&lt;"ERRNO: "&lt;&lt;errno&lt;&lt;"\n"&lt;&lt;"FD: "&lt;&lt;socket_fd&lt;&lt;"\n";
      }
      return buffer;
  }
  
  DisplayMsgFun::DisplayMsgFun(char* buffer, int socket) :
      BaseFun(buffer, socket)
  {}
  
  void DisplayMsgFunFun::operator()()
  {
      std::cout&lt;&lt;"Message:\n\t"&lt;&lt;buffer_read()&lt;&lt;"\nEND\n";
  }
  </code></pre>
  
  <p>Snippet where above is called: </p>
  
  <pre><code>void Server::server_run()
  {
      sockaddr_in client_addr;
      socklen_t c_len = sizeof(client_addr);
  
      client_fd = accept(sock_fd, (sockaddr*)&amp;client_addr, &amp;c_len);
      DisplayMsgFun dm(server_buffers-&gt;front().data(), client_fd);
      std::thread job(dm);
      job.join();
  }
  </code></pre>
  
  <p>And <code>main()</code></p>
  
  <pre><code>int main()
  {
      Server srv(PORT);
      if (srv.server_create()) {
          std::cout &lt;&lt; "Server bind!\n";
          srv.server_run();
      }
      else {
          std::cout &lt;&lt; "Bind fail! ERRNO: "&lt;&lt;errno&lt;&lt;"\n";
          return -1;
      }
      return 0;
  }
  </code></pre>