[alt.sources.amiga] ipc.docs -- Documentation for IPC

amiga-sources@sugar.uu.net (alt.sources.amiga) (09/11/88)

Archive: uunet!~uucp/amiga-sources/ipc.docs.Z

:
#! /bin/sh
# This is a shell archive, created on Sugar Land Unix (..!uunet!sugar)
# by amiga-sources (alt.sources.amiga) on Sun Sep 11 08:14:11 1988
# Remove anything before the "#! /bin/sh" line, then unpack it by saving
# it into a file and typing "sh file".  If you do not have sh, you need 
# unshar, a dearchiving program which is widely available.  In the absolute
# wost case, you can crack the files out by hand.
# If the archive is complete, you will see the message "End of archive."
# at the end.
# This archive contains the following files...
# 'READ_ME'
# 'ipc.doc'
# To extract them, run the following through /bin/sh
echo x - READ_ME
sed 's/^X//' > READ_ME << '//END_OF_FILE'
X
X               Inter-Process Communication Standard
X               ====================================
X
X                             July/Aug 1988
X
X
XThe stuff in this release is a result of several months' work by several
Xpeople on usenet. The goal has been to develop a standard for Inter-Process
XCommunication on the Amiga (henceforth known as "IPC").  This standard is
Xcompletely Public Domain, and we think it could lead to some outstanding
Xnew capabilities for this machine.  The basic standard is now in a fairly
Xstable -- hence publishable -- form.  So, here it is.
X
X
X                  What's in this release
X                  ======================
X
XThis release (through alt.sources.amiga) contains only sources and
Xdocumentation. There should be four shar format files in the package,
Xas follows (see below for details):
X
X IPC_docs.shar		-- this READ_ME and ipc.doc
X IPC_src.shar		-- IPC include headers and system source files
X IPC_demo_src.shar	-- Some simple demo code 
X IPC_manx_demos.shar	-- Some demo code written directly in Manx/Aztec C
X
X
XThe complete release (available by anonymous FTP from ucbvax) currently
Xcontains the documentation (plain text) file, the sources in shar format,
Xand one zoo-format compressed binary file containing the demo (demo_src)
Xin executable form.  [DON'T FORGET to use BINARY mode when ftp'ing this!].
X
X
XIPC_docs.shar	--  contains this READ_ME, plus:
X
X      ipc.doc   --  A description of the IPC concept and this standard.
X                    (Not yet as complete as I know it ought to be...)
X
XIPC_src.shar
X                --  An archive containing the source files for the IPC
X                    system routines. See the READ_ME file in the archive
X                    for contents and details.
X
XIPC_demo_src.shar
X                --  An archive containing source files for the demo
X                    program modules "Pserver" and "MinClient".  See the
X                    READ_ME file in the archive.
X
XIPC_manx_demo.shar
X                --  A client/server pair written by Brian J. Witt in
X                    Manx/Aztec C to demonstrate and test the IPC system.
X                    (They will also compile under Lattice.)
X
X
X                                %%%%%%%%%%%%%
X
X
XAcknowledgments and attributions:
X
XThis package and its contents were compiled by Pete Goodeve, who should be
Xflamed... er.. blamed... for all its inadequacies.  All the code here except
Xfor the Manx demos was also written by Pete.
X
XThe IPCMessage format was largely the design of Peter da Silva.
X
XThe mechanism used to manage IPCPorts safely ("use counts") was originally
Xsuggested by Matt Dillon.
X
XThe additions to IPC.h and IPC.c needed to make it compatible with Manx C
Xwere supplied by Brian Witt, who also wrote the Manx format demos.
X
XEssential criticism and suggestions have come from Stuart Ferguson, Ron
XMinnich, Chuck McManis, Leo Schwab, and many other denizens of the net.
XI know I've omitted some names I shouldn't have, but a lot of messages (of
Xthe net variety) have been flowing during the past many months.
XMuch appreciation is due to all who have taken the trouble to read,
Xconsider, and contribute to the mass of material that has accumulated.
XThank you all!
X
X                                                1988 September 1
X
X                                                Pete Goodeve
X                                                3012 Deakin Street #D
X                                                Berkeley, Calif. 94705
X
X                                                [...ucbvax!violet!pete]
X
X
X                                %%%%%%%%%%%%%
X
//END_OF_FILE
echo x - ipc.doc
sed 's/^X//' > ipc.doc << '//END_OF_FILE'
X
X          An Inter-Process Communication Standard for the Amiga
X          =====================================================
X
XThis is initial documentation for the IPC standard developed via usenet
Xover the past several months.  A large part of the standard is now fairly
Xstable (the IPCPort mechanism in particular), but there is a lot of work
Xstill to be done on the details, on developing message IDs for specific
Xfunctions, and on publishing them.  Anyway, in its present state, here it
Xis.
X
X
XWhy IPC?
X========
X
XUp to now, even though the Amiga is the first really totally multitasking
Xpersonal computer, programs for it have been written much as for any of the
Xolder one-job-at-a-time machines (though they often take good advantage of
Xthe windowing environment): they run as single processes.  A few programs
Xspawn child tasks to perform some of their functions, but they are still
Xmonolithic in their design.
X
XThere is an alternative.  A ... let's call it a "Job environment"... could
Xbe serviced by a number of more specialized processes, communicating with
Xeach other.  Depending on the needs of that environment, these processes
Xcould be very specialized -- a note bender in a MIDI system, say -- or more
Xgeneral, like a text editor that called up things like a spell checker or
Xoutput formatter when needed.  Such a system would give the user much more
Xchoice in configuring it to his/her preferences. (Not forgetting though
Xthat a default configuration would have to be as easy to use as any well
Xdesigned program!)  The modules in an environment wouldn't all have to come
Xfrom one company, as the interface to invoke a module's function would be
Xpublished with the module.  You could add special purpose functions to a
Xpaint program say, just by starting up another process that would
Xrecognize, or be recognized by, the paint program.
X
XThere are a lot of possible applications of this principle, with widely
Xvarying requirements.  Here is a very incomplete list of a few that come to
Xmind:
X
X    *   Communications -- connect terminal emulators, protocol handlers
X                    [Kermit, XModem etc.], auto-answer modules, script
X                    processors etc. to suit the user's environment.
X                    [Note the wide range of parameters such as processing
X                    speed demanded by different modules: protocol handlers
X                    will have to operate character by character at baud
X                    rates, while script servers and auto-answer can be much
X                    more leisurely.]
X
X    *   MIDI Modules -- a lot of possibilities here for a fast IPC
X                    protocol; anything you might want to do to a MIDI
X                    channel could be a "plug-in" module.
X
X    *   Data Acquisition and Control -- there are untapped opportunities
X                    for a multitasking machine in the laboratory; being
X                    able to "plug" modules together like you can with lab
X                    equipment would be a great attraction.
X
X    *   Desktop Publishing -- put together a comprehensive and competent
X                    system from the pieces YOU prefer.
X
X    *   Desktop Video and Presentation -- lots of enticing possibilities
X                    here; the real-time nature of presentation gives lots
X                    of opportunities for fast IPC.  (One might even think
X                    of coupling several machines together...!)
X
X    *   Service Programs -- to do common jobs for other modules; small ones
X                    -- print format servers, pattern matchers, directory
X                    searchers etc. -- can take a lot of the load off other
X                    modules that would otherwise have to include code for
X                    those things; larger ones could handle jobs like spell-
X                    checking for any program that wanted it.
X
X    *   A Multitasking H*perC*rd -- a somewhat vaguely specified, but
X                    highly enticing, goal; dream your own scenario...
X
X
XThis should give some flavor of the ways in which I think a general
X"Cooperating Processes Paradigm" would be a winner.  You can see that a
Xwide range of schemes could fall under the term "IPC".  It would be nice if
Xthey could all be handled by one underlying protocol.
X
XThere are a number of possible candidates.  Processes can pass information
Xbetween each other via files and pipes, for example.  This has the great
Xadvantage that it is already built into the system, but its disadvantage is
Xthe heavy overhead involved in file-type I/O.  Also, simple serial stream,
Xunstructured, communication isn't good enough for a system that is going to
Xpass around many different types of information.  The receiver of
Xinformation has to know exactly what it is getting, and the sender must
Xknow exactly how to tell it.
X
XThis means some kind of standard structure for the data that can be
Xunderstood by all processes. IFF is such a standard, but again
Xunfortunately it is too complex and serial-oriented for very fast
Xcommunication.  Its principles make a good starting point though.
X
XThere is an obvious candidate built into the Amiga Exec: Messages and
XPorts.  These are actually just about what we want, but there are a couple
Xof problems with them as they stand.
X
XFirst, although ports work perfectly when child tasks spawned and managed
Xby a single master process use them to talk to each other, there is no
Xprotection against accidents that are likely to occur when independent
Xprocesses communicate.  The problem is that, as ports are accessed by a
Xpointer, there is no way of being sure that the port pointed to still
Xexists when you want it, unless you lock out all other processes before you
Xget the pointer, and don't unlock them again until you've used it.  This
Xcan get VERY cumbersome and inefficient if you want to send a lot of
Xmessages to a port, as you have to do the Forbid/Find pointer/Use pointer/
XPermit sequence for every message.
X
XSecond, there is the problem of a process knowing exactly what is in the
Xmessage it has received.  As we said, there must be a Standard Structure
Xfor the data in the message so that it becomes easy for different authors
Xto write programs that can understand each other.
X
XHence the IPC Standard really breaks down into two parts: IPCPorts and
XIPCMessages.  These are essentially independent of each other, in that the
XPorts have no knowledge or concern about the message structure (aside from
Xthe necessity for the standard Exec Message structure at its heart), and
Xconversely the Messages are not concerned with the Port procedures.
X
XIt should be pointed out that this is a "Foundation Level" protocol.  It
Xdefines how ports should be managed, and the common structure of messages,
Xbut says nothing more about how they are to be used.  There are many higher
Xlevel considerations, such as how the processes should appear to the user,
Xand how he is to control them, that need to be worked out.  There are a lot
Xof possibilities here: control panels, patch panels, "drop-in" menus; some
Xapplications will need added capabilities such as command languages and
Xscripts; others would be slowed unacceptably by such overhead.  But with
Xluck this standard will be general enough to cover the range.
X
XThere are other schemes, actual and potential, that have to be considered
Xin relation to this one.  In general there is probably no need for them to
Xbe competitors.  One such is AREXX, which has already been successful in
Xapplications like integrating editors with text formatters; because it is
Xbasically an interpreted script language, it doesn't seem so suitable for
Xsome of the other potential applications mentioned above.  There seems no
Xreason though why an interface between AREXX and this standard could not be
Xwritten; only a restricted set of IPCMessages could be handled, but
Xprobably enough to give great flexibility.
X
XAnother possibility is an "Object Oriented" communication scheme. This has
Xboth similarities and differences to this protocol, but is still in rather
Xformative stages at this point.  We will have to wait to see if the two
Xschemes can coexist: I believe they can.
X
X
XIPCPorts
X========
X
XAn IPCPort is a rendezvous point between processes where messages can be
Xdropped off and picked up.  It is identical in concept to the standard
XAmiga Exec MsgPort (see the Rom Kernel Manual), but is managed so that
Xmessages cannot be sent to a non-existent port (if the processes obey the
Xrules!).  Any number of "Client" processes can be sending messages to a
Xport at one time, but there can be only one "Server" on a port.  If a port
Xdoesn't have a Server -- either running or in the process of being loaded
X--, it is "Closed", and won't accept messages.
X
XUnlike an Exec MsgPort, an IPCPort doesn't "belong" to any particular
Xprocess, and a program must never create one directly or assign memory in
Xits own space for one: a port will be created by the first process that
Xneeds it, and will remain available until all references to it have been
Xcleared; it may be finally deleted by the last user long after the first
Xhas gone away. Either a Server or Client may make the first reference.
X
XEach port is identified by a unique name (although unnamed anonymous ports
Xare also possible, as we'll see later); the name may be any appropriate
Xnull-terminated byte string.  A port is located by an exact match to the
Xstring: the case of the characters is respected.  The author of a server
Xwill publish the names of the ports it services, so that others can write
Xclients to access it; if two programs offer alternatives for the same
Xservice, they should use the same port name, so that the user may plug one
Xof them in without changing the client.
X
XIPCPorts are managed by a procedure module linked in with each program that
Xuses IPC.  No separate manager process is needed, although for more
Xflexibility it is possible to run a "Port Broker" that manages the loading
Xof servers when their ports are requested (this will probably become the
Xusual mode).  At the moment, each program must have its own copy of the
Xcode, but it will eventually be a resident library.
X
X
XClients and IPCPorts
X====================
X
XWhen a Client process first needs a port of a particular name, it must get
Xa pointer to that port.  The pointer will then remain valid until the
XClient specifically drops its access request.  Each request made MUST be
Xpaired eventually with a drop for correct port management.
X
XThere are three possible ways of getting a port pointer.  Each of these
Xprocedures takes a names string as argument and returns the pointer if
Xpossible.  They differ in the actions they take to ensure the status of the
Xport.
X
X    GetIPCPort(name)    always returns a valid pointer (unless memory is
X                        full, or some other disaster strikes).  The port is
X                        created if it doesn't exist.  No indication is
X                        given as to whether there is a current server.
X
X    FindIPCPort(name)   only returns a pointer if the port already exists
X                        and has a server; otherwise it returns NULL.
X
X    LoadIPCPort(name)   (an addition to the basic procedures that is in its
X                        own module) does a GetIPCPort, but if the port has
X                        no server it calls on a "Port Broker" process
X                        (also an addition to the basic system) to load one;
X                        if the broker can't do this (or the broker doesn't
X                        exist) the port will be dropped again, and NULL
X                        will be returned.  If a valid pointer is returned,
X                        you can assume that a server exists or is being
X                        loaded.
X
X                        LoadIPCPort does not wait for the server to be
X                        loaded, but the "Loading" flag will be set in the
X                        port so that it will accept messages for the server
X                        to handle when it arrives.
X
XEach successful call to one of these procedures increments the "Use Count"
Xof the port.  To reduce the use count again you must end the Client's
Xaccess to the port by:
X
X    DropIPCPort(port)   where 'port' is the pointer returned by any of the
X                        above calls.  The use count is reduced by one: if
X                        it goes to zero, the port is deleted.
X
XA Client must not exit without dropping all the ports it has acquired (and
Xof course must not drop them more times than it has acquired them!).
X
X
XA Client sends messages to an IPCPort by a call exactly analogous to Exec's
XPutMsg(), but the Exec call has no way of detecting the presence or absence
Xof a Server, so it cannot be used.  Instead use:
X
X    PutIPCMsg(port,message) where 'port' is a valid pointer, and 'message'
X                            is a pointer to an IPCMessage.  It returns TRUE
X                            if the message was successfully queued on the
X                            port; if the port has no server either present
X                            or loading, it will not send the message and
X                            will return FALSE.
X
XUnless there are specific reasons otherwise, a message sent to a Server
Xwill eventually be replied, and the Client must handle this also by
Xsupplying a Reply Port.  The reply path does not need the IPCPort protocol,
Xbecause a Client MUST keep the reply port available until it has received
Xback ALL the replies it is expecting, so normally this can be a standard
XExec MsgPort.  There is no reason though why it should not be an IPCPort as
Xwell if you prefer -- even one used for other communications -- as long as
Xyou bear in mind that replies will be sent to it whether or not it has a
Xserver assigned.
X
X
XServers and IPCPorts
X====================
X
XThe Server uses a complementary set of procedures to a Client to manage a
Xport.  There is only one way it can acquire a port:
X
X    ServeIPCPort(name)  makes this process the server for the named port
X                        if possible and returns a valid pointer to the
X                        port. The port is created if it doesn't exist.  If
X                        a server already exists for the port, the call will
X                        return NULL. (If successful, it also increments the
X                        use count.)
X
XTerminating service on the other hand is normally a two-step process.
XFirst the server must shut the port against further incoming messages, then
Xhandle and reply to any messages still queued on the port, and finally free
Xup the port for eventual reclamation or for another server to claim it.
X
X    ShutIPCPort(port)   just marks the port as "Shut".  The server remains
X                        attached to the port and can receive signals from
X                        it (for example if the number of clients changes,
X                        see below), but PutIPCMsg calls will be blocked.
X
X    LeaveIPCPort(port)  removes this process from association with the
X                        port.  Also does a DropIPCPort to decrement the use
X                        count and delete if appropriate.
X
XBetween the ServeIPCPort and the ShutIPCPort, the server must be prepared
Xto accept messages on that port.  In most cases it will probably spend the
Xmajor portion of its time waiting on that port -- or possibly several ports
X-- for a message to arrive.  All this area of the server's operation is
Xhandled by standard Exec calls: WaitPort() or Wait(), GetMsg(), and
XReplyMsg() (see the Rom Kernel Manual).
X
XIf it only has one port to wait on, it can use:
X
X    WaitPort(port)  which suspends the process until a message arrives at
X                    that port.
X
XThis is liable to be inadequate though, because it will only be woken up by
Xmessages arriving on that particular port.  It is NOT awakened by other
Xsignals to the process, even if they use the same signal bit (see the RKM
Xfor Task Signals).  Thus you are more likely to want to use:
X
X    Wait(sigbits)   where 'sigbits' is a 32-bit mask of all the signals you
X                    want to be awakened on.  It returns the signals that
X                    were actually set, so the process can determine if it
X                    needs to take unusual action.
X
XThis means, though, that you have to create the sigbits mask from the
Xsignal bit number contained in the port itself (and other bits that you
Xwant to respond to).  There is no specific call to get this (though there
Xshould probably be at least a macro), but if the server is just using IPC.h
Xas a header (and not IPCPorts.h) IPCPorts are equated to MsgPorts, so you
Xcan get the bit by:
X
X    sigbit = 1L<<port->mp_SigBit;
X
XNote that this bit is also used by the "Notify" feature (below) to awaken
Xthe server if the number of clients changes.  No message is associated with
Xthis signal, but all the server has to do is check the number of clients
X(again, below) each time it is awakened.
X
XTo process a received message, the server simply uses GetMsg(), though it
Xis preferable to cast the returned value to the correct type:
X
X    msg = (struct IPCMessage *)Getmsg(port);
X
XWhen done with the message, it should use ReplyMsg() in the normal way
X(using a cast if your compiler applies prototype checks):
X
X    ReplyMsg((struct Message *)msg);
X
X
XChecking IPCPort Status
X=======================
X
XEither Client or Server can get information about the current state of an
XIPCPort with the CheckIPCPort() call.  The Server alone can also set
Xthe state of certain flags in the port (only one is currently defined).
X
X    CheckIPCPort(port,flags)    as long as the high bit of 'flags'
X                                (a 16-bit value!) is not set, returns the
X                                number of users (including the server)
X                                currently aware of the port; if the high
X                                bit is set (0x8000 -- this should be a
X                                defined identifier... an omission in the
X                                current IPC.h, sorry), the call instead
X                                returns the current flags set in the port.
X                                When called by the current Server ONLY, the
X                                value in the low 8-bits of the 'flags'
X                                argument will be set into the port's Flags
X                                slot; system flags in the upper 8-bits of
X                                the slot are not affected.
X
XAlthough a Client may use this call, it will probably have no need to,
Xunless it wants to check for the presence of a Server without making a
XPutIPCMsg call.  The Server, however, can use the call to keep tabs on how
Xmany clients actually require its services, and optionally terminate if
Xthere are none.  To do this it will want to be notified if the number of
Xclients changes; this can be done by setting the IPP_NOTIFY flag in the
Xport: while that is set, any call that acquires or drops a port will send a
Xsignal to the Server process (using the signal bit defined for that message
Xport); no message is actually sent, but the Server should call CheckIPCPort
Xeach time it is woken up.
X
X
XAnonymous IPCPorts
X==================
X
XIt is possible to create IPCPorts that are unnamed, but these obviously
Xcannot be acquired independently by other processes without a name to
Xaccess them by.  The associated pointers must be passed to other processes
Xvia some standard message pathway (left up to the processes concerned).
XThey still should obey the IPC rules, though, so another procedure is
Xprovided for acquiring them:
X
X    UseIPCPort(port)    registers another user for that port (i.e.
X                        increments the use count).
X
XWhen the user process is done, it issues DropIPCPort in the usual way.
X
XYou create an anonymous IPCPort by:
X
X    ServeIPCPort(NULL)  which will return a pointer to a NEW port for
X                        each call, and set the caller as the Server.
X                        (It will only fail if there is no memory or some
X                        such fatal problem.)
X
XFor special cases -- e.g. ReplyPorts -- where you know PutIPCMsg will never
Xbe used, you could instead use GetIPCPort(NULL), but there is NO way of
Xregistering a server on an anonymous port except at creation time.
X
X                            +++++++++++
X
XIPCMessages
X===========
X
XThe format of IPCMessages is intended to be very flexible, yet specific
Xenough that a Server can immediately determine the function and content of
Xa message it receives (or reject it if it does not recognize it).
X
XThe protocol has two levels where identification is specified.  There is a
Xfixed structure Message header (basically an Exec Message structure with
Xadded information) which includes a Message ID, followed by an arbitrary
Xnumber of "Items", each again of fixed structure with its own Item ID.
XEach item in turn usually points to a block of memory where the actual data
Xfor the item is stored.  Instead of a pointer, a single 32-bit value can be
Xstored in the item itself.  In special cases, the data pointed to may be
Xmore complex than a single data block (a list, say) but then the
Xrestrictions on what can be done with the message increase markedly.
XAs long as all the items in a message are simple data blocks (or single
Xwords), it can be passed between servers that do not have to understand the
Xcontents of those blocks: deletion of the message, for example can be done
Xby any server.  Flags in the message and each item indicate whether the
Xdata is private to the originating process or can be transferred to the
Xreceiver, whether it is suitable to send out on a network, and so on.
X
XAn ID -- Message or Item -- is a 32-bit longword, normally a four-character
XASCII code.  All "Published" IDs should be of this form, but cooperating
Xprocesses could perhaps use non-ASCII numeric values internally.  If the
Xfirst (high) byte is zero, the ID is a private one.  Codes of less than
Xfour characters may of course be used, but they preferably should be padded
Xon the right with blanks (rather than nulls).  Case is important naturally;
Xby convention (and analogy to IFF) upper case is preferred, but there is no
Xfirm requirement for this; lower case should probably be used to extend on
Xmeanings that were orignially upper case.
X
XFor details on IPCMessage structure, and the various flags currently
Xdefined, please refer to the IPC.h header file.  [A fuller discussion will
Xbe included in a future revision of this document...]  For examples of IDs,
Xlook at the demo example sources on this disk. [Again, at some point not to
Xfar distant, I hope to publish a list of IDs suggested for various
Xfunctions.]  When assigning your own IDs, please do it with future
Xexpansion in mind, and publish them on usenet or elsewhere as soon as
Xpossible for comment.
X
X
XMessage Structure
X=================
X
X(briefly)
X
XEach message has a header which is a standard message structure, followed
Xby an ID field (32-bits), a 32-bit Flags field, and an Item Count
X(16-bits).  This is immediately followed by that number of items, each of
Xwhich has the following structure:  Item ID (32-bits), Flags (32-bits),
XSize of data block (32-bits), and Pointer to data block.  This may in turn
Xbe followed by a data area containing the data for some or all of the items
Xin a message; this may or may not be convenient, depending on the nature of
Xthe data.  The mn_Length field in the standard message structure indicates
Xthe complete length of the message (remember it is only 16-bits, so the
Xmaximum size of a message containing in-line data is 64K).
X
XAs already remarked, the "Pointer" field of an item may not in fact point
Xto a single block of data, but may be a single value or a NON-STANDARD
Xpointer (a BPTR for example). In both these cases, the Size of the item
Xshould be set to ZERO.  The Flags field will give other information about
Xthe item, some system, some private (defined by the application).  For the
Xcurrent system flags, please see IPC.h.
X
X
XManaging IPCMessages
X====================
X
XTwo system procedures are provided for convenient management of memory for
XIPCMessages (much preferable to the program doing it all for itself).
X
X    CreateIPCMsg(items, extra, replyport)   creates a new message block
X                                            for that number of 'items'
X                            (0..n), with 'extra' bytes of memory after the
X                            items for data storage (you will have to get
X                            its offset as the location of the "item"
X                            following the last actual item); the
X                            'replyport' pointer is inserted in the standard
X                            message structure.  It returns a pointer to the
X                            created message (or NULL if there is no space).
X
X    DeleteIPCMsg(msg)       deletes the memory block created by
X                            CreateIPCMsg.  It does NOT attempt to handle
X                            memory occupied by data outside the message and
X                            pointed to by its items.
X
X
X[This document is still in progress -- apologies for omissions]
X
X
X                            +++++++++++
X
X                                            Pete Goodeve
X                                            July 1988
X
//END_OF_FILE
echo "End of archive."
# end of archive.
exit 0