Doors are made visible to the applications programmer as standard UNIX file descriptors (or “door descriptors”). To make a door visible to other applications, a process may attach an existing door descriptor to an existing regular file in the UNIX file system, using a standard SVR4 mechanism for associating STREAMS file descriptors with files in the file system.
What follows is a list of the relevant library routines encompassing the Solaris Doors API, and the two related routines fattach(3) and fdetach(3). Most detail is omitted, since it is covered at length in the Solaris documentation [7], but there should be enough to provide a general overview of the supported functionality.
• door create(3) is used to create a new door. The function takes as its arguments a
server procedure, data cookie, and flags. The data cookie is a value passed to the
server procedure every time this door is the target of a door call(3) method invocation.
The result of the function call is a door descriptor, which can subsequently be used
for door call(3) invocations, attached to a file with fattach(3), or passed directly to
other processes (again via door call(3)). The process which calls door create(3) is the
same process which handles door call(3) invocations. Any running process can be a
door server, simply by calling door create(3).
• door call(3) is used to invoke a procedure call in the remote server process which
created the door using door create(3). The function takes as its arguments a door
descriptor, representing the procedure to call in the server, a memory block (contain-
ing the arguments for the procedure call), and a set of door descriptors which are to
be passed to the server process. The door descriptor is the only required argument,
the memory block and set of doors are each independently optional. The result of
the function call is either an error code, or another memory block and set of door
descriptors from the server process (again, both are optional, at the server’s discre-
tion). The client process may provide a memory buffer in which the results (if any)
from the server will be placed. If the client-provided result buffer is too small to hold
the results from the server, the operating system will allocate a new memory block
large enough to hold the results of the call.
• door return(3) is used within a server procedure to return values to the client process.
It is only valid to call door return(3) within a server procedure called by a door call(3)
invocation. The arguments that this function takes are a memory block and set of
doors to be returned to the client process (as the results of door call(3)). Both
arguments are optional.
• fattach(3) is used to attach a door descriptor to a regular file in the UNIX file system.
The function takes as arguments the door descriptor and a pathname to the regular
file.
• fdetach(3) is used to detach a door descriptor from a regular file (attached via fat-
tach(3)). The function takes the pathname to the file as its argument.
• door revoke(3) is used to revoke access to a door. All future door call(3) invocations
through any door descriptor referring to this door will fail.
• door info(3) is used to get information about a door. This function returns the process
id of the server which handles door call(3) invocations, the server procedure (address
in the server process), the data cookie for this door, a system-wide unique identifier
for the door, and certain other attributes, such as whether the current process is the
server for the door, whether the door has been revoked, etc.
• door cred(3) can be used within a server procedure to get the credentials of the client
process giving the current door call(3) invocation. This function returns the user id,
group id, and process id of the calling thread’s client.
• door server create(3) is used to register a function which will be called in the server
process whenever the kernel thinks that a new thread should be created. This allows
the programmer the ability to control how many threads are actually created in the
server and the initial parameters of the server threads (e.g. scheduling parameters,
signal dispositions, etc.).
• door bind(3) is used to bind the calling thread to a particular door. The calling thread
will be one of a set of threads which will specifically handle invocations on this door.
The door must have been created will the “private” attribute (via door create(3))
indicating that it has a private pool of server threads.
• door unbind(3) is used to remove the calling thread from a particular door’s private
server pool.
The Doors API was engineered with certain performance optimizations in mind. Server
threads will be created in the calling process in proportion to the load on the server (at
most one per concurrent request) [6]. The server may control how many threads are created
via door server create(3). Since the programmer doesn’t necessarily provide the memory
block to receive arguments to and from door call(3), the kernel may optimize the transfer
of large arguments by mapping the underlying pages of memory into the target process and
copying a page only if a process attempts to modify it. The kernel may also use handoff
scheduling to optimize door call(3) invocations [6].