[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-panel-devel
Subject:    Re: Threading in Plasma applets
From:       "Richard Dale" <richard.j.dale () gmail ! com>
Date:       2008-04-07 13:30:03
Message-ID: 491684420804070630o2f383fdfudc9e4e151c964d82 () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


On Mon, Apr 7, 2008 at 12:38 PM, Richard Dale <richard.j.dale@gmail.com>
wrote:

>
>
> On Mon, Apr 7, 2008 at 11:23 AM, Richard Dale <richard.j.dale@gmail.com>
> wrote:
>
>
> > Although it made the STACK_LEVEL_MAX figure bigger (15987856 in the
> > above example), it didn't make any difference. I wonder if Ruby is getting
> > the stack direction wrong, I've no idea - so I'll do a bit of googling and
> > investigate further.
> >
> Doh! The problem isn't that Ruby is going off the end of the stack, it's
> that it is dropping below where it believes the stack started. So if I make
> the stack huge it doesn't have any effect on this underflow. When a ruby
> plasma plugin is loaded the RUBY_INIT_STACK macro will assume that the stack
> starts where it happens to be for the plugin loader code. It really needs to
> be run in main() though as that is where the real root of the stack. One way
> to work round this is to call RUBY_INIT_STACK at every entry point to the
> Ruby code (eg virtual method callbacks, and slot invocations). But make sure
> it is only called once if a virtual method calls another virtual method for
> instance by incrementing and decrementing a global 'nested_calls' count.
> Swig uses a couple of macros to do that:
>
> /*
>   If your swig extension is to be run within an embedded ruby and has
>   director callbacks, you should set -DRUBY_EMBEDDED during compilation.
>   This will reset ruby's stack frame on each entry point from the main
>   program the first time a virtual director function is invoked (in a
>   non-recursive way).
>   If this is not done, you run the risk of Ruby trashing the stack.
> */
>
> #ifdef RUBY_EMBEDDED
>
> #  define SWIG_INIT_STACK                            \
>       if ( !swig_virtual_calls ) { RUBY_INIT_STACK } \
>       ++swig_virtual_calls;
> #  define SWIG_RELEASE_STACK --swig_virtual_calls;
> #  define Ruby_DirectorTypeMismatchException(x) \
>           rb_raise( rb_eTypeError, x ); return c_result;
>
>       static unsigned int swig_virtual_calls = 0;
>
> #else  /* normal non-embedded extension */
>
> #  define SWIG_INIT_STACK
> #  define SWIG_RELEASE_STACK
> #  define Ruby_DirectorTypeMismatchException(x) \
>           throw Swig::DirectorTypeMismatchException( x );
>
> #endif  /* RUBY_EMBEDDED *
>
>  Another way might be to provide a longjmp target in the Plasma main()
> function that the Ruby extension code could jump to and then call
> RUBY_INIT_STACK there.
>
> Another way would be to always assume that Plasma will load Ruby code, and
> introduce a link time dependency and just call RUBY_INIT_STACK/ruby_init()
> in the main(), but I don't think that is very elegant.
>

I've just commited a fix based on the SWIG macros and it all works very well
now - phew!

-- Richard

[Attachment #5 (text/html)]

<br><br><div class="gmail_quote">On Mon, Apr 7, 2008 at 12:38 PM, Richard Dale &lt;<a \
href="mailto:richard.j.dale@gmail.com">richard.j.dale@gmail.com</a>&gt; wrote:<br><blockquote \
class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt \
0.8ex; padding-left: 1ex;"> <br><br><div class="gmail_quote"><div class="Ih2E3d">On Mon, Apr 7, \
2008 at 11:23 AM, Richard Dale &lt;<a href="mailto:richard.j.dale@gmail.com" \
target="_blank">richard.j.dale@gmail.com</a>&gt; wrote:<br><br><blockquote class="gmail_quote" \
style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: \
1ex;">

<div class="gmail_quote"><div><br>Although it made the STACK_LEVEL_MAX figure bigger (15987856 \
in the above example), it didn&#39;t make any difference. I wonder if Ruby is getting the stack \
direction wrong, I&#39;ve no idea - so I&#39;ll do a bit of googling and investigate \
further.<br>


</div></div></blockquote></div><div>Doh! The problem isn&#39;t that Ruby is going off the end \
of the stack, it&#39;s that it is dropping below where it believes the stack started. So if I \
make the stack huge it doesn&#39;t have any effect on this underflow. When a ruby plasma plugin \
is loaded the RUBY_INIT_STACK macro will assume that the stack starts where it happens to be \
for the plugin loader code. It really needs to be run in main() though as that is where the \
real root of the stack. One way to work round this is to call RUBY_INIT_STACK at every entry \
point to the Ruby code (eg virtual method callbacks, and slot invocations). But make sure it is \
only called once if a virtual method calls another virtual method for instance by incrementing \
and decrementing a global &#39;nested_calls&#39; count. Swig uses a couple of macros to do \
that:<br>

<br>/*<br>&nbsp; If your swig extension is to be run within an embedded ruby and has<br>&nbsp; \
director callbacks, you should set -DRUBY_EMBEDDED during compilation.&nbsp; <br>&nbsp; This \
will reset ruby&#39;s stack frame on each entry point from the main <br>

&nbsp; program the first time a virtual director function is invoked (in a <br>&nbsp; \
non-recursive way).<br>&nbsp; If this is not done, you run the risk of Ruby trashing the \
stack.<br>*/<br><br>#ifdef RUBY_EMBEDDED<br><br>#&nbsp; define \
SWIG_INIT_STACK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb \
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( !swig_virtual_calls ) { RUBY_INIT_STACK } \
\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++swig_virtual_calls;<br>#&nbsp; define SWIG_RELEASE_STACK \
--swig_virtual_calls;<br>#&nbsp; define Ruby_DirectorTypeMismatchException(x) \
\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rb_raise( rb_eTypeError, x ); \
return c_result;<br>

<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static unsigned int swig_virtual_calls = \
0;<br><br>#else&nbsp; /* normal non-embedded extension */<br><br>#&nbsp; define \
SWIG_INIT_STACK<br>#&nbsp; define SWIG_RELEASE_STACK<br>#&nbsp; define \
Ruby_DirectorTypeMismatchException(x) \<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw \
Swig::DirectorTypeMismatchException( x );<br><br>#endif&nbsp; /* RUBY_EMBEDDED \
*<br><br>&nbsp;Another way might be to provide a longjmp target in the Plasma main() function \
that the Ruby extension code could jump to and then call RUBY_INIT_STACK there. <br>

<br>Another way would be to always assume that Plasma will load Ruby code, and introduce a link \
time dependency and just call RUBY_INIT_STACK/ruby_init() in the main(), but I don&#39;t think \
that is very elegant.</div></div> </blockquote><div><br>I&#39;ve just commited a fix based on \
the SWIG macros and it all works very well now - phew!<br><br>-- \
Richard<br>&nbsp;<br></div></div><br>



_______________________________________________
Panel-devel mailing list
Panel-devel@kde.org
https://mail.kde.org/mailman/listinfo/panel-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic