Go to the previous, next section.
This chapter describes the use of ILU with C++ in a manner compliant with the CORBA 2.0 C++ language mapping specification. (see http://www.omg.org/corba/corbiiop.htm) The use of ILU's original C++ support is deprecated.
Any function or type which is not part of the CORBA 2.0 specification has the prefix 'ilu'. It should be understood that use of 'ilu' prefixed functionality is not portable to other (non-ILU) CORBA implementations.
Some arguments or return values of functions (e.g. char*) have storage management requirements. Basically this revolves around whether the caller retains or gets ownership of the parameter and is therefore responsible for eventually releasing it, or if ILU takes or retains ownership, where it will be released at ILU's discretion. Any function parameter that becomes owned by ILU is marked with the comment /* ILUowned */ Any return value (or 'out' parameter) that remains under the ownership of ILU is similarly marked. Anything not so marked is not ILU's responsibility.
Note that ILU support for C++ does rely on having argument prototypes, all C++ library functions, and the capabilities of the C++ pre-processor.
The CORBA 2.0 C++ chapters 15 though 18 describes the mapping of OMG IDL
to C++. For those elements of ISL for which there is a direct counterpart
in IDL, the ISL component is mapped just as the IDL component is. Those
ISL concepts with no IDL counterpart (marked with a '-
' in the table below)
have a mapping separately described in a following section.
ISL IDL ------------------------------------- INTEGER long SHORT INTEGER short LONG INTEGER - CARDINAL unsigned long SHORT CARDINAL unsigned short LONG CARDINAL - BYTE octet BOOLEAN boolean REAL double SHORT REAL float LONG REAL - CHARACTER - SHORT CHARACTER char PICKLE Any ARRAY array SEQUENCE sequence RECORD struct UNION union OPTIONAL - ENUMERATION enum OBJECT object CString string SEQUENCE OF CHARACTER - EXCEPTION -, exception INTERFACE module
The following table describes the mappings for ISL types that have no IDL counterparts. The C++ column gives the mapping modulo indirection and/or 'const' qualification dictated by parameter directionality (i.e., IN vs OUT vs INOUT vs return values).
ISL C++ -------------------------------------------------------------- LONG INTEGER iluLongInteger LONG CARDINAL iluLongCardinal LONG REAL iluLongReal CHARACTER iluCharacter OPTIONAL X X* for operation parameters; 'managed X*' for embedded types. SEQUENCE OF CHARACTER iluCharacter* EXCEPTION Any ISL exception that is not a RECORD, maps to a subclass of CORBA::UserException, that has a _value() member function which returns a value of the type associated with the exception.
To provide a consistent naming scheme, in many cases, a type defined in the ILU kernel has been typedeffed to appear in C++ as the corresponding type name without the intervening underscore, and with the following letter capitalized, e.g. typedef ilu_cardinal iluCardinal;
The mapping for an ISL Object 'A' produces 3 C++ classes:
This mapping allows servers to be developed that do not contain surrogate stub code (if they don't need it), and also prevents the situation where a server method override is forgotten, resulting in surrogate stub code being called as it it were 'true' code.
For each ISL Object 'A' for which a true side implementation is to be developed, the true side implementer should define a class A_impl that inherits virtually from the C++ class A, and implements the actual true methods as member functions (in whatever manner is appropriate). The implementer is free to use delegation, implementation inheritance, whatever - the only restriction is that if a class B_impl inherits implementation from a class X, and class X inherits from a class in the abstract object hierarchy, (e.g. when X is A_impl), then X's inheritance from the abstract object hierarchy must be 'public virtual'.
Each produced C++ class e.g. A, will have a constructor C++: A ( char* pc_instance_handle, ilu_Server& r_an_ilu_server = iluServer::GetDefaultServer(), ILUCPP_BOOL b_within_object_table = ILUCPP_FALSE ) : iluObject ( A::m_ILUClassRecord, pc_instance_handle, r_an_ilu_server, b_within_object_table).
In IDL, Union arms all have names, in ISL, the names may not be specified. If a name isn't specified for an arm, the name the stubber produces is the arm's typename, prefixed with '_', and suffixed with '_arm'.
For example,
TYPE someuniontype = short cardinal UNION bar = 0, 1 END, integer = DEFAULT END;
would produce the C++ names _bar_arm, and _integer_arm to reference the bar and integer arms.
OPTIONAL
type maps either to the same C++ type as its base
type, if that base type is represented with an C++ pointer type, or to a pointer to that base type,
if it is not represented with a C++ pointer type.
Additionally, all OPTIONAL
types T have an associated
C++ T_var.
For non-parameters (i.e., RECORD
members, ARRAY
and SEQUENCE
elements) an
ISL OPTIONAL
type maps to a 'managed pointer', analagous to the mapping
for non-parameter ISL OBJECT
(CORBA interface
) and
ISL SEQUENCE OF SHORT CHARACTER
(CORBA string
). (This
'managed pointer' behaves similarly to T_var; however, CORBA does
not allow compliant applications to use 'managed pointer' types directly, as the actual
type is implementation-specific)
The following ISL and C++ code fragments illustrate:
ISL TYPE SomeType = ... TYPE MyOptional = OPTIONAL SomeType; TYPE MyRec = RECORD member: MyOptional END; TYPE MyArray = ARRAY OF 10 MyOptional; member: MyOptional END; C++ ... MyRec myRec; MyArray myArray; SomeType st; SomeType* stPtr; MyOptional myOptional; // MyOptional is equivalent to SomeType* MyOptional_var stVar; ... myRec.member = myArray[0]; // free old myRec.member, deep copy myArray[1] = stVar; // free old myArray[1], deep copy myRec.member = stPtr; // free old myRec.member, assume ownership myRec.member = myOptional; // free old myRec.member, assume ownership myRec.member = &st; // ILLEGAL - can't free &st myRec.member = new SomeType(st); // OK; free old myRec.member, assume ownership stPtr = myArray[2]; // Simple pointer assignment, no copy stVar = myRec.member; // free old stVar, deep copy
The lifetime of recA.member
and each myArray[n]
are tied to recA
and myArray, respectively; when an optional-containing variable goes out of scope
or is destroyed, its optional members/elements are freed. Thus, the assignment
myRec.member = &st
in the example above is illegal and can lead to calamitous
results when an attempt is made to free &st.
Any ISL exception that is not a RECORD, maps to a subclass of CORBA::UserException, that has a _value() member function which returns a value of the type associated with the exception.
In IDL, methods may be ASYCHRONOUS
. Asynchronous methods cannot have
return values or raise exceptions. Hence, they result in a C++
member function declared to return void.
In IDL, methods may be FUNCTIONAL
. In the C++ mapping,
FUNCTIONAL
is ignored. The ability to create custom C++ surrogates allows
the implementation to decide what and how caching may be implemented on any
method, as well as perform any other sorts of message 'filtering'.
An ISL object being declared COLLECTIBLE
has not effect on the
mapping per-se. It will however cause ILU to adjust an object's reference
count based on interest or dis-interest from clients.
If an ISL Object A has no supertypes, the A class 'public virtual' inherits from the iluObject class. An object described in IDL will implicity inherit from CORBA::Object (which in turn inherits from iluObject). (The idl2isl translator automatically adds ilu.CORBA-Object as a SUPERTYPE.) So, if you define an object in ISL, and do not explicitly declare ilu.CORBA-Object as a SUPERTYPE, you will not have the member functions of CORBA::Object available since you do not inherit from it.
The CORBA 2.0 C++ mapping allows for variations in the mapping depending on the C++ compilers support for Name Spaces, Exception Handling, and Run-Time Type information.
The ILU CORBA 2.0 C++ mapping implementation assumes that the C++ compiler supports exceptions. We also assume that the compiler supports RTTI should someone want to do narrowing within the exception hierarchy. [Given that ILU does not provide a Dynamic Invocation Interface, there's no real need to narrow exceptions anyway.]
During the configuration phase of ILU installation (or for Windows, per the definitions in `ILUSRC/runtime/kernel/iluwin.h') a determination is made as to whether or not to use namespaces, nested classes or underscores for IDL modules, based on the C++ compiler in use. [This can be overridden with the configuration option --with-cplusplus-mapping= switch to config.] This results in a C++ runtime that is constructed with one of these approaches in mind. Should a user decide to use a different mapping, this can be done by setting appropriate switches to the stubber, but you must bear in mind that the C++ runtime needs to be in correspondence, since the selection radically changes the names seen by a linker. Based on our knowledge (as of the date of this writing), of the degree of support/bugs for namespaces and nested classes, the following describes the IDL module mapping based on compiler:
C++ Compiler Module Mapping
Compiler Mapping --------------------------------------- Microsoft Visual C++ underscores SunPro nested classes Gnu nested classes
To portably reference things in a interface when the stubber is directed to produce portable code, the stubber generates two macros, one for referring to things from outside the namespace (e.g. when defining a member function), and another for inside the namespace (e.g. inside a class declaration). The names of these macros are the interface name, and the interface name with a '_' (underscore) suffix. These macros expand to some other macros that are defined in the cppportability.hpp file.
To refer to things in the CORBA interface, one uses the CORBA macro. For example, CORBA(Boolean) b_my_result = ILUCPP_TRUE;
Because of possible variations in compiler support for Booleans, CORBA(Boolean) is defined as ILUCPP_BOOL, where ILUCPP_BOOL is defined as either an int (with ILUCPP_TRUE and ILUCPP_FALSE #defined as 1 and 0), or as a bool (with ILUCPP_TRUE and ILUCPP_FALSE #defined as true and false).
In ILU there is a concept of an 'server object'.
In the kernel this is the ilu_Server, which in the C++
runtime is encapsulated asn an iluServer
object. This 'server'
effectively forms a 'scope' in which true objects reside. This is why
for example, and object lookup requires both the 'server' ID,
and the object's instance handle - both are needed to uniquely
denote an object.
Now a server has some number of 'ports'. A port is basically a
means of communicating with the objects inside a server, using a
particular combination of protocol and transport. For example,
when create an iluServer
, the constructor for iluServer
automatically
adds a port for the communication protocol and transport specified
as constructor arguments. We can call iluServer::iluAddPort
to have additional
ports added. For example we may want to be able to communicate
with the objects using sunrpc
over tcp/ip
, as well as http
over
tcp/ip
. The iluServer has a notion of a default port. This is initially
one as specified during construction, but this can be changed
if when calling iluServer::iluAddPort
we specify that this should become
the default port. The default port is the one used when we ask for
contact information for an object - that is, if we get the string
binding handle for an object, the contact information in that
string will reflect the default server port.
True objects may either be created ahead of time, or on an 'as needed' basis, i.e. when
a call comes in involving them. The 'as needed' situation is made possible by 'object tables'.
An iluServer
may have associated with it (at construction time) an iluObjectTable
object.
When a call comes involving an object in that iluServer
that the ILU doesn't already
know about, the iluObjectTable
object's iluObjectOfInstanceHandle
gets
called. It is the job of this function to create and return a new object
with that instance handle. How it does this is specific to your application -
it may read object state off a disk for example. In any event, one thing this
function must do is ensure that when it calls the true objects constructor, that
it sets the constructor's b_within_object_table argument to true. (Otherwise,
internal locking constraints will be violated). While in the iluObjectOfInstanceHandle
function, the associated iluServer
's lock is held, and if the resulting object is expected to be
of a COLLECTIBLE type, the global kernel mutex "gcmu" is also held. The fact that these locks
are held somewhat restricts what an application can do inside this mapping procedure.
The ILU C++ support may be initialized to run in either
threaded or non-threaded mode. In non threaded mode, a call to iluServer::iluRun
member function results in a call to ILU's 'mainloop'. The mainloop
basically sits waiting for an incoming request. When one comes in, the request is
invoked. If the implementation of the invoked method makes a call to some other
remote object, the mainloop is recursively entered while awaiting a reply. This
allows additional requeste to come in and get serviced, preventing deadlock.
When intialized to run in threaded mode, ILU will run one thread for each incoming connection. Note that there may be multiple connections for a particular port (either from different clients, or from the same client who needed another connection because all the ones it had so far were busy at the time). In the case of a non-concurrent protocol (sunrpc, http, courier), the connection thread receives an incoming request, processes it itself, and then waits for the next request. In the case of a concurrent protocol (csunrpc, iiop), the connnection thread receives an incoming request, spawns a worker thread to carry out the request, and immediately goes back to waiting for more incoming requests.
The ILU C++ provides no special concurrency control for methods in your objects (to do so would be presumptive on our part). The method implementor must put appropriate locking in place if it is possible that multiple threads (or recursive mainloop invocations) might be running 'in' an object simultaneously.
A surrogate is an object that is used to represent a remote object. When a method is invoked on a surrogate, the methods implementation in the surrogate transfers the call to the true object, and returns the result of this call, thus providing location transparency. There are times however when it is useful to have the surrogate's method implementation do more than just forward the call to the true object. An application may want a surrogate method implementation that caches the results of calls (potentially reducing network overhead), perform transformations on arguments, output diagnostic information, or whatever.
To facilitate this, the ILU C++ support allows an implementation
to supply a function that is called when a surrogate for a particular object
type is needed. The function iluCppRuntime::iluSetSurrogateCreator
tells the C++ runtime what function to call when a surrogate for an
object of the specified class is needed. This allows an
implementation to subclass off a surrogate class, and write a new
surrogate creation function that creates an instance of this new
subclass. Call iluCppRuntime::iluSetSurrogateCreator
after you've performed
initialization, but before you do any operations which might create a
surrogate of the specified class. It basically overwrites the default
surrogate creation function set up by the surrogate stubs. It returns
the old surrogate creator function, or NULL
if was previously no
surrogate creator for that class.
A surrogate creator function should at the minimum create an instance of a surrogate, call
the instances member function iluAssociateKernelObject passing the
iluKernelObject
, and then return a pointer to the new instance.
A String Binding Handle is a textual representation of an object reference.
It contains the object's server id, instance id, information about how to
contact the object, as well as other information. ILU C++ provides
the functions iluCppRuntime::iluFormSBH
, iluCppRuntime::iluFormSBHUsingContactInfo
,
and iluCppRuntime::iluParseSBH
for constructing and parsing string binding handles.
An object may be obtained from a string binding handle using iluObject::iluStringToObject
and the string bindign handle of an object may be obtained by calling the iluObjectToString
member function.
When creating a service, there needs to be some way for clients to find out
about the service. ILU C++ provides a simple mechanism
to achieve this. Objects may be published, looked up, and their publications
withdrawn using the appropriate member functions (iluPublish
, iluLookup
,
iluWithdraw
).
An true object is initially 'Active', which means that its ISL (or IDL as the case may be) defined methods may be invoked on it from outside its process (or from another language within that same process). An object may be made unavailable to outside calls, i.e. marked 'inactive' by calling its iluDeactivate member function. It may may be reactivated by calling its iluActivate member function.
An object is initially available from the outside until it is deactivated Objects that are involved in a call (i.e. sent or received as arguments, or the object the method is being invoked on) need to be protected from deletion for the duration of that involvement (for example, you don't want some thread deleting a true object when it's currently the target of a method call). The C++ runtime keeps track of what objects are involved in a call, and will attempt to prevent them from being deleted until the call is completed.
The application programmer needs to assist in this by calling, in the
most specific destructor, iluDeactivate (inherited virtually from
iluObject
). iluDeactivate blocks any further incoming calls involving
the object, and wait for any ongoing calls using the object to
complete. Next the destructor should perform any object specific
cleanup. Finally, the destructor in iluObject
will break the
association between the kernel object and this object, allowing the
kernel object to be potentially freed.
A client may set the Passport to be used on outgoing calls by creating
and setting up an iluPassport,
and then passing the passport in a call
to iluPassport::iluSetPassport. This sets the passport to be used in
the thread that made the call - i.e. iluPassport
are on a per thread
basis. Note that before your thread exits, you should either call
iluSetPassport(NULL
), or delete the iluPassport
in use (assuming it's
only in use for a single thread). The iluPassport
(if any) currently
setup for a thread can be retrieved by calling
iluPassport::iluGetPassport.
A Server may obtain the iluPassport
of the caller (if any) of a
method by using the iluPassport::iluGetCallerPassport() function.
A iluServer
may be constructed to use a particular identity by specifying a
iluPassport
as a constructor argument. This identity is used to identify
the principal offering the service.
The C++ Runtime normally relies on the static initializers in the files that the stubber generates to place initialization functions onto internal lists so that they will be invoked when the application calls iluCppRuntime::Initialize. However, it is not guaranteed by the ANSI C++ that static initializers are called upon the loading of a compilation unit. We have only had a report of one compiler that did not run the static initializers at load time (in fact, it was reported that it did not run them ever! - bug!?). We have observed static initialization at load time in Visual C++, SunPro and GNU compilers. In the event that you end up using a compiler that does not call the static initializers at load time, you can use the stubber defined initialization macros that are generated in the common header file for each interface.
(It should be pointed out that the CORBA 2.0 C++ Runtime does not suffer from the static initializer issues that plagued ILU's original C++ support. No ILU calls are actually made until iluCppRuntime::iluInitialize is called, allowing one to set up different mainloops, etc.)
To generate CORBA 2.0 C++ stubs from an ISL file, use the program cpp2-stubber. The stubber has the following usage:
Usage: cpp2-stubber [arguments] Islfile [ISLFILE ...] [arguments] can be any of the following: [-nu|-underscores] [-np|-portable] [-nn|-nested] [-ns|-namespaces]
The switches can be used to direct the stubber to produce code that using a specific module mapping, or portable module mapping. The default is whatever is found appropriate during the configuration phase of ILU installation (see "Portability and Mapping Variations"). Note that generating a specific (non-portable) mapping that does not match the platform default, is likely to cause errors at link time due to naming differences.
For an interface Foo
the stubber generates:
`Foo-cpp.hpp' which contains the classes for the abstract object hierarchy, as well as any other declarations needed by both client and server.
`Foo-cpp.cpp', which contains any definitions needed by both client and server
`Foo-cppsurrogate.hpp' which contains the classes for the surrogate object hierarchy, as well as any other declarations needed just by a client. This file #includes Foo-cpp.hpp
`Foo-cppsurrogate.cpp', which contains any definitions needed just by a client. This file #includes Foo-cppsurrogate.hpp
`Foo-cpptrue.hpp' which contains any declarations needed just by a server. This file #includes Foo-cpp.hpp
`Foo-cpptrue.cpp', which contains any definitions needed just by a server. This file #includes Foo-cpptrue.hpp. All header files use the usual #ifdef method to prevent multiple inclusions.
A client only will #include Foo-cppsurrogate.hpp, and link with `Foo-cpp.o' and `Foo-cppsurrogate.o'
A server only will #include Foo-cpptrue.hpp, and link with `Foo-cpp.o' and `Foo-cpptrue.o'
A client and server will #include Foo-cpptrue.hpp, #include Foo-cppsurrogate.hpp, and and link with `Foo.o', `Foo-cpptrue.o', and `Foo-cppsurrogate.o'
The basic steps in creating a simple server application are as follows (assuming we have a ISL file called `foo.isl', describing an interface 'foo' with an object type 'bar'):
class foo_bar_impl : public virtual foo(bar) { ... };
iluServer
as arguments, and calls the iluObject
constructor
appropriately, e.g.
foo_bar_impl::foo_bar_impl(char* pc_instance_handle, iluServer& r_an_ilu_server) : iluObject(foo(bar)::m_ILUClassRecord, pc_instance_handle, r_an_ilu_server) {}
foo_bar_impl::~foo_bar_impl() { iluDeactivate(); // other app specific things that may need to be done }
virtual CORBA(Boolean) zap( CORBA(Long) inarg, CORBA(Octet)& inoutarg, CORBA(Double)& outarg ) throw (CORBA(SystemException), foo(zapexception));
CORBA(Boolean) foo_bar_impl::zap( CORBA(Long) inarg, CORBA(Octet)& inoutarg, CORBA(Double)& outarg ) throw (CORBA(SystemException), foo(zapexception)) { // do whatever must be done }
// Set up the runtime for threaded operation iluCppRuntime::iluInitialize(ILUCPP_TRUE);
iluServer
. e.g.
iluServer server ("MyFooBarServerOnMyHost");
p_true_foo_bar = new foo_bar_impl("foo_bar_instance_0", server);
p_true_foo_bar->iluPublish()
server.iluRun();
The basic steps in creating a simple client application are as follows (assuming we have a ISL file called `foo.isl', describing an interface 'foo' with an object type 'bar'):
// Set up the runtime for threaded operation iluCppRuntime::iluInitialize(ILUCPP_TRUE);
foo(bar_var) mybar_var = foo(bar)::iluLookup ("foo_bar_instance_0", "MyFooBarServerOnMyHost");
try { bool_return_value = mybar_var->zap(inarg, inoutarg, outarg); } catch (const foo(zapexception)& the_exception) { /* do whatever */ } catch (const CORBA(SystemException)& the_exception) { /* do whatever */ } catch (...) { /* do whatever */ }
The ILU examples directory contains two examples that use the CORBA 2.0 C++ mapping. See cpp2foo, and test1. The cpp2foo example illustrates a lot: object tables; collectible; custom surrogates; lookups; anys; return, in, inout, and out of most types; use of _vars; and more;
The classes of interest to the application programmer are listed below. Nearly all non-static member functions are virtual to allow creative overrides (at your own risk of course).
iluCppRuntime
- Abstract class that provides various static member
functions that the application can use to control the runtime's
behavior.
iluServer
- Provides the C++ view of a kernel server object.
iluObject
- The most base class for all ILU C++ objects. All objects inherit either
directly or indirectly from this class.
iluObjectTable
- An abstract C++ class for developers to derive from
to provide Object Tables.
iluPassport
- encapsulates ilu_Passport functionality
iluGSS
- encapsulates GSS functionality
iluMainLoop
- An abstract base class for developers to derive from to
create their own main loop.
iluWString_var
Class - analog to CORBA(String_var) only for ILU Characters
(See `ILUSRC/runtime/cpp2/ilu.hpp' and `ILUSRC/runtime/cpp2/corba.hpp' for more complete descriptions.)
An Abstract class that provides various static member functions that
the application can use to control the runtime's behavior.
iluCppRuntime
is not meant to ever be subclassed.
C++: static void iluCppRuntime::iluInitialize ( ILUCPP_BOOL b_use_native_threads = ILUCPP_FALSE
)
Initializes the C++ runtime for use. Also calls all the functions (typically interface initialization functions in generated stubs) that are on the C++ Runtime's initialization function list (see iluCppRuntime::iluAddInitializationFunction).
iluCppRuntime::iluInitialize's use depends on your use of threading:
C++: static void iluCppRuntime::iluAddInitializationFunction ( iluPFunctionInitializer pf_initialize )
Adds an initialization function onto the runtime's list of (typically interface initialization) functions to call when iluCppRuntime::iluInitialize is called. iluPFunctionInitializer is typedeffed as
C++: void (* iluPFunctionInitializer ) ( )
C++: static void iluCppRuntime::iluSetNonNativeThreadIDFunction ( iluNonNativeThreadIDFunction p_thread_id_function )
When running non-native threaded, this should be called (before
initialization) set to the function that will return a thread unique
iluCardinal
id of the current thread. iluNonNativeThreadIDFunction is
typedeffed as
C++: iluCardinal (* iluNonNativeThreadIDFunction )( )
C++: static iluPFunctionSurrogateCreator iluCppRuntime::iluSetSurrogateCreator ( iluClass surrogate_class, iluPFunctionSurrogateCreator pfunction_surrogate_creator )
Tells the C++ runtime what function to call when a surrogate for an
object of the specified class is needed. This allows an
implementation to subclass off a surrogate class, and write a new
surrogate creation function that creates an instance of this new
subclass. This more specialized surrogate might do message filtering,
caching, monitoring, etc. Call this function after you've performed
initialization, but before you do any operations which might create a
surrogate of the specified class. It basically overwrites the default
surrogate creation function set up by the surrogate stubs. It returns
the old surrogate creator function, or NULL
if was previously no
surrogate creator for that class (note: NULL
return should not really
happen unless a mistake or something clever is being done - this means
you've added a new node to the surrogate creator function list).
iluPFunctionSurrogateCreator is typedeffed as
C++: iluObject* (* iluPFunctionSurrogateCreator ) ( iluKernelObject).
A surrogate creator function should at the minimum create an instance of a surrogate, call
the instances member function iluAssociateKernelObject passing the
iluKernelObject,
and then return a pointer to the new instance.
C++: static void iluCppRuntime::iluSetForkProcedure ( iluForkProc pfunction_fork_procedure )
If your using your own threads package call this before calling the ILU kernel functions ilu_SetWaitTech, etc. and pass a pointer to your function that forks a thread. iluForkProc is typedeffed as
C++: iluBoolean (* iluForkProc ) ( void (*pfunction_procedure) (void* pv_argument),
void* pv_argument, ILU_ERRS((no_memory, no_resources, internal)) * p_error )
C++: static iluCardinal iluCppRuntime::iluCharacterStringLength ( const iluCharacter* p_chars )
Returns the length of the iluCharacter
string
C++: static iluCharacter* iluCppRuntime::iluCharacterStringCopy ( iluCharacter* p_chars_destination, const iluCharacter* p_chars_source )
Copies the source iluCharacter
string to the destination, returns the
destination.
C++: static iluCharacter* iluCppRuntime::iluCharacterStringDuplicate ( const iluCharacter* p_chars_source )
Returns a duplicate of the source iluCharacter
string
C++: static ILUCPP_BOOL iluCppRuntime::iluCharacterStringEqual ( const iluCharacter* p_chars_one, const iluCharacter* p_chars_two )
Returns true if strings are the same, else false.
C++: static iluCharacter* iluCppRuntime::iluCharStringFromShortCharString ( const iluShortCharacter* pc_shortchars )
Returns a new iluCharacter
string filled in from the iluShortCharacter
string.
C++: static ILUCPP_BOOL iluCppRuntime::iluCharStringShortCharStringEqual ( const iluCharacter* pc_chars, const iluShortCharacter* pc_shortchars )
Returns true if the iluCharacter
string matches the iluShortCharacter
string.
C++: static char* iluCppRuntime::iluFormSBH ( const char* pc_serverid, const char* pc_instance_handle, iluClass the_ilu_class, iluProtocolInfo pc_protocol_type = ((iluProtocolInfo) NULL), iluTransportInfo transport_info = ((iluTransportInfo) NULL) )
C++: static char* iluCppRuntime::iluFormSBHUsingContactInfo ( const char* pc_serverid, const char* pc_instance_handle, iluClass the_ilu_class, const char* p_str_encodedContactInfo = NULL )
Use these to form a string binding handle from relevant parts, if protocol and/or transport info are NULL, current defaults are used. For iluFormSBHUsingContactInfo, p_str_encodedContactInfo is as would be obtained from iluParseSBH.
C++: static ILUCPP_BOOL iluCppRuntime::iluParseSBH ( iluCString str_encodedSBH, iluCString* p_str_plainInstanceHandle = NULL, iluCString* p_str_plainServerID = NULL, iluCString* p_str_plainMstid = NULL, iluCString* p_str_encodedContactInfo = NULL, iluCardinal* p_card_encodedContactInfoLen = NULL )
Parse a string binding handle, returning whichever elements are specified by passing in non-NIL pointers. Caller retains ownership of URL argument. If p_str_plainInstanceHandle != NIL, ownership of *p_str_plainInstanceHandle is passed to caller iff successful. Similarly for p_str_plainServerID and p_str_plainMstid. *p_str_encodedContactInfo is set to point into the given URL (The whole sequence of contact info is returned in *p_str_encodedContactInfo) , and *p_card_encodedContactInfoLen is set to the length of the contact info substring; the next character is left unmolested.
C++: static iluCardinal iluCppRuntime::iluGetFDBudget( )
C++: static iluCardinal iluCppRuntime::iluSetFDBudget ( iluCardinal card_size )
Get and set ILU file descriptor budget. iluSetFDBudget returns the new budget. Because ILU may open multiple connections to a server, we need some policy for when to close them. That policy is this: the application gives the ILU kernel a "File Descriptor Budget" (initally 16). The ILU kernel promises to use no more than this many File Descriptors at once.Off the top of this budget we take FDs needed for serving (one per listening socket and one per accept). The remainder is allocated to outgoing connections (over transports that use FDs -- ie, not inmemory). When we want to consume a new FD, and there's no room left in the budget, we go looking for an idle outgoing connection (one with no outstanding calls) to close. All idle outgoing connections are kept in a doubly-linked list, ordered by when the connection went idle (most recently at the front).
C++: static void iluCppRuntime::iluFree ( void* pv /* ILUowned */ )
Use this to free things returned by ILU
C++: static void* iluCppRuntime::iluMalloc ( iluCardinal card_size )
You can use this to malloc things from ILU.
iluServer
provides a the C++ view of a kernel server object.
iluServers
cannot be copied or assigned.
C++: iluServer::iluServer ( char* pc_server_id = NULL
, iluObjectTable* p_object_table = NULL
/* ILUowned */ , char * pc_protocol_type = NULL
, iluTransportInfo transport_info = NULL
, iluPassport* p_passport = NULL
)
Constructor - If no pc_server_id is specified, one is automatically created based on
based on time, hostname, and process id. If p_object_table is NULL
, a default
object table implementation is used. A port is created and added to the
server using the specified protocol and transport, and becomes the default
port of the server. pc_protocol_type and transport_info default to whatever
the default protocol and transport are currently set to. Caller owns pc_server_id
p_object_table, pc_protocol_type, transport_info, and p_passport. p_passport points
to an iluPassport,
defaulted to NULL
- this passport containing an ILU GSS identity,
which is used as the identity of the principal offering the service, and put into the
connection information in the string binding handle of objects on that server.
C++: virtual iluServer::~iluServer ( )
Destructor - basically destroys the kernel server and breaks
all associations between kernel objects in this server and
their language specific objects. Indirectly also deletes any
iluObjectTable
used with this iluServer.
C++: virtual void iluServer::iluAddPort (char* pc_protocol_type,
iluTransportInfo transport_info,
ILUCPP_BOOL b_become_default_port = ILUCPP_FALSE
,
iluPassport* p_passport = NULL
)
Adds another port to an existing server If b_become_default_port is
ILUCPP_TRUE
the new port will become the default port for this server.
p_passport points to an iluPassport,
defaulted to NULL
. this passport containing
an ILU GSS identity, which is used as the identity of the principal offering the
service, and put into the connection information in the string binding handle
of objects on that server. Caller owns the arguments.
C++: virtual void iluServer::iluRun ( int* p_i_stop_on_non_zero = NULL
)
This runs the main, outer loop of an iluServer. It never returns if p_i_stop_on_non_zero isn't supplied, else it returns when *p_i_stop_on_non_zero is non zero. If you're running threaded this routine simply goes into a sleep loop,
C++: static char* iluServer::iluGetDefaultProtocol ( )
C++: static void iluServer::iluSetDefaultProtocol( char* pc_new_default_protocol )
Get and set the default protocol used when adding a port on a
iluServer
- initialized to whatever is set to be the default
in the kernel (found in `ILUSRC/runtime/kernel/iluconf.h'
or `ILUSRC/runtime/kernel/iluwin.h')
C++: static const iluTransportInfo iluServer::iluGetDefaultTransport ( )
C++: static void iluServer::iluSetDefaultTransport( iluTransportInfo ppc_new_default_transport_info )
Get and set the default transports used when adding a port on a
iluServer
- initialized to whatever is set to be the default
in the kernel (found in `ILUSRC/runtime/kernel/iluconf.h'
or `ILUSRC/runtime/kernel/iluwin.h')
Callee owns pc_new_default_transport_info.
C++: {static iluServer@ampnr{}} iluServer::iluGetDefaultServer ( )
Returns the default iluServer
, creating one if need be.
C++: static iluServer* iluServer::iluSetDefaultServer ( iluServer& new_default_server )
Sets the default iluServer,
returns old default, which is NULL
if no default currently is set.
The most base class for all ILU C++ objects. All objects inherit either
directly or indirectly from iluObject
. All non-static member functions are virtual
to allow creative overrides (at your own risk of course). iluObjects
cannot be copied or assigned.
C++: iluObject::iluObject ( iluClass the_Class, char* pc_instance_handle = NULL
, iluServer& the_server = iluServer::iluGetDefaultServer(), ILUCPP_BOOL b_within_object_table = ILUCPP_FALSE )
Constructor - This constructor must be called (only) from the constructors for true objects. For example, in an implementation of a foo::bar :
foo_bar_impl(char* pc_instance_handle, iluServer& r_an_ilu_server, CORBA(Boolean) b_within_object_table = ILUCPP_FALSE : iluObject(foo(bar)::m_ILUClassRecord, pc_instance_handle, r_an_ilu_server, b_within_object_table) {}
If no instance handle is specified, then the value of a monotonicaly
increasing, iluServer
specific counter will be used to generate one.
If no server is specified, then the default server will be used.
(The default server is generated automatically if needed, and has the
an id based on time, hostname, and process id.) Caller owns pc_instance_handle.
The new object has a reference count of 1. If b_within_object_table is true,
then it is assumed the object is being created inside an iluObjectTable's
iluObjectOfInstanceHandle function, meaning that the locks on the server should
not be modified.
C++: static iluObject* iluObject::iluStringToObject ( char* pc_string_binding_handle )
Given a string binding handle (e.g. as obtained from iluObjectToString) returns an iluObject* for that object, with the reference count incremented.
C++: virtual iluObject::~iluObject ( )
Destructor ensures that this object is completely disassociated from the ILU kernel
The most specific destructor of an object should call iluDeactivate
on the object to block any further incoming calls, and wait for any
ongoing calls to complete. Next it should perform any object specific
cleanup. Finally, the destructor in iluObject
will break the association
between the kernel object and this object, allowing the kernel object
to be potentially freed.
C++: virtual void iluObject::iluDeactivate ( )
Ensures this object is not available from the outside. This must be the first thing called by the most specific destructor of an object. If if isn't, then the potential exists (in multithread case) for a call to come in for an object that's in the middle of destruction - a bad thing! This function blocks until there are zero ongoing calls.
C++: virtual void iluObject::iluKernelObjectUnlinked ( )
Called by iluUnlinkKernelObject - you can override this virtual
function in your objects to do whatever you like when the association
between your object and the kernel object is broken - e.g. delete yourself
The implementation in iluObject
deletes this.
C++: virtual ILUCPP_BOOL iluObject::iluPublish ( )
Publishes binding information for this object in the binding service Has no effect on object reference count.
C++: virtual ILUCPP_BOOL iluObject::iluWithdraw ( )
Removes binding information for this object from the binding service Has no effect on object reference count.
C++: static void* iluObject::iluLookup (char* pc_instance_handle, char* pc_server_id, iluClass the_class )
Used by stubber generated iluLookup functions in derived classes to lookup an object in the binding service based on its instance and server id and class. Increments reference count of object. To Lookup objects of type T, use the T::iluLookup(char* pc_instance_handle, char* pc_server_id; function produced by the stubber. For example:
mybar_var = foo(bar)::iluLookup("foo_instance_0", pc_serverid )
C++: virtual iluServer* iluObject::iluGetServer ( )
Returns pointer to the iluServer that this object resides in.
C++: virtual const char* /* ILUowned */ iluObject::iluId ( )
Returns the objects instance id.
C++: virtual const char* /* ILUowned */ iluObject::iluServerId ( )
Returns the id of the objects ILU Server.
C++: virtual iluCString iluObject::iluObjectToString ( )
Returns the ILU string binding handle for the object. Caller get ownership of the string
C++: ILUCPP_BOOL iluObject::iluIsCollectibleObject ( )
Returns true if the object is of a collectible class.
C++: virtual iluCString iluObject::iluObjectToIORString ( )
Returns a string which is the object's name and contact information
as specified by the CORBA IIOP spec - caller gets ownership of the string.
May return NULL if the object is not exported through an IIOP
ilu_Port.
(Available only when IIOP
support is configured into ILU.)
C++: virtual iluCString iluObject::iluObjectToURLString ( )
Returns a string which is the object's name and contact information
as specified by an HTTP
URL - caller gets ownership of the string.
May return NULL if the object is not exported through an HTTP
ilu_Port
(Available only when HTTP
support is configured into ILU.)
C++: ILUCPP_BOOL iluObject::iluPing()
Returns ILUCPP_TRUE
if the true object exists, and the process
serving it can be contacted, otherwise ILUCPP_FALSE
.
C++: ILUCPP_BOOL iluObject::_is_equivalent(iluObject* p_obj)
Returns ILUCPP_TRUE
if the two objects denote the same thing.
C++: ILUCPP_BOOL iluObject::iluInSameServer(iluObject* p_obj)
Returns ILUCPP_TRUE
if the two objects are in the same ILU server.
Used, for example, to determine if objects are SIBLINGS.
C++: virtual const char* /* ILUowned */ iluObject::iluClassName ( )
C++: virtual const char* /* ILUowned */ iluObject::iluClassId ( )
Return the ILU class name and type id - primarily informational use.
C++: virtual void iluObject::iluIncrementReferenceCount( )
C++: virtual void iluObject::iluDecrementReferenceCount( )
Reference count operations - when an object is first created, it has a reference count of one. If the reference count ever goes to zero, delete is called on this. CORBA compliant apps (where objects derive from CORBA::Object) should use the duplicate and release functionality defined in the CORBA specification.
C++: virtual iluCardinal iluObject::iluGetReferenceCount( )
Returns what the current reference count is.
C++: static iluObject* _duplicate(iluObject* p_obj)
Increments the reference count on the object and returns it. Returns NULL if passed NULL.
C++: static iluObject* _narrow(iluObject* p_obj)
Effectively casts the object pointer to an iluObject*.
An abstract C++ class for developers to derive from to
provide Object Tables. Object tables cannot be copied or assigned.
Besides doing whatever application specific things might need to be
done in the constructor and destructor, a class derived from iluObjectTable
must provide the iluObjectOfInstanceHandle virtual member function.
C++: virtual iluObject* iluObjectTable::iluObjectOfInstanceHandle (iluCString pc_instance_handle /* ILUowned */) = 0;
Called by ILU to create and return a new iluObject
* with the specified instance
handle. ILU retains ownership of pc_instance_handle - i.e. copy it if you need
want to hang on to it. Note that when in this function, you are 'inside' the object's server -
i.e. you hold the locks on the server - this means that when you create the object, you must
specify the 3rd argument to the object's constructor (b_within_object_table) as true.
C++: virtual iluServer* iluObjectTable::iluGetServer ();
Returns the pointer to the iluServer this object table is associated with.
C++: virtual iluObjectTable::~iluObjectTable ( )
Do whatever destroying the Object Table needs to do to free up resources, etc.
It gets called when the iluServer
it's associated with it is shut down.
Encapsulates ilu_Passport
functionality
C++: iluPassport::iluPassport ( iluIdentityInfo p_identity_info = NULL
)
Constructor - creates and returns a passport, optionally containing the specified identity.
C++: virtual iluPassport::~iluPassport ( )
Destructor - frees any associated identities in addition to freeing the passport
C++: static iluPassport* iluPassport::iluGetPassport ( )
C++: static iluPassport* iluPassport::iluSetPassport (iluPassport* p_passport )
Get and set the passport being used for outgoing calls - in the multi-threaded case, this is per-thread
Set returns the old iluPassport
. Note that before your thread exits, you should either call
iluSetPassport(NULL
), or delete the iluPassport
in use (assuming it's only in use for a single thread).
C++: static iluPassport* /* ILUowned */ iluPassport::iluGetCallerPassport( )
Get the passport of the caller.
C++: virtual void iluPassport::iluAddIdentity ( iluIdentityInfo p_identity_info /* ILUowned */ )
Adds identity to Passport. Only one identity of each type is allowed.
C++: virtual iluIdentityInfo /* ILUowned */ iluPassport::iluFindIdentity ( iluIdentityType p_identity_type )
Returns identity of specified type, if present else NULL
C++: static iluIdentityInfo iluPassport::iluCopyIdentity ( iluIdentityInfo p_identity_info )
Returns a copy of the passed identity
C++: ilu_Passport /* ILUowned */ iluPassport::iluGetIluPassport ()
Returns the (kernel) ilu_Passport
Encapsulates GSS functionality - only defined when ILU is configured with secure transport.
C++: static iluIdentityInfo iluGSS::iluAcquireGSSIdentity ( gss_cred_id_t gss_credential )
C++: static ILUCPP_BOOL iluGSS::iluDecodeGSSIdentity ( iluIdentityInfo p_identity_info, gss_name_t* p_name, iluFineTime* p_good_till_time,gss_OID mechanism, ILUCPP_BOOL* p_b_local, iluCardinal* p_card_flags )
p_identity_info - input; retain; info to decode p_name - output; name in identity p_good_till_time - output; good-till mechanism - input; actual mechanism desired; optional p_b_local - if TRUE, local; otherwise remote p_card_flags - connection flags, as in gss_inquire_context
C++: static gss_cred_id_t iluGSS::iluAcquireGSSCredForName ( char* pc_name, iluCardinal card_lifetime, gss_OID mechanism, ILUCPP_BOOL b_accept_only )
C++: static iluCString iluGSS::iluGSSNameToString ( gss_name_t name )
Subclass from the iluMainLoop
class if you want to have your
own version of the main loop. iluMainLoops
cannot be copied or assigned.
A single threaded application should supply all functions.
An application making use of ILU's OS multi-threaded
operation should not use a different mainloop. If you're using your
own thread package, you must supply all functions, and see the comment
for iluCppRuntime::iluInitialize
C++: virtual void iluMainLoop::iluRun ( int* p_i_stop_on_non_zero ) = 0;
Runs the main loop until *p_i_stop_on_non_zero is non-zero.
C++: virtual void iluMainLoop::iluExit ( int* p_i_stop_on_non_zero ) = 0;
Causes the main loop to exit
C++: virtual ILUCPP_BOOL iluMainLoop::iluRegisterInputHandler (int i_fd,
void (* pfunction_input_handler )(int i_fd, void* pv_input_handler_arg ), void* pv_input_handler_arg ) = 0;
Input Handlers - When there is input activity on the file descriptor
i_fd, the mainloop will call the registered handler procedure
pfunction_input_handler, passing it i_fd and pv_input_handler_arg as arguments.
Returns ILUCPP_FALSE
if it can't do it's job due to some resource limitation.
C++: virtual ILUCPP_BOOL iluMainLoop::iluUnregisterInputHandler ( int i_fd,
void (** ppfunction_input_handler )(int i_fd, void* pv_input_handler_arg ), void** ppv_input_handler_arg ) = 0;
Returns ILUCPP_FALSE
if input on i_fd was being handled, else ILUCPP_TRUE
.
Sets function and arg ptrs to what they were if anything.
C++: virtual ILUCPP_BOOL iluMainLoop::iluRegisterOutputHandler (int i_fd, void (* pfunction_output_handler )(int i_fd, void* pv_output_handler_arg ), void* pv_output_handler_arg ) = 0;
Output Handlers - When it is possible to perform output on the file descriptor i_fd, the mainloop will call the registered handler procedure pfunction_output_handler, passing it i_fd and pv_output_handler_arg as arguments.
C++: virtual ILUCPP_BOOL iluMainLoop::iluUnregisterOutputHandler (int i_fd,
void (** ppfunction_output_handler )(int i_fd, void* pv_output_handler_arg ), void** ppv_output_handler_arg ) = 0;
Returns ILUCPP_FALSE
if output on i_fd had a handler, else ILUCPP_TRUE
Sets function and arg ptrs to what they were if anything.
C++: virtual iluAlarm iluMainLoop::iluCreateAlarm ( ) = 0;
Creates an alarm. An alarm is an active object which can be set to asynchronously invoke a procedure with an argument at a specified time. An alarm may be something like a pointer to a structure that has some internal structure, but from the point of view of an alarm user, it's just a handle that is used to specify a particular alarm to be set or cleared.
C++: virtual void iluMainLoop::iluSetAlarm(iluAlarm the_alarm, iluFineTime alarm_time, void (*pfunction_alarm_handler)(void* pv_alarm_handler_arg), void* pv_alarm_handler_arg ) = 0;
Sets up an alarm to call the handler procedure pfunction_alarm_handler, passing it pv_alarm_handler_arg as an argument, when the alarm_time occurs. C++: virtual void iluMainLoop::iluClearAlarm ( iluAlarm the_alarm ) = 0;
Cancels the alarm (effectively sets the alarm time to infinity).
C++: virtual void iluMainLoop::iluDestroyAlarm ( iluAlarm the_alarm ) = 0;
Destroys the alarm (if alarm is set, does not invoke).
C++: static void iluMainLoop::iluSetFineTimeFromNow( ilu_FineTime* p_finetime, ilu_integer i_secs, ilu_cardinal i_msecs )
Utility function to set the pointed to ilu_FineTime to a time i_secs + i_msecs in the future
C++: static void iluMainLoop::iluSetMainLoop ( iluMainLoop* p_mainloop_instance )
C++: static iluMainLoop* iluMainLoop::iluGetMainLoop ( )
Setting the Main Loop to be used - Call iluSetMainLoop set your mainloop as the one for ILU to use. It should called before any ILU initialization.
C++: static iluAlarm iluMainLoop::iluDefaultLoopCreateAlarm ( )
C++: static void iluMainLoop::iluDefaultLoopSetAlarm ( iluAlarm the_alarm, iluFineTime alarm_time, void (* pfunction_alarm_handler )(void* pv_alarm_handler_arg ), void* pv_alarm_handler_arg )
C++: static void iluMainLoop::iluDefaultLoopClearAlarm ( iluAlarm the_alarm )
C++: static void iluMainLoop::iluDefaultLoopDestroyAlarm ( iluAlarm the_alarm )
When you haven't set the main loop (i.e. you're using ILU's default loop), you can call these functions to create, set and unset alarms. (If you set your own main loop, just call its alarm functions.)
Go to the previous, next section.