Click here to get back home

is Win32::GUI thread safe?

 HomeNewsGroups | Search | About
 comp.lang.perl.misc    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
is Win32::GUI thread safe? Tom F. 10-02-2008
Get Chitika Premium
Posted by Tom F. on October 2, 2008, 11:36 pm
Please log in for more thread options


I've been working on a script for a little while now
It's a program that will periodically log me into my campus's content
filtering device (Barracuda). Of course, it makes sense to implement
some sort of timeout handling, just in case I lose the net connection or
happen to have my laptop somewhere else.

Here's the problem: the script keeps crashing with the following message:

Free to wrong pool 3d9b108 not 1981c78 at C:/Perl/site/lib/Win32/GUI.pm
line 3480 during global destruction.

the crazy thing is, no GUI element is changed during the spot where I
split into threads and then re-join into one. through the use of print
statements, I've narrowed it down to the statement where I join a thread.

(2 threads: 1 timer, 1 do-er; if the timer is ready but the do-er isn't,
then kill it)

and it happens no matter which thread is joined!

I've tested all the net stuff without the GUI (but using threads) and it
works fine. So, that leads me to think Win32::GUI is not thread safe,
and the mere presence of any of the different GUI objects is causing my
problem.

Google has only revealed very old information and other dead ends. Help!

Posted by zentara on October 3, 2008, 9:22 am
Please log in for more thread options


On Thu, 02 Oct 2008 23:36:16 -0400, "Tom F."
>
>I've tested all the net stuff without the GUI (but using threads) and it
>works fine. So, that leads me to think Win32::GUI is not thread safe,
>and the mere presence of any of the different GUI objects is causing my
>problem.
>
>Google has only revealed very old information and other dead ends. Help!

Perl/Tk is the same way...not thread safe. It can still be used with
threads with precautions, google for "perl tk threads" for examples.

I would bet that you can solve the problem by :

1. Create the thread first in the program, before any gui code is
invoked. For instance, you cannot reliably launch threads from
a gui callback. Threads get a copy of the parent when spawned,
so you want to spawn early before gui code statements are used.

2. Never try to access gui widgets from a thread, use shared variables
to communicate back to the main thread, and manipulate the widgets
from the main thread.

zentara


--
I'm not really a human, but I play one on earth.
http://zentara.net/Remember_How_Lucky_You_Are.html

Posted by Tom F. on October 3, 2008, 2:34 pm
Please log in for more thread options


zentara wrote:
> On Thu, 02 Oct 2008 23:36:16 -0400, "Tom F."
>> I've tested all the net stuff without the GUI (but using threads) and it
>> works fine. So, that leads me to think Win32::GUI is not thread safe,
>> and the mere presence of any of the different GUI objects is causing my
>> problem.
>>
>> Google has only revealed very old information and other dead ends. Help!
>
> Perl/Tk is the same way...not thread safe. It can still be used with
> threads with precautions, google for "perl tk threads" for examples.
>
> I would bet that you can solve the problem by :
>
> 1. Create the thread first in the program, before any gui code is
> invoked. For instance, you cannot reliably launch threads from
> a gui callback. Threads get a copy of the parent when spawned,
> so you want to spawn early before gui code statements are used.

Is there any way to tell perl or the threads module not to make that
copy? I saw something like this:

sub Win32::GUI::CLONE_SKIP ;

that would stop the copy, but I'm not sure it was working when I tried
to use it, though I wasn't sure if I had absolutely covered all the
different non thread-safe modules that were being used inside these
(i.e., Win32::GUI::Window might use non-thread-safe Win32::foo::bar
internally)

> 2. Never try to access gui widgets from a thread, use shared variables
> to communicate back to the main thread, and manipulate the widgets
> from the main thread.

I knew about that, and was/am avoiding it.

Do you think trying to use the GUI elements as shared variables would
solve it (does sharing simply synchronize the copies or does it stop the
copying?)

> zentara
>
>

Posted by zentara on October 4, 2008, 10:04 am
Please log in for more thread options


On Fri, 03 Oct 2008 14:34:48 -0400, "Tom F."

>zentara wrote:

