[#395238] rubygem: ispunity (unite all your internet connections) — Arun Tomar <tomar.arun@...>

Dear friends,

12 messages 2012/05/01

[#395250] Overwriting one Ruby array or arrays with another — Craig Law <lists@...>

Hi

14 messages 2012/05/02

[#395258] array of strings - finding letter combinations — "Sebastjan H." <lists@...>

Hi All,

16 messages 2012/05/02

[#395357] Why Enumerator#next does not return more than one value? — Földes László <lists@...>

If I have an Enumerator which yields elements of a mathematical series

10 messages 2012/05/07

[#395373] How to use Data_Wrap_Struct to assign the DATA VALUE to an exsiting Ruby object? — Iñaki Baz Castillo <ibc@...>

Hi, my code receives an arbitrary klass name (provided by the user)

8 messages 2012/05/07

[#395429] passing via instance variable or regular () — sam jam <lists@...>

def first

10 messages 2012/05/10

[#395463] I'm looking for a Metaprogramming Project — Phil Stone <lists@...>

Hello,

19 messages 2012/05/11

[#395548] A million reasons why Encoding was a mistake — Marc Heiler <lists@...>

Newcomer wants to try Ruby.

15 messages 2012/05/15
[#395561] Re: A million reasons why Encoding was a mistake — Ryan Davis <ryand-ruby@...> 2012/05/15

[#395595] Re: A million reasons why Encoding was a mistake — Brian Candler <lists@...> 2012/05/16

I will add that the OP is not entirely alone in his opinion.

[#395551] How to ensure that a block runs entirely after other threads? (Thread.exclusive does not "work") — Iñaki Baz Castillo <ibc@...>

Hi, I expected that in the following example code, thread t1 would not

8 messages 2012/05/15

[#395575] GUI with ruby on windows — David Acosta <lists@...>

hello friends, i am a begginer and i have a litlle question, how can i

17 messages 2012/05/16

[#395604] what is going wrong here? — roob noob <lists@...>

Notice the initialization of both classes in each of the examples, if

20 messages 2012/05/16

[#395646] rb_gc_register_address() or rb_gc_mark()? — Iñaki Baz Castillo <ibc@...>

Hi, I've bad experiences with rb_gc_register_address(), it does never

16 messages 2012/05/17

[#395686] reading from and writing to a Unicode encoded file — "Sebastjan H." <lists@...>

Hi,

19 messages 2012/05/18
[#395694] Re: reading from and writing to a Unicode encoded file — Regis d'Aubarede <lists@...> 2012/05/18

Hello,

[#395697] Re: reading from and writing to a Unicode encoded file — "Sebastjan H." <lists@...> 2012/05/18

Regis d'Aubarede wrote in post #1061272:

[#395698] Re: reading from and writing to a Unicode encoded file — Regis d'Aubarede <lists@...> 2012/05/18

Sebastjan H. wrote in post #1061276:

[#395699] Re: reading from and writing to a Unicode encoded file — "Sebastjan H." <lists@...> 2012/05/18

Regis d'Aubarede wrote in post #1061277:

[#395750] Re: reading from and writing to a Unicode encoded file - issues when using Shoes — "Sebastjan H." <lists@...> 2012/05/21

Hi,

[#395754] Re: reading from and writing to a Unicode encoded file - issues when using Shoes — "Sebastjan H." <lists@...> 2012/05/21

Sebastjan H. wrote in post #1061483:

[#395740] ? Ruby through CGI and Rails — Shaun Lloyd <list@...>

Hi everybody,

22 messages 2012/05/21
[#395764] Re: Ruby through CGI and Rails — Brian Candler <lists@...> 2012/05/21

Shaun Lloyd wrote in post #1061455:

[#395786] Re: Ruby through CGI and Rails — Shaun Lloyd <list@...> 2012/05/22

On 22/05/12 03:37, Brian Candler wrote:

[#395838] Re: Ruby through CGI and Rails — Brian Candler <lists@...> 2012/05/23

Shaun Lloyd wrote in post #1061602:

[#395787] Changing self class from inside a method?? — David Madison <lists@...>

Let's start off with the assumption I want a method that allows an

10 messages 2012/05/22

[#395841] Memory-efficient set of Fixnums — George Dupre <lists@...>

Hi,

25 messages 2012/05/23

[#395883] looking for a ruby idiom : r=foo; return r if r — botp <botpena@...>

Hi All,

11 messages 2012/05/24

[#395966] Am I justified to use a global variable if it must be used in all scopes? — Phil Stone <lists@...>

Hello,

12 messages 2012/05/27

[#396010] does this leak more than the size of the string via timing side channels — rooby shoez <lists@...>

string1 = "string"

16 messages 2012/05/29

[#396038] Is it possible to avoid longjmp in exceptions, Thread#kill, exit(), signals? — Iñaki Baz Castillo <ibc@...>

Hi, my Ruby C extension runs a C loop (libuv) without GVL. At some

8 messages 2012/05/29

Re: [C exten] Is it possible to avoid longjmp in exceptions, Thread#kill, exit(), signals?

From: Iñaki Baz Castillo <ibc@...>
Date: 2012-05-30 11:26:10 UTC
List: ruby-talk #396048
2012/5/29 Peter Zotov <whitequark@whitequark.org>:
> Exceptions are a mechanism of control flow which is both nonlocal and can=
not
> be represented by procedure calls/returns. The only way to do that in C i=
s
> longjmp. (In a proper language like Lisp there are also continuations, fo=
r
> example.)
> Well, technically there is no way to do this in C-as-a-language, and long=
jmp
> 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 intern=
al
> 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 o=
f
> 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 =3D 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.


Hi Peter, thanks a lot for your explanation. It's clear and I think I
found the way to go:

My C exten runs a libuv (https://github.com/joyent/libuv/) C loop
without GVL and when an event occurs (data received, timer fires...)
it acquires the GVL and executes the user provider Ruby callback in
Ruby land. In this trip from C to Ruby it could occur that, when Ruby
takes the control, it decides to generate a SystemExit or whatever
interruption (due to a non-trapped signal, exit() command or
whatever). If I set a rescue/ensure after my Ruby blocking function
(which started the libuv loop) then libuv gets broken due the longjmp
and I cannot recover it.

So the solution has been to use rb_protect() when executing the Ruby
callback and catch ***any*** kind of exception:



------------------------------------------------
static
VALUE execute_function_with_glv_and_rb_protect(function_with_gvl_and_protec=
t
function)
{
  int exception_tag =3D 0;
  VALUE ret;

  ret =3D rb_protect(function, Qnil, &exception_tag);

  // If an exception occurred then call to handle_exception() method.
  if (exception_tag) {
    VALUE exception =3D rb_errinfo();

    // Dissable the current thread exception.
    rb_set_errinfo(Qnil);
    // Call AsyncEngine.handle_exception().
    rb_funcall2(mAsyncEngine, method_handle_exception, 1, &exception);

    return exception;
  }
  // Otherwise just return the VALUE returned by rb_protec() above.
  else
    return ret;
}


/*
 * Executes the given function taking the GVL and using rb_protect().
 */
VALUE ae_execute_in_ruby_land(function_with_gvl_and_protect function)
{
  AE_TRACE();

  return rb_thread_call_with_gvl(execute_function_with_glv_and_rb_protect,
function);
}
-------------------------------------------



So when a libuv C callback is called, I call within it to
ae_execute_in_ruby_land(some_C_function). If an exception has occurred
during the trip to Ruby I call to my handle_exception() Ruby method by
passing the exception. It decides whether to absorb it ot store it in
@_exit_exception and properly release/stop the libuv loop, so after it
ends the @_exit_exception will be raised.

It seems to work ok. So basically I've avoided the longjmp *while* my
C libuv loop is running.


Really thanks a lot for your explanation and help.




--=20
I=C3=B1aki Baz Castillo
<ibc@aliax.net>

In This Thread