Subject: FVWM: Threading.

From: Rusty Phillips <[email-masked]>
Date: Wed, 07 Jul 2004 10:18:41 -0500

I don't think detach works the way it should for me.  Any time you
execute "exit" anywhere in any thread (when forking - whether I fork or
FvwmPerl does), all threads exit in FvwmPerl.  This isn't what we want,
is it?

So far I have two solutions to this:
1)  Have the process kill itself when it finishes.
2)  Use perlthreads (using either the "threads" package or the "forks"
package) and detach the process

In the interest of not using extra Perl packages when I wasn't using a
module, I implemented solution #1. 
I had a bit of trouble actually getting the PID of the child process
from itself.  For some reason, $$ maps to fvwm rather than the child
process.
I had to either use Linux::Pid, or make a shell call.

Of course, a better solution to all this would be to figure out whats
wrong with FvwmPerl's exit and fix it so that detach works (I'm testing
with FvwmPerl from CVS from June 30, btw).

I put a lock on xwd usage.  A lot of this is an ugly hack.  But the
beauty is that it works, and I didn't have to implement another module.

So...here you go.

DestroyFunc CaptureIcon
AddToFunc CaptureIcon
+ I raise
+ I eval \
    $g=1 if(!$g=~/0|1/); \
    while($g==0) {  } \
    $g=0;\
    $e{$[w.id]} =`xwd -silent -id $[w.id] 2>&1`; \
    $g=1;\
    if(substr($e{$[w.id]},0,10)=~/Error/) { \
    for(my $i=0; $i<8; $i++)  \
    { \
        $e{$[w.id]} = `xwd -silent -id $[w.id]`; \
        last if(!(substr($e{$[w.id]},0,10)=~/Error/)); \
    } } \
    $f{$[w.id]}=1;

DestroyFunc UseCaptured
AddToFunc UseCaptured
+ I eval my $pid; $SIG{'CHLD'}='IGNORE'; if(!($pid=fork)) { \
        $pid=`echo $$$$$$$$`; \
    setpriority 0,0,19; \
    while (!exists($f{$[w.id]}))  { }; \
    open(TEMP12, "|convert -scale $[fvwm_icon_size] -frame 1x1 \
    -mattecolor black -quality 0 xwd:- \
    png:$[HOME]/.fvwm/icon.tmp.$[w.id].png"); \
print TEMP12 $e{$[w.id]}; close(TEMP12); \
cmd("WindowId $[w.id] WindowStyle IconOverride, \
     Icon $[HOME]/.fvwm/icon.tmp.$[w.id].png, StaysOnBottom"); \
     delete $e{$[w.id]}; \
     delete $f{$[w.id]}; \
     kill 9,$pid; \ 
    };

DestroyFunc FastThumb
AddToFunc FastThumb
+ I CaptureIcon
+ I Iconify
+ I UseCaptured

--
Visit the official FVWM web page at <URL: http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Mikhael Goikhman <[email-masked]>
Date: Wed, 7 Jul 2004 16:41:36 +0000

> FvwmPerl does), all threads exit in FvwmPerl.  This isn't what we want,

I am aware about a problem with detach() since your previous messages.
Probably some recent change caused the current behaviour, no idea yet.

>     while($g==0) {  } \

This is endless loop.

Please wait until I investigate the problem with detach(), before writing
yet another long message to the list. I will provide the correct and
clean solution to your problem once I restore the intended functionality.

Also it will help me if you try to use meaningful subject lines (the ones
you used during the last 3 days are not), and stay in one thread per
problem. Thank you.

Regards,
Mikhael.

---

From: Rusty Phillips <[email-masked]>
Date: Wed, 07 Jul 2004 14:26:35 -0500

Yeah, I'm done.  No more code from me on this.  To tell the truth, I
have done nearly as much work if I had realized that detach was just
broken.  I thought it was supposed to do that before I read through
FvwmPerl.

> This is endless loop.

Actually it's not.  The only thing that can make g==0 is another
process.  It's a locking mechanism to guarantee that only one copy of
xwd is running at a time, because xwd is not thread safe.  It's a hack.
Watch the process listings while running this and you'll see that it
works.

---

From: Mikhael Goikhman <[email-masked]>
Date: Wed, 7 Jul 2004 21:46:58 +0000

> Watch the process listings while running this and you'll see that it

No, this is an incorrect explanation. This is endless loop. However
$g is never 0 here, so this loop is never entered. One process can't
modify the memory of another, there are no threads at all.

Here is a short explanation of how modules interact with fvwm on
SendToModule:

  fvwm    -> fvwm sends SendToModule argument to module ->    module
             and waits for answer if module asked so;
          <- module may optionally send some commands   <-
             but usually it just immediatelly
          <- sends unlock, so fvwm may continue further <-

             however FvwmPerl does not itself unlock during eval,
             so fvwm is synchronized with FvwmPerl by default;
             to unlock fvwm, use unlock() or detach() functions

There are no threads, one main module process reads messages from fvwm.
If you unlock(), but not detach(), then what happens is fvwm may send the
next SendToModule message to a busy module, and noone will read it until
the previous eval is finished. If eval is finished within ModuleTimeout,
then module may read the new message from fvwm and unlock it, otherwise
the non-responding module is killed. After detach() the work is done in
the second process that should in no way affect the main one. In theory.

Regards,
Mikhael.