[comp.sys.mac.programmer] Communicating between separate pieces of software without IPC

tim@hoptoad.uucp (Tim Maroney) (06/10/89)

siegel@endor.harvard.edu (Rich Siegel) wrote:
> 	Hey, I never said it would work forever. It's actually an
> educated bet, because it's highly possible that when separate code
> and data spaces are implemented in the OS, the support structure
> desk accessories may be radically different, and may well support
> base-register-relative globals for DA's. Who knows?

Someone at Apple knows, but they may not be on the network or free to
speak.  There's an understandable reluctance to talk publically about
features still in development.

Your suggestion is interesting.  I think it's more likely that DAs will
go on just as they are now, and Apple's policy for small utilities will
be to write a small application instead.  They have announced that in
7.0 you will be able to double-click desk accessories like
applications, which implies Suitcase-like functionality with respect to
owned resources and multiple files, but at that point MultiFinder will
always be running as well, so DAs lose all their advantages over small
applications.  (Including access from the Apple menu; another nifty
announced feature is that you will be able to install applications and
documents in the Apple menu.  I believe this will be done by placing
them in a special folder, which will include links to files stored
elsewhere.)  I think they will try to push applications over DAs based
on the second Q&A in the infamous "Developer's Conference Q&A" under
"Finder 7.0".

> 	For example, suppose you have an INIT and a cdev that need to
> share information with one another? How do you propose to have them
> communicate? Remember, there's no low memory you can use, and there's
> no place to place a base register. Well, you could put a block in the
> system heap with your unique signature in it, and crawl the system
> heap for it, BUT that (a) won't work when the format of heap blocks
> changes, and (b) won't work when the system heap becomes protected.

This used to be the recommended approach given by Developer Support.
It may still be.  I don't think either of those problems will
necessarily happen.  Crawling the system heap can be done on a
block-by-block basis, but the better way to do it is by bytes, ignoring
block structures.  This should allow the retrieval function to survive
the 32-bit Memory Manager.  The rationale is that an INIT will place it
in the system heap early, so it will be quick to find from the start of
the heap space.

Even if you do search block by block, the block structure may not
change.  The block header format in the current Memory Manager is
32-bit clean; it's only the master pointers that aren't clean, and they
are all buried inside nonrelocatable blocks.  If you take
&zone->heapData as a pointer to the first block, then I think there's a
good chance that you will be able to walk normally through blocks in
the 32-bit Memory Manager.

As for the protection of the system heap. INITs *do* need to have write
access to the system heap, unlike most applications.  INITs create
lasting trap patches and vertical retrace routines, as well as other
things, which must outlast the closing of the INIT file.  In a
hypothetical memory-protected OS, it seems very likely that INITs would
run in a context that allowed system heap writing.  The CDEVs would
retain read-only access (or for some CDEVs, read-write access would be
required) and would be able to find what the INIT placed.

However, I've always thought of this solution as a bit of a hack, and
the bit of a hack that I prefer is to patch some trap in a way that
allows it to be double-functioned.  For instance, for TOPS TCP/IP I
provided communication to the INIT-installed code by turning _Control
into a dispatch mechanism.  I gave myself a high positive reference
number, which would always return a bad unit error if TOPS TCP/IP
weren't installed.  The patch checks for this unit number and passes it
off to the real _Control if the reference number doesn't match.  This
is only two instructions or so, so the performance hit is negligible.
The rest of the parameter block to PBControl contains the arguments for
the dispatched routine.  This could be used for your INIT/CDEV
situation (in fact, I did call TCP/IP from the Control Panel interface
at points) but it is actually accessible from just about any code
running in the system, including interrupt-driven code with no globals
register as well as DAs and applications and definition routines, etc.

A better overall solution would be to install a module-independent
dispatching routine.  The glue would be a simple routine that stores
pairs of (signature,dispatch), keyed by "signature", where signature is
a four-byte creator ID registered with Apple (and presumably used for
one or more of your files) and dispatch is a function pointer
indicating a function dispatch switch where the first argument is a
numerical routine selector.  Then you need two entry points, a store
routine and a fetch routine (delete might also be useful).  These could
be implemented in a number of ways, but a _Control patch like the one
above suggests itself.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com
Postal: 424 Tehama, SF CA 94103; Phone: (415) 495-2934

"There are no Famous People on the net.  Only some of us with bigger mouths
 than others."  -- Dan'l Danehy-Oakes, The Roach