digitalmars.D.learn - libevent and exceptions
When using the C libevent library (http://www.monkey.org/~provos/libevent/), i can't throw any exceptions from inside an event callback (trying to do so results in a segmentation fault). Example : import std.stdio; import std.math; import std.date : TicksPerSecond; import c.libevent; // C bindings, if you want to see them just tell me void main() { auto base = event_init(); auto event = new event; event_set(event, -1, EV_TIMEOUT, &foo, null); int time = 3 * TicksPerSecond; auto tv = new timeval; tv.tv_sec = cast(int) floor(time / TicksPerSecond); tv.tv_usec = cast(int) ceil((time / TicksPerSecond) * 1000000); event_add(event, tv); event_base_loop(base, 0); } extern(C) void foo(int fd, short type, void* arg) { writefln("Boo."); throw new Exception("Booboo."); } Result : $ dmd excptest.d c/libevent.d -L-levent -L-L/usr/local/libevent/lib gcc excptest.o libevent.o -o excptest -m32 -lphobos -lpthread -lm -Xlinker -levent -Xlinker -L/usr/local/libevent/lib -Xlinker -L/usr/local/dmd/lib $ ./excptest Boo. Segmentation fault Any ideas how to make this work ? e-t172
Mar 22 2007
C does not know how to handle exceptions. It rightfully should segfault (or abort suddenly). You're basically telling it to unwind its stack suddenly and it doesn't know how to handle it. Same as with c++ functions called by C. The proper approach is to return error values to the caller. I'm not familiar with libevent, but most callback frameworks offer some sort of cancellation due to an error return. If you must throw an exception.. throw it in a pure D function and have it wrapped by an extern C function in D, but ensure that that extern C function only returns an error. due to the caught exception. e-t172 Wrote:When using the C libevent library (http://www.monkey.org/~provos/libevent/), i can't throw any exceptions from inside an event callback (trying to do so results in a segmentation fault). Example : import std.stdio; import std.math; import std.date : TicksPerSecond; import c.libevent; // C bindings, if you want to see them just tell me void main() { auto base = event_init(); auto event = new event; event_set(event, -1, EV_TIMEOUT, &foo, null); int time = 3 * TicksPerSecond; auto tv = new timeval; tv.tv_sec = cast(int) floor(time / TicksPerSecond); tv.tv_usec = cast(int) ceil((time / TicksPerSecond) * 1000000); event_add(event, tv); event_base_loop(base, 0); } extern(C) void foo(int fd, short type, void* arg) { writefln("Boo."); throw new Exception("Booboo."); } Result : $ dmd excptest.d c/libevent.d -L-levent -L-L/usr/local/libevent/lib gcc excptest.o libevent.o -o excptest -m32 -lphobos -lpthread -lm -Xlinker -levent -Xlinker -L/usr/local/libevent/lib -Xlinker -L/usr/local/dmd/lib $ ./excptest Boo. Segmentation fault Any ideas how to make this work ? e-t172
Mar 23 2007
rovar a écrit :If you must throw an exception.. throw it in a pure D function and have it wrapped by an extern C function in D, but ensure that that extern C function only returns an error. due to the caught exception.All right. Thanks.
Mar 23 2007
e-t172 Wrote:import c.libevent; // C bindings, if you want to see them just tell me<snip> can you please post it here or to my mail address (if you feel that is more appropriate) ? thank you anupam
Apr 16 2007
I would like to see your c.libevent :) gifford <DOT> hesketh <AT> gmail <DOT> com
Apr 27 2007