www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - libevent and exceptions

reply e-t172 <idontlikespam nospam.com> writes:
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
next sibling parent reply rovar <rick.richardson gmail.com> writes:
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
parent e-t172 <idontlikespam nospam.com> writes:
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
prev sibling next sibling parent anupam <anupam.kapoor gmail.com> writes:
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
prev sibling parent gifford <gifford.hesketh gmail.com> writes:
I would like to see your c.libevent :)

gifford
<DOT>
hesketh
<AT>
gmail
<DOT>
com
Apr 27 2007