Jump to content

Distributed SOM (DSOM): Difference between revisions

From EDM2
Ak120 (talk | contribs)
Line 442: Line 442:


====Using specific servers====
====Using specific servers====
In DSOM, the process that manages a target object is called the object's server. Servers are implemented as programs that use SOM classes. Server implementations are registered with DSOM in an Implementation Repository. The Implementation Repository is a database queried by clients in order to find desired servers, and queried by DSOM in order to activate those servers upon demand.
The example above placed no constraints on the DSOM Object Manager as to where the remote "Stack" object should be created. The somdNewObject call creates a remote object of a specified class in an arbitrary server that implements that class. However, the DSOM Object Manager provides methods for finding specific servers.
For example, the client program above can be modified slightly to find a specific server named "StackServer", which has already been registered in DSOM's Implementation Repository. (Note that the programmer knew or discovered that the "StackServer" server implementation supports the "Stack" class.) The highlighted lines below show the changes that were made:
<PRE>
#include <somd.h>
#include <stack.h>
int main(int argc, char *argv[]) {
        Stack stk;
        Environment e;
        SOMDServer server;
        SOM_InitEnvironment(&e);
        SOMD_Init(&e);
        server =
          _somdFindServerByName(SOMD_ObjectMgr, &e, "StackServer");
        stk = _somdCreateObj(server, &e, "Stack", "");
        _push(stk,&e,100);
        _push(stk,&e,200);
        _pop(stk,&e);
        if (!_empty(stk,&e)) somPrintf("Top: %d\n", _top(stk,&e));
        _somdDeleteObj(server, &e, stk);
        _somdReleaseObject(SOMD_ObjectMgr, &e, stk);
        _somdReleaseObject(SOMD_ObjectMgr, &e, server);
        SOMD_Uninit(&e);
        SOM_UninitEnvironment(&e);
        return(0);
}
</PRE>
This version of the program replaces the somdNewObject operation with calls to somdFindServerByName and somdCreateObj. The somdFindServerByName method consults the Implementation Repository to find the DSOM server implementation whose name is "StackServer", and creates a server proxy, which provides a connection to that server. Every DSOM server process has a server object that defines methods to assist in the creation and management of objects in that server. Server objects must be instances of SOMDServer or one of its subclasses. The somdFindServerByName returns a proxy to the SOMDServer object in the named server.
Once the client has the server proxy, it can create and destroy objects in that server. The somdCreateObj call creates an object of the class "Stack" in the server named "StackServer".
To free the remote "Stack" object, the example shows a somdDeleteObj request on the stack object's server. Next, somdReleaseObject requests are made on the DSOM Object Manager, to free the stack proxy and the server proxy in the client. (Note that these three calls are equivalent to the somdDestroyObject call in the previous example.)


===A note on finding existing objects===
===A note on finding existing objects===

Revision as of 04:11, 9 May 2021

System Object Model Programming Guide
  1. About This Book
  2. Introduction to the SOMobjects Developer Toolkit
  3. Tutorial for Implementing SOM Classes
  4. Using SOM Classes in Client Programs
  5. SOM IDL and the SOM Compiler
  6. Implementing Classes in SOM
  7. Distributed SOM (DSOM)
  8. The SOM Interface Repository Framework
  9. The Metaclass Framework
  10. The Event Management Framework
  11. SOMobjects Error Codes
  12. SOM IDL Language Grammar
  13. Implementing Sockets Subclasses
  14. Glossary

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Note: The SOMobject Base Toolkit provides the capability for implementing Workstation Distributed System Object Module (DSOM) (distribution among processes on a single machine). Implementing an application that is distributed across a network of machines requires Workgroup DSOM, which is available only in the full-capability SOMobjects Developer Toolkit.

The following subjects are discussed in this section:

  • A Simple DSOM Example
  • Basic Client Programming
  • Basic Server Programming
  • Implementing Classes
  • Configuring DSOM Applications
  • Running DSOM Applications
  • DSOM as a CORBA-compliant Object Request Broker
  • Advanced Topics
  • Error Reporting and Troubleshooting
  • Limitations

What is Distributed SOM?

Whereas the power of SOM technology comes from the fact that SOM insulates the client of an object from the object's implementation, the power of DSOM lies in the fact that DSOM insulates the client of an object from the object's location.

Distributed SOM (or DSOM) provides a framework that allows application programs to access objects across address spaces. That is, application programs can access objects in other processes, even on different machines. Both the location and implementation of an object are hidden from a client, and the client accesses the object (by way of method calls) in the same manner regardless of its location.

DSOM currently supports two types of distribution:

  1. distribution among processes on the same machine (referred to as Workstation DSOM)
  2. and distribution among a network of machines (referred to as Workgroup DSOM).

DSOM runs on the AIX (Release 3.2.5 and above) and OS/2 (Release 2.0 and above) operating systems. A Workstation DSOM application can run on a machine in either environment using core capabilities of the SOMobjects system. Under the full capability SOMobjects Developer Toolkit, Workgroup DSOM supports distribution across local area networks comprised of both OS/2 and AIX systems. Future releases of DSOM may support large, enterprise-wide networks.

Support for TCP/IP and NewWare IPX/SPX is provided on AIX, OS/2, and Windows. NetBIOS support is provided for OS/2 and Windows. DSOM communications is extensible in that an application can provide its own transport (see Appendix C of the SOMobjects Base Toolkit Users Guide).

DSOM can be viewed in two ways:

  1. As a System Object Model extension that allows a program to invoke methods on SOM objects in other processes.
  2. As an Object Request Broker (ORB); that is, a standardized "transport" for distributed object interaction. In this respect, DSOM complies with the Common Object Request Broker Architecture (CORBA) specification, published by the Object Management Group (OMG) and x/Open.

This chapter describes DSOM from both perspectives.

DSOM features

Here is a quick summary of some of DSOM's more important features:

  • Uses the standard SOM Compiler, Interface Repository, language bindings, and class libraries. Thus, DSOM provides a growth path for non-distributed SOM applications.
  • Allows an application program to access a mix of local and remote objects. The fact that an object is remote is transparent to the program.
  • Provides run-time services for creating, destroying, identifying, locating, and dispatching methods on remote objects. These services can be overridden or augmented to suit the application.
  • Uses existing interprocess communication (IPC) facilities for Workstation communication, and common local area network (LAN) transport facilities for Workgroup communications. Support for TCP/IP, Netware IPX/SPX, and NetBios is provided. DSOM communications is extensible in that an application can provide its own transport.
  • Provides support for writing multi-threaded servers and event-driven programs.
  • Provides a default object server program, which can be easily used to create SOM objects and make those objects accessible to one or more client programs. If the default server program is used, SOM class libraries are loaded upon demand, so no server programming or compiling is necessary.
  • Complies with the CORBA 1.1 specification, which is important for application portability.

When to use DSOM

