Thread overview
libevent and exceptions
Mar 22, 2007
e-t172
Mar 23, 2007
rovar
Mar 23, 2007
e-t172
Apr 16, 2007
anupam
Apr 27, 2007
gifford
March 22, 2007
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
March 23, 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

March 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.
April 16, 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
April 27, 2007
I would like to see your c.libevent :)

gifford
<DOT>
hesketh
<AT>
gmail
<DOT>
com