>> I would bet that you can solve the problem by :
>>
>> 1. Create the thread first in the program, before any gui code is
>> invoked. For instance, you cannot reliably launch threads from
>> a gui callback. Threads get a copy of the parent when spawned,
>> so you want to spawn early before gui code statements are used.
>
>Is there any way to tell perl or the threads module not to make that
>copy? I saw something like this:
>
>sub Win32::GUI::CLONE_SKIP ;
>
>that would stop the copy, but I'm not sure it was working when I tried
>to use it, though I wasn't sure if I had absolutely covered all the
>different non thread-safe modules that were being used inside these
>(i.e., Win32::GUI::Window might use non-thread-safe Win32::foo::bar
>internally)

I don't use win32, so use a grain of salt with this.
Did CLONE_SKIP seem to work? Also test 10 or 20 runs. Threads will
act funny sometimes, seeming to run fine, then crashing unexpectedly
after 20 tests.

Gtk2 has a thread safety mechanism similar to the CLONE_SKIP you
mention, it's called set_threadsafe. BUT it is at the lowest level of
Glib, which the Gtk2 gui code is based on; so in theory it accounts for
all objects. One thing though, Glib::Object->set_threadsafe(1) must
be the first statement in the script.
So maybe make sure CLONE_SKIP is the first line in your script.
Also I'm not an expert at this, but I believe these thread safety
mechanisms only affect the ref_count of the objects.....in reality,
the spawned threads get an exact copy of the parent at the time of
creation...... the gui code in the spawned thread may be disabled, but
it still gets copied due to the way threads get spawned. I may be wrong,
I seldom delve that deep and prefer just to work around it with the
hacks that I've mentioned.

>Do you think trying to use the GUI elements as shared variables would
>solve it (does sharing simply synchronize the copies or does it stop the
>copying?)

You don't share the GUI widgets as shared variables, Perl only allows
scalars in shared vars. In Gtk2 ,you can pass in a widget reference in
the threads->new(\&codeblock, $somewidget), and then access the widget
by a Glib->Idle_add() statement. Does Win32::Gui have something like
Idle_add? Adds a callback at first idle moment in the event loop.

What I meant about shared vars was try to keep only non-gui code in the
threads, and use timers in the parent thread to read shared vars set in
the thread. Then the timer can manipulate the gui widget with that data.
You need a timer in the parent thread constantly reading the shared
variables, because they are NOT automatically updated in the parent
thread, when a child thread sets them.
The only exception to this, is shared filehandles, which the parent can
read as it comes in.

For deeper expertise, you might want to ask on http://perlmonks.org

Hope that helps,
zentara


--
I'm not really a human, but I play one on earth.
http://zentara.net/Remember_How_Lucky_You_Are.html

Posted by Tom F. on October 4, 2008, 7:16 pm
Please log in for more thread options


zentara wrote:
>> zentara wrote:
>
>>> I would bet that you can solve the problem by :
>>>
>>> 1. Create the thread first in the program, before any gui code is
>>> invoked. For instance, you cannot reliably launch threads from
>>> a gui callback. Threads get a copy of the parent when spawned,
>>> so you want to spawn early before gui code statements are used.

> You don't share the GUI widgets as shared variables, Perl only allows
> scalars in shared vars. In Gtk2 ,you can pass in a widget reference in
> the threads->new(\&codeblock, $somewidget), and then access the widget
> by a Glib->Idle_add() statement. Does Win32::Gui have something like
> Idle_add? Adds a callback at first idle moment in the event loop.

Thanks, I think I am just going to have to use shared variables as flags and
whatnot. Dang, I had this thing written 5 times over if only it was friggin'
thread safe.

Similar ThreadsPosted
Is LWP thread-safe? February 10, 2005, 5:28 am
Win32 thread vs fork December 10, 2005, 1:02 am
Win32::OLE error in thread (ActiveSatate 5.8) on XP November 13, 2006, 2:29 am
Win32::OLE error in thread (ActiveSatate 5.8) on XP March 26, 2007, 3:57 am
Problem starting a new thread from another thread July 25, 2006, 7:18 pm
How safe is $0? August 24, 2007, 6:00 am
Checking for safe paths March 9, 2005, 7:59 pm
Safe Merge module March 31, 2006, 7:53 pm
safe-module and namespaces May 31, 2006, 8:05 am
Safe Pipe Open question March 21, 2006, 8:00 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap