char buffer[1500];
int sock;
ssize_t size;
+ set<int> fds = {d_nsock4, d_nsock6};
// receive incoming notifications on the nonblocking socket and take them off the list
- while(waitFor2Data(d_nsock4, d_nsock6, 0, 0, &sock) > 0) {
+ while(waitForMultiData(fds, 0, 0, &sock) > 0) {
fromlen=sizeof(from);
size=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr *)&from,&fromlen);
if(size < 0)
return ret;
}
+// returns -1 in case of error, 0 if no data is available, 1 if there is. In the first two cases, errno is set
+int waitForMultiData(const set<int>& fds, const int seconds, const int useconds, int* fd) {
+ set<int> realFDs;
+ for (const auto& fd : fds) {
+ if (fd >= 0 && realFDs.count(fd) == 0) {
+ realFDs.insert(fd);
+ }
+ }
+
+ struct pollfd pfds[realFDs.size()];
+ memset(&pfds[0], 0, realFDs.size()*sizeof(struct pollfd));
+ int ctr = 0;
+ for (const auto& fd : realFDs) {
+ pfds[ctr].fd = fd;
+ pfds[ctr].events = POLLIN;
+ ctr++;
+ }
+
+ int ret;
+ if(seconds >= 0)
+ ret = poll(pfds, realFDs.size(), seconds * 1000 + useconds/1000);
+ else
+ ret = poll(pfds, realFDs.size(), -1);
+ if(ret <= 0)
+ return ret;
+
+ set<int> pollinFDs;
+ ctr = 0;
+ for (const auto& fd : realFDs) {
+ if (pfds[ctr].revents & POLLIN) {
+ pollinFDs.insert(pfds[ctr].fd);
+ }
+ ctr++;
+ }
+ set<int>::const_iterator it(pollinFDs.begin());
+ advance(it, random() % pollinFDs.size());
+ *fd = *it;
+ return 1;
+}
+
// returns -1 in case of error, 0 if no data is available, 1 if there is. In the first two cases, errno is set
int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int*fd)
{
string urlEncode(const string &text);
int waitForData(int fd, int seconds, int useconds=0);
int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int* fd);
+int waitForMultiData(const set<int>& fds, const int seconds, const int useconds, int* fd);
int waitForRWData(int fd, bool waitForRead, int seconds, int useconds, bool* error=nullptr, bool* disconnected=nullptr);
uint16_t getShort(const unsigned char *p);
uint16_t getShort(const char *p);