Issue 141: Practical problem with DII using Request Pseudo Object
Issue 647: include files
Issue 1418: C++ _var type widening proposal
Issue 1659: Section 7.3.6: PortableServer::ValueRefCountBase
Issue 1799: struct containing Fixed type
Issue 1971: Extraction of strings from an Any
Issue 1983: Extraction of Fixed from Any
Issue 1984: Generic extraction of Fixed
Issue 2207: Need more info for custom marshalled value in C++
Issue 2222: Is public _ptr member mandatory?
Issue 2253: portable includes
Issue 2285: Value Box Mapping
Issue 2306: Valuetypes as operation arguments
Issue 2309: Memory management of recursive value
Issue 2497: Value boxes and sensible value issue
Issue 2614: Setting the TypeCode of an Any without setting a value
Issue 2640: IDL that is not IDL!
Issue 2875: ValueBase::_copy_value clarification
Issue 3055: _default_POA
Issue 3074: Problem with AbstractBase definition
Issue 3111: Abstract interface and DSI issue with C++
Issue 3150: Exceptions in servant constructors
Issue 3161: _out types and nested calls
Issue 3217: Any and UnknownUserException
Issue 3225: C++ ValueBox & Fixed question
Issue 3242: C++ spec: Valuebase missing get_value_def
Issue 3245: Construction of _var types
Issue 3246: UnknownUserException and stubs
Issue 3247: fixed-length _var assignment from pointer
Issue 3248: Object Reference insertion/extration to Any
Issue 3326: ValueBase::_copy_value() function is underspecified
Issue 3331: Valuetype "copying" semantics underspecified? (C++ issue # 1)
Issue 3332: Valuetype "copying" semantics underspecified? (C++ Issue # 2)
Issue 3339: ref counting ambiguous?
Issue 3340: set_servant and null servant
Issue 3359: Issue with valuetypes & inout/out parameters
Issue 3380: Constructor for structures?
Issue 3401: void * operations on Any?
Issue 3532: DSI and implicit activation
Issue 3537: Sequence mapping & custom marshalling
Issue 3538: Read-only parameter remnants
Issue 3539: Variable-length out params and exceptions
Issue 3562: Supporting typedefs for _var types?
Issue 3567: Any insertion for Boolean/Octet/Char
Issue 3574: unclear semantics for valuetype insertion into Any
Issue 3603: unspecified criterion for Any extraction
Issue 3616: CORBA::Environment for EH compilers
Issue 3673: CORBA::release and CORBA::is_nil on POA_ptr
Issue 3966: _default_POA if no default ORB?
Issue 4002: CORBA::RequestSeq or CORBA::ORB::RequestSeq?
Issue 4119: questions to IDL - C++ mapping ( CORBA 2.3, valuebox)
Issue 4144: ORB::destroy() missing
Issue 4150: Optional parameters for _create_request?
Issue 4151: Passing two context lists to _create_request()
Issue 4157: publication of messaging / unchecked_narrow
Issue 4199: Inserters/extractors for boxed strings?
Issue 4288: ServantBase needs _get_domain_managers()?
Issue 4533: Fixed and truncation/rounding?
Issue 4539: UTF-8 and IDL character types in C++
Issue 4797: Add set of typedefs that would facilitate template programming
Issue 5440: Prohibit extracting from any into _out type?
Issue 5466: conversion algorithm not specified
Issue 5854: 1.16.3 Extraction from any
Issue 6163: _var's and valuetypes
Issue 6245: No portable way to create a OUT argument for a DII request
Issue 6276: Sequence _var needs const operator []
Issue 6413: Concrete ValueType _init class problem
Issue 11403: Section: 13.6 Server mapping
Issue 14852: Describe operator != and == for all generated types
Issue 16528: valuetype example has errors
Issue 16892: need unchecked narrow
Issue 141: Practical problem with DII using Request Pseudo Object (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized
Severity:
Summary: Summary: If I want to use the DII to send out multiple simultaneous requests, I don"t see a practical way to associate any client specific context that is C++ compliant to those requests.
Resolution:
Revised Text:
Actions taken:
October 1, 1996: Received issue
Discussion: deferred in June 2011 to the next RTF
Issue 647: include files (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized
Severity:
Summary: Summary: There seems to be nothing in the spec that specifies the name of the include files for things in the CORBA module (e.g. type definitions). Add such a requirement to each language mapping
Resolution:
Revised Text:
Actions taken:
August 1, 1997: received issue
Discussion:
Issue 1418: C++ _var type widening proposal (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: Michi Henning & Steve Vinoski have previously challenged people to come
up with a modification to the C++ language mapping that would allow for
type safe widening of object reference _var types for assignment or copy
construction. I believe I have come up with the solution, and Michi
agrees with me:
Proposal:
For object reference _var types, replace the copy and assignment
operators:
class T_var {
public:
...
T_var(const T_var &);
T_var &operator = (const T_var &);
...
};
with:
class T_var {
public:
...
template <class C_var>
T_var(const C_var &cv) : ptr_(T::_duplicate(cv.in()) {
}
template <class C_var>
T_var &operator = (const C_var &cv) {
if ((void *)this != (void *)cv) {
CORBA::release(ptr_);
ptr_ = T::_duplicate(cv.in());
}
return *this;
}
...
private:
T_ptr ptr_;
};
Resolution:
Revised Text:
Actions taken:
June 2, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 1659: Section 7.3.6: PortableServer::ValueRefCountBase (cxx_revision)
Click here for this issue's archive.
Nature: Revision
Severity:
Summary: Summary: There is no mention of PortableServer::ValueRefCountBase after this
page. It is not clear why values that also implement interfaces
do not use the same reference counting scheme as other values.
Resolution:
Revised Text:
Actions taken:
July 9, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 1799: struct containing Fixed type (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: Section 20.9, page 20-28 of orbos/98-07-12 describes what types are
considered variable-length. Since the new Fixed class has non-trivial
constructors, it should also be a considered a variable-length type. Note
that any fixed-length struct containing one cannot be statically initialized.
Resolution:
Revised Text:
Actions taken:
August 11, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 1971: Extraction of strings from an Any (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: What happens if I write
CORBA::Any a = ...;
const char *p;
a >>= p;
and the type code in the Any indicates a *bounded* string? Does the extraction
succeed or fail? The mapping doesn"t say.
Resolution:
Revised Text:
Actions taken:
September 17, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 1983: Extraction of Fixed from Any (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: The mapping right now offers Any::to_fixed to get a Fixed value out of an Any:
to_fixed(Fixed &f, UShort d, UShort s);
The spec doesn"t state what should happen if the digits and scale do
not match what is in the type code. I believe extraction should fail in
this case.
Resolution:
Revised Text:
Actions taken:
September 22, 1998: receive dissue
Discussion: deferred in June 2011 to the next RTF
Issue 1984: Generic extraction of Fixed (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary:
The C++ mapping does not permit extraction of a Fixed from an Any
in a generic way -- I must always specify matching digits and scale in
order to call Any::to_fixed(). This is inconvenient if an application
wants to deal with Fixed values generically (because Fixed is a generic
type in C++ anyway).
Proposal:
Add an overloaded >>= operator for extraction of Fixed from an Any.
The operator sets the Fixed value to whatever scale and digits
are present in the type code.
Cheers,
Michi.
Resolution:
Revised Text:
Actions taken:
September 22, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2207: Need more info for custom marshalled value in C++ (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: The current C++ chapter for custom marshalled values on p. 20-94 lacks
information about how one implements a custom value.
The "Value Type Semantics" chapter in "ptc/98-10-06, 15 Oct. 98[REVIEW]"
p. 5-11 says,
" The implementer of a custom value type shall provide an
implementation of the CustomMarshaller operations. The manner
in which this [sic] done shall be specified for each language mapping..."
Resolution:
Revised Text:
Actions taken:
November 12, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2222: Is public _ptr member mandatory? (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: In a number of places in the sample code for the C++ binding, the symbol
_ptr is used as a member variable in _var types. In all of these the
actual member is shown as private, so it is clear that actual
implementations could use something else.
The one exception to this is in section 20.10 on the Mapping for Struct
Types. This discusses (without sample code) the mapping for string and
object reference members of structs.
Resolution:
Revised Text:
Actions taken:
November 19, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2253: portable includes (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: We all know that the names of the C++ #include files generated from IDL are
not standardized, and are thus the one remaining major source portability
issue. One way to fix this would be to agree on some standard filenames,
but we"ve tried this before and have never succeeded.
Just thinking out loud here, but another way to fix it would be to agree on
some standard macro names that applications could use to portably include
the appropriate files. For example, define one macro for a client-side
include and one macro for a server-side include, both taking the basename
of the IDL file as an argument:
#ifndef CORBA_CXX_CLIENT_INCLUDE
#define CORBA_CXX_CLIENT_INCLUDE(base) <base ## Client.hh>
#endif
#ifndef CORBA_CXX_SERVER_INCLUDE
#define CORBA_CXX_SERVER_INCLUDE(base) <base ## Server.hh>
#endif
Obviously, the exact definition of the macro would depend on the names of
the generated files.
I believe these could then be used portably in the client and server source
code like this:
#include CORBA_CXX_CLIENT_INCLUDE(file)
With this approach, nobody has to change the names of the files they
currently generate.
Resolution:
Revised Text:
Actions taken:
December 14, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2285: Value Box Mapping (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: This may be a naive question, but it seems like the C++ mapping
for value boxes is incomplete. As far as I can tell, the specification
defines the mapping for the following types:
basic types, enum, objref, string, wstring, struct, union, sequence, array, fixed, any
But what about the types that have not been mentioned?
value, value box, TypeCode, Principal, native, except
If these types aren"t allowed, does the specification say that somewhere?
Resolution:
Revised Text:
Actions taken:
December 23, 1998: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2306: Valuetypes as operation arguments (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: The C++ mapping document (98-09-03, p. 108) states that "... the callee
shall receive a copy of each valuetype argument passed to it even if the
caller and callee are collocated in the same process."
In the collocated case, should the ORB invoke _copy_value() to produce
the copy?
Since the user could implement _copy_value() to return a nil value, it
seems unlikely that the ORB could rely on this mechanism. However, a
properly implemented _copy_value() would likely provide a significant
speed improvement over marshalling and unmarshalling.
Resolution:
Revised Text:
Actions taken:
January 18, 1999: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2309: Memory management of recursive value (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: Section 20.21, "Argument Passing Considerations," says that for valuetypes:
"The caller shall eventually invoked _remove_ref on the valuetype
instance it receives back as either an inout, out, or return value."
For memory management purposes, this is not sufficient in some cases.
Resolution:
Revised Text:
Actions taken:
January 20, 1999: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2497: Value boxes and sensible value issue (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: Value Boxes inherit from CORBA::ValueBase and
must therefore implement get_value_def(), but
cannot return a sensible value.
Resolution:
Revised Text:
Actions taken:
March 1, 1999: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2614: Setting the TypeCode of an Any without setting a value (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: Consider the following IDL:
----------------------------------------------------------------------
// IDL
typedef long MyArray[1000000];
interface I
{
void set_array(in MyArray array);
};
----------------------------------------------------------------------
Now let"s assume that I want to implement this using the DSI:
----------------------------------------------------------------------
// C++
void
I_impl::invoke(ServerRequest_ptr request) throw()
{
String_var name = request -> op_name();
if(strcmp(name, "set_array") == 0)
{
NVList_ptr list;
orb -> create_list(0, list);
Any* any = list -> add(ARG_IN) -> value();
XXX
request -> params(list);
MyArray_forany arg;
*any >>= arg;
... // Do something with arg;
return;
}
else
{
NVList_ptr list;
orb -> create_list(0, list);
request -> params(list);
Any* any = new Any;
*any <<= new BAD_OPERATION();
request -> exception(any);
}
}
----------------------------------------------------------------------
At the line I marked with XXX, I have to set the TypeCode of the
Any.
Resolution:
Revised Text:
Actions taken:
April 20, 1999: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2640: IDL that is not IDL! (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: The C++ language mapping chapter contains many blocks of IDL like stuff
with the comment
// IDL
in the first line, but the stuff in the block is not valid IDL for
various reasons:
(i) Uses "pseudo" as an apparent keyword.
(ii) Contains declarations like
attribute exception exception;
I suggest that the comment "// IDL" be replaced by "// Augmented IDL
(see "Usage" on page x-y)" cross-referencing to section 20.23 Usage, so
that people know for sure that this is not IDL.
Furthermore, to make the claim in section 20.23 true, the declaration:
attribute exception exception;
should be fixed to be something else, or alternatively, the exceptional
use of exception should be called out as a specific augmentation of IDL
in section 20.23.
Resolution:
Revised Text:
Actions taken:
May 6, 1999: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 2875: ValueBase::_copy_value clarification (cxx_revision)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: Summary: The ValueBase::_copy_value() function is included in the discussion
of the "reference counting interface" in section 1.17.5 of 99-07-41.
Later, the description of the reference counting mix-in classes
says:
"Each of these classes shall be fully concrete and shall completely
fulfill the ValueBase reference counting interface..."
However, I do not believe that the intent was to require the mix-in
classes to implement _copy_value().
Therefore I suggest one of two clarifications:
1) Move the discussion of _copy_value() out of the reference-counting
section, or
2) Specify which functions the mix-in classes are actually expected to
implement, e.g.,
"Each of these classes shall be fully concrete and shall completely
fulfill the ValueBase reference counting interface (_add_ref,
_remove_ref, and _refcount_value), ..."
Resolution:
Revised Text:
Actions taken:
September 9, 1999: received issue
Discussion: deferred in June 2011 to the next RTF
Issue 3055: _default_POA (cxx_revision)
Click here for this issue's archive.
Source: Triodia Technologies Pty Ltd (Mr. Michi Henning, michi(at)triodia.com)
Nature: Uncategorized Issue
Severity:
Summary:
what should _default_POA() return if no default ORB exists in the server (that is, ORB_init() with an empty ORB ID was never called)?
deferred in June 2011 to the next RTF
In the CORBA 2.3 spec, section 6.2, CORBA::AbstractBase is defined as:
module CORBA {
native AbstractBase;
};
This implies that the C++ mapping for AbstractBase when used as a
parameter is like this:
class DataOutputStream { // from CORBA 2.3, section 5.5.2
void write_Abstract(AbstractBase value);
};
But section 1.18.1 of the CORBA 2.3 C++ mapping makes it clear that the
signature should be:
class DataOutputStream { //
void write_Abstract(AbstractBase_ptr value);
};
Now I know that DataInputStream & DataOutputStream can be special cased
to handle this, but if we need to add additional operations that use
AbstractBase in the future, it would be nice if this could be fixed to
behave consistently with the other native type mappings to C++.
deferred in June 2011 to the next RTF
There doens't appear to be any portable way to implement an object that inherits from an abstract interface using the DSI in C++ without compile time knowledge of the abstract interface. The basic problem is that I can create an object reference from a POA, but there is no way to convert the reference into an abstract interface reference so that I can send it out on the wire. We need some mechanism to coerce an object reference into an abstract interface reference (with a runtime check) to make this work.
deferred in June 2011 to the next RTF
I think we have a defect/omission in the C++ mapping with respect
to exception safety. Consider a servant class with a constructor:
class FooImpl : public virtual POA_Foo {
public:
FooImpl();
// ...
};
Consider what happens if FooImpl() throws an exception for some reason.
By the time FooImpl() runs, the base class constructor POA_Foo() has run
already. So, when the compiler deals with the exception, it invokes
~POA_Foo().
The problem arises because, in our implementation at least, ~POA_Foo()
checks if the reference count is zero and asserts if not.
deferred in June 2011 to the next RTF
consider:
// IDL
struct VariableStruct { ... };
interface I
{
void foo(out VariableStruct s);
void bar(out VariableStruct s);
};
Then:
// C++
void
MyImplForI::foo(VariableStruct_out s)
{
bar(s);
bar(s); // Leak here
}
void
MyImplForI::bar(VariableStruct_out s)
{
s = new VariableStruct;
}
The freeing of memory for out params relies on the default conversion
by the _out constructor from a pointer to the _out type which, as a
side effect, frees the memory return by the previous call. However,
in this case, and _out param is passed to another call, so the
assignment operator runs, not the constructor:
T_out& operator=(T* p) { ptr_ = p; return *this; }
The assignment operator doesn't free the previous memory, so we get
the leak.
Should the assignment operator be changed?deferred in June 2011 to the next RTF
The mapping requires that it must be possible to insert CORBA::Exception into an any (section 1.19.2). Question: Is it possible to insert UnknownUserException into an Any? If the answer is yes, what are the members of UnknownUserException, what is its CDR representation, and what is its TypeCode? If the answer is no, we should clearly state this and specify what happens if I attempt to insert UnknownUserException into an Any.
deferred in June 2011 to the next RTF
Section 1.17.7.5 states: "Value boxes for these types [including Fixed]
map to classes that have exactly the same public interfaces as the
underlying boxed types...".
Does this also include overloaded operators that are defined in the
Fixed class?
It sure seems weird to allow some operators to work but not others:
// IDL
valuetype FixedVal fixed<5,2>;
// C++
FixedVal *fv = ...;
++fv; // legal?
CORBA::Fixed f = fv * 2; // illegal?
deferred in June 2011 to the next RTF
In section 1.17.5, the C++ class for Valuebase does not show the get_value_def operation.
deferred in June 2011 to the next RTF
the spec says (on page 1-23): The T* constructor creates a T_var that, when destroyed, will delete the storage pointed to by the T* parameter. The parameter to this constructor should never be a null pointer. Compliant implementations are not required to detect null pointers passed to this constructor. This seems broken for two reasons: - In an environment without real exceptions, null pointers must be returned for variable-length types in the presence of an exception. So if I write Foo_var fv(some_ref->op(my_corba_environment)); and op() raises an exception (which will be returned in the environment), I'm hosed. - The assignment operator permits assignment of null, but the constructor doesn't. This is inconsistent, if nothing else. It seems that disallowing initialization from null pointer is some historical hangover? I think the restriction should be removed.
deferred in June 2011 to the next RTF
the spec currently says (page 1-101):
Request invocations made through the DII may result in
user-defined exceptions that cannot be fully represented
in the calling program because the specific exception type
was not known at compile-time. The mapping provides the
UnknownUserException so that such exceptions can be represented
in the calling process: [...]
Here is a code snippet for the DII:
req->invoke();
if (req->env()->exception()) {
// Got an exception
CORBA::Exception * ep = req->env()->exception();
// ...
}
The para on page 1-101, by implication, says that:
- If there are concrete C++ types available in the caller that
can represent the user exception, a real user exception is
instantiated and the pointer returned by exception() points
at the concrete user exception instance.
- If there is no concrete C++ type available in the caller for
a user exception, the pointer returned by exception() points
at an instance of UnknownUserException.
It's not as clearly spelled out as this, but it can be implied from the
words on page 1-101.
This is bad. For one, it implies "action at a distance". For example,
linking the stubs for a user exception into a completely unrelated
part of the same binary (possibly via a library) would change
the behavior of the above DII call. Further, to make this behavior
happen would require some form of global initialization data structure.
In effect, there would have to be something that would let the ORB
know (globally) for which user exceptions stub code is linked in.
We rejected the need for global data recently in another context (for
the proposed extraction operator for user exceptions). For the same reason,
we should reject this here and mandate that, if I use the DII, *all* user
exceptions are *always* returned as UnknownUserException.
deferred in June 2011 to the next RTF
the new mapping for _var types for fixed-length underlying types shows:
T_var &operator=(T *t) {
if (t != m_ptr) {
delete m_ptr;
m_ptr = t;
}
return *this;
}
This guards against self assignment when a pointer is assigned to the _var.
I don't think this is right:
- Assigning a pointer to a _var that already owns what the pointer
points at is almost certainly an error:
MyStruct * p = ...;
MyStruct_var v = p; // OK
// ...
v = p; // Almost certainly an error
- We don't do the same thing elsewhere. On page 1-13:
A_var &operator=(const A_var& a) {
reset(p); return *this;
}
This is inconsistent: assignment of a _ptr to a _var reference
is not safe against self assignment, so assignment of a pointer
to the _var for a fixed-length type shouldn't be either.
Note that the other assignment operators are just fine -- I'm only objecting
to testing for self-assignment for operator= with a pointer as the RHS.
(A nice compiler could even insert an assertions if a _var is assigned the
same thing that it already points at.)
deferred in June 2011 to the next RTF
I believe the specification for insertion of object references to Anys is
somewhat ambiguous. And, if it is intended to be as I think, it may also be
less than ideal.
Consider the following idl:
interface B {...};
interface D : B {...};
And then consider the following code:
D_ptr d; // initialize this to non-null value somehow
B_ptr b = B::_narrow(d);
Any ab;
ab <<= b;
Any ad;
ad <<= d;
// ...
B_ptr b_val;
if (ab>>=b_val) { /* do stuff with b_val */ }; // 1
if (ad>>=b_val) { /* do stuff with b_val */ }; // 2
D_ptr d_val;
if (ab>>=d_val) { /* do stuff with d_val */ }; // 3
if (ad>>=d_val) { /* do stuff with d_val */ }; // 4
>From what I can see of the spec, it is a bit unclear about whether then
insertion of an object should use the static type or the dynamic type of the
object to initialize the typecode. Simplicity and consistency with other
related operations suggests that it should use the static type. That is what
we currently do, and a quick test of ORBIX 2000 seems to tell me it does it
that way too.
With that interpretation, 1&4 will work, while 2&3 will fail.
Nobody should be surprised that 3 fails, but it is inconvenient
that 2 doesn't work.
If insertion used the dynamic type of its argument, then 1&2
would work, while 3&4 would fail.
To get reasonable behavior when derived types might be present,
(and how often can you be certain they cannot?)
it seems that one should almost never use type specific object
extraction. Instead, one must do something like:
Object_var o;
B_var bv;
if (ad>>=to_object(o._out()) &&
!CORBA::is_nil(bv = B::_narrow(o)))
{ // do stuff with bv };
This is unfortunately a bit inconvenient.
So, is there any text in the spec that says, when inserting an object
reference type into an any, if the repository id in the typecode should be
the static type of the inserted argument or the dynamic type of the value of
the argument?
If not, I think we need to add some text.
deferred in June 2011 to the next RTF
The CORBA 2.3 C++ mapping is clear on what the use of ValueBase::_copy_value is, but is unclear as to who is responsible for providing an overriding definition of this pure virtual function. Is it the IDL compiler, generating an overriding _copy_value() function for each valuetype C++ class, or is the user, when he provides a valuetype implementation class?
deferred in June 2011 to the next RTF
C++ issue #1: The C++ specification should state that valuetype parameters which are copied by the ORB for collocated invocations are done using an ORB internal mechanism, not _copy_value().
deferred in June 2011 to the next RTF
C++ issue #2: The ValueBase::_copy_value() function should be
deprecated in favor of a new ValueBase::_clone_value() operation:
// IDL
module CORBA {
abstract valuetype CloneContext { };
};
// C++
namespace CORBA {
...
class ValueBase {
...
public:
ValueBase *_clone_value(CloneContext *&);
};
...
};
The _clone_value() function provides an independant copy of the
valuetype it is invoked on. Any valuetypes reachable via the state of
the original valuetype are also copied, and relationships between
original valuetype(s) will be preserved in the cloned copies. The
CloneContext argument provides the necessary state information for the
ORB to properly maintain relationships between copied valuetypes. If
_clone_value() is called with a null CloneContext, a new CloneContext
will be generated and returned by the ORB as a result of the call.
deferred in June 2011 to the next RTF
For servant reference counting, the words "at least once" appear in a number of places when it comes to servant activation. set_servant(), activate_object(), activate_object_with_id(), servant_to_id(), servant_to_reference(), and _this() all use this language (pages 1-137 and 1-138): ... will invoke _add_ref at least once on the Servant argument... Problem: suppose my ORB calls _add_ref() twice in each of these operations for some reason. I now have a problem. That's because, for servant activators, responsibility for calling _remove_ref() passes to etherialize(). However, if the ORB is permitted to call _add_ref() as many times as it likes, I have no idea how many times I have to call _remove_ref() from within etherealize(). I think that the spec should say that _add_ref() is called *exactly* once for these operations *if* the corresponding servant is not in the AOM already. I vaguely remember the discussion about optimization of the calls to _add_ref() and _remove_ref(). I think the idea was to permit the ORB to avoid redundant calls. However, it seems that the language in the spec isn't precise enough. Under one interpretation, the refcount counts the number of entries in the AOM. Under another interpretation, it counts the number of calls in progress as well (because an ORB could call _add_ref() when a call is dispatched and call _remove_ref() when it finishes). Under yet a third interpretation, the refcount counts the number of object references in my address space. That interpretation is happens if *every* call to _this() calls _add_ref()... The language is not precise enough, I think...
deferred in June 2011 to the next RTF
the text for set_servant doesn't say what should happen if I call set_servant(0). I would suggest to throw BAD_PARAM in this case.
Transfer to C++ RTF deferred in June 2011 to the next RTF
The CORBA 2.3 C++ specification, section 1.22 states that valuetypes passed as in parameters to an invocation of an object are copied, even if the object is collocated with the caller. It does not make this statement for inout or out parameters (or return results), which strongly suggests that valuetype copying is not necessary. In fact, the text for valuetype inout parameters strongly suggests that copying is not performed. I think this is wrong and inout & out valuetypes should be copied as well (inout parameters should be copied before and after the invocation, while out and return values should be copied after the invocation completes.) Without the copies, call transparency will be broken and the client can distinguish between a local and a remote call.
deferred in June 2011 to the next RTF
The mapping for user exceptions and structures is identical, except for one thing: user exceptions have an additional constructor with one parameter for each member, so I can construct and throw the exception with a single throw statement. However, structures are second-class citizens: I can't instantiate and initialize a structure at the same time. (Well, at least not in general, because static initialization only works for aggregates and, at any rate, I can only instantiate and initialize with compile-time constants.) So, why don't we add the same constructor to the mapping for structures? It seems inconsistent to have one mapping for structures and a slightly different one for exceptions, when in fact they both could be the same.
deferred in June 2011 to the next RTF
I seem to remember that we decided to deprecate the void * functions on type Any. However, looking at the latest C++ draft, they are not marked as deprecated. Can anyone remember what we decided to do? Is this a bug in the spec or a bug in my memory?
deferred in June 2011 to the next RTF
The C++ "Mapping of PortableServer Dynamic Implementation Routine" states that "If DynamicImplementation::_this() is invoked outside of the context of a request invocation on a target object being served by the DSI servant, it raises the PortableServer::WrongPolicy exception". This conflicts with the behaviour of _this() in static skeletons as de- fined in "Skeleton Operations". In particular, this means that DSI servants cannot be implicitly acti- vated, and therefore, the choice of DSI vs. static skeleton is not trans- parent to the application integrator. Is there any rationale behind this?
deferred in June 2011 to the next RTF
Section 1.17.11 of ptc/2000-01-02 says that DataInputStream & DataOutputStream are mapped according to the normal valuetype mappings. This mapping results in operations that are at best cumbersome to use in marshalling sequences of primitive types: Operations read_xxx_array and write_xxx_array are defined, taking argments of type CORBA::xxxSeq. These are obviously intended to be sufficient for marshalling all defined sequences of the corresponding primitive type xxx. However, the c++ mapping for sequences requires that each distinctly declared sequence type be unique and separately overloadable. This guarantees that a marshaller attempting to marshal an sequence of primitive other than CORBA::xxxSeq will not be able to pass that sequence to the corresponding read_xxx_array and write_xxx_array operations. Instead, code must be written to bypass strict typing. To fix this, either the mappings for DataInputStream and DataOutputStream need to be non-standard, the mapping of sequences needs to change, or the mapping of CORBA::xxxSeq needs to change to something special.
deferred in June 2011 to the next RTF
in the resolution to issue 863, we decided to get rid of the read-only restriction for parameters. However, we forgot to remove a few snippets. Page 1-110, table, case 3: Remove the following text: Following the completion of a request, the caller is not allowed to modify any values in the returned storage--to do so, the caller must first copy the returned instance into a new instance, then modify the new instance. Page 1-110, table, case 6: Remove the following text: Following completion of a request, the caller is not allowed to modify any values in the returned storage--to do so, the caller must first copy the returned array instance into a new array instance, then modify the new instance.
deferred in June 2011 to the next RTF
the spec is currently not terribly clear about the server's responsibilities
when throwing an exception from an operation that has a variable-length
out param.
The intent of the spec is that the server is responsible for deleting
the memory it allocated to an out param before it throws an exception:
// Correct implementation
void
Foo_impl::
op(CORBA::String_out out_p) throw(CORBA::SystemException)
{
CORBA::String_var tmp = CORBA::string_dup("Hello");
bar(); // bar() may throw
out_p = tmp._retn(); // No leak, even if bar() throws
}
// Incorrect implementation
void
Foo_impl::
op(CORBA::String_out out_p) throw(CORBA::SystemException)
{
out_p = CORBA::string_dup("Hello");
bar(); // Leak if bar() throws
}
However, the spec never states this clearly. In fact, it sort of says
the opposite. On page 1-110, table item 3:
To maintain local/remote transparency, the caller must always
release the returned storage, regardless of whether the callee
is located in the same address space as the caller or is located
in a different address space.
There is no mention here of what should happen in the presence of exceptions.
I think it would be nice to clarify that the skeleton will never look
at an out param in the presence of exceptions and that the operation
implementation is responsible for deallocating memory in this case.
deferred in June 2011 to the next RTF
quite some time ago, we added the _var_type and _ptr_type definitions to proxies to make it easier to write templates. Similarly, we have the _whatever_seq typedefs for recursive structs and unions, to avoid problems with anonymous types. What's missing at the moment is a similar feature for _var types. When I'm writing a template that does it's job in terms of _var types, I also quite often want to do something to the underlying target type of the _var. However, I can't do that unless I pass in an extra template parameter (which, in turn, doesn't always work if I also want to use STL standard binders and such...) So, why not add a typedef for the target type to every _var type?
deferred in June 2011 to the next RTF
The mapping is currently a bit ambiguous about the insertion/extraction operators for Any. It says: Assuming that boolean, char, and octet all map the C++ type unsigned char, the private and unimplemented operator<<= and operator>>= functions for unsigned char will cause a compile-time error if straight insertion or extraction of any of the boolean, char, or octet types is attempted. This is ambiguous. It is not clear what is qualified by the first part of the sentence "Assuming that...". It could qualify all of the paragraph, in which case the interpretation is: Only on platform where these three types indeed map to the same C++ type will it be necessary to have these unimplemented operators. // C++ Octet oct = 040; Any any; any <<= oct; // this line will not compile any <<= Any::from_octet(oct); // but this one will This is unambiguous, but it doesn't make it clear whether this will be the case for all mapping implementations, or only those where the IDL types map to ambiguous C++ types. It is important to note that the previous example is only one possible implementation for these helpers, not a mandated one. Other compliant implementations are possible, such as providing them via in-lined static any member functions if boolean, char, and octet are in fact mapped to distinct C++ types. All compliant C++ mapping implementations must provide these helpers, however, for purposes of portability. Again, this is slightly ambiguous because, even though it requires the presence of the helpers, it doesn't make any statement about whether the prohibition of the direct insertion operators is mandatory for all implementations. I would suggest to clarify the text to state that direct insertion/extraction of Bool, Octet, and Char must fail with a compile-time error, regardless of how these types are mapped.
deferred in June 2011 to the next RTF
The semantics for insertion of a valuetype into an Any are unclear. (Note, this is related to issue 2531 in the IDL-to-Java RTF. It is also related to orb_revision issue 3205.) In section 1.16.2 of ptc/2000-01-02, two forms of insertion are defined: copying and non-copying. The non-copying form is described as: "The noncopying valuetype insertion consumes the valuetype pointed to by the pointer that T** points to. After insertion, the caller may not access the valuetype instance pointed to by the pointer that T* points to. The caller maintains ownership of the storage for the pointed-to-T* itself." There is no specific description of the copying form specific to valuetypes, so the generic description must apply: "For the copying version of operator<<=, the lifetime of the value in the any is independent of the lifetime of the value passed to operator<<=. The implementation of the any may not store its value as a reference or pointer to the value passed to operator<<=." One possible interpretation (1) is that the copying form should be implemented via a call to the _copy_value virtual function, while the non-copying form should simply retain the provided pointer (without calling _add_ref) and eventually call _remove_ref when done with it. If so, what is the significance of the rule about the caller not continuing to use the pointer? It it only that it has lost a reference count, and may continue using the pointer if it has another reference count? Or does this imply that continued access to the value is forbidden regardless of reference count? Another possible interpretation (2) is that the description is nonsense, and that the non-copying form should use _add_ref and the copying form should use _copy_value. In this interpretation the caller would be free to continue using the original pointer and would be obligated to _remove_ref it eventually. This seems like a more practical interpretation, but is inconsistent with usage for other non-copying insertions. Suggested Resolution: Replace the paragraph on non-copying insertion of valuetypes (quoted above) with: "The noncopying valuetype insertion takes ownership of one reference count to the valuetype pointed to by the pointer that T** points to. After insertion, the caller should treat the pointer as if _remove_ref had been called on it. The caller maintains ownership of the storage for the pointed-to-T* itself." "For copying valuetype insertion, the lifetime of the value in the any is independent of the lifetime of the value provided. The implementation of the any shall duplicate the value using the virtual function _copy_value or an equivalent mechanism. The caller retains ownership of the T* pointer and remains obliged to call _remove_ref on it."
deferred in June 2011 to the next RTF
The C++ language mapping does not specify what criterion should be used to
determine the validity of a typesafe extraction from an Any.
The closest it ever comes is the statement in 1.16.3:
"In this case, the version of operator>>= for type Long must be able to
determine whether the Any truly does contain a value of type Long...".
There are two obvious candidates: the equal and equivalent operations of
TypeCode.
Proposed resolution:
Replace the first sentence of 1.16.3:
"To allow type-safe retrieval of a value from
an any, the mapping provides the following
operators for each OMG IDL type T:"
with:
To allow type-safe retrieval of a value
from an Any, the mapping provides an
operator>>= for each OMG IDL type T.
Each such operator returns a boolean
indicating success or failure, and if
successful, makes the value of the any
available via a user supplied argument.
The success of the operation is determined
by applying the {equal | equivalent}
operation to the typecode of the any and
the typecode of the target type.
The exact form of operator>>= varies
according to the type T as follows:
The choice of {equal | equivalent} needs to be discussed. I believe there
are valid arguments for each.deferred in June 2011 to the next RTF
Question: Is it legal to do the following if I use a C++ mapping that uses C++ exceptions instead of using CORBA::Environment to handle errors? CORBA::Environment my_env; The spec says (page 114): The C++-PIDL specification differs from the C-PIDL specification as follows: [...] Supports a default constructor that initializes it to hold no exception information. However, the class definition that follows does *not* show the default constructor. So, the text disagrees with the class definition that is shown because "supports a default constructor" does not have a "may" or "might", so the text would appear to make the default constructor mandatory for *both* EH and non-EH mappings.
deferred in June 2011 to the next RTF
I believe that the CORBA::release and CORBA::is_nil
functions that take a POA_ptr argument do not
reference the proper scope:
1.41.11 release and is_nil
// C++
namespace CORBA {
...
void release(POA_ptr);
...
Boolean is_nil(POA_ptr);
...
}
Should be:
1.41.11 release and is_nil
// C++
namespace CORBA {
...
void release(PortableServer::POA_ptr);
...
Boolean is_nil(PortableServer::POA_ptr);
...
}
I don't see in the specification where the scope
of POA_ptr is explicitly defined. But, I believe
that the correct definition of POA_ptr is in the
PortableServer namespace (i.e. the enclosing scope
of the POA class).
Then again I can't find anything in the specification
that asserts that any Foo_ptr type must go in the
immediately enclosing class or namespace containing
the Foo type. :-/
Also, if POA_ptr is in PortableServer when an ORB is
mapping of modules to classes the definition of the
above release and is_nil functions in the CORBA class
will be impossible.
So I feel compelled to ask:
Do we really need to have release and is_nil functions
for types outside of the CORBA module?
deferred in June 2011 to the next RTF
what should _default_POA() return if the default ORB was never initialized? The spec doesn't say...
deferred in June 2011 to the next RTF
with 2.3, we got rid of all the C/C++ pseudo code for the DII and replaced
it with IDL. Unfortunately, this has broken something in the C++ mapping...
In the 2.0 spec, we had:
pseudo interface ORB {
typedef sequence<Request> RequestSeq;
// ...
};
With 2.3, we changed this to:
module CORBA {
// ...
typedef sequence<Request> RequestSeq;
// ...
};
Unfortunately, the C++ mapping still shows the (now incorrect) definition
from CORBA 2.0 in Section 1.33.1.
In addition, the C++ mapping shows in Section 1.33.2:
class ORB {
public:
class RequestSeq {...};
// ...
};
But then, in Section 1.41.21:
class ORB {
public:
typedef sequence<Request_ptr> RequestSeq;
// ...
};
The latter definition isn't C++...
So, we have several issues here:
1) How can we fix the C++ mapping to be in line with the core?
I'm toying with the idea of saying that RequestSeq is defined
in the CORBA namespace, with a typedef for backward compatibility
in the ORB interface. But I'm not sure what will break with
this kind of aliasing (repository IDs might change unexpectedly?)
2) Section 1.41.21 should be changed to show legal C++.
3) Depending on the resolution to this issue, both 1.33.2 and
1.41.21 will probably need updating to reflect the resolution.
deferred in June 2011 to the next RTF
I have the following questions to IDL - C++ mapping CORBA 2.3 (concerning valueboxes). Can somebody give me an answer? 1. I assume that valueboxes T as a special kind of valuetypes also need in C++ the T_var and the T_out types and the T_out types will be used in function signatures for IDL out-parameters. Is it true? 2. The mapping for strings and wstrings requires a definition of C++ operators << and >> to allow a use of strings (wstrings) with the c++ iostreams. What about valueboxes of strings (wstrings) - chapter 1.17.7.4? Is it required to define (in C++) the operators <<, >> to use T_var and T_out with C++ iostreams, where T is a type for a valuebox T of string (wstring)?
deferred in June 2011 to the next RTF
The June 99 version of the C++ mapping doesn't mention ORB::destroy(). It should.
deferred in June 2011 to the next RTF
On page 1-119, the spec says the following about _create_request() and _create_request2(): [...] the ORB requires: - a target object reference - an operation name - a list of arguments (optional) ^^^^^^^^^^ - a place to put the result (optional) ^^^^^^^^^^ - a place to put any returned exceptions - a Context (optional) ^^^^^^^^^^ - a list of the user-defined exceptions that can be thrown (optional) ^^^^^^^^^^ - a list of Context strings that must be sent with the operation (optional) ^^^^^^^^^^ Note all the "optional" remarks. It's not clear what "optional" actually means. We have two cases for these parameters: - Arguments, user exceptions, and IDL contexts are *sequences*. - Result and context are object references. Two questions: - What does it mean for a sequence parameter to be "optional"? That I can pass a null pointer or that I can pass an empty sequence? I assume that an empty sequence is meant, but the spec doesn't say that. - What does it mean for a reference parameter to be "optional"? That I can pass a nil reference or that I must pass a reference to some dummy object that indicates that the value really isn't there? Where this is particularly annoying is for the return value. (The "result" parameter to _create_request()): - If I can pass a nil reference, no problem. This could be interpreted to mean the same thing as a void return type. - If I can't pass a nil reference, what should I pass? Obviously, it would have to be a reference to a valid NamedValue object. But how do I create that NamedValue object? I can call ORB::create_named_value(), but what should I do then? CORBA::NamedValue_var result; orb->create_named_value(result); At this point, I have a NamedValue containing an Any with tk_null (because that's what the Any default constructor creates). However, to correctly indicate that the operation I want to call has a void return type, I have to make a NamedValue that contains an Any with tk_void. But, how do I achieve that? I can't use one of the Any inserters to turn the TypeCode in the Any into tk_void, and I can't use the type() member of the Any because I can't change the type of an Any if it isn't consistent with the TypeCode that's already there... Even worse, the NamedValue doesn't seem to make sense as the return value at all. For one, it has a name attribute. - What is the value of that name for a return value? - How would I set that string after having create the NamedValue by calling create_named_value()? - What is the value of that string once I have called create_named_value()? Second, the NamedValue contains a flags attribute. - What is the value of that flags attribute for a return value? None of ARG_IN, ARG_INOUT, or ARG_OUT make sense. (One could argue that ARG_OUT could be used, but I think that sucks...) - How would I set that flag on the NamedValue I have just created? The mapping for NamedValue only offers accessor but no modifiers, so I can't set the value of the flag. - What is the value of the flag once I have called create_named_value()? It seems that the easiest way to fix the problem is to state that, if a parameter isn't needed, this is indicated by an empty sequence for lists, and by a nil reference for objects. However, the problems around create_named_value() and appear to be more serious. How should we fix those?
deferred in June 2011 to the next RTF
The second version of _create_request() accepts two context lists:
void Object::_create_request(
Context_ptr ctx, // <===
const char * operation,
NVList_ptr arg_list,
NamedValue_ptr result,
ExceptionList_ptr,
ContextList_ptr, // <===
Request_out request,
Flags req_flags
);
The spec then says:
The ContextList differs from the Context in that the former supplies
only the context strings whose values are to be looked up and sent
with the request invocation (if applicable), while the latter
is where those values are obtained.
So, I *think* (but I'm not sure), this means to say that:
- The Context parameter points at a tree of context objects.
- The ContextList pointer points at an object that contains
a sequence of strings.
- The ContextList determines which context values are to be
picked out of the tree pointed at by the Context parameter and
to be sent with the invocation.
If that is the intended interpretation, it's very difficult to discern
from the words in the spec now. I think this needs clarification.
Questions:
- What happens if the ContextList contains the name of a context
variable that isn't available in the context tree?
- What happens if I have a non-empty context list but a nil
context tree?
Also, looking at the ContextList interface:
pseudo interface ContextList {
readonly attribute unsigned long count;
void add(in string ctxt);
string item(in unsigned long index) raises(Bounds);
void remove(in unsigned long index) raises(Bounds);
};
There is no further documentation on this. Some questions:
- As far as I can see, this interface is meant to maintain a
simple sequence of strings. So, why not simply use a string
sequence?
- At what position does add() add the item? Presumably at the tail,
but that isn't stated.
- How can I replace the value of string at a certain position?
It looks like I can't do that at all because there is no
random-access modifier.
This seems insanely complex.
Suggestion: We should
- add words to make it clear how the context parameters work
- consider overloading _create_request() yet again to use
an ordinary string sequence
- deprecate the ContextList pseudo interface
Or, we could drop support for IDL context altogether (but I suspect we
can't get away with that ;-)
Incorporate Messaging changes relevant to the C++ mapping, as shown in orbos/98-05-05 pages 115 and 116 together with any changes made to them by the Messaging RTF, into the IDL-C++ mapping chapter.
deferred in June 2011 to the next RTF
Given valuetype WStringValue wstring; is there any requirement to have stream inserters and extractors for the boxed value type itself? The spec is currently silent on this issue. Should the following work? WStringValue ws; cin >> ws; cout << ws;
deferred in June 2011 to the next RTF
The Object::get_domain_managers() operation is a transmissible operation with CORBA 2.3. Does ServantBase need anything added to handle this or is this managed internally by the ORB/POA?
deferred in June 2011 to the next RTF
Suppose we have:
typedef fixed<4,3> FT;
interface I {
FT op();
};
Suppose the server does:
FT
I_impl::
op() throw(CORBA::SystemException)
{
double d = 1.0/3.0;
return CORBA::Fixed(d);
}
There are lots more digits in the return value than what is expected by the
client. What should be returned to the client. The rounded value? The
truncated value?
Similarly, what if we have:
double d = 10000000;
return CORBA::Fixed(d);
Do we return 9.999 to the client (which is the best we can do in this case)?
Of course, it is the responsibility of the programmer to make sure that
nonsense such as the second case doesn't happen. But the spec has to say
what happens if it does happen ;-)
Also, the first case will be very common -- what should happen in this case?
deferred in June 2011 to the next RTF
implementing support for wchar/wstring I ran into some potential problems with the UTF-8 encoding for the IDL 'char' type. Lets suppose we have a C++ server with a native single-byte code set like ISO 8859-1. The Code Set Conversion specification states that UTF-8 is the fallback code set for 'char'. -> a client could decide to send characters in UTF-8 encoding. What happens on the server side with UTF-8 encoded characters that use more than 1 byte and thus don't fit into the single byte character as specified by the C++ mapping for IDL type 'char'?
deferred in June 2011 to the next RTF
The addition amounts to a set of typedefs that would facilitate template
programming, added to each C++ skeleton class created for an IDL interface,
and analogous to the typedefs that already exist in the mapping for the stub
side. Say we have an IDL file
module foo
{
interface bar {};
};
Then in generated code we're talking about something like:
namespace POA_foo
{
class bar
{
public:
typedef foo::bar _stub_type;
typedef foo::bar_ptr _stub_ptr_type;
typedef foo::bar_var _stub_var_type;
.
.
.
};
};
deferred in June 2011 to the next RTF
Just as we prohibited direct extraction from any any into a _var type due to the perils of memory management problems, we ought to prohibit extracting into _out types of variable sized structured types for the same reason
deferred in June 2011 to the next RTF
C++ programmers will often want to use strings as
object identifiers, the C++ mapping provides several conversion
functions that convert strings to ObjectId and vice-versa:"
The purpose is so the programmer can pick an arbitrary natural language
string and use it as an ObjectId, not so that the programmer can
generate a randomly unreadable string out of a binary ObjectId.
[...] the C++ mapping provides several conversion functions
that convert strings to ObjectId and viceversa:
[...]
If conversion of an ObjectId to a string would result in
illegal characters in the string (such as a NUL), the first two
functions throw the CORBA::BAD_PARAM exception.
The conversion algorithm is not specified, and the ORB is free to
choose whatever encoding it likes for its Object IDs. (Object IDs
in stringified form need not be moved across address spaces (or,
at least, not across ORB boundaries), so having a proprietary
encoding is perfectly OK.)
deferred in June 2011 to the next RTF
The question is about 99-07-41.pdf, as far as I know the latest C++ mapping specification. "1.41.5 Any Class" prescribes "Boolean operator>>=(const Any&, const char*&);" for unbounded strings, and "1.16.3 Extraction from any" says that unbounded strings are extracted by value. This seems to be contradictory: I seem to remember that const char* cannot be delete'd, though I don't find it in ISO/IEC 14882:1998(E). But, regardless of anything imposed by C++, the current mapping precludes a safe technique like (safe as in exception-proof): >> String_var theString; if(!(theAny>>=theString.out())){ ... } << I therefore propose that the mapping be changed to "Boolean operator>>=(const Any&, char*&);". This seems to work all right on my implementation (RayORB), for gcc 3.2 (MS VC++ 6.0 doesn't seem to care one way or the other, but I suppose that is wrong, although I'm not entirely sure).
deferred in June 2011 to the next RTF
1.9.1 says: "The copy constructor deep-copies any data pointed to by the T_var constructor parameter. This copy will be destroyed when the T_var is destroyed or when a new value is assigned to it. Compliant implementations may, but are not required to, utilize some form of reference counting to avoid such copies." and "The normal assignment operator deep-copies any data pointed to by the T_var assignment parameter. This copy will be destroyed when the T_var is destroyed or when a new value is assigned to it. Assigning a null pointer to a T_var is legal and results in deallocation of the data pointed to by the T_var." So my question is, is it legal to use ValueBase::_add_ref() and _remove_ref() instead of _copy_value() in this instance when T_var is representing a valuetype?
deferred in June 2011 to the next RTF
Since the Any constructor from type code, void* value and boolean release flag has been eliminated, there is no longer any portable way to create an OUT argument for a DII request, without also assigning a value to it. I propose either a constructor from type code or changing the behavior of the type code set method to always succeed if the Any's TCKind is tk_null.
deferred in June 2011 to the next RTF
Footnote 11 on page 1-48 of the 1.1 version of the C++ language mapping states that sequence _var classes don't have a const version of "operator []". The justification in the footnote is incorrect. This footnote should be removed, and the operator provided, since it otherwise prevents accessing sequence members through a const reference to a sequence _var.
deferred in June 2011 to the next RTF
The second-to-last paragraph of section 1.17.10.3 says "For valuetypes that have no operations or initializers, a concrete type-specific factory class is generated whose implementation of the create_for_unmarshal function simply constructs an instance of the OBV_ class for the valuetype using new and the default constructor." As specified, that requires the generation of invalid C++. The OBV_ class is abstract since it does not have implementations of the ValueBase reference counting functions. Perhaps the intention is that the OBV_ classes in such cases should derive from DefaultValueRefCountBase. However, the wording and explanation in section 1.17.6 explicitly forbids this: "Note that it is the application-supplied concrete valuetype classes that must derive from these mix-in classes, not the valuetype classes generated by the IDL compiler." One solution that avoids the problem, and avoids restricting the application's use of the OBV_ classes is to generate yet another class that derives from both the OBV_ class and DefaultValueRefCountBase, for instantiation by the _init class's create_for_unmarshal function.
deferred in June 2011 to the next RTF
Althrough I report my issue as a C++ issue, actually it is a common issue for other languages also. In current CORBA standard, a activated CORBA Servant object in the POA is shared by all the clients. But in many applications, a client connects to the server and calls some CORBA object methods to create a lot of connection related CORBA objects. Normally, the client will call "destroy" method of these CORBA object to destroy them before existing. But if the client exists abnormally, these created CORBA object will never be destroyed and never be used by any client. We can call this kind of CORBA object as "floating" CORBA object. The CORBA server application runs longer, the "floating" CORBA objects becomes more. And eventually, these "floating" CORBA objects will consume all the memory resources/CPU resources, then the CORBA server crashes and has to be restarted. The "floating" CORBA objects problem at the server side is not easy to be solved. For this problem, if the CORBA standard provides a method to solve it, the CORBA server will run more robust. Actually, the underlying network connection broken can be detected very effectively and rapidly. The CORBA server just simply ignores the network connection lost event and does not pass it to activated CORBA object even if the CORBA object is connection related object because current CORBA standard thinks that all the CORBA objects in the server are shared to all clients. If the server can notify the network connection lost event to the connection related CORBA objects, the developper can do the clean job on it. A simple method can solve the "floating" CORBA object problem. It is not required to add any new interface or data structure to current orb.idl. It is just required to add some new language mapping methods at server side only. I will give an example in C++ to show this simple method. A IShared,IConnSpec and IOtherConnectionSpec interfaces are defined below: interface IOtherConnectionSpec { ... } interface IConnectionSpec { IOtherConnectionSpec someMethod(); } interface IShared { IConnectionSpec createConnSpec( in string param ); }; These interfaces will be used in this example. 1) the IShared will be shared by all the clients, it is activated like this: SharedImpl sharedImpl( ... ); ... sharedImpl._this(); 2) add new mapping method for the "POA_IShared::createConnSpec()" like this: IConnectionSpec_ptr POA_IShared::createConnSpec( char* param, const ConnectionContext& connCtx ); In this method, a parameter named ConnectionContext that represents the connection between the client and server is added. This method has a default implementation like this: IConnectionSpec_ptr POA_IShared::createConnSpec( const char* param, const ConnectionContext& connCtx ){ //just ignore the connCtx like the current CORBA standard defines return createConnSpec( param ); } 3) If the user wants to create a connection related object, he/she must overload the "IConnectionSpec_ptr createConnSpec( char* param, const ConnectionContext& connCtx )" method and active the object with "this_( const ConnectionContext& connCtx )" method: IConnectionSpec_ptr POA_IShared::createConnSpec( const char* param, const ConnectionContext& connCtx ){ ... IConnectionSpec *connSpecImpl = new IConnectionSpec( ... ); ... //use the connection related active method return connSpecImpl->this_( connCtx ); } in this method, the user uses the "this_( const ConnectionContext& connCtx)" method instead of the old "this()"" method to active the CORBA object. This activated CORBA object becomes a connection related object instead of shared object. Note: User can use the "this_( const ConnectionContext& connCtx)" method to active a shared object also. At this time, the ConnectionContext is a global variable "NO_CONNECTION_CONTEXT". 4) add a new mapping method named "getConnectionContext()" for every CORBA object. const ConnectionContext& IShared::getConnectionContext(); const ConnectionContext& POA_IConnectionSpec::getConnectionContext(); In this way, the IConnectionSpec can create and activate any other connection related CORBA object like this: IOtherConnectionSpec_ptr POA_IConnectionSpec::someMethod() { ... OtherConnectionSpecImpl *otherConnSpecImpl = new OtherConnectionSpecImpl(...); ... return otherConnSpecImpl->this_( getConnectionContext() ); //or ? //return otherConnSpecImpl->this_( this ); } 5) add a new mapping method named "connectionLost()" for every CORBA object. When the network connection is lost, the CORBA server should find all the CORBA object associated with this network connection and call their "connectionLost()" method. The "connectionLost()" and its default implementation is listed below: void POA_IConnectionSpec::connectionLost() { //just delete this connection related object simply delete this; } void POA_IOtherConnectionSpec::connectionLost() { //just delete this connection related object simply delete this; } Because the SharedImpl object that created in the 1) step does not assicate with any connection, its "connectionLost()" method will not be called for ever.
deferred in June 2011 to the next RTF
the C++ mapping should explicitly list operator == and operator != in the examples and text. If it is not allowed to use ==/!= the methods should be declared private
In IDL it gives:
// IDL
valuetype V {
factory create_bool(boolean b);
factory create_(char c);
factory create_(octet o);
factory create_(short s, string p);
...
};
But it should be
// IDL
valuetype V {
factory create_bool(boolean b);
factory create_char(char c);
factory create_octet(octet o);
factory create_other(short s, string p);
...
};need an _unchecked_narrow static operation that is similar to the _narrow. It will take in an object pointer but unlike _narrow will not check for compatibility before creating a new object reference.