[comp.sys.amiga.tech] IPCMessages -- A Prototype

shf@well.UUCP (Stuart H. Ferguson) (06/18/88)

At the June 16th BADGE meeting, Pete Goodeve presented his (and Peter da
Silva's) proposed Interprocess Communication standard with an excellent
slide show and examples.  Well done, Peter. 

The best part was when he revealed that the slide show program he was
running was itself an example of IPC at work.  It consisted of three
separate programs (four, if you count the semi-working Joystick Reader
;-) all operating asynchronously and communicating with each other using
the proposed standard.  The Script Manager asks the ILBM Manager to
pre-load images into bitmaps in memory and free them up when the Script
Manager thinks they won't be needed again.  The Script Manager also
sends messages to the Display Manager to take a pre-loaded bitmap
structure and display it.  The Display Manager in turn sends messages to
the Script Manager when the user clicks the mouse to move forward or
backward in the presentation. 

Altogether it made for an interesting demonstration, but there was one
aspect of it which exemplifies a problem with the proposed standard
which I have mentioned before.  The problem is that IPCMessages do not
provide for standardized data formats.  They deal with standard
_message_ formats reasonably well, but data is handled very
incompletely.  Peter ran into this very problem himself in implementing
his slide show program(s) and kludged around it. 

His Script Manager calls on the ILBM Manager to read an ILBM file and
return a bitmap structure.  The Script Manager then passes this bitmap
on to the Display Manager for display.  So far so good.  The problem is
that a bitmap can consist of several different chunks of memory: the 
bitmap structure itself, a color map, up to six bitplanes and possibly 
other stuff.  Because of the way the IPCMessage is designed, each of
these requires its own IPCItem entry.  The question then becomes: Who 
creates those IPCItems?

The correct answer would seem to be the ILBM Manager.  It is the expert 
on bitmaps, after all, so it should know what items would be needed.  
Also, it's the only process that knows how many bitplanes this image is 
supposed to have.  But if the bitmap is to be the reply to a message 
from the Script Manager, then it is the Script Manager that would be 
required to initialize all the item fields for the return value of the
request.  This is clearly wrong, since the Script Manager should not be
required to understand bitmaps.  Another part of the problem is that the
Script Manager sends this same bitmap to the Display Manager.  If the 
Script Manager is going to construct its own message to pass to the 
Display Manager, it will have to allocate the space for and copy the 
items associated with bitmaps from the ILBM Manager.  This means that 
the Script Manager has to grok bitmaps again.

Peter's solution was to have the ILBM Manager construct the message that
will be sent to the Display Manager, and return that _message_ to the
Script Manager.  The Script Manager then uses that message to control
the Display Manager without understanding much of its contents.  No
reflection on Peter's programming skills, but this is a kludge.  Not
only does it (probably) violate the IPCMessage design, it also makes the
ILBM Manager a solution to this specific problem, and not a general
purpose tool for reading bitmaps. 

In prototyping the system, Peter has uncovered what I believe to be a 
major drawback of the IPCMessage design.  A solution to this problem is 
to implement a standard for abstract data objects, such as bitmaps.  If 
this were done, then the Script Manager could ask for a bitmap and get a 
pointer to one without having to know anything about it.  It could then 
pass this pointer on to a display program or anything else with the same 
blissful ignorance of what it really points to.  Obviously the ILBM
reader and the display program need to speak the same language about
what a bitmap is, but this is as it should be, just as it should be that
the script program need not know. 

Peter has done a great job so far in allowing others to contribute to 
his design project.  Keep it up.
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC		(shf@Solar.Stanford.EDU)

peter@sugar.UUCP (Peter da Silva) (06/18/88)

Regarding Pete Goodeve's demo of IPCMessages... (wish I was there).

In article <6306@well.UUCP>, shf@well.UUCP (Stuart H. Ferguson) writes:
> His Script Manager calls on the ILBM Manager to read an ILBM file and
> return a bitmap structure.  The Script Manager then passes this bitmap
> on to the Display Manager for display.  So far so good.  The problem is
> that a bitmap can consist of several different chunks of memory: the 
> bitmap structure itself, a color map, up to six bitplanes and possibly 
> other stuff.  Because of the way the IPCMessage is designed, each of
> these requires its own IPCItem entry.  The question then becomes: Who 
> creates those IPCItems?

Well, there are really only three peices of information you need: the
bitmap (BMAP), the color map (CMAP), and the display modes. The struct
bitmap contains all the bitplanes.

Now you only have three objects that need to be dealt with. Voila.

> In prototyping the system, Peter has uncovered what I believe to be a 
> major drawback of the IPCMessage design.  A solution to this problem is 
> to implement a standard for abstract data objects, such as bitmaps.

If you look at my original proposal, you would have seen at least one
such data object: a file. The format for a file structure was a lock
on the directory the file was in, and the name of the file in that
directory.

There is nothing that says that the primitive structures the IPC items
point to can't be defined at a higher level than Amiga native structures.
The main point is that they be tagged (BMAP, CMAP, and VMOD on the one
hand, or IMAG on the other, where IMAG is a struct { struct bitmap *BMAP,
USHORT *CMAP, ULONG VMOD }. The reader program would fill in either of these
structures. When you're finished you can grok bitmaps yourself and free them,
or send the reader (or any other program that groks it) a destroy message.

I still think that a better high-level protocol for this stuff is necessary.
Stuart Ferguson's own object oriented stuff is a good start. It just needs
tagged structures, I think (and I could be all wet about that). Here the reader
and the displayer TOGETHER should somewhere have a name. The reader tells
the object server that it knows about the IMAG/READ and IMAG/KILL pairs.
The displayer knows about the IMAG/SHOW and maybe IMAG/EDIT pairs...

Then the master program asks the object server for a program that knows
about each of IMAG/SHOW, IMAG/KILL, and IMAG/READ. It gets three message
ports (one repeated). Voila. When finished it replies to the IPCMessages
it got from the object server, and the server tells the programs they can
exit if they like...

And of course the object server talks in IPCMessages...

> If 
> this were done, then the Script Manager could ask for a bitmap and get a 
> pointer to one without having to know anything about it.

No problem.

> It could then 
> pass this pointer on to a display program or anything else with the same 
> blissful ignorance of what it really points to.  Obviously the ILBM
> reader and the display program need to speak the same language about
> what a bitmap is, but this is as it should be, just as it should be that
> the script program need not know. 

Right. It just knows that there's an object called "IMAG" that it can read from
the reader and send to the displayer.

> Peter has done a great job so far in allowing others to contribute to 
> his design project.  Keep it up.

Which Peter? Or both?
-- 
-- `-_-' Peter (have you hugged your wolf today?) da Silva.
--   U   Mail to ...!uunet!sugar!peter, flames to /dev/null.
-- "A foolish consistancy is the hobgoblin of little minds".

rogerh@arizona.edu (Roger Hayes) (06/21/88)

In article <6306@well.UUCP> shf@well.UUCP (Stuart H. Ferguson) writes:
>...  The problem is that IPCMessages do not
>provide for standardized data formats.  They deal with standard
>_message_ formats reasonably well, but data is handled very
>incompletely.  Peter ran into this very problem himself in implementing
>his slide show program(s) and kludged around it. 
>

Stuart goes on to suggest "abstract data types", such as bitmaps, for
data.  I would like to offer a slightly different suggestion.

IPC messages should be easy to use from our programming languages, so
they should contain data of the familiar types (int, float, string) and
type constructors (record, array).  To be most useful on the Amiga,
they might also have special constructs for the common Amiga data
structures (like Port or Bitmap).

We gain the most flexibility if the IPC ports can be connected freely
at runtime, without compiling the two ends together.  In order to do
this while preserving the meaning of the data, messages should be
self-describing.  That is, an int value is preceded by a tag that says
'INT'.

If anyone is intrigued by this idea, I have it implemented in C for
Unix.  The system includes a stub generator for remote procedure calls,
data translation routines, and a rudimentary execution manager.  The
code is *not* production quality.

I'm not planning to port it to the Amiga myself, as I've promised my
advisor that I won't get an Amiga compiler until I am done with my
dissertation.  If anyone is seriously interested in doing so, write me
for details.

				Roger Hayes
				rogerh@arizona.edu

shf@well.UUCP (Stuart H. Ferguson) (06/21/88)

+--- From: peter@sugar.UUCP (Peter da Silva)
| Regarding Pete Goodeve's demo of IPCMessages... (wish I was there).- 
| In article <6306@well.UUCP>, shf@well.UUCP (Stuart H. Ferguson) writes:
...
| > that a bitmap can consist of several different chunks of memory: the 
| > bitmap structure itself, a color map, up to six bitplanes and possibly 
| > other stuff.  Because of the way the IPCMessage is designed, each of
| > these requires its own IPCItem entry.  The question then becomes: Who 
| > creates those IPCItems?
| Well, there are really only three peices of information you need: the
| bitmap (BMAP), the color map (CMAP), and the display modes. The struct
| bitmap contains all the bitplanes.

Therein lies the problem.  See below.

| > In prototyping the system, Peter has uncovered what I believe to be a 
| > major drawback of the IPCMessage design.  A solution to this problem is 
| > to implement a standard for abstract data objects, such as bitmaps.
| If you look at my original proposal, you would have seen at least one
| such data object: a file. The format for a file structure was a lock
| on the directory the file was in, and the name of the file in that
| directory.

Sorry, I didn't remember that from your early postings on the subject.
My understanding was that when passing memory between programs with an
IPCMessage, each continious block of memory needs its own IPC item.  That
constraint, as I recall, is required to allow IPCMessages to be passed
over a network.  I may have missed something, but isn't that what the
IPC_NETWORK and IPC_INMESSAGE flag bits are about as well? 

| There is nothing that says that the primitive structures the IPC items
| point to can't be defined at a higher level than Amiga native structures.

Having IPC item pointers that point to structures containing pointers is
what Pete Goodeve called, "the royal road to chaos," in his response to
a message of mine.  If you take out the pesky network limitations then
you can have pointers to pointers all over the place -- it just won't
work over a network. 

| I still think that a better high-level protocol for this stuff is necessary.
| Stuart Ferguson's own object oriented stuff is a good start. It just needs
| tagged structures, I think (and I could be all wet about that). Here the 
| reader and the displayer TOGETHER should somewhere have a name. The reader 
| tells the object server that it knows about the IMAG/READ and IMAG/KILL 
| pairs.  The displayer knows about the IMAG/SHOW and maybe IMAG/EDIT pairs...

| Then the master program asks the object server for a program that knows
| about each of IMAG/SHOW, IMAG/KILL, and IMAG/READ. It gets three message
| ports (one repeated). Voila. When finished it replies to the IPCMessages
| it got from the object server, and the server tells the programs they can
| exit if they like...

This is a reasonably good summary of the concept.  Implementational 
details are different the way I imagine them, but this is the basic 
idea.

| And of course the object server talks in IPCMessages...

Perhaps.  My design doesn't quite jive with some of the basic
assumptions of the IPCMessage and IPCPort design.  For example, the
ports need to be kept in a private list and not made available to
clients directly.  By keeping ports insulated from client tasks, the
port for a given service (such as "IMAG/SHOW" in Peter's example) can
change on the fly without the server knowing it.  Also, since clients
are not posting to ports directly, the ports are "safe."  This is a
completely different concept than the IPCPort "reference count" idea. 
There are other significant clashes that would need to be ironed out in
order to implement one under the other. 

When I get some free time (hah!) I'll try doing just what Pete Goodeve 
did and prototype my idea.  There's nothing quite so persuasive as 
working code.  (On that note, the Arexx demo the same night was also
really impressive.  Makes one realize the true (rather than
hypothetical) power of multitasking with an integrated environment.) 

| > Peter has done a great job so far in allowing others to contribute to 
| > his design project.  Keep it up.
| Which Peter? Or both?

My apologies.  Of course I meant Peters, plural. :-)

|
+--- -- `-_-' Peter (have you hugged your wolf today?) da Silva.
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC		(shf@Solar.Stanford.EDU)

peter@sugar.UUCP (Peter da Silva) (06/22/88)

In article <6338@well.UUCP>, shf@well.UUCP (Stuart H. Ferguson) writes:
> Me:
> | There is nothing that says that the primitive structures the IPC items
> | point to can't be defined at a higher level than Amiga native structures.

> Having IPC item pointers that point to structures containing pointers is
> what Pete Goodeve called, "the royal road to chaos," in his response to
> a message of mine.  If you take out the pesky network limitations then
> you can have pointers to pointers all over the place -- it just won't
> work over a network. 

The problem is that the Amiga is just chock-full of pointers to pointers
all over the place. It's way too late to change that, so let's take advantage
of the significant performance advantages we get from this. If you want
to shove stuff over a network, use files. Use IFF. There's really nothing
fundamentally wrong with either, except speed... and since you're actually
copying the data over the network anyway an extra couple of context switches
really won't hurt.

> | I still think that a better high-level protocol for this stuff is necessary.
> | Stuart Ferguson's own object oriented stuff is a good start....
    [summary deleted]

> This is a reasonably good summary of the concept.  Implementational 
> details are different the way I imagine them, but this is the basic 
> idea.

> | And of course the object server talks in IPCMessages...

> Perhaps.  My design doesn't quite jive with some of the basic
> assumptions of the IPCMessage and IPCPort design.

I noticed. Still, I think that we're really dealing with seperate levels
of the problem here. You're concentrating on how the tasks meet each
other, and I'm concentrating on what they say.

> For example, the
> ports need to be kept in a private list and not made available to
> clients directly.  By keeping ports insulated from client tasks, the
> port for a given service (such as "IMAG/SHOW" in Peter's example) can
> change on the fly without the server knowing it.  Also, since clients
> are not posting to ports directly, the ports are "safe."  This is a
> completely different concept than the IPCPort "reference count" idea. 
> There are other significant clashes that would need to be ironed out in
> order to implement one under the other. 

My objection to this is speed. I can send a message to a destination port
and get the response back in two context switches. I don't have to search
any lists, private or otherwise. You paid some slight attention to this
problem with your caching setup. But the cache is obtrusive, and doesn't
behave in a predictable way.

Also, you can completely implement your protocol under PPIPC, down to changing
ports on the fly, just by searching the lists for every message. The
overhead can't be any worse.

I can't see using the OOIPC to do real-time stuff, like games. PPIPC would
be just fine: you have a dependable fixed overhead to sending a message.

Finally, I personally am not married to the high-level part of PPIPC. If you
can come up with something that gives you the flexibility of OOIPC with the
real-time reliability of PPIPC, I'll be happy to go for it. Come on. I keep
asking.  Don't make me beg. :->.

But it's got to be at least as good as Pete Goodeve's stuff.
-- 
-- `-_-' Peter (have you hugged your wolf today?) da Silva.
--   U   Mail to ...!uunet!sugar!peter, flames to /dev/null.
-- "A foolish consistancy is the hobgoblin of little minds".

peter@sugar.UUCP (Peter da Silva) (06/23/88)

In article <338@boing.UUCP>, dale@boing.UUCP writes:
> +--- From: peter@sugar.UUCP (Peter da Silva)
> | Well, there are really only three peices of information you need: the
> | bitmap (BMAP), the color map (CMAP), and the display modes. The struct
> | bitmap contains all the bitplanes.

> My concern has nothing really to do with IPC stuff, except that these
> structures may change in new releases of the o.s. In particular, since
> you can only get a colormap structure from the system via GetColorMap
> the 'struct ColorMap' is bigger in V1.4

Well, the "colormap" I was referring to wasn't a struct ColorMap, just
the IFF CMAP chunk. But your message does emphasise that there are
lots of stuff that you *do* want to ship around that *can't* be
allocated in contiguous memory.

Or is IFF changing in 1.4 ;->?

> Just thought you should know that in order for us to make forward
> progress you need to be careful about how you play with internal amiga
> structures.

I always am. Could you guys give us a "DEVS:" device so we can Examine
and ExNext it and stop looking through the device list? There are a few
other places, too, where it would be desirable to have a more secure
interface...
-- 
-- `-_-' Peter (have you hugged your wolf today?) da Silva.
--   U   Mail to ...!uunet!sugar!peter, flames to /dev/null.
-- "A foolish consistancy is the hobgoblin of little minds".

peter@sugar.UUCP (06/29/88)

In article <6387@well.UUCP>, shf@well.UUCP (Stuart H. Ferguson) writes:
> | My objection to this is speed. I can send a message to a destination port
> | and get the response back in two context switches. I don't have to search
> | any lists, private or otherwise. You paid some slight attention to this
> | problem with your caching setup. But the cache is obtrusive, and doesn't
> | behave in a predictable way.

> I'm pleased to see that Peter read my preliminary design spec.

I try to avoid commenting on stuff without reading it, even if I'm not
always successful :->.

> Second, caching makes list searching a rare event.  A cache is just a
> pointer to a port plus a flag to indicate if the cache is still valid.

How about adding one more thing to a cache: the object and method it's
a cache on. That way you can use the cache as an "opened" port, and
not have to deal with the rest of the info again. That makes it a lot
less obtrusive.

> If you think of a cache as just a pointer to a port, it's no more
> obtrusive than having an explicit pointer.

Except that now you have two names for the port that you have to pass
around... see above.

> want to make your objects network transparent, implement a `SAVE' method
> on them.  This allows specific objects to use their own compression
...
> in-memory bitmap object could have the `SAVE' method write the bitmap
> out as an IFF file.  Since this is something that is generally useful,

Good idea.

> My main point is that I cannot implement an object-oriented scheme under
> PPIPC as I understand it (at least not efficiently -- a broker with a
> search every time and four context switches doesn't make it), whereas I can
> implement everything that can be done with PPIPC under OOIPC nearly as
> efficiently.

Well, the broker doesn't *have* to be a seperate program, any more than
it does with OOIPC. Like I said, the high-level behaviour of messages is
wide open.

Tell you what, then. Implement a demo OOIPC system and let's play with
it. Submit it to alt.sources.amiga...
-- 
-- `-_-' Peter (have you hugged your wolf today?) da Silva.
--   U   Mail to ...!uunet!sugar!peter, flames to /dev/null.
-- "A foolish consistancy is the hobgoblin of little minds".

jesup@cbmvax.UUCP (Randell Jesup) (06/29/88)

In article <6387@well.UUCP> shf@well.UUCP (Stuart H. Ferguson) writes:
>The object-oriented approach does offer the possibility of transparent
>network support while preserving arbitrarily complex structure
>definitions by defining a "packetize" method on objects to convert them
>into filesystem compatible entities.  By giving the method a standard
>name, such as `SAVE', a network server need know nothing about the
>object itself, it just has to try the `SAVE' method on it and if it
>works, it can transmit it over a network.  If not, it can't.  If you

	I really like this, it seems very natural, extensible, and clean.
I vote for OOIPC.  I think object-orientedness is a BIG win, especially in
dealing transparently with a networked envirionment.

>		Stuart Ferguson		(shf@well.UUCP)

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

shf@well.UUCP (Stuart H. Ferguson) (07/01/88)

| From: peter@sugar.UUCP (Peter da Silva)

[discussion of caching deleted]
| > Second, caching makes list searching a rare event.  A cache is just a
| > pointer to a port plus a flag to indicate if the cache is still valid.
| How about adding one more thing to a cache: the object and method it's
| a cache on. That way you can use the cache as an "opened" port, and
| not have to deal with the rest of the info again. That makes it a lot
| less obtrusive.

It's actually like that already; I just didn't specify that before.  The
cache structure I'm using as a strawman is as follows:

struct Cache {
	struct Nod owner_node;
	struct Nod base_node;
	struct Server *server;
	long valid;
	long class,cmd;
}
/* Cache structure.  A cache contains a pointer to a server and validity 
 * flag.  Flag gets set to INVALID whenever anything in the class tree 
 * for this cache changes, so the server pointer will always be marked 
 * appropriately.  The cache is also associated with a task, so when the 
 * task closes the library, its caches are freed.
 */

As you can see, the Cache does contain a reference to the class and cmd 
(method) codes for this server.  You can also find these by following the 
Server pointer.  The function used to apply methods to objects is 
defined as:

	long Dispatch(object,cmd,cache)
		struct Object  *object;
		struct Command *cmd;
		struct Cache  **cache;

The Object and Command structs contain the class and cmd (method) codes, 
respectively, for this request.  Note that the combination of object and 
command uniquely define the server to be used, so no port actually need 
be referenced explictly.  Dispatch() can be called with cache=NULL, and 
if it is the server and port will be looked up in the service database.  
If there is a cache, the Dispatch() function checks its validity and if 
it's good, compares the cached class and cmd codes to those requested.
If they match, the cached service port is used immediately.  If not, the
correct service port is looked up in the database and stored in the
cache. 

Note that if caching is used and the object class and command code are
the same on each call to Dispatch(), which is often the case, then the
response is very good.  Note also that caching is optional, which is
consistent with the OOIPC design philosophy -- that is, that you make
requests in the form of methods to be applied to objects, not commands
sent to ports.  The fact that there are ports involved is deliberately
obscure. 

| > want to make your objects network transparent, implement a `SAVE' method
| > on them.  This allows specific objects to use their own compression
| ...
| > in-memory bitmap object could have the `SAVE' method write the bitmap
| > out as an IFF file.  Since this is something that is generally useful,
| Good idea.

Thanx.

| > My main point is that I cannot implement an object-oriented scheme under
| > PPIPC as I understand it (at least not efficiently -- a broker with a
| > search every time and four context switches doesn't make it), whereas I can
| > implement everything that can be done with PPIPC under OOIPC nearly as
| > efficiently.
| Well, the broker doesn't *have* to be a seperate program, any more than
| it does with OOIPC. Like I said, the high-level behaviour of messages is
| wide open.

Some of the issue is personal preference.  It's obvious that some
programmers are going to want an IPC mechanism more like PPIPC and some
are going to want OOIPC.  It's silly to restrict people to using only
one paradigm.  There may be a way to integrate the two approaches and
get the best of both worlds in terms of performance and features.  

| Tell you what, then. Implement a demo OOIPC system and let's play with
| it. Submit it to alt.sources.amiga...

Funny you should suggest that...  In fact, I'm writing such a beast
right now.  I've been thinking about the design so long that the actual
coding is going very fast.  Although the full-blown system is a little 
elaborate, there are reasonable places I can short-cut to get things
working quickly.  The real test, of course, is to build some demo
applications and see how it works. 

Side note: Is there any way to use SDB when writing a shared library?

Curiously enough, I found that my original spec for standard messages
and objects may not be sufficient, and the result of the redesign is
starting to look a little like IPCMessages.  Highly simplified, with
only 2 flag bits instead of 7 or 8, but its ancestry is clearly evident. 
:-)
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC		(shf@Solar.Stanford.EDU)

peter@sugar.UUCP (Peter da Silva) (07/02/88)

In article <6416@well.UUCP>, shf@well.UUCP (Stuart H. Ferguson) writes:
> | From: peter@sugar.UUCP (Peter da Silva)
> | > Second, caching makes list searching a rare event.  A cache is just a
> | > pointer to a port plus a flag to indicate if the cache is still valid.

> | How about adding one more thing to a cache: the object and method it's
> | a cache on. That way you can use the cache as an "opened" port, and
> | not have to deal with the rest of the info again. That makes it a lot
> | less obtrusive.

> It's actually like that already; I just didn't specify that before.  The
> cache structure I'm using as a strawman is as follows:

Good. Now then...

> 	long Dispatch(object,cmd,cache)

Might I make a suggestion. First, once the cache is set up, allow this:

	lresult = Dispatch(object, 0, cache)

If the cache is invalidated, it still contains the class and command, no?
This cuts down the baggage you need to carry around. I guess this could
be a macro, but then the user needs to look at the cache internals, which
is probably not a good idea.

Finally, have a call to set up the cache ahead of time:

	lresult = InitCache(class,cmd,cache)

This way, the cache can be though of as an opened port to the class and
command. Also, this lets you do the "slow" location of the port outside the
realtime loop.

> The Object and Command structs contain the class and cmd (method) codes, 
> respectively, for this request.  Note that the combination of object and 
> command uniquely define the server to be used, so no port actually need 
> be referenced explictly.

Also, as noted above, the combination of object and cache also uniquely define
the server to be used.

> The fact that there are ports involved is deliberately obscure. 

Even if you use the cache in the way I described, it doesn't have to look like
a port. In fact, now that I think of it, you don't necessarily even need to
use messages and ports.

This way the OOIPC stuff can have varying implementations: all OO, but maybe
not all IPC. You could even have (say) an ILBM library that you register as the
default ILBM server, so that the Dispatch function actually makes library
calls instead of sending messages... you get all the flexibility of IPC, and
maybe even higher preformance.

> [Some] programmers are going to want an IPC mechanism more like PPIPC and some
> are going to want OOIPC.  It's silly to restrict people to using only
> one paradigm.  There may be a way to integrate the two approaches and
> get the best of both worlds in terms of performance and features.  

Complete agreement. Which is why I encourage you to use PPIPC messages...

> Curiously enough, I found that my original spec for standard messages
> and objects may not be sufficient, and the result of the redesign is
> starting to look a little like IPCMessages.  Highly simplified, with
> only 2 flag bits instead of 7 or 8, but its ancestry is clearly evident. 
> :-)

Well, would it be possible to bring the actual message formats closer? What
do you need that PPIPC messages don't provide?
-- 
-- `-_-' Peter (have you hugged your wolf today?) da Silva.
--   U   Mail to ...!uunet!sugar!peter, flames to /dev/null.
-- "Running DOS on a '386 is like driving an Indy car to the Stop-N-Go"

peter@sugar.UUCP (Peter da Silva) (07/09/88)

In article <6467@well.UUCP>, shf@well.UUCP writes:
> Well, the "cmd" argument cannot be ignored so easily.  It's actually a
> pointer to a struct containing not only the method code, but any
> arguments that method requires, since most commands are more than just a
> single code.  For example, if you want to tell a bitmap to `SHOW'
> itself, you also have to tell it _how_ to show itself. 

OK. I got the impression this stuff was in the object. Silly me.

> | [ object servers that aren't seperate processes ]

> This is a *neat* idea.  I'm not really sure how to do something like
> this, but it sounds great!  Of course, everything can be done with IPC,
> but sometimes using IPC for relatively simple things seems like
> overkill.  Got more details on what you're thinking of here, Peter? 

Off the top of my head:

You have a routine in your program, or [more likely] in from a library
You call "DeclareServerRoutine(command, class, routine, priority)". When you
try to send a message to a routine, it uses this subject to the priority:

	Priority < 0	-- Use message server if available (the "default"
			   routine).
	Priority > 0	-- Use routine unconditionally (the "override"
			   routine).
	Priority = 0	-- This is the ultimate default routine.

I don't know any other meaningful priorities, but you might as well use all
the bits.

Then when you call Dispatch(), it searches your queue for hipri servers, then
the message ports, then your queue again for lopri servers (this can be
optimised by putting the queue in order). If all else fails it calls the
0 priority routine.

If the routine is used, it's called with the object and command arguments
from Dispatch(). Normally this routine will just return "server not found",
but you can use it to gateway to an alternate server.

> I've added some OOIPC specific fields to the standard part of the
> message, and I've made items simpler by eliminating most of
> the flag bits.  The message format is something like this: 

[ Basically looks like a PPIPC message with an extra pair of fields: an
  object and an alias ]

Why pass the object in the call to Dispatch *and* in the command itself?
Otherwise, the structures are close enough for government work.

I'm also not sure about the purpose of the "alias". Could you be more specific?

> By allowing `data' to point to an object, most of the flag bits under 
> PPIPC become unnecessary.  If something has a complex behavior, that can 
> be encoded into its methods if it's an object.

That's cool. Got to worry about server loops, though.
-- 
-- `-_-' Peter (have you hugged your wolf today?) da Silva.
--   U   Mail to ...!uunet!sugar!peter, flames to /dev/null.
-- "Running DOS on a '386 is like driving an Indy car to the Stop-N-Go"

shf@well.UUCP (Stuart H. Ferguson) (07/15/88)

+--- From: peter@sugar.UUCP (Peter da Silva)
| > [the cmd argument is a]
| > pointer to a struct containing not only the method code, but any
| > arguments that method requires, since most commands are more than just a
| > single code.  
| OK. I got the impression this stuff was in the object. Silly me.

I guess the other Peter thought this as well.  OOIPC is not as different 
from PPIPC at this level than it might at first appear.
 
| > | [ object servers that aren't seperate processes ]
| > This is a *neat* idea.  [...] Got more details on what you're thinking 
| > of here, Peter? 
| Off the top of my head:
[top of the head details deleted...]

I sounds sort of sensible.  In fact, I'm revising the OOIPC design to
include some sort of priorities for servers since this seems more useful
than not.  It might be fairly easy to add different classes of servers,
i.e. message port servers, function servers, (other types?).  I'm a
little concerned about public memory considerations since this scheme
would seem to mix things up pretty seriously, but obviously this isn't a
real concern with current Amigas. 

 
[discussing message formats ...]
| [ Basically looks like a PPIPC message with an extra pair of fields: an
|   object and an alias ]
 
| Why pass the object in the call to Dispatch *and* in the command itself?

I debated this a little, and I still may go and do it another way.  
Right now you just do Dispatch (command, object, cache) and the first 
thing Dispatch() does is:

	command->object = object;

I was trying to make commands and objects distinct things, but perhaps 
that's not such a good idea since it's not strictly true.

| I'm also not sure about the purpose of the "alias". Could you be more 
| specific?

Sure.  Suppose you have a server with one service port and you want it 
to serve lots of diverse commands and methods.  You could do:

	RegisterService (port, OBJ1, MTH1, 0);
	RegisterService (port, OBJ1, MTH2, 0);
	RegisterService (port, OBJ2, MTH3, 0);

and so on.  This means that any of these types of requests could be 
posted to this same message port requiring the server to look into the
command code and object class fields in order to determine what it is
supposed to do.  But this was already done by the library when it looked
up the port in the first place.  Why do it twice?  Thus aliases.  In
order to make to lookup happen only once, the server can register a
specific alias to be associated with a given service applied to a given
port, as in: 

	RegisterService (port, OBJ1, MTH1, 0);	/* alias 0 */
	RegisterService (port, OBJ1, MTH2, 1);	/* alias 1 */
	RegisterService (port, OBJ2, MTH3, 2);	/* alias 2 */

and so on.  When the server gets a command on its service port, it only 
has to look at the alias code to determine the nature of the request.  
In the example above, alias value 0 is a request for method code 1 on
object class 1, value 1 is method 2, object 1 and so on.  Using 
sequential integers as above makes for efficient switch blocks, or you 
could just pass the function pointer itself as the alias and just do 
(*com->alias)(com), if you're a trusting soul.

| Otherwise, the structures are close enough for government work.

Intentionally.  I could have used vanilla PPIPC messages, but I have 
conceptual difficulties with all the flag bits and was trying to see if
I could do it with fewer. 

| > By allowing `data' to point to an object, most of the flag bits under 
| > PPIPC become unnecessary.  If something has a complex behavior, that can 
| > be encoded into its methods if it's an object.
| That's cool. Got to worry about server loops, though.

What do you mean by "server loop?"  If you mean that servers can't 
normally be called recursively, then yes, that's something to worry 
about.  I haven't really got a good answer for that one, except perhaps 
using software interrupt style service ports, or using your suggestion 
of functions for synchronous requests instead of messages.

| -- `-_-' Peter (have you hugged your wolf today?) da Silva.
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC		(shf@Solar.Stanford.EDU)