User data of epoll event is reported abnormally by epoll_wait.

blake kim via Digitalmars-d digitalmars-d at puremagic.com
Tue Aug 19 23:11:41 PDT 2014


I am a newbie on D and studying interfacing to C API.

I found abnormal work of epoll_wait.

I stored an arbitrary 64bit number to u64 of epoll_event and 
registered the event with valid fd using epoll_ctl.

When the fd is activated on EPOLLIN, I found u64 value is not 
normal.

epoll has lost the high 4 bytes and just report low 4 bytes.
For example,

import core.sys.linux.epoll;
...
epoll_event event;
event.events = EPOLLIN;
event.u64 = 0x1122334455667788;
epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);
...
int nfd = epoll_wait(...,&epollevent,...)
...
assert(epollevent.u64==0x1122334455667788); // ==> u64 value is 
55667788

In my investigation, this problem appears by memory align 
mismatch.

In C, sizeof(epoll_event) is 12 but D tells this is 
16.(epoll_event.sizeof)

I wonder why there is this difference between C and D in default 
align.

I got the normal result by modifying epoll_event as follows 
manually.

struct epoll_event {
align(4):
     uint events;
     epoll_data_t data;
}


But I don't think this is right. Many C APIs need structure as 
argument and adjusting align each structure doesn't make sense.

Is this problem a Bug of D ?

I tested this problem on ubuntu 64bit and full example source as 
follows.

-----------------------------------------------------------------------
import std.stdio;
import core.sys.linux.epoll;
import core.sys.posix.unistd;
import std.conv;
import core.thread;

enum  {
     EFD_SEMAPHORE = octal!1,
     EFD_CLOEXEC = octal!2000000,
     EFD_NONBLOCK = octal!4000
}
extern(C) int eventfd(uint initval, int flags);

void testepoll() {
	
	class MyThr: Thread {
		int msgfd;
		this() {
			super(&thread_proc);
			
		}
		
		void thread_proc() {
			int efd = epoll_create(10);
			int fd = eventfd(0, EFD_NONBLOCK);
			msgfd =fd;
			
			epoll_event event;
			event.events = EPOLLIN;
			event.data.u64 = 0x1122334455667788;
			epoll_ctl(efd, EPOLL_CTL_ADD, fd, &event);
			
			ulong val=1;
			core.sys.posix.unistd.write(msgfd, &val, 8);
			
			int nfd;
			epoll_event pollevent;
			for(;;) {
				nfd = epoll_wait(efd, &pollevent, 1, -1);
				if(nfd>0) {
					ulong d = pollevent.data.u64;
					writefln("user, %0x", d); // -> print out is 55667788, high 
4 bytes(0x11223344) is lost !!!
					break;
					
				}
			}
			
		}
	}
	
	auto thr = new MyThr();
	thr.start();
	thr.join();
}

void main() {
	testepoll();
}
---------------------------------------------------------------------------------


More information about the Digitalmars-d mailing list