[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 <<a \
href="mailto:richard.j.dale@gmail.com">richard.j.dale@gmail.com</a>> 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 <<a href="mailto:richard.j.dale@gmail.com" \
target="_blank">richard.j.dale@gmail.com</a>> 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'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.<br>
</div></div></blockquote></div><div>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:<br>
<br>/*<br> If your swig extension is to be run within an embedded ruby and has<br> \
director callbacks, you should set -DRUBY_EMBEDDED during compilation. <br> This \
will reset ruby's stack frame on each entry point from the main <br>
program the first time a virtual director function is invoked (in a <br> \
non-recursive way).<br> If this is not done, you run the risk of Ruby trashing the \
stack.<br>*/<br><br>#ifdef RUBY_EMBEDDED<br><br># define \
SWIG_INIT_STACK &nb \
sp; \<br>
if ( !swig_virtual_calls ) { RUBY_INIT_STACK } \
\<br> ++swig_virtual_calls;<br># define SWIG_RELEASE_STACK \
--swig_virtual_calls;<br># define Ruby_DirectorTypeMismatchException(x) \
\<br> rb_raise( rb_eTypeError, x ); \
return c_result;<br>
<br> static unsigned int swig_virtual_calls = \
0;<br><br>#else /* normal non-embedded extension */<br><br># define \
SWIG_INIT_STACK<br># define SWIG_RELEASE_STACK<br># define \
Ruby_DirectorTypeMismatchException(x) \<br>
throw \
Swig::DirectorTypeMismatchException( x );<br><br>#endif /* RUBY_EMBEDDED \
*<br><br> 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't think \
that is very elegant.</div></div> </blockquote><div><br>I've just commited a fix based on \
the SWIG macros and it all works very well now - phew!<br><br>-- \
Richard<br> <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