I have run into a problem when using the 2.6 kernel and using poll ( I have the problem w/ Fedora Core 5 and not with RedHat 8.0 ).
Despite having 'ulimit -n' and /proc/sys/fs/file-max set very high, say 10000 and 20000 respectively to avoid errno 24 (too many open files), I've made the following observations that seem to be rooted in polling file descriptors set to -1.
1) The poll call will return EINVAL when polling more than 1024 file descriptors and some of the file descriptors are set to -1. This is my problem.
2) The poll call will NOT return EINVAL when polling 1024 file descriptors or less and some of the file descriptors are set to -1.
3) The poll call will NOT return EINVAL when polling more than 1024 file descriptors and all file descriptors are valid.
I am looking for an answer as to why 1) happens and if there is something I can do about it. I don't want to change my code to avoid using -1 in poll calls, using -1 in poll calls is allowed.
Here is a program that exemplifies the problem.
Cut and past and compile as follows 'g++ ./test1.cpp -o test1'.
The program takes an optional command line parameter that is the number of file descriptors to test poll with. The default is 1024.
The program needs file, ./test_file, to exist in the directory where the program is executed. Do 'touch ./test_file' before running this program.
This problem has driven me crazy and far too 'wordy' as you can tell from this long post.
Thanks,
mallport
----here is the test program ---------------
Code:
#include <unistd.h>
#include <iostream.h>
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int main(const int argc, const char** argv) {
bool DoPoll = true;
int NumFds = 1024;
struct pollfd* pPollFds;
int RetVal;
bool UseOther = false;
if( (argc > 1) ) {
NumFds = atoi(argv[1]);
cout << "using input number of fds " << NumFds << endl;
} else {
cout << "using number of fds " << NumFds << endl;
}
try {
pPollFds = new struct pollfd[NumFds];
} catch(...) {
cout << "caught exception making pollfds, exiting" << endl;
exit(1);
}
memset(reinterpret_cast<void*>(pPollFds), -1, (NumFds * (sizeof(struct pollfd))));
for(int i = 0; i < NumFds; i++) {
UseOther = !UseOther;
//
// add some 'unitialized' file descriptors
//
if( (UseOther) ) {
pPollFds[i].fd = -1;
} else {
//
// generate a valide file descriptor by opening test_file
//
pPollFds[i].fd = open("./test_file", O_RDONLY);
if( (-1 == pPollFds[i].fd) ) {
cout << "open failed, i is " << i
<< " errno is " << errno << " \"" << strerror(errno) << "\" " << endl;
DoPoll = false;
break;
}
}
pPollFds[i].events = POLLIN;
}
if( (DoPoll) ) {
cout << "polling ..." << endl;
RetVal = poll(pPollFds, NumFds, 5000);
if( (-1 == RetVal) ) {
cout << "poll failed, errno is " << errno << " \"" << strerror(errno) << "\" " << endl;
} else {
cout << "poll worked" << endl;
}
} else {
cout << "Not doing poll" << endl;
}
for(int i = 0; i < NumFds; i++) {
close(pPollFds[i].fd);
}
delete [] pPollFds;
return(0);
}
--------------------------------------------