user2716363
user2716363

Reputation:

poll(2) does not return when there is data ready

I am attempting to write a socket abstraction in C++. I am using the poll() system call to wait for data to become ready for reading. However, when I run my program, poll() never returns if I have it set to indefinitely poll, even if I send the socket data.

Here is a simple program to illustrate my problem. I am compiling it on OSX with this line: clang++ -g -Wall -pedantic -std=c++0x -stdlib=libc++ pollTest.cpp -o pollTest. I am using the nc program to set up a listening socket for the program to connect to. When I run this, the poll() call hangs forever, never returning due to data being ready to read.

#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <unistd.h>
#include <poll.h>
#include <fcntl.h>
#include <cstdlib>
#include <iostream>

void connectSocket(int& fd, std::string hostname, std::string service) {
  struct addrinfo hints, *res, *res0;
  int error;
  int s;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_STREAM;
  error = getaddrinfo(hostname.c_str(), service.c_str(), &hints, &res0);
  if (error) {
    throw error;
  }
  s = -1;
  for (res = res0; res; res = res->ai_next) {
    s = socket(res->ai_family, res->ai_socktype,
                res->ai_protocol);
    if (s < 0) {
      continue;
    }

    if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
      close(s);
      s = -1;
      continue;
    }

    break;  /* okay we got one */
  }

  if (s < 0) {
    throw s;
  }
}

int main() {
  int socketFileDescriptor = -1;
    connectSocket(socketFileDescriptor, "localhost", "9999");

  pollfd socketPolls[1];
  socketPolls[0].fd = socketFileDescriptor;
  socketPolls[0].events = POLLIN | POLLPRI | POLLRDBAND | POLLRDNORM;
  poll(socketPolls, 1, -1);
  std::cerr << socketPolls[0].revents;
}

Any ideas on why this is happening? I feel as if I have read the documentation well, and am using the system calls correctly. (I didn't do error checking in this example program, but I do in my project). Any help would be appreciated!

Upvotes: 2

Views: 1217

Answers (1)

icktoofay
icktoofay

Reputation: 129139

In connectSocket, you never set fd to anything, so in main, socketFileDescriptor remains -1 and poll won't find any data on the socket. You probably meant to unify s and fd. That said, I think you'd be better off returning the file descriptor rather than using a reference.

Upvotes: 5

Related Questions