KCMS CMM Developer's Guide

KcsLoadable Class

The KcsLoadable class allows derivatives to be saved and generated from a static store and possibly minimized and regenerated from that original store at a later time.

If a class cannot regenerate itself at runtime, it must generate itself fully on construction. With KcsLoadable class derivatives, you must allocate and deallocate loadable objects if those objects require regeneration and are not supported by the contained class.

All derived objects return KCS_NOT_RUNTIME_LOADABLE whenever regeneration is unsupported. KCS_NOT_RUNTIME_LOADABLE indicates that you must use the constructor and destructor methods to regenerate at runtime.

To relax the requirements on a derivative, assume it is loadable and do not provide any special generation support. That is, allocate the object, load it when necessary, unload it when it is not needed and assume everything worked. In this case, ignore the KCS_NOT_RUNTIME_LOADABLE status message returned by the load()() and unload()() methods.

If the object does not support regeneration it returns KCS_NOT_RUNTIME_LOADABLE when issued a load()() or unload()() command. The object remains loaded in memory so it is not necessary to observe this protocol unless more flexibility is required for performance reasons.

UIDs and Sharing

All KcsLoadable classes have unique identifiers (UIDs). The combination of a chunkSet and a chunkId allows you to save the state of KcsLoadable derivatives for later use. To do this, either minimize and regenerate by calling unload()() and load()(), or save the UID of the instance and reallocate the instance with the UID-based constructor.

Because classes that contain other loadable objects use the same chunkSet, you must save the chunkId within your own data store. To explain this further, an example with an KcsXform class is used; see Chapter 7, KcsXform Derivative " for more information. For example, a sequence transformation saves its array of transform chunkIds in the same chunkset as it does its own state. The KcsXformSeq class has an array of pointers to KcsXforms when it is allocated in memory.

Since all of these transforms have unique identifiers, the KcsXformSeq class places the UID of each transform in an array and saves it. Once this sequence is constructed and told to load, (the chunkId is passed into the constructor) it gets the chunk and, for each transform chunkId, it calls the KcsXform::createXform(uid)() constructor. This constructor allocates the transform associated with that chunkId.

All loadable derivatives should support construction based on this chunkSet and chunkId combination. Loadable objects are shared by using a UID map table kept in the static KcsLoadable data member. When a new loadable object is created, this UID map table is searched first to see if an object with a particular ChunkSet and ChunkId has already been instantiated. If so, the pointer to that object is returned; if not, a new object is created and entered into the table.

Example

*aStat

= KcsLoadable::LoadCreator(Kcs2Id('P', 'f', 'm', 't'),  Kcs2Id('K', 'C', 'M',

'S'), Kcs2Id('0', '1', '\0', '\0'),  Kcs2Id('B', 'l', 'n', 'k'),  (void *

(**)())&sCreateFunction,

&sDLHandle);

This LoadCreator()() example returns a function pointer in sCreateFunction that is cast and called with the arguments as follows:

KcsProfileFormat::KcsProfileFormat(KcsStatus

*aStat,  	KcsId aCmmId, KcsVersion aCmmVersion, KcsId aProfileId,  	KcsVersion

aProfVersion)

KcsEkPfmticc30.so.1 is a KcsProfileFormat derivative whose method's object code is contained in the file mapped from the arguments to the LoadCreator()() method. The B, l, n, and k arguments are qualifiers for the constructor to use. In this case it is the Id-based constructor that generates a blank profile format. This call makes runtime loadabilty of derivatives platform independent. If aDerivId is a non-ASCII printable character, it is treated as BCD for these reasons: the ICC identifies their versions in BCD, and the runtime derivatives naming conventions need to conform to file naming conventions. Therefore, the operating system cannot use anything nonprintable to name files. If available, the method calls the initialization entry points upon the first load of the sharable. Currently, when an object is loaded, it is not unloaded until the program exits. The dlopen(3x) call returns a pointer to the same handle when it is opened.

Derivatives

Use a KcsIO class derivative for a static store. These derivatives can be memory based, disk based, and network based. The object does not care where the information is actually stored. The KcsIO base class has a file-like interface. Loadable derivatives also use the KcsChunkSet abstraction. This provides a random access bit bucket that is built on top of the KcsIO hierarchy.

Once a loadable object is minimized (or unloaded), a derived object regenerates or reloads itself in the manner described below.

The derivation implements the unload()() method to minimize the state of the object in memory. Then in the load()() method, it restores the state of the object to that described by the chunkSet and iChunkId member fields of the loadable base class. If in the unloaded state, it returns an error to signal that a load()() call in this state is not adequate for all methods. Additionally, for methods that need access to the state, it loads the minimum state according to the specific derivative's load hints. Then it continues the original method's functionality.

It is assumed that if hints are allowed for loading, the derivative overloads the load()() method to allow the hints to be passed to its contained object's load()() method.