DSOM should be used for those applications that require sharing of objects among multiple programs. The object actually exists in only one process (this process is known as the object's server); the other processes (known as clients) access the object through remote method invocations, made transparent by DSOM.

DSOM should also be used for applications that require objects to be isolated from the main program. This is usually done in cases where reliability is a concern, either to protect the object from failures in other parts of the application, or to protect the application from an object.

Some distributed applications may have special performance, reliability,or cooperative processing requirements, to which the SOM Replication framework is better suited. The Replication framework is oriented toward "groupware" (multi-party cooperative processing) applications, and has facilities for fault tolerance and recovery. The Replication framework is distinct from DSOM in that it maintains a complete replica of an object in each participant's address space, while DSOM establishes remote connections to shared objects. The Replication Framework is available only in the full-capability SOM objects Developer Toolkit.

Chapter Outline

Briefly, this section covers the following subjects:

  • Tutorial example
  • Programming DSOM applications
  • Configuring DSOM applications
  • Running DSOM applications
  • DSOM and CORBA
  • Advanced topics
  • Error reporting and troubleshooting

Tutorial example

First, a complete example shows how an existing SOM class implementation (a "stack") can be used with DSOM to create a distributed "Stack" application. Using the "Stack" example as a backdrop, the basic DSOM interfaces are introduced.

Programming DSOM applications

All DSOM applications involve three kinds of programming:

  • Client programming: writing code that uses objects;
  • Server programming: writing code that implements and manages objects.
  • Implementing classes: writing code that implements objects.

Three sections ("Basic Client Programming", "Basic Server Programming", and Implementing Classes") describe how to create DSOM applications from these three points of view. In turn, the structure and services of the relevant DSOM run-time environment are explained.

Note: The three sections are presented in the order above to aid in their explanation. However, the actual programming tasks are likely to be performed in the opposite order.

Additional examples are provided in these sections to illustrate DSOM services.

Configuring DSOM applications

The section "Configuring DSOM Applications" explains what is necessary to set up a DSOM application, once the application has been built.

Running DSOM applications

The section "Running DSOM Applications" explains what is necessary to run a DSOM application, once it has been built and configured.

DSOM and CORBA

Those readers interested in using DSOM as a CORBA-compliant ORB should read the section entitled "DSOM as a CORBA compliant Object Broker." That section answers the question: How are CORBA concepts implemented in DSOM?

Advanced topics

The section on "Advanced Topics" covers the following:

  • Peer versus client/server processes" demonstrates how peer-to-peer object interactions are supported in DSOM.
  • Dynamic Invocation Interface" details DSOM support for the CORBA dynamic invocation interface to dynamically build and invoke methods on remote objects.
  • Creating user-supplied proxy classes" describes how to override proxy generation by the DSOM run time and, instead, install a proxy object supplied by the user.
  • Customizing the default base proxy class"discusses how the SOMDClientProxy class can be subclassed to define a customized base class that DSOM will use during dynamic proxy-class generation.
  • Sockets class" describes how DSOM uses Sockets subclasses.

Error reporting and troubleshooting

The section on "Error Reporting and Troubleshooting" discusses facilities to aid in problem diagnosis.

A Simple DSOM Example

A sample "Stack" application is presented in this section as a tutorial introduction to DSOM. It demonstrates that, for simple examples like a "Stack", after very little work, the class can be used to implement distributed objects that are accessed remotely. The example first presents the "Stack" application components and the steps that the implementer must perform before the application can be run, and then describes the run time activity that results from executing the application. This run-time scenario introduces several of the key architectural components of the DSOM run-time environment.

The source code for this example is provided with the DSOM samples in the SOMobjects Developer Toolkit.

The "Stack" interface

The example starts with the assumption that the class implementer has successfully built a SOM class library DLL, called "stack.dll", in the manner described in Section 5.6, "Creating a SOM Class Library," of Chapter 5, "Implementing Classes in SOM." The DLL implements the following IDL interface.

#include <somobj.idl>

interface Stack: SOMObject
{
    const long stackSize = 10;
    exception STACK_OVERFLOW{};
    exception STACK_UNDERFLOW{};
    boolean full();
    boolean empty();
    long top() raises(STACK_UNDERFLOW);
    long pop() raises(STACK_UNDERFLOW);
    void push(in long element) raises(STACK_OVERFLOW);

    #ifdef __SOMIDL__
    implementation
    {
      releaseorder: full, empty, top, pop, push;
      somDefaultInit: override;
      long stackTop;                  // top of stack index
      long stackValues[stackSize];    // stack elements
      dllname = "stack.dll";
    };
    #endif
};

This DLL could have been built without the knowledge that it would ever be accessed remotely (that is, built following the procedures in Chapter 5). Note, however, that some DLLs may require changes in the way their classes pass arguments and manage memory, in order to be used by remote clients (see the topic "Implementation Constraints" in section 6.5, "Implementing Classes").

The "Stack" class implementation

#define Stack_Class_Source
#include <stack.ih>

SOM_Scope boolean  SOMLINK full(Stack somSelf, Environment *ev)
{
    StackData *somThis = StackGetData(somSelf);
    StackMethodDebug("Stack","full");

    /* Return TRUE if stack is full. */
    return (_stackTop == stackSize);
}

SOM_Scope boolean  SOMLINK empty(Stack somSelf, Environment *ev)
{
    StackData *somThis = StackGetData(somSelf);
    StackMethodDebug("Stack","empty");

    /* Return TRUE if stack is empty.*/
    return (_stackTop == 0);
}

SOM_Scope long  SOMLINK top(Stack somSelf, Environment *ev)
{
    StackData *somThis = StackGetData(somSelf);
    StackMethodDebug("Stack","top");

    if (_stackTop > 0)
    {
       /* Return top element in stack without removing it from
        * the stack.
        */
       return (_stackValues[_stackTop-1]);
    }
    else
    {
       somSetException(ev, USER_EXCEPTION,
                       ex_STACK_UNDERFLOW, NULL);
       return (-1L);
    }
}

SOM_Scope long  SOMLINK pop(Stack somSelf, Environment *ev)
{
    StackData *somThis = StackGetData(somSelf);
    StackMethodDebug("Stack","pop");

    if (_stackTop > 0)
    {
       /* Return top element in stack and remove it from the
        * stack.
        */
       _stackTop--;
       return (_stackValues[_stackTop]);
    }
    else
    {
       somSetException(ev, USER_EXCEPTION,
                       ex_STACK_UNDERFLOW, NULL);
       return (-1L);
    }
}

SOM_Scope void  SOMLINK push(Stack somSelf,
                             Environment *ev, long el)
{
    StackData *somThis = StackGetData(somSelf);
    StackMethodDebug("Stack","push");

    if (_stackTop < stackSize)
    {
      /* Add element to top of the stack. */
      _stackValues[_stackTop] = el;
      _stackTop++;
    }
    else
    {
       somSetException(ev, USER_EXCEPTION,
                       ex_STACK_OVERFLOW, NULL);
    }
}

SOM_Scope void  SOMLINK somDefaultInit(Stack somSelf,
                                       somInitCtrl* ctrl)
{
    StackData *somThis;
    somInitCtrl globalCtrl;
    somBooleanVector myMask;
    StackMethodDebug("Stack","somDefaultInit");
    Stack_BeginInitializer_somDefaultInit;

    Stack_Init_SOMObject_somDefaultInit(somSelf, ctrl);

    /* stackTop is index into stackValues for next pushed
     * stack element.
     * stackValues[0..(stackSize-1)] holds stack elements.
     */
    _stackTop = 0;
}

Client program using a local stack

A simple client program written to use a local "Stack" object is displayed below. This C program is shown so that the differences between a local and remote client program can be highlighted.

#include <stack.h>

boolean OperationOK(Environment *ev);

int main(int argc, char *argv[])
{
  Environment ev;
  Stack stk;
  long num = 100;

  SOM_InitEnvironment(&ev);

  /* The StackNewClass invocation is optional and unnecessary
   * in the client program when the class object is created in
   * the SOMInitModule function that is invoked during DLL
   * initialization.
   */
  StackNewClass(Stack_MajorVersion, Stack_MinorVersion);
  stk = StackNew();

  /* Verify successful object creation */
  if ( stk != NULL )
  {
     while ( !_full(stk, &ev) )
     {
        _push(stk, &ev, num);
        somPrintf("Top: %d\n", _top(stk, &ev));
        num += 100;
     }

     /* Test stack overflow exception */
     _push(stk, &ev, num);
     OperationOK(&ev);

     while ( !_empty(stk, &ev) )
     {
        somPrintf("Pop: %d\n", _pop(stk, &ev));
     }

     /* Test stack underflow exception */
     somPrintf("Top Underflow: %d\n", _top(stk, &ev));
     OperationOK(&ev);
     somPrintf("Pop Underflow: %d\n", _pop(stk, &ev));
     OperationOK(&ev);

     _push(stk, &ev, -10000);
     somPrintf("Top: %d\n", _top(stk, &ev));
     somPrintf("Pop: %d\n", _top(stk, &ev));

     _somFree(stk);
  }

  SOM_UninitEnvironment(&ev);

  return(0);
}

boolean OperationOK(Environment *ev)
{
   char *exID;

   switch (ev->_major)
   {
     case SYSTEM_EXCEPTION:
       exID = somExceptionId(ev);
       somPrintf("System exception: %s\n", exID);
       somdExceptionFree(ev);
       return (FALSE);

     case USER_EXCEPTION:
       exID = somExceptionId(ev);
       somPrintf("User exception: %s\n", exID);
       somdExceptionFree(ev);
       return (FALSE);

     case NO_EXCEPTION:
       return (TRUE);

     default:
       somPrintf("Invalid exception type in Environment.\n");
       somdExceptionFree(ev);
       return (FALSE);
   }
}

Client program using a remote stack

The preceding program has been rewritten below showing how DSOM can be used to create and access a "Stack" object somewhere in the system. The exact location of the object does not matter to the application; it just wants a "Stack" object. Note that the stack operations of the two programs are identical. The main differences lie in stack creation and destruction, as highlighted below. (Also see "Memory management" later for more information on allocating and freeing memory.)

#include <somd.h>
#include <stack.h>

int main(int argc, char *argv])
{
  Environment ev;
  Stack stk;
  long num = 100;

  SOM_InitEnvironment(&ev);
  SOMD_Init(&ev);

  /* The StackNewClass invocation is optional and unnecessary
   * in the client program when the class object is created in
   * the SOMInitModule function that is invoked during DLL
   * initialization.
   */
  StackNewClass (Stack_MajorVersion, Stack_MinorVersion);   
  stk = _somdNewObject(SOMD_ObjectMgr, &ev, "Stack", "");

  /* Verify successful object creation */
  if ( OperationOK(&ev) )
  {
     while ( !_full(stk, &ev) )
     {
        _push(stk, &ev, num);
        somPrintf("Top: %d\n", _top(stk, &ev));
        num += 100;
     }

     /* Test stack overflow exception */
     _push(stk, &ev, num);
     OperationOK(&ev);

     while ( !_empty(stk, &ev) )
     {
        somPrintf("Pop: %d\n", _pop(stk, &ev));
     }

     /* Test stack underflow exception */
     somPrintf("Top Underflow: %d\n", _top(stk, &ev));
     OperationOK(&ev);
     somPrintf("Pop Underflow: %d\n", _pop(stk, &ev));
     OperationOK(&ev);

     _push(stk, &ev, -10000);
     somPrintf("Top: %d\n", _top(stk, &ev));
     somPrintf("Pop: %d\n", _top(stk, &ev));
        
     _somdDestroyObject(SOMD_ObjectMgr, &ev, stk);

     if ( OperationOK(&ev) )
     {
        somPrintf("Stack test successfully completed.\n");
     }
  }
  SOMD_Uninit(&ev);
  SOM_UninitEnvironment(&ev);

  return(0);
}

boolean OperationOK(Environment *ev)
{
   char *exID;

   switch (ev->_major)
   {
     case SYSTEM_EXCEPTION:
       exID = somExceptionId(ev);
       somPrintf("System exception: %s\n", exID);
       somdExceptionFree(ev);
       return (FALSE);

     case USER_EXCEPTION:
       exID = somExceptionId(ev);
       somPrintf("User exception: %s\n", exID);
       somdExceptionFree(ev);
       return (FALSE);

     case NO_EXCEPTION:
       return (TRUE);

     default:
       somPrintf("Invalid exception type in Environment.\n");
       somdExceptionFree(ev);
       return (FALSE);
   }
}

Let's step through the differences.

First, every DSOM program must include the file <somd.h> (when using C++, <somd.xh>). This file defines constants, global variables, and run-time interfaces used by DSOM. Usually, this file is sufficient to establish all necessary DSOM definitions.

Next, DSOM requires its own initialization call.

SOMD_Init(&ev);

The call to SOMD_Init initializes the DSOM run-time environment SOMD_Init must be called before any DSOM run-time calls are made. A side effect of calling SOMD_Init is that a run-time object, called the DSOM Object Manager, is created, and a pointer to it is stored in the global variable, SOMD_ObjectMgr, for programming convenience. The DSOM Object Manager provides basic run-time support for clients to find, create, destroy, and identify objects. The Object Manager is discussed in detail in the section entitled "Basic Client Programming."

Next, the local stack creation statement,

stk = StackNew();

was replaced by

stk = _somdNewObject(SOMD_ObjectMgr, &ev, "Stack", "");

The call to somdNewObject asks the DSOM Object Manager (SOMD_ObjectMgr) to create a "Stack" object, wherever it can find an implementation of "Stack". (There are other methods with which one can request specific servers.) If no object could be created, NULL is returned, and an exception is raised. Otherwise, the object returned is a "Stack" proxy.

Note: On AIX, the following call may be needed before the somdNewObject call, if the "Stack" class implementation has been linked directly with the program executable (vs. using a dynamic link library, or DLL). This call will properly initialize the class for use by DSOM (this initialization is done in SOMInitModulefor DLLs):

StackNewClass(Stack_MajorVersion, Stack_MinorVersion);

A proxy is an object that is a local representative for a remote target object. A proxy inherits the target object's interface, so it responds to the same methods. Operations invoked on the proxy are not executed locally, but are forwarded to the "real" target object for execution. The client program always has a proxy for each remote target object on which it operates.

From this point on, the client program treats the "Stack" proxy exactly as it would treat a local "Stack". The "Stack" proxy takes responsibility for forwarding requests to, and yielding results from, the remote "Stack". For example,

_push(stk,&ev,num);

causes a message representing the method call to be sent to the server process containing the remote object. The DSOM run-time in the server process decodes the message and invokes the method on the target object. The result (in this case, just an indication of completion) is then returned to the client process in a message. The DSOM run time in the client process decodes the result message and returns any result data to the caller.

At the end of the original client program, the local "Stack" was destroyed by the statement,

_somFree(stk);

whereas, in the client program above, the "Stack" proxy and the remote "Stack" are destroyed by the statement,

_somdDestroyObject(SOMD_ObjectMgr, &ev, stk);

If the client only wants to release its use of the remote object (freeing the proxy) without destroying the remote object, it can call the somdReleaseObject method instead of somdDestroyObject.

Finally, the client must shut down DSOM, so that any operating system resources acquired by DSOM for communications or process management can be returned:

SOMD_Uninit(&ev);

This call must be made at the end of every DSOM program.

Using specific servers

In DSOM, the process that manages a target object is called the object's server. Servers are implemented as programs that use SOM classes. Server implementations are registered with DSOM in an Implementation Repository. The Implementation Repository is a database queried by clients in order to find desired servers, and queried by DSOM in order to activate those servers upon demand.

The example above placed no constraints on the DSOM Object Manager as to where the remote "Stack" object should be created. The somdNewObject call creates a remote object of a specified class in an arbitrary server that implements that class. However, the DSOM Object Manager provides methods for finding specific servers.

For example, the client program above can be modified slightly to find a specific server named "StackServer", which has already been registered in DSOM's Implementation Repository. (Note that the programmer knew or discovered that the "StackServer" server implementation supports the "Stack" class.) The highlighted lines below show the changes that were made:

#include <somd.h>
#include <stack.h>

int main(int argc, char *argv[]) {
        Stack stk;
        Environment e;
        SOMDServer server;

        SOM_InitEnvironment(&e);
        SOMD_Init(&e);

        server =
          _somdFindServerByName(SOMD_ObjectMgr, &e, "StackServer");
        stk = _somdCreateObj(server, &e, "Stack", "");

        _push(stk,&e,100);
        _push(stk,&e,200);
        _pop(stk,&e);
        if (!_empty(stk,&e)) somPrintf("Top: %d\n", _top(stk,&e));

        _somdDeleteObj(server, &e, stk);
        _somdReleaseObject(SOMD_ObjectMgr, &e, stk);
        _somdReleaseObject(SOMD_ObjectMgr, &e, server);
        SOMD_Uninit(&e);
        SOM_UninitEnvironment(&e);

        return(0);
}

This version of the program replaces the somdNewObject operation with calls to somdFindServerByName and somdCreateObj. The somdFindServerByName method consults the Implementation Repository to find the DSOM server implementation whose name is "StackServer", and creates a server proxy, which provides a connection to that server. Every DSOM server process has a server object that defines methods to assist in the creation and management of objects in that server. Server objects must be instances of SOMDServer or one of its subclasses. The somdFindServerByName returns a proxy to the SOMDServer object in the named server.

Once the client has the server proxy, it can create and destroy objects in that server. The somdCreateObj call creates an object of the class "Stack" in the server named "StackServer".

To free the remote "Stack" object, the example shows a somdDeleteObj request on the stack object's server. Next, somdReleaseObject requests are made on the DSOM Object Manager, to free the stack proxy and the server proxy in the client. (Note that these three calls are equivalent to the somdDestroyObject call in the previous example.)

A note on finding existing objects

"Stack" server implementation

Compiling the application

Installing the implementation

Setting environment variables

Registering the class in the Interface Repository

Registering the server in the Implementation Repository

Running the application

"Stack" example run-time scenario

Summary

Basic Client Programming

       DSOM Object Manager
       Initializing a client program
       Exiting a client program
       Creating remote objects
           Creating an object in an arbitrary server
           Proxy objects
           Servers and server objects
           Creating an object in a specific server
           Inquiring about a remote object's implementation 
       Destroying remote objects
           Destroying objects via a proxy
           Destroying objects via the DSOM Object Manager
           Destroying objects via a server object 
       Creating remote objects using user-defined metaclasses
       Saving and restoring references to objects
           Finding existing objects 
       Finding server objects
       Invoking methods on remote objects
           Determining memory allocation and ownership 
       Passing object references in method calls
       Memory management
           Memory management for method parameters
           The CORBA policy for parameter memory management
           The 'somdReleaseResources' method and object-owned parameters 
       Writing clients that are also servers
       Compiling and linking clients 

Basic Server Programming

       Server run-time objects
           Server implementation definition
           SOM Object Adapter (SOMOA)
           Server object 
       Server activation
       Initializing a server program
           Initializing the DSOM run-time environment
           Initializing the server's ImplementationDef
           Initializing the SOM Object Adapter
           When initialization fails 
       Processing requests
       Exiting a server program
       Managing objects in the server
           Object references, ReferenceData, and the ReferenceData table
           Simple SOM object references
           SOMDServer (default server-object class)
           Creation and destruction of SOM objects
           Mapping objects to object references
           Hints on the use of create vs. create_constant
           Mapping object references to objects
           Dispatching a method 
       Example: Writing a persistent object server
       Identifying the source of a request
       Compiling and linking servers 

Implementing Classes

       Using SOM class libraries
           Role of DSOM generic server program
           Role of SOM Object Adapter
           Role of SOMDServer
           Implementation constraints 
       Using other object implementations
           Wrapping a printer API 
       Parameter memory management
       Building and registering class libraries 

Configuring DSOM Applications

       Preparing the environment
       Registering class interfaces
       Registering servers and classes
       The 'regimpl', 'pregimpl', 'wregimpl' registration utilities
           Registration steps Using 'regimpl'
           Command line interface to 'regimpl'
           Registration steps using 'pregimpl' or 'wregimpl' 
       Programmatic interface to the Implementation Repository
       The 'dsom' server manager utility
           Interpretation of 'dsom' messages 
       Verifying the DSOM environment with 'somdchk'
       Freeing interprocess communication resources on AIX
           Using 'somdclean'
           Using 'cleanipc' 

Running DSOM Applications

       Running the DSOM daemon (somdd)
       Running DSOM servers 

DSOM as a CORBA-compliant Object Request Broker

       Mapping OMG CORBA terminology onto DSOM
           Object Request Broker run-time interfaces
           Object references and proxy objects
           Creation of remote objects
           Interface definition language
           C language mapping
           Dynamic Invocation Interface (DII)
           Implementations and servers
           Object Adapters
           Extensions and limitations 

Advanced Topics

       Peer vs. client/server processes
           Multi-threaded DSOM programs
           Event-driven DSOM programs using EMan
           Sample server using EMan 
       Dynamic Invocation Interface
           The NamedValue structure
           The NVList class
           Creating argument lists
           Building a Request
           Initiating a Request
           Example code 
       Creating user-supplied proxies
       Customizing the default base proxy class
       Sockets class 

Error Reporting and Troubleshooting

       Error codes
       Troubleshooting hints
           Checking the DSOM setup
           Analyzing problem conditions

Limitations