[comp.sys.amiga] IPC - The Object-Oriented Approach Made Easy

shf@well.UUCP (Stuart H. Ferguson) (03/17/88)

InterProcess Communication - Object-Oriented Approach

So far the response to my "object-oriented" IPC proposal has been generally
favorable.  In this message I hope to show that this approach is actually
simple and easy to implement, as well as being straightforward to expand
and customize.  

Basics:

craig@unicus.UUCP (Craig D. Hubley) lucidly comments on and discusses the
proposed IPC model, including this brief and clear summary of the approach:

>...  Stuart is proposing an object-oriented model
>for the IPC, that is, `Please [method] my [object]' rather than 
>`[program] controls [program]'.  I think this is the right way to go,
>since it is no more difficult, lends itself to reliable control structures,
>and is a general case of the more specific master-slave paradigm.
...
>The Amiga environment as it stands is preserved.  Extensions to it consist
>of placing a conceptual envelope around each data structure to turn it into
>an object:
>        A Class 
>        Set of methods performable on this class
...
>        Any class exists because a program claims it exists.
>        Any method exists because a program claims it exists.

He also describes the basics of a possible system to implement this idea,
but his proposal is a little too complex for my liking.  I think the whole
thing can be done with almost embarassing simplicity.

Processes offer to service messages.  The messages consist of commands
to objects (i.e. something of the form "please [method] my [object]").
Object classes and methods are specified by unique longword identifiers,
like `PIPE' or `EDIT'.  Services are specified as Class.Method, as in
"ILBM.SHOW", or "FILE.COPY".  There is one message port associated with each
unique Service.

The association between Services and message-ports is managed by a runtime
library.  The list is kept in the Base structure of the library and is
locked so that only one process can alter the data in Base at one time.
Processes offer Services by calling a runtime routine.  For example:

   port = OpenServicePort ();
   RegisterService (ILBM, EDIT, 0);
   ...
   WaitPort (port);
   ...

That's all there is to it.  Since the library is runing within the calling
processes context, it can take care of the port.

If a client program wants to use a service, it just does:

   result = Dispatch (object,command);

where result and object are pointers to Objects, and command is a pointer to
a command block.  The runtime library checks the class of the object and
the requested method and looks up this Class.Method entry in its list of
available Services.  It then dispatches the command message to the
appropriate port and waits for a reply.  There would also be calls for
asyncronous message passing.

This is the basic interface.  I glossed over the details of the object and
command (method request) specification, but library routines could be
provided to manipulate the object structures so that user programs wouldn't
have to know any specifics.  One might imagine requesting a decending sort
on an ascii file by doing:

   struct Object *obj,*result;
   struct Command *com;
   ...
      /* create an instance of a FILE object,
       * with a given file lock and
       * with TEXT attribute flag */
   obj = NewObject (FILE);
   AddObjAttribute (obj, LOCK, filelockptr);
   AddObjAttribute (obj, TEXT, 0);
      /* specify a decending sort */
   com = NewCommand (SORT);
   AddCmdOption (com, DESC, 0);
      /* dispatch the request */
   result = Dispatch (obj, com);
      /* clean up */
   DisposeObject (obj);
   DisposeCommand (com);
   ...

The "result" pointer would be the output object, like a file or a pipe for
example.  The program could then send that object the SAVE command and it
would save itself to disk if it turned out to be a pipe, or rename itself if
it was already on disk.  Note that the programmer need know nothing about
how object structures are organized.  He does, however, have to know about
what attributes are valid for the class of object he wants to use.

Object class hierarchies would be easy to implement and more or less
transparent to the programmer.  If the library can't find a given
Class.Method, it will look for the Super-Class.Method and relay the command
to that method server if it finds it.  It will look up the tree until it
reaches a root class and then it will give up and return an error.  Class
hierarchies are useful to organize objects in a logical fassion, and help to
prevent code duplication yet again.

Specifics:

The basic approach I've outlined addresses many specific concerns as special
cases.  For example, Craig suggested that the system should have the
following feature:

>        A permanent editable list of where methods that are currently
>                unavailable (not in memory) might be found.  (A text file)
>                A preference flag somewhere decides whether the user is to 
>                be consulted as a last resort, or whether the request fails.

This could be implemented by a "service broker" on top of the basic system.
The broker would be a small program that would register the services of
other programs not currently in memory.  When it received a request for one
of its services, it would LoadSeg() the actual server and relay the request.

>Streams I haven't thought broadly about yet. ...

I have.  Streams can be implemeted as objects.  A process can register
itself as a method on stream-class objects.  `Grep' and most other Unix(tm)
utilities are just methods on streams.  For example, to `grep' a stream, one
might do:

   /* obj is a pointer to a stream class object such as a pipe or a file */
   com = NullCommand (GREP);
   AddCmdOption (com, REX, "pattern");
   result = Diat
they will do that can be specified before programmers go off and design
their own objects and methods, the more uniform and consistent the results
will be.  A set of root classes will provide a platform for developers to
use, as well as examples of how to "do it right" as far as creating new
classes and methods.
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC		(shf@Solar.Stanford.EDU)