Message-ID: <333FE040.6CF2@mail.amsinc.com>
Date: Mon, 31 Mar 1997 09:03:12 -0700
From: Tom Hawker <Tom_Hawker_at_AMS-Notes@mail.amsinc.com>
Organization: American Management Systems, Inc.
X-Mailer: Mozilla 3.01Gold (WinNT; I)
MIME-Version: 1.0
Newsgroups: comp.lang.smalltalk
Subject: Re: Catching signals in VW2.0
References: <5hb9n6-r6c@svusenet.ubs.ch>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: simpm2
Lines: 67
Path: cantaloupe.srv.cs.cmu.edu!nntp.club.cc.cmu.edu!uhog.mit.edu!news.kei.com!newsfeed.internetmci.com!howland.erols.net!ais.net!uunet!in3.uu.net!162.70.244.3!dns.amsinc.com!simpm2

Helfenberger Theo wrote:
> 
> From my VW2.0 image (running on Solaris 2.5) I want to be able to catch a SIGUSR1
>  signal. The handler should then perfom some methods on a object in the image.
> Can anyone tell me how to implement this?
> --
> Your Name Theo Helfenberger
> -------------------------------------------------------------------------
> OE-x1x  office-loc   Tel. 6 xx xx / +41 (0)1 236 xx xx
> Union Bank of Switzerland, Zurich

You will need DLL/C Connect or user primitives.  Here's how to do it
with DLL/C Connect (user primitives is the same but uses a different
interface):

1.  Write a C routine that takes an object handle as argument.  The
handle is to a Semaphore.  The C routine declares the USR1 interrupt
handler and registers the semaphore handle (so that the handle remains
"permanent", as if it were referenced from a global).

2.  Write a C routine that is the USR1 interrupt handler.  The handler,
when activated, uses VM safe interfaces to signal the semaphore.  This
may be somewhat convoluted, such as VM callbacks to a third routine when
object memory is "safe".  (They used to do this.)  Remember, this
routine could interrupt the operation of the memory manager, so you
can't arbitrarily muck around with objects or object memory.

3.  Write a C routine that disables the USR1 interrupt handler and
deregisters the semaphore handle.

4.  Package these routines together as a DLL/shared library.

5.  In Smalltalk, build a subclass of ExternalInterface to reference
your DLL.  Define the procedures that access routines #1 and #3.

6.  Write a method in your application that invokes routine #1 at the
proper time.  This needs to supply a Semaphore as argument.

7.  Write a method that forks a Smalltalk process into the background. 
The method should look something like this, assuming that "semaphore"
and "eventProcess" are both instance variables or methods:

	eventProcess

	eventProcess == nil
	    ifFalse:
		[eventProcess :=
		    [[self semaphore wait.
		    self interrupted] repeat]
			forkAt: Processor userBackgroundPriority].
	^eventProcess.

I have chosen to place this process in the background, so that it runs
whenever the GUI is not active.  You could run it at a higher priority
so that it preempts the GUI, such as "userSchedulingPriority + 1".

8.  Write the method "interrupted" to do whatever work you wanted to do
on the interrupt.  Because this will run as an independent thread, you
must use mutual-exclusion semaphores or RecursionLocks to protect any
objects that will be modified by the method.

9.  Write a method to shutdown the background process and disable the
interrupt handler, if required.

10.  Call these methods from the appropriate places in the application.

Tom Hawker
