Defining and using a child directory

A collection of child objects needs a directory to map each child dispatcher to a child ID. RPC Services provide two ways of establishing and maintaining this association:

TDispatcherChildDictionary works well if you are not creating a multithreaded server and if you do not want to define a specific protocol. You do not need to write any code to use TDispatcherChildDictionary.

If you prefer a different type of association than the dictionary provides, you need to derive your own concrete class from TDispatcherChildDirectory. Deriving your own class gives you the benefit of controlling how you keep track of instances, using the protocol that you find appropriate to your implementation.

NOTE For multithreaded servers, you must define your own directory class (derived from TDispatcherChildDirectory) to add multithread safety. Do not use TDispatcherChildDictionary for these servers.

Initializing a child directory

The instance that creates the receiver stream, instantiates the parent dispatcher, and starts the dispatcher thread also instantiates the TDispatcherChildDirectory. This instance is responsible for deleting the directory when the server terminates.

You associate a parent dispatcher with a directory, rather than associating a directory with a parent dispatcher. This allows multiple dispatchers to share a single child directory. To establish this association, call MRemoteDispatcher::SetChildDirectory in the parent dispatcher's constructor and pass the appropriate TDispatcherChildDirectory instance as the argument.

Once you instantiate a child directory, the parent dispatcher's implementation instance is the main user of the directory. For details on how to use a class derived from TDispatcherChildDirectory, see "Writing the parent implementation" on page 102.

Defining a new child directory

To derive a new concrete class from TDispatcherChildDirectory, instead of using TDispatcherChildDictionary, override the following member functions:

    ChildID Add(MRemoteDispatcher* childInstance). This member function adds a child dispatcher (childInstance) to the parent dispatcher's directory of children. Because you define the request that calls Add, you can also make the Add function specific to your caller-dispatcher protocol. You can include parameters that match fields you want to record in the directory.
    MRemoteDispatcher* Remove(ChildID whichChild). This member function removes a child (whichChild) from the parent dispatcher's directory of children. The caller of this function is responsible for deleting the dispatcher that Remove returns.
    MRemoteDispatcher* Lookup(ChildID whichChild). This member function looks up the MRemoteDispatcher child that corresponds to whichChild and returns a pointer to the child. If your server is multithreaded, child objects might be shared among multiple parents. In this case, you must call Lookup within the scope of a lock.
If you plan to use an instance of this class with a multithreaded server, you must also override:

    MRemoteDispatcher* Use(ChildID whichChild). This member function defines the beginning of access that needs protection. This member function performs a Lookup by default. Override Use to add code that acquires a lock on the child dispatcher.
    void DoneWith(MRemoteDispatcher* ChildInstance). This member function defines the end of protected access. By default, this member function does nothing. Override DoneWith to release the lock that Use established on the child dispatcher.

[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker