Threading in Plasma applets

Richard Dale richard.j.dale at gmail.com
Mon Apr 7 15:30:03 CEST 2008


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

>
>
> On Mon, Apr 7, 2008 at 11:23 AM, Richard Dale <richard.j.dale at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.kde.org/pipermail/panel-devel/attachments/20080407/8b3e21fd/attachment-0001.html 


More information about the Panel-devel mailing list