I have two calls of event_wait.
Thread 1: Listening pipes from child processes
struct epoll_event *ev;
struct EpollStub stub[pool->plugins.count];
...
epollfd = epoll_create1(0);
if (epollfd == -1) {
return -1;
}
ev->events = EPOLLIN;
for(int i=0;i<plugins->count;i++) {
inf = &plugins->stp[i];
stub[i].type = EREAD_STAP;
stub[i].pointer = inf;
ev->data.ptr = stub+i;
if (epoll_ctl(pool->epollfd, EPOLL_CTL_ADD, inf->fd, ev) == -1) {
close(epollfd);
return -1;
}
}
do {
n = epoll_wait(pool->epollfd, evs, EPOLL_EVENTS_MAX, -1);
for(int i=0;i<n;i++) {
ev = evs + i;
struct EpollStub *stub = (struct EpollStub *)ev->data.ptr;
if(stub->type!=EREAD_STAP) {
#ifdef __MDEBUG
printf("EREAD: Wrong event: %d\n",stub->type);
#endif
continue;
}
else {
// inf = (struct StpInfo*)ev->data.ptr;
inf = (struct StpInfo*)stub->pointer;
fd = inf->fd;
#ifdef __MDEBUG
printf("EREAD fd: %d\n",fd);
#endif
///do something here
}
....
Thread 2: Listening clients sockets
struct epoll_event ev;
pool->epollfd = epoll_create1(0);
if (pool->epollfd == -1) {
return -1;
}
ev.events = EPOLLIN;
for(int i=0;i<pool->sockets.count;i++) {
struct EpollStub *stub = &pool->sockets.stub[i];
stub->type = EACCEPT_CONN;
stub->pointer = pool->sockets.fd[i];
ev.data.ptr = stub;
if (epoll_ctl(pool->epollfd, EPOLL_CTL_ADD, (int)stub->pointer, &ev) = -1) {
return -1;
}
}
...
cfd = epoll_wait(pool->epollfd, &ev, 1, -1);
if(is_working(pool,cfd)) {
struct EpollStub *stub = (struct EpollStub *)ev.data.ptr;
if(stub->type!=EACCEPT_CONN) {
#ifdef __MDEBUG
printf("EACCEPT: Wrong event: %d\n",stub->type);
#endif
}
else {
#ifdef __MDEBUG
printf("EACCEPT fd: %d\n",(int)stub->pointer);
#endif
break;
///do something here
}
}
....
kernel: opensuse-3.1.0-1.2-desktop
They get events from each other. I made EpollStub just to be shure that they get. Without this first event returns a pointer second a handle, and the result is a segmentation fault when recieve descriptor and use it as a pointer.
I do not think this is normal behavior. This is a bug in the kernel or where am I wrong?
It’s a bug in your code. You have confused
pool->epollfdwithepollfdin a few places, for example:You create
epollfd, but then modifypool->epollfdand wait on that. If you have two different event sets, you need to use the two different epoll fds.The epoll mechanism is completely thread-agnostic. It doesn’t bind events or sets to threads. Any thread can add or remove a descriptor to or from a set. Any thread can get events for any set.