From: Peter Zotov Date: 2012-05-30T06:10:15+09:00 Subject: Re: [C exten] Is it possible to avoid longjmp in exceptions, Thread#kill, exit(), signals? Iñaki Baz Castillo писал 29.05.2012 22:37: > Please forget this for now. I've realized that my call to > rb_protect() > didn't rescue exceptions if they were not StandardError (due to a > check I did in my C code). So I *do* can rescue at C level any kind > of > error/exception, inclouding Interrupt or Exit and act according. > > So please let me work a bit on it and I will comment the result. > > Thanks a lot. > > >> >> My question is: is there any way to avoid the longjmp? or a >> different >> approach: is there any way from my C code to avoid being interrupted >> while I go to Ruby land (by acquiring the GVL)? Let me still answer your question. Exceptions are a mechanism of control flow which is both nonlocal and cannot be represented by procedure calls/returns. The only way to do that in C is longjmp. (In a proper language like Lisp there are also continuations, for example.) Well, technically there is no way to do this in C-as-a-language, and longjmp is a platform-specific and IIRC nonstandard extension (I'm not quite sure, through). So.. if you want exceptions in C, you need longjmp, period. (You can also avoid using system stack, i.e. represent nested Ruby calls by some internal structure, rather the current way where nested Ruby calls map to nested native stack frames, but that will degrade performance significantly.) Thread#kill and exit() both send signals. POSIX threads are a weird kind of processes, hence they can receive signals too, and Thread#kill works that way. Actually, signals are a mechanism of asynchronous prioritized execution of code in a context of another thread, and, surprise, there is no way to do that in C. (Signals are also pretty evil, too, because not only they are asynchronous, but also there is no sane way to synchronize their execution with main control flow, which is the reason 99% of signal handlers are of form "void signal() { flag = 1; }".) So, if you want to deliver asynchronous external events to your program without an explicit event loop (which you will probably need anyway, see above), you need to use signals, period. I don't really think that there is some magical (i.e. nonstandard) way to avoid signal/longjmp-caused interruptions for your code. I would also really discourage you from messing with signals: they're already a big pile of crap, don't add even more compelxity there. Longjmp is, too, but at least it's synchronous. -- WBR, Peter Zotov.