summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-01-19 17:33:09 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-01-19 17:33:09 +0000
commit460279ae76a5462897352ccf44ecbeb1a8f6f1be (patch)
tree3bb8d0ca73334d03ab019af5a2b4a9a53cc82732
parentf19615175f2a732685ae41dcbf0294b2fedcbff8 (diff)
downloadATCD-460279ae76a5462897352ccf44ecbeb1a8f6f1be.tar.gz
ChangeLogTag:Mon Jan 19 11:28:47 1998 Carlos O'Ryan <coryan@cs.wustl.edu>
-rw-r--r--TAO/ChangeLog-98c5
-rw-r--r--TAO/TAO-INSTALL.html4
-rw-r--r--TAO/TAO_IDL/VCAUTO.MAK1
-rw-r--r--TAO/TAO_IDL/be/be_visitor_sequence.cpp42
-rw-r--r--TAO/VCAUTO.MAK3
-rw-r--r--TAO/docs/releasenotes/index.html11
-rw-r--r--TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp14
-rw-r--r--TAO/tao/VCAUTO.MAK1
-rw-r--r--TAO/tao/corba.h5
-rw-r--r--TAO/tao/corbacom.h3
-rw-r--r--TAO/tao/orbobj.h56
-rw-r--r--TAO/tao/orbobj.i162
-rw-r--r--TAO/tao/sequence.cpp202
-rw-r--r--TAO/tao/sequence.h191
-rw-r--r--TAO/tao/sequence.i89
-rw-r--r--TAO/tao/sequence_T.cpp243
-rw-r--r--TAO/tao/sequence_T.i69
-rw-r--r--TAO/tests/Cubit/TAO/MT_Cubit/server.cpp14
18 files changed, 813 insertions, 302 deletions
diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c
index d7ceca8661b..9400d1c1c05 100644
--- a/TAO/ChangeLog-98c
+++ b/TAO/ChangeLog-98c
@@ -1,3 +1,8 @@
+Mon Jan 19 11:28:47 1998 Carlos O'Ryan <coryan@cs.wustl.edu>
+
+ * Merged changes from main_to_poa_merge_9 up to
+ main_to_poa_merge_10.
+
Sun Jan 18 01:04:22 1998 <coryan@MILONGA>
* TAO_IDL/be/be_attribute.cpp:
diff --git a/TAO/TAO-INSTALL.html b/TAO/TAO-INSTALL.html
index e1cb22273f2..4a15a512a86 100644
--- a/TAO/TAO-INSTALL.html
+++ b/TAO/TAO-INSTALL.html
@@ -32,7 +32,9 @@ undefined and most likely unpredictable and erroneous results. <P>
<ol>
<li>Set <code>ACE_ROOT</code> environment variable as outlined
- in the <a href="../ACE-INSTALL.html">ACE installation
+ in the <a
+href="http://www.cs.wustl.edu/~schmidt/ACE-INSTALL.html">ACE
+installation
notes</a>.</li> <P>
<li>Build and install ACE under <CODE>$ACE_ROOT</CODE>.</li> <P>
diff --git a/TAO/TAO_IDL/VCAUTO.MAK b/TAO/TAO_IDL/VCAUTO.MAK
index 3095d772741..3aa0d8e38b9 100644
--- a/TAO/TAO_IDL/VCAUTO.MAK
+++ b/TAO/TAO_IDL/VCAUTO.MAK
@@ -1,3 +1,4 @@
+# TAO/TAO_IDL/
MAK_LIST = tao_idl
diff --git a/TAO/TAO_IDL/be/be_visitor_sequence.cpp b/TAO/TAO_IDL/be/be_visitor_sequence.cpp
index b49d5b95b68..846cb978a72 100644
--- a/TAO/TAO_IDL/be/be_visitor_sequence.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_sequence.cpp
@@ -71,17 +71,23 @@ int be_visitor_sequence_ch::visit_sequence (be_sequence *node)
switch (node->managed_type ())
{
case be_sequence::MNG_OBJREF: // sequence of objrefs
- case be_sequence::MNG_STRING: // sequence of objrefs
if (node->unbounded ())
- os << "TAO_Unbounded_Managed_Sequence<";
+ os << "TAO_Unbounded_Object_Sequence<";
else
- os << "TAO_Bounded_Managed_Sequence<";
+ os << "TAO_Bounded_Object_Sequence<";
+ break;
+ case be_sequence::MNG_STRING: // sequence of strings
+ if (node->unbounded ())
+ os << "TAO_Unbounded_String_Sequence";
+ else
+ os << "TAO_Bounded_String_Sequence<";
break;
default: // not a managed type
if (node->unbounded ())
os << "TAO_Unbounded_Sequence<";
else
os << "TAO_Bounded_Sequence<";
+ break;
}
@@ -94,13 +100,23 @@ int be_visitor_sequence_ch::visit_sequence (be_sequence *node)
-1);
}
- if (node->unbounded ())
+ if (node->managed_type () == be_sequence::MNG_STRING)
{
- os << " >";
+ if (!node->unbounded ())
+ {
+ os << "<" << node->max_size () << ">";
+ }
}
else
{
- os << ", " << node->max_size () << " >";
+ if (node->unbounded ())
+ {
+ os << " >";
+ }
+ else
+ {
+ os << ", " << node->max_size () << " >";
+ }
}
os << " " << node->local_name () << ";" << nl;
@@ -196,7 +212,7 @@ be_visitor_sequence_base_ch::visit_predefined_type (be_predefined_type *node)
switch (node->pt ())
{
case AST_PredefinedType::PT_pseudo:
- os << "CORBA::Object, TAO_Object_Manager<CORBA::Object> ";
+ os << "CORBA::Object";
default:
os << node->name ();
}
@@ -223,10 +239,6 @@ be_visitor_sequence_base_ch::visit_interface (be_interface * /* node */)
{
TAO_OutStream &os = this->stream ();
os << this->current_type_->nested_type_name (this->seq_scope ());
- os << ", ";
- os << "TAO_Object_Manager<"
- << this->current_type_->nested_type_name (this->seq_scope ())
- << "> ";
return 0;
}
@@ -235,22 +247,16 @@ be_visitor_sequence_base_ch::visit_interface_fwd (be_interface_fwd *node)
{
TAO_OutStream &os = this->stream ();
os << this->current_type_->nested_type_name (this->seq_scope ());
- os << ", ";
- os << "TAO_Object_Manager<"
- << this->current_type_->nested_type_name (this->seq_scope ())
- << "> ";
return 0;
}
int
be_visitor_sequence_base_ch::visit_string (be_string * /* node */)
{
- TAO_OutStream &os = this->stream ();
- os << "char*, TAO_String_Manager ";
+ // NO-OP, we have ad-hoc classes from strings.
return 0;
}
-
int
be_visitor_sequence_base_ch::visit_structure (be_structure *node)
{
diff --git a/TAO/VCAUTO.MAK b/TAO/VCAUTO.MAK
index e57821b95ee..ca7cb555dca 100644
--- a/TAO/VCAUTO.MAK
+++ b/TAO/VCAUTO.MAK
@@ -1,4 +1,5 @@
+# TAO/
-DIR_LIST = TAO.dir tao_idl.dir
+DIR_LIST = TAO.dir tao_idl.dir tests.dir
!INCLUDE <$(ACE_ROOT)\include\makeinclude\VC50_DIR.MAK>
diff --git a/TAO/docs/releasenotes/index.html b/TAO/docs/releasenotes/index.html
index 55e8f48d634..5d3f405cfeb 100644
--- a/TAO/docs/releasenotes/index.html
+++ b/TAO/docs/releasenotes/index.html
@@ -212,7 +212,8 @@ Point of contact: <A HREF="mailto:coryan@cs.wustl.edu">Carlos O'Ryan</A>
<LI>
The current Event Channel is working on TAO,
the Scheduling Service still has some problems,
-apparently related to the IDL compiler.</LI>
+apparently related to sequences of variable sized structures as out
+parameters.</LI>
<LI>
The configuration runs can be done even on the distributed scenario, using
@@ -222,7 +223,8 @@ the Real-time "Scheduling Service", which now has an IDL interface.</LI>
At run-time (no config runs) there is no need to use the Real-time Scheduling
Service, a faster, collocated implementation for the service is available.
Obviously the information is generated on the config runs and linked into
-the program. Unfortunately the schedule information cannot be
+the program.
+Unfortunately the schedule information cannot be
downloaded from the service right now.</LI>
<LI>
@@ -260,6 +262,11 @@ but requires a (small) amount of dynamic memory allocation.
It could be interesting to "save" the schedule computation in some
persistent form, so startup cost are lower too.</LI>
+<LI>
+The user should have complete control of services collocation,
+ACE services for dynamically loaded objects should help in this area,
+but we need to add support for NT DLLs in the IDL compiler.</LI>
+
</UL>
<P>For general documentation on the Event Service please read
<A HREF="http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz">
diff --git a/TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp b/TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp
index fa2e4687412..d21f6c81194 100644
--- a/TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp
+++ b/TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp
@@ -130,14 +130,18 @@ Cubit_Task::create_servants ()
"implementation object&d\n",
i), 2);
- CORBA::OctetSeq obj_key;
-
- obj_key.buffer = (CORBA::Octet *) obj_str;
- obj_key.length = obj_key.maximum = ACE_OS::strlen (obj_str);
+ TAO_opaque obj_key (ACE_OS::strlen (obj_str));
+ for (CORBA::ULong i = 0;
+ i < obj_key.maximum ();
+ ++i)
+ {
+ obj_key[i] = obj_str[i];
+ }
+ obj_key.length (obj_key.maximum ());
CORBA::Object_ptr obj = 0;
- if (oa_ptr_->find (obj_key, obj) == -1)
+ if (this->oa_ptr_->find (obj_key, obj) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
" (%P|%t) Unable to locate object with key '%s', %p\n",
key),
diff --git a/TAO/tao/VCAUTO.MAK b/TAO/tao/VCAUTO.MAK
index ec0eb04c66c..28f48c75716 100644
--- a/TAO/tao/VCAUTO.MAK
+++ b/TAO/tao/VCAUTO.MAK
@@ -1,3 +1,4 @@
+# TAO/tao/
MAK_LIST = TAO
diff --git a/TAO/tao/corba.h b/TAO/tao/corba.h
index a2081407bb8..0ec14b0a3cf 100644
--- a/TAO/tao/corba.h
+++ b/TAO/tao/corba.h
@@ -91,6 +91,10 @@
// individual CORBA classes
#include "tao/sequence.h"
#include "tao/sequence_T.h"
+
+typedef TAO_Unbounded_Sequence<CORBA::Octet> TAO_opaque;
+extern CORBA::TypeCode TC_opaque;
+
#include "tao/any.h"
#include "tao/params.h"
@@ -147,7 +151,6 @@ extern TAO_Export int operator== (const TAO::ObjectKey &l,
#include "tao/orb_core.i"
#include "tao/corbacom.i"
-#include "tao/sequence.i"
#include "tao/typecode.i"
#include "tao/nvlist.i"
#include "tao/any.i"
diff --git a/TAO/tao/corbacom.h b/TAO/tao/corbacom.h
index ceb2aebbd09..9e41ff6fa49 100644
--- a/TAO/tao/corbacom.h
+++ b/TAO/tao/corbacom.h
@@ -672,9 +672,6 @@ public:
};
}; // end of class (namespace) CORBA
-typedef TAO_Unbounded_Sequence<CORBA::Octet> TAO_opaque;
-extern CORBA::TypeCode TC_opaque;
-
typedef void (*TAO_Skeleton)(CORBA::ServerRequest &,
void *, // object_ptr
void *, // context_ptr
diff --git a/TAO/tao/orbobj.h b/TAO/tao/orbobj.h
index 7fced50cf79..e0ef8b40a38 100644
--- a/TAO/tao/orbobj.h
+++ b/TAO/tao/orbobj.h
@@ -4,7 +4,7 @@
//
// = LIBRARY
// TAO
-//
+//
// = FILENAME
// orbobj.h
//
@@ -17,7 +17,7 @@
//
// = AUTHOR
// Copyright 1994-1995 by Sun Microsystems Inc.
-//
+//
// ============================================================================
#if !defined (TAO_ORBOBJ_H)
@@ -48,7 +48,7 @@ public:
static CORBA::ORB_ptr _duplicate (CORBA::ORB_ptr orb);
// Return a duplicate of <{orb}>. When work with this duplicate is
// complete, it should be freed up using <CORBA::release()>.
-
+
static CORBA::ORB_ptr _nil (void);
// Returns a pointer to a nil ORB, i.e., an non-existent ORB. This
// can be used for initialization or in comparisons.
@@ -74,18 +74,18 @@ public:
// Of all of these operations, only <run> is currently implemented.
// Others require clarification of design or more implementation
// than is currently available.
-
+
CORBA::Boolean work_pending (void);
// Returns an indication of whether the ORB needs the <{main thread}> to
// perform some work.
-
+
int perform_work (ACE_Time_Value * = 0);
// If called by the <{main thread}>, this operation performs an
// implementation-defined unit of work. Otherwise, it does nothing.
//
// It is platform-specific how the application and ORB arrange to
// use compatible threading primitives.
-
+
int run (ACE_Time_Value *tv = 0);
// Instructs the ORB to initialize itself and run its event loop in
// the current thread, not returning until the ORB has shut down.
@@ -97,7 +97,7 @@ public:
// is returned.
//
// <{Note that this interface differs from the POA specification,
- // which is reproduced below:}>
+ // which is reproduced below:}>
//
// Returns when the ORB has shut down. If called by the main
// thread, it enables the ORB to perform work using the main
@@ -204,4 +204,46 @@ private:
CORBA_ORB &operator= (const CORBA_ORB &);
};
+class CORBA_ORB_var
+{
+public:
+ CORBA_ORB_var (void); // default constructor
+ CORBA_ORB_var (CORBA::ORB_ptr);
+ CORBA_ORB_var (const CORBA_ORB_var &); // copy constructor
+ ~CORBA_ORB_var (void); // destructor
+
+ CORBA_ORB_var &operator= (CORBA::ORB_ptr);
+ CORBA_ORB_var &operator= (const CORBA_ORB_var &);
+ CORBA::ORB_ptr operator-> (void) const;
+
+ operator const CORBA::ORB_ptr &() const;
+ operator CORBA::ORB_ptr &();
+ // in, inout, out, _retn
+ CORBA::ORB_ptr in (void) const;
+ CORBA::ORB_ptr &inout (void);
+ CORBA::ORB_ptr &out (void);
+ CORBA::ORB_ptr _retn (void);
+ CORBA::ORB_ptr ptr (void) const;
+
+private:
+ CORBA::ORB_ptr ptr_;
+};
+
+class CORBA_ORB_out
+{
+public:
+ CORBA_ORB_out (CORBA::ORB_ptr &);
+ CORBA_ORB_out (CORBA_ORB_var &);
+ CORBA_ORB_out (CORBA_ORB_out &);
+ CORBA_ORB_out &operator= (CORBA_ORB_out &);
+ CORBA_ORB_out &operator= (const CORBA_ORB_var &);
+ CORBA_ORB_out &operator= (CORBA::ORB_ptr);
+ operator CORBA::ORB_ptr &();
+ CORBA::ORB_ptr &ptr (void);
+ CORBA::ORB_ptr operator-> (void);
+
+private:
+ CORBA::ORB_ptr &ptr_;
+};
+
#endif /* TAO_ORBOBJ_H */
diff --git a/TAO/tao/orbobj.i b/TAO/tao/orbobj.i
index 2bd0967e784..e7c96b1481f 100644
--- a/TAO/tao/orbobj.i
+++ b/TAO/tao/orbobj.i
@@ -52,8 +52,168 @@ ACE_INLINE void
CORBA_ORB::shutdown (CORBA::Boolean wait_for_completion)
{
ACE_UNUSED_ARG (wait_for_completion);
-
+
this->should_shutdown_ = CORBA::B_TRUE;
TAO_ORB_Core_instance ()->reactor ()->wakeup_all_threads ();
return;
}
+
+// *************************************************************
+// Inline operations for class CORBA_ORB_var
+// *************************************************************
+
+ACE_INLINE
+CORBA_ORB_var::CORBA_ORB_var (void) // default constructor
+ : ptr_ (CORBA_ORB::_nil ())
+{}
+
+ACE_INLINE
+CORBA_ORB_var::CORBA_ORB_var (CORBA::ORB_ptr p)
+ : ptr_ (p)
+{}
+
+ACE_INLINE CORBA::ORB_ptr
+CORBA_ORB_var::ptr (void) const
+{
+ return this->ptr_;
+}
+
+ACE_INLINE
+CORBA_ORB_var::CORBA_ORB_var (const CORBA_ORB_var &p) // copy constructor
+ : ptr_ (CORBA_ORB::_duplicate (p.ptr ()))
+{}
+
+ACE_INLINE
+CORBA_ORB_var::~CORBA_ORB_var (void) // destructor
+{
+ CORBA::release (this->ptr_);
+}
+
+ACE_INLINE CORBA_ORB_var &
+CORBA_ORB_var::operator= (CORBA::ORB_ptr p)
+{
+ CORBA::release (this->ptr_);
+ this->ptr_ = p;
+ return *this;
+}
+
+ACE_INLINE CORBA_ORB_var &
+CORBA_ORB_var::operator= (const CORBA_ORB_var &p)
+{
+ if (this != &p)
+ {
+ CORBA::release (this->ptr_);
+ this->ptr_ = CORBA_ORB::_duplicate (p.ptr ());
+ }
+ return *this;
+}
+
+ACE_INLINE
+CORBA_ORB_var::operator const CORBA::ORB_ptr &() const // cast
+{
+ return this->ptr_;
+}
+
+ACE_INLINE
+CORBA_ORB_var::operator CORBA::ORB_ptr &() // cast
+{
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA::ORB_ptr
+CORBA_ORB_var::operator-> (void) const
+{
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA::ORB_ptr
+CORBA_ORB_var::in (void) const
+{
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA::ORB_ptr &
+CORBA_ORB_var::inout (void)
+{
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA::ORB_ptr &
+CORBA_ORB_var::out (void)
+{
+ CORBA::release (this->ptr_);
+ this->ptr_ = CORBA_ORB::_nil ();
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA::ORB_ptr
+CORBA_ORB_var::_retn (void)
+{
+ // yield ownership of managed obj reference
+ CORBA::ORB_ptr val = this->ptr_;
+ this->ptr_ = CORBA_ORB::_nil ();
+ return val;
+}
+
+// *************************************************************
+// Inline operations for class CORBA_ORB_out
+// *************************************************************
+
+ACE_INLINE
+CORBA_ORB_out::CORBA_ORB_out (CORBA::ORB_ptr &p)
+ : ptr_ (p)
+{
+ this->ptr_ = CORBA_ORB::_nil ();
+}
+
+ACE_INLINE
+CORBA_ORB_out::CORBA_ORB_out (CORBA_ORB_var &p) // constructor from _var
+ : ptr_ (p.out ())
+{
+ CORBA::release (this->ptr_);
+ this->ptr_ = CORBA_ORB::_nil ();
+}
+
+ACE_INLINE
+CORBA_ORB_out::CORBA_ORB_out (CORBA_ORB_out &p) // copy constructor
+ : ptr_ (p.ptr_)
+{}
+
+ACE_INLINE CORBA_ORB_out &
+CORBA_ORB_out::operator= (CORBA_ORB_out &p)
+{
+ this->ptr_ = p.ptr_;
+ return *this;
+}
+
+ACE_INLINE CORBA_ORB_out &
+CORBA_ORB_out::operator= (const CORBA_ORB_var &p)
+{
+ this->ptr_ = CORBA_ORB::_duplicate (p.ptr ());
+ return *this;
+}
+
+ACE_INLINE CORBA_ORB_out &
+CORBA_ORB_out::operator= (CORBA::ORB_ptr p)
+{
+ this->ptr_ = p;
+ return *this;
+}
+
+ACE_INLINE
+CORBA_ORB_out::operator CORBA::ORB_ptr &() // cast
+{
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA::ORB_ptr &
+CORBA_ORB_out::ptr (void) // ptr
+{
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA::ORB_ptr
+CORBA_ORB_out::operator-> (void)
+{
+ return this->ptr_;
+}
diff --git a/TAO/tao/sequence.cpp b/TAO/tao/sequence.cpp
index b892f8e92c2..746ec881c06 100644
--- a/TAO/tao/sequence.cpp
+++ b/TAO/tao/sequence.cpp
@@ -4,6 +4,10 @@
#include "tao/corba.h"
+#if !defined (__ACE_INLINE__)
+#include "tao/sequence.i"
+#endif /* __ACE_INLINE__ */
+
// *************************************************************
// Operations for class TAO_Base_Sequence
// *************************************************************
@@ -12,21 +16,14 @@ TAO_Base_Sequence::~TAO_Base_Sequence (void)
{
}
-// *************************************************************
-// Operations for class TAO_String_Manager
-// *************************************************************
-
-// destructor
-TAO_String_Manager::~TAO_String_Manager (void)
+void TAO_Base_Sequence::_shrink_buffer (CORBA::ULong, CORBA::ULong)
{
+ // default is no op.
}
-// copy constructor
-TAO_String_Manager::TAO_String_Manager(const TAO_String_Manager &rhs)
-{
- *this->ptr_ = CORBA::string_dup (*rhs.ptr_);
- this->release_ = 1;
-}
+// *************************************************************
+// Operations for class TAO_String_Manager
+// *************************************************************
// assignment
TAO_String_Manager&
@@ -36,58 +33,177 @@ TAO_String_Manager::operator=(const TAO_String_Manager &rhs)
return *this;
if (this->release_) // need to free old one
- CORBA::string_free (*this->ptr_);
-
- *this->ptr_ = CORBA::string_dup (*rhs.ptr_);
- this->release_ = 1;
+ {
+ CORBA::string_free (*this->ptr_);
+ *this->ptr_ = CORBA::string_dup (*rhs.ptr_);
+ }
+ else
+ {
+ *this->ptr_ = *rhs.ptr_;
+ }
return *this;
}
// assignment from char*
TAO_String_Manager &
-TAO_String_Manager::operator= (char * p)
+TAO_String_Manager::operator= (const char * p)
{
- if (this->release_) // need to free old one
- CORBA::string_free (*this->ptr_);
+ if (this->release_)
+ {
+ CORBA::string_free (*this->ptr_);
+ *this->ptr_ = CORBA::string_dup (p);
+ }
+ else
+ {
+ *this->ptr_ = ACE_const_cast(char*,p);
+ }
+ return *this;
+}
- *this->ptr_ = p; // no copy
- this->release_ = 0;
+// *************************************************************
- return *this;
+// constructor for unbounded seq
+TAO_Unbounded_String_Sequence::
+TAO_Unbounded_String_Sequence (CORBA::ULong maximum)
+ : TAO_Unbounded_Base_Sequence (maximum,
+ TAO_Unbounded_String_Sequence::allocbuf (maximum))
+{
}
-TAO_String_Manager &
-TAO_String_Manager::operator= (const char * p)
+TAO_Unbounded_String_Sequence::
+TAO_Unbounded_String_Sequence (const TAO_Unbounded_String_Sequence &seq)
+ : TAO_Unbounded_Base_Sequence (seq)
{
- if (this->release_) // need to free old one
+ this->buffer_ =
+ TAO_Unbounded_String_Sequence::allocbuf (this->maximum_);
+
+ char* *tmp1 = ACE_reinterpret_cast(char* *,this->buffer_);
+ char* *tmp2 = ACE_reinterpret_cast(char* *,seq.buffer_);
+ for (CORBA::ULong i = 0; i < seq.length_; ++i)
+ tmp1 [i] = CORBA::string_dup (tmp2 [i]);
+
+ this->release_ = 1;
+}
+
+TAO_Unbounded_String_Sequence::~TAO_Unbounded_String_Sequence (void)
+{
+ this->_deallocate_buffer ();
+}
+
+TAO_Unbounded_String_Sequence&
+TAO_Unbounded_String_Sequence::
+operator= (const TAO_Unbounded_String_Sequence &seq)
+{
+ if (this == &seq)
+ return *this;
+
+ if (this->release_)
{
- CORBA::string_free (*this->ptr_);
- *this->ptr_ = CORBA::string_dup (p);
- this->release_ = 1;
+ char* *tmp = ACE_reinterpret_cast(char* *,this->buffer_);
+ for (CORBA::ULong i = 0; i < this->length_; ++i)
+ {
+ CORBA::string_free (tmp[i]);
+ }
+ if (this->maximum_ < seq.maximum_)
+ {
+ this->buffer_ =
+ TAO_Unbounded_String_Sequence::allocbuf (seq.maximum_);
+ }
}
else
{
- *this->ptr_ = (char *)p;
- this->release_ = 0;
+ this->buffer_ =
+ TAO_Unbounded_String_Sequence::allocbuf (this->maximum_);
}
+
+ char* *tmp1 = ACE_reinterpret_cast(char* *,this->buffer_);
+ char* *tmp2 = ACE_reinterpret_cast(char* *,seq.buffer_);
+ CORBA::ULong i=0;
+ for (; i < seq.length_; ++i)
+ tmp1 [i] = CORBA::string_dup (tmp2 [i]);
+
return *this;
}
-// mapping for variable size - out
-char *&
-TAO_String_Manager::out (void)
+char* *
+TAO_Unbounded_String_Sequence::allocbuf (CORBA::ULong nelems)
{
- if (this->release_)
- CORBA::string_free (*this->ptr_);
- *this->ptr_ = 0;
- return *this->ptr_;
+ char* *buf = new char*[nelems];
+ for (CORBA::ULong i=0; i < nelems; i++)
+ buf[i] = 0;
+ return buf;
+}
+
+void
+TAO_Unbounded_String_Sequence::freebuf (char* *buffer)
+{
+ if (buffer == 0)
+ return;
+
+ // {orbos/97-05-15:16.11}
+ // The freebuf function ensures that the destructor for each element
+ // is called before the buffer is destroyed, except for string
+ // elements, which are freed using string_free(), and object
+ // reference elements, which are freed using release(). The freebuf
+ // function will ignore null pointers passed to it.
+
+ // @@ How are we supposed to implement that! We don't know the
+ // length of the buffer here.
+ // Mark the length in the first four bytes? For the moment we let
+ // that be.
+
+ char* *tmp = ACE_reinterpret_cast (char**,buffer);
+ delete[] tmp;
+}
+
+void
+TAO_Unbounded_String_Sequence::_allocate_buffer (CORBA::ULong length)
+{
+ char* *tmp;
+ ACE_NEW (tmp, char* [length]);
+
+ if (this->buffer_ != 0)
+ {
+ char* *old = ACE_reinterpret_cast(char**,this->buffer_);
+ for (CORBA::ULong i = 0; i < this->length_; ++i)
+ {
+ // Only call duplicate when we did not own the previous
+ // buffer, since after this method we own it we must also
+ // own the objects. If we already own the objects there is
+ // no need to copy them, if we did we would also have to
+ // remove the old instances.
+ if (!this->release_)
+ tmp [i] = CORBA::string_dup (old[i]);
+ else
+ tmp [i] = old[i];
+ }
+ if (this->release_)
+ delete[] old;
+ }
+ this->buffer_ = tmp;
+}
+
+void
+TAO_Unbounded_String_Sequence::_deallocate_buffer (void)
+{
+ if (this->buffer_ == 0 || this->release_ == 0)
+ return;
+ char* *tmp = ACE_reinterpret_cast (char**,this->buffer_);
+ for (CORBA::ULong i = 0;
+ i < this->length_;
+ ++i)
+ {
+ CORBA::string_free (tmp[i]);
+ }
+ delete[] tmp;
+ this->buffer_ = 0;
}
-// _retn (gives up ownership)
-char *
-TAO_String_Manager::_retn (void)
+void
+TAO_Unbounded_String_Sequence::_shrink_buffer (CORBA::ULong nl,
+ CORBA::ULong ol)
{
- char *tmp = *this->ptr_;
- *this->ptr_ = 0;
- return tmp;
+ char* *tmp = ACE_reinterpret_cast (char**,this->buffer_);
+ for (CORBA::ULong i = ol; i < nl; ++i)
+ CORBA::string_free (tmp[i]);
}
diff --git a/TAO/tao/sequence.h b/TAO/tao/sequence.h
index ca9f24a069f..1437048dad8 100644
--- a/TAO/tao/sequence.h
+++ b/TAO/tao/sequence.h
@@ -26,7 +26,6 @@ class TAO_Export TAO_Base_Sequence
// This class provides a common interface for all IDL sequences,
// hence the interpreted marshal engine can manipulate them in a
// type safe manner.
- //
public:
friend class TAO_Marshal_Sequence;
// We give access to TAO_Marshal_Sequence, this allows a safe yet
@@ -38,9 +37,6 @@ public:
CORBA::ULong maximum (void) const;
// return the maximum length of the sequence
- // void length (CORBA::ULong length);
- // set the length
-
virtual void _allocate_buffer (CORBA::ULong length) = 0;
// Ensure that the buffer contains space for at least <length>
// elements. The constructor must be called for any new elements,
@@ -51,6 +47,13 @@ public:
virtual void _deallocate_buffer (void) = 0;
// Must deallocate the buffer and then set it to zero.
+ virtual void _shrink_buffer (CORBA::ULong new_length,
+ CORBA::ULong old_length);
+ // Some sequences (of objects and strings) require some cleanup if
+ // the sequence is shrunk. The spec requires the destructor to
+ // release the objects only from position <0> to <length-1>; so
+ // shrink and then delete could result in a memory leak.
+
protected:
TAO_Base_Sequence (void);
// Default constructor.
@@ -100,8 +103,13 @@ class TAO_Export TAO_Unbounded_Base_Sequence : public TAO_Base_Sequence
// generated code in the templates.
public:
void length (CORBA::ULong length);
- // set the length, for this sequences this call increases the
- // capacity on demand.
+ // = SPEC {16.11.2}
+ // For an unbounded sequence, setting the length to a larger value
+ // than the current length may reallocate the sequence
+ // data. Reallocation is conceptually equivalent to creating a new
+ // sequence of the desired new length, copying the old sequence
+ // elements zero through length into the new sequence, and then
+ // assigning the old sequence to be the same as the new sequence.
CORBA::ULong length (void) const;
// return the current length, it cannot go into the base class due
@@ -161,9 +169,6 @@ protected:
/****************************************************************/
-template<class T, class Manager> class TAO_Unbounded_Managed_Sequence;
-template<class T, class Manager, CORBA::ULong MAX> class TAO_Bounded_Managed_Sequence;
-
class TAO_Export TAO_String_Manager
{
// = TITLE
@@ -179,30 +184,25 @@ class TAO_Export TAO_String_Manager
// for the sequence as a whole.
// The difference wrt Object_Manager is that strings are
// duplicated using CORBA::string_copy() as opposed to
- // T::_duplicate().
+ // T::_duplicate(), and released using CORBA::string_free()
+ // instead of CORBA::release()
//
// This class implements the generic string manager and is used to
// instantiate the proper sequence types.
//
- // = NOTES
- // It has been proposed that the class should be parametric on
- // both T and T_ptr, IMHO this is no necesary: though the IDL spec
- // says that T_ptr *could* map to a type different to T* in the
- // particular case of TAO it does map to <T*>.
- //
public:
- friend class TAO_Unbounded_Managed_Sequence<char*,TAO_String_Manager>;
+ friend class TAO_Unbounded_String_Sequence;
- // @@ Use partial template specialization here to give access only
- // to the right kind of sequence.
+ // @@ Giving friendship to a template is not implemented on several
+ // compilers:
// friend template<CORBA::ULong MAX>
- // class TAO_Bounded_Managed_Sequence<char*,TAO_String_Manager,MAX>;
+ // class TAO_Bounded_String_Sequence<TAO_String_Manager,MAX>;
TAO_String_Manager (const TAO_String_Manager &);
// copy constructor
- TAO_String_Manager (char **buffer, CORBA::Boolean release);
+ TAO_String_Manager (char* *buffer, CORBA::Boolean release);
// constructor from address of an element
~TAO_String_Manager (void);
@@ -211,43 +211,140 @@ public:
TAO_String_Manager &operator= (const TAO_String_Manager&);
// assignment from another managed type
- TAO_String_Manager &operator= (char *);
- // assignment from a char*
-
TAO_String_Manager &operator= (const char *);
// assignment from a constant char*
operator const char*() const;
// cast (read-only)
- operator char *();
- // cast
-
- char &operator[] (CORBA::ULong index);
- // accessor
-
- const char* &operator[] (CORBA::ULong index) const;
- // read-only accessor
+private:
+ char* *ptr_;
+ // address of string element from the parent's buffer
- // in, inout, out, _retn
- const char *in (void) const;
- // returns the underlying string
+ CORBA::Boolean release_;
+ // control memory managment semantics.
+};
- char *&inout (void);
- // returns a reference to the underlying string for in arguments
+class TAO_Unbounded_String_Sequence : public TAO_Unbounded_Base_Sequence
+{
+ // =TITLE
+ // Parametric sequence for types that require managers.
+ //
+ // =DESCRIPTION
+ // Some IDL types require that sequences on them have a "manager"
+ // class, in charge of handling the object lifetime, examples are
+ // pseudo objects, object references and strings.
+
+ // = SPEC
+ // 16.8 Mapping for Structured Types
+ // The mapping for struct, union, and sequence (but not array) is a
+ // C++ struct or class with a default constructor, a copy
+ // constructor, an assignment operator, and a destructor.
+ //
+public:
+ typedef TAO_String_Manager Manager;
- char *&out (void);
- // used for out arguments
+ // =operations for the Unbounded_ObjectSequence
- char *_retn (void);
- // gives up ownership, used for return types.
+ TAO_Unbounded_String_Sequence (void);
+ // {orbos/97-05-15:16.8}
+ // The default constructor initializes object reference members to
+ // appropriately typed nil object references and string members to
+ // NULL; all other members are initialized via their default
+ // constructors.
+ //
+ // {orbos/97-05-15:16.11}
+ // For both bounded and unbounded sequences, the default constructor
+ // (as shown in the example above) sets the sequence length equal to
+ // 0.
+
+ TAO_Unbounded_String_Sequence (CORBA::ULong maximum);
+ // Unbounded sequences provide a constructor that allows only the
+ // initial value of the maximum length to be set (the ``maximum
+ // constructor'' shown in the example above). This allows
+ // applications to control how much buffer space is initially
+ // allocated by the sequence. This constructor also sets the length
+ // to 0 and the release flag to TRUE.
+
+ TAO_Unbounded_String_Sequence (CORBA::ULong maximum,
+ CORBA::ULong length,
+ char* *data,
+ CORBA::Boolean release=0);
+ // The ``T *data'' constructor (as shown in the example above)
+ // allows the length and contents of a bounded or unbounded sequence
+ // to be set. For unbounded sequences, it also allows the initial
+ // value of the maximum length to be set. For this constructor,
+ // ownership of the contents vector is determined by the release
+ // parameter---FALSE means the caller owns the storage, while TRUE
+ // means that the sequence assumes ownership of the storage.
+ // If release is TRUE, the contents vector must have been allocated
+ // using the sequence allocbuf function, and the sequence will pass
+ // it to freebuf when finished with it.
+
+ TAO_Unbounded_String_Sequence(const TAO_Unbounded_String_Sequence&);
+ // The copy constructor performs a deep copy from the existing
+ // structure to create a new structure, including calling _duplicate
+ // on all object reference members and performing the necessary
+ // heap allocations for all string members.
+ //
+ // The copy constructor creates a new sequence with the same maximum
+ // and length as the given sequence, copies each of its current
+ // elements (items zero through length-1), and sets the release
+ // flag to TRUE.
+
+ ~TAO_Unbounded_String_Sequence (void);
+ // The destructor releases all object reference memebrs and frees
+ // all string members.
+
+ TAO_Unbounded_String_Sequence &operator= (const TAO_Unbounded_String_Sequence &);
+ // The assignment operator first releases all object reference
+ // members and frees all string members, and then performs a
+ // deep­copy to create a new structure.
+ //
+ // The assignment operator deep­copies its parameter, releasing
+ // old storage if necessary. It behaves as if the original sequence
+ // is destroyed via its destructor and then the source sequence
+ // copied using the copy constructor. If release=TRUE, the
+ // destructor destroys each of the current elements (items zero
+ // through length--1).
+ // For an unbounded sequence, if a reallocation is necessary due to
+ // a change in the length and the sequence was created using the
+ // release=TRUE parameter in its constructor, the sequence will
+ // deallocate the old storage. If release is FALSE under these
+ // circumstances, old storage will not be freed before the
+ // reallocation is performed. After reallocation, the release flag
+ // is always set to TRUE.
+
+ Manager operator[] (CORBA::ULong index) const;
+ // read-write accessor
+
+ static char* *allocbuf (CORBA::ULong);
+ // The allocbuf function allocates a vector of T elements that can
+ // be passed to the T *data constructor. The length of the vector is
+ // given by the nelems function argument. The allocbuf function
+ // initializes each element using its default constructor, except
+ // for strings, which are initialized to null pointers, and object
+ // references, which are initialized to suitably typed nil object
+ // references. A null pointer is returned if allocbuf for some
+ // reason cannot allocate the requested vector. Vectors allocated by
+ // allocbuf should be freed using the freebuf function.
+
+ static void freebuf (char* *);
+ // The freebuf function ensures that the destructor for each element
+ // is called before the buffer is destroyed, except for string
+ // elements, which are freed using string_free(), and object
+ // reference elements, which are freed using release(). The freebuf
+ // function will ignore null pointers passed to it.
+
+ virtual void _allocate_buffer (CORBA::ULong length);
+ virtual void _deallocate_buffer (void);
+ virtual void _shrink_buffer (CORBA::ULong new_length,
+ CORBA::ULong old_length);
+};
-private:
- char **ptr_;
- // address of string element from the parent's buffer
- CORBA::Boolean release_;
- // based on parent's release flag
-};
+#if defined (__ACE_INLINE__)
+#include "tao/sequence.i"
+#endif /* __ACE_INLINE__ */
#endif /* TAO_SEQUENCE_H */
diff --git a/TAO/tao/sequence.i b/TAO/tao/sequence.i
index 5be4f3bae3f..9b728b899c5 100644
--- a/TAO/tao/sequence.i
+++ b/TAO/tao/sequence.i
@@ -73,30 +73,6 @@ TAO_Base_Sequence::maximum (void) const
return this->maximum_;
}
-#if 0
-ACE_INLINE void
-TAO_Base_Sequence::length (CORBA::ULong length)
-{
- if (length > this->maximum_)
- {
- if (this->_bounded ())
- {
- // @@ TODO maybe we should throw?
- return;
- }
- this->_allocate_buffer (length);
- this->maximum_ = length;
- }
- this->length_ = length;
-}
-
-ACE_INLINE CORBA::ULong
-TAO_Base_Sequence::length (void) const
-{
- return this->length_;
-}
-#endif
-
// ****************************************************************
ACE_INLINE
@@ -136,10 +112,14 @@ TAO_Unbounded_Base_Sequence::length (CORBA::ULong length)
this->_allocate_buffer (length);
this->maximum_ = length;
}
+ else
+ {
+ this->_shrink_buffer (length, this->length_);
+ }
this->length_ = length;
}
-
+// ****************************************************************
ACE_INLINE
TAO_Bounded_Base_Sequence::TAO_Bounded_Base_Sequence (void)
@@ -177,5 +157,64 @@ TAO_Bounded_Base_Sequence::length (CORBA::ULong length)
{
return;
}
+ else
+ {
+ this->_shrink_buffer (length, this->length_);
+ }
this->length_ = length;
}
+
+// ****************************************************************
+
+ACE_INLINE
+TAO_String_Manager::TAO_String_Manager(char** buffer,
+ CORBA::Boolean release)
+ : ptr_ (buffer),
+ release_ (release)
+{
+}
+
+ACE_INLINE
+TAO_String_Manager::TAO_String_Manager(const TAO_String_Manager &rhs)
+ : ptr_ (rhs.ptr_),
+ release_ (rhs.release_)
+{
+}
+
+ACE_INLINE
+TAO_String_Manager::~TAO_String_Manager (void)
+{
+}
+
+ACE_INLINE
+TAO_String_Manager::operator const char* (void) const
+{
+ return *this->ptr_;
+}
+
+// ****************************************************************
+
+//default constructor
+ACE_INLINE
+TAO_Unbounded_String_Sequence::TAO_Unbounded_String_Sequence (void)
+{
+}
+
+ACE_INLINE
+TAO_Unbounded_String_Sequence::
+TAO_Unbounded_String_Sequence (CORBA::ULong maximum,
+ CORBA::ULong length,
+ char* *value,
+ CORBA::Boolean release)
+ : TAO_Unbounded_Base_Sequence (maximum, length, value, release)
+{
+}
+
+ACE_INLINE TAO_Unbounded_String_Sequence::Manager
+TAO_Unbounded_String_Sequence::operator[] (CORBA::ULong index) const
+{
+ ACE_ASSERT (index < this->maximum_);
+ char** tmp = ACE_reinterpret_cast (char**, this->buffer_);
+ return Manager (tmp + index, this->release_);
+}
+
diff --git a/TAO/tao/sequence_T.cpp b/TAO/tao/sequence_T.cpp
index b79392b29d0..efa04fdb964 100644
--- a/TAO/tao/sequence_T.cpp
+++ b/TAO/tao/sequence_T.cpp
@@ -150,14 +150,14 @@ TAO_Object_Manager<T>::~TAO_Object_Manager (void)
template <class T>
TAO_Object_Manager<T>::TAO_Object_Manager (const TAO_Object_Manager &rhs)
+ : ptr_ (rhs.ptr_),
+ release_ (rhs.release_)
{
- this->ptr_ = rhs.ptr_;
- this->release_ = rhs.release_;
}
template <class T>
TAO_Object_Manager<T>&
-TAO_Object_Manager<T>::operator= (const TAO_Object_Manager &rhs)
+TAO_Object_Manager<T>::operator= (const TAO_Object_Manager<T> &rhs)
{
if (this == &rhs)
return *this;
@@ -179,42 +179,44 @@ TAO_Object_Manager<T>::operator=(T* p)
return *this;
}
-// mapping for variable size
-template <class T> T* &
-TAO_Object_Manager<T>::out (void)
-{
- if (this->release_)
- CORBA::release (*this->ptr_);
- *this->ptr_ = T::_nil ();
- return *this->ptr_;
-}
-
-template <class T> T*
-TAO_Object_Manager<T>::_retn (void)
-{
- T* tmp = *this->ptr_;
- *this->ptr_ = T::_nil ();
- return tmp;
-}
-
// *************************************************************
-// Operations for class TAO_Unbounded_Managed_Sequence
+// Operations for class TAO_Unbounded_Object_Sequence
// *************************************************************
-template<class T, class Manager>
-TAO_Unbounded_Managed_Sequence<T,Manager>::~TAO_Unbounded_Managed_Sequence (void)
+// constructor for unbounded seq
+template <class T>
+TAO_Unbounded_Object_Sequence<T>::
+TAO_Unbounded_Object_Sequence (CORBA::ULong maximum)
+ : TAO_Unbounded_Base_Sequence (maximum,
+ TAO_Unbounded_Object_Sequence<T>::allocbuf (maximum))
{
- this->_deallocate_buffer ();
}
// copy constructor
-template <class T, class Manager>
-TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence
-(const TAO_Unbounded_Managed_Sequence<T,Manager> &seq)
+template <class T>
+TAO_Unbounded_Object_Sequence<T>::
+TAO_Unbounded_Object_Sequence (const TAO_Unbounded_Object_Sequence<T> &seq)
: TAO_Unbounded_Base_Sequence (seq)
{
- this->buffer_ = TAO_Unbounded_Managed_Sequence<T,Manager>::
- allocbuf (this->maximum_);
+ if (this->release_)
+ {
+ T* *tmp = ACE_reinterpret_cast(T* *,this->buffer_);
+ for (CORBA::ULong i = 0; i < this->length_; ++i)
+ {
+ CORBA::release (tmp[i]);
+ }
+ if (this->maximum_ < seq.maximum_)
+ {
+ this->buffer_ =
+ TAO_Unbounded_Object_Sequence<T>::allocbuf (seq.maximum_);
+ }
+ }
+ else
+ {
+ this->buffer_ =
+ TAO_Unbounded_Object_Sequence<T>::allocbuf (this->maximum_);
+ }
+
T* *tmp1 = ACE_reinterpret_cast(T* *,this->buffer_);
T* *tmp2 = ACE_reinterpret_cast(T* *,seq.buffer_);
for (CORBA::ULong i=0; i < seq.length_; i++)
@@ -222,18 +224,33 @@ TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence
}
// assignment operator
-template <class T, class Manager>
-TAO_Unbounded_Managed_Sequence<T,Manager>&
-TAO_Unbounded_Managed_Sequence<T,Manager>::operator=
-(const TAO_Unbounded_Managed_Sequence<T,Manager> &seq)
+template <class T>
+TAO_Unbounded_Object_Sequence<T>&
+TAO_Unbounded_Object_Sequence<T>::
+operator= (const TAO_Unbounded_Object_Sequence<T> &seq)
{
- if (this == &seq) return *this;
+ if (this == &seq)
+ return *this;
+
if (this->release_)
- {
- T* *tmp = ACE_reinterpret_cast (T* *,this->buffer_);
- TAO_Unbounded_Managed_Sequence<T,Manager>::freebuf (tmp,
- this->maximum_);
- }
+ {
+ T* *tmp = ACE_reinterpret_cast(T* *,this->buffer_);
+ for (CORBA::ULong i = 0; i < this->length_; ++i)
+ {
+ CORBA::release (tmp[i]);
+ }
+ if (this->maximum_ < seq.maximum_)
+ {
+ this->buffer_ =
+ TAO_Unbounded_Object_Sequence<T>::allocbuf (seq.maximum_);
+ }
+ }
+ else
+ {
+ this->buffer_ =
+ TAO_Unbounded_Object_Sequence<T>::allocbuf (this->maximum_);
+ }
+
T* *tmp1 = ACE_reinterpret_cast(T* *,this->buffer_);
T* *tmp2 = ACE_reinterpret_cast(T* *,seq.buffer_);
for (CORBA::ULong i=0; i < seq.length_; i++)
@@ -241,27 +258,39 @@ TAO_Unbounded_Managed_Sequence<T,Manager>::operator=
return *this;
}
-template <class T, class Manager> T* *
-TAO_Unbounded_Managed_Sequence<T,Manager>::allocbuf (CORBA::ULong nelems)
+template <class T> T* *
+TAO_Unbounded_Object_Sequence<T>::allocbuf (CORBA::ULong nelems)
{
- T* *buf = new T*[nelems]; // allocate from heap
+ T* *buf = new T*[nelems];
for (CORBA::ULong i=0; i < nelems; i++)
- buf[i] = T::_nil ();
+ buf[i] = T::_nil ();
return buf;
}
-template <class T, class Manager> void
-TAO_Unbounded_Managed_Sequence<T,Manager>::freebuf (T* *seq,
- CORBA::ULong nelems)
+template <class T> void
+TAO_Unbounded_Object_Sequence<T>::freebuf (T* *buffer)
{
- if (!seq) return; // null sequence
- for (CORBA::ULong i=0; i < nelems; i++)
- CORBA::release (seq[i]);
- TAO_Unbounded_Managed_Sequence<T,Manager>::freebuf (seq);
+ if (buffer == 0)
+ return;
+
+ // {orbos/97-05-15:16.11}
+ // The freebuf function ensures that the destructor for each element
+ // is called before the buffer is destroyed, except for string
+ // elements, which are freed using string_free(), and object
+ // reference elements, which are freed using release(). The freebuf
+ // function will ignore null pointers passed to it.
+
+ // @@ How are we supposed to implement that! We don't know the
+ // length of the buffer here.
+ // Mark the length in the first four bytes? For the moment we let
+ // that be.
+
+ T* *tmp = ACE_reinterpret_cast (T**,buffer);
+ delete[] tmp;
}
-template<class T, class Manager>
-void TAO_Unbounded_Managed_Sequence<T,Manager>::_allocate_buffer (CORBA::ULong length)
+template<class T>
+void TAO_Unbounded_Object_Sequence<T>::_allocate_buffer (CORBA::ULong length)
{
T* *tmp;
ACE_NEW (tmp, T* [length]);
@@ -271,42 +300,63 @@ void TAO_Unbounded_Managed_Sequence<T,Manager>::_allocate_buffer (CORBA::ULong l
T* *old = ACE_reinterpret_cast(T**,this->buffer_);
for (CORBA::ULong i = 0; i < this->length_; ++i)
{
- tmp [i] = T::_duplicate (old[i]);
+ // Only call duplicate when we did not own the previous
+ // buffer, since after this method we own it we must also
+ // own the objects. If we already own the objects there is
+ // no need to copy them, if we did we would also have to
+ // remove the old instances.
+ if (!this->release_)
+ tmp [i] = T::_duplicate (old[i]);
+ else
+ tmp [i] = old[i];
}
- delete[] old;
+ if (this->release_)
+ delete[] old;
}
this->buffer_ = tmp;
}
-template<class T, class Manager>
-void TAO_Unbounded_Managed_Sequence<T,Manager>::_deallocate_buffer (void)
+template<class T>
+void TAO_Unbounded_Object_Sequence<T>::_deallocate_buffer (void)
{
if (this->buffer_ == 0 || this->release_ == 0)
return;
T* *tmp = ACE_reinterpret_cast (T**,this->buffer_);
- // XXXASG: Do we release each object here?
- // @@ TODO add static methods to Manager to release each object.
+ for (CORBA::ULong i = 0;
+ i < this->length_;
+ ++i)
+ {
+ CORBA::release (tmp[i]);
+ }
delete[] tmp;
this->buffer_ = 0;
}
+template<class T> void
+TAO_Unbounded_Object_Sequence<T>::_shrink_buffer (CORBA::ULong nl,
+ CORBA::ULong ol)
+{
+ T* *tmp = ACE_reinterpret_cast (T**,this->buffer_);
+ for (CORBA::ULong i = ol; i < nl; ++i)
+ CORBA::release (tmp[i]);
+}
+
// *************************************************************
-// Operations for class TAO_Bounded_Managed_Sequence
+// Operations for class TAO_Bounded_Object_Sequence
// *************************************************************
-template<class T, class Manager, CORBA::ULong MAX>
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::~TAO_Bounded_Managed_Sequence (void)
+template<class T, CORBA::ULong MAX>
+TAO_Bounded_Object_Sequence<T,MAX>::~TAO_Bounded_Object_Sequence (void)
{
this->_deallocate_buffer ();
}
-// copy constructor
-template <class T, class Manager, CORBA::ULong MAX>
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::TAO_Bounded_Managed_Sequence
-(const TAO_Bounded_Managed_Sequence<T,Manager,MAX> &seq)
- : TAO_Unbounded_Base_Sequence (seq)
+template <class T, CORBA::ULong MAX>
+TAO_Bounded_Object_Sequence<T,MAX>::
+TAO_Bounded_Object_Sequence (const TAO_Bounded_Object_Sequence<T,MAX> &seq)
+ : TAO_Bounded_Base_Sequence (seq)
{
- this->buffer_ = TAO_Bounded_Managed_Sequence<T,Manager,MAX>::
+ this->buffer_ = TAO_Bounded_Object_Sequence<T,MAX>::
allocbuf (this->maximum_);
T* *tmp1 = ACE_reinterpret_cast(T* *,this->buffer_);
T* *tmp2 = ACE_reinterpret_cast(T* *,seq.buffer_);
@@ -315,18 +365,18 @@ TAO_Bounded_Managed_Sequence<T,Manager,MAX>::TAO_Bounded_Managed_Sequence
}
// assignment operator
-template <class T, class Manager, CORBA::ULong MAX>
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>&
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::operator=
-(const TAO_Bounded_Managed_Sequence<T,Manager,MAX> &seq)
+template <class T, CORBA::ULong MAX>
+TAO_Bounded_Object_Sequence<T,MAX>&
+TAO_Bounded_Object_Sequence<T,MAX>::operator=
+(const TAO_Bounded_Object_Sequence<T,MAX> &seq)
{
- if (this == &seq) return *this;
+ if (this == &seq)
+ return *this;
if (this->release_)
- {
- T* *tmp = ACE_reinterpret_cast (T* *,this->buffer_);
- TAO_Bounded_Managed_Sequence<T,Manager,MAX>::freebuf (tmp,
- this->maximum_);
- }
+ {
+ T* *tmp = ACE_reinterpret_cast (T* *,this->buffer_);
+ TAO_Bounded_Object_Sequence<T,MAX>::freebuf (tmp);
+ }
T* *tmp1 = ACE_reinterpret_cast(T* *,this->buffer_);
T* *tmp2 = ACE_reinterpret_cast(T* *,seq.buffer_);
for (CORBA::ULong i=0; i < seq.length_; i++)
@@ -334,27 +384,17 @@ TAO_Bounded_Managed_Sequence<T,Manager,MAX>::operator=
return *this;
}
-template <class T, class Manager, CORBA::ULong MAX> T* *
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::allocbuf (CORBA::ULong nelems)
+template <class T, CORBA::ULong MAX> T* *
+TAO_Bounded_Object_Sequence<T,MAX>::allocbuf (CORBA::ULong nelems)
{
T* *buf = new T*[nelems]; // allocate from heap
for (CORBA::ULong i=0; i < nelems; i++)
- buf[i] = T::_nil ();
+ buf[i] = T::_nil ();
return buf;
}
-template <class T, class Manager, CORBA::ULong MAX> void
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::freebuf (T* *seq,
- CORBA::ULong nelems)
-{
- if (!seq) return; // null sequence
- for (CORBA::ULong i=0; i < nelems; i++)
- CORBA::release (seq[i]);
- TAO_Bounded_Managed_Sequence<T,Manager,MAX>::freebuf (seq);
-}
-
-template<class T, class Manager, CORBA::ULong MAX> void
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::_allocate_buffer (CORBA::ULong length)
+template<class T, CORBA::ULong MAX> void
+TAO_Bounded_Object_Sequence<T,MAX>::_allocate_buffer (CORBA::ULong length)
{
T* *tmp;
ACE_NEW (tmp, T* [length]);
@@ -363,16 +403,14 @@ TAO_Bounded_Managed_Sequence<T,Manager,MAX>::_allocate_buffer (CORBA::ULong leng
{
T* *old = ACE_reinterpret_cast(T**,this->buffer_);
for (CORBA::ULong i = 0; i < this->length_; ++i)
- {
- tmp [i] = T::_duplicate (old[i]);
- }
+ tmp [i] = old[i];
delete[] old;
}
this->buffer_ = tmp;
}
-template<class T, class Manager, CORBA::ULong MAX>
-void TAO_Bounded_Managed_Sequence<T,Manager,MAX>::_deallocate_buffer (void)
+template<class T, CORBA::ULong MAX>
+void TAO_Bounded_Object_Sequence<T,MAX>::_deallocate_buffer (void)
{
if (this->buffer_ == 0 || this->release_ == 0)
return;
@@ -383,4 +421,13 @@ void TAO_Bounded_Managed_Sequence<T,Manager,MAX>::_deallocate_buffer (void)
this->buffer_ = 0;
}
+template<class T, CORBA::ULong MAX> void
+TAO_Bounded_Object_Sequence<T,MAX>::_shrink_buffer (CORBA::ULong nl,
+ CORBA::ULong ol)
+{
+ T* *tmp = ACE_reinterpret_cast (T**,this->buffer_);
+ for (CORBA::ULong i = ol; i < nl; ++i)
+ CORBA::release (tmp[i]);
+}
+
#endif /* TAO_SEQUENCE_T_C */
diff --git a/TAO/tao/sequence_T.i b/TAO/tao/sequence_T.i
index 9fd2439490d..1ca5d8a57d7 100644
--- a/TAO/tao/sequence_T.i
+++ b/TAO/tao/sequence_T.i
@@ -123,6 +123,8 @@ TAO_Object_Manager<T>::TAO_Object_Manager(T** ptr, CORBA::Boolean release)
: ptr_ (ptr),
release_ (release)
{
+ if (this->release_)
+ T::_duplicate (*this->ptr_);
}
template <class T> ACE_INLINE
@@ -137,81 +139,58 @@ TAO_Object_Manager<T>::operator T* &() // cast
return *this->ptr_;
}
-template <class T> ACE_INLINE const T*
-TAO_Object_Manager<T>::in (void) const
-{
- return *this->ptr_;
-}
-
-template <class T> ACE_INLINE T*&
-TAO_Object_Manager<T>::inout (void)
-{
- return *this->ptr_;
-}
-
// *************************************************************
-// class TAO_Unbounded_Managed_Sequence
+// class TAO_Unbounded_Object_Sequence
// *************************************************************
-template <class T, class Manager> ACE_INLINE void
-TAO_Unbounded_Managed_Sequence<T,Manager>::freebuf (T* *seq)
-{
- delete []seq;
-}
-
//default constructor
-template <class T, class Manager> ACE_INLINE
-TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence (void)
-{}
-
-// constructor for unbounded seq
-template <class T, class Manager> ACE_INLINE
-TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence
-(CORBA::ULong maximum)
- : TAO_Unbounded_Base_Sequence (maximum, TAO_Unbounded_Managed_Sequence<T,Manager>::allocbuf (max))
+template <class T> ACE_INLINE
+TAO_Unbounded_Object_Sequence<T>::TAO_Unbounded_Object_Sequence (void)
{
}
-// constructor from data buffer
-template <class T, class Manager> ACE_INLINE
-TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence
-(CORBA::ULong max, CORBA::ULong length, T* *value, CORBA::Boolean release)
- : TAO_Unbounded_Base_Sequence (max, length, value, release)
+template <class T> ACE_INLINE
+TAO_Unbounded_Object_Sequence<T>::
+TAO_Unbounded_Object_Sequence (CORBA::ULong maximum,
+ CORBA::ULong length,
+ T* *value,
+ CORBA::Boolean release)
+ : TAO_Unbounded_Base_Sequence (maximum, length, value, release)
{
}
-template <class T, class Manager> ACE_INLINE Manager
-TAO_Unbounded_Managed_Sequence<T,Manager>::operator[] (CORBA::ULong index) const
+template <class T> ACE_INLINE TAO_Object_Manager<T>
+TAO_Unbounded_Object_Sequence<T>::operator[] (CORBA::ULong index) const
{
ACE_ASSERT (index < this->maximum_);
- T* tmp = ACE_reinterpret_cast (T*, this->buffer_);
+ T** tmp = ACE_reinterpret_cast (T**, this->buffer_);
return Manager (tmp + index, this->release_);
}
// *************************************************************
-// class TAO_Bounded_Managed_Sequence
+// class TAO_Bounded_Object_Sequence
// *************************************************************
-template <class T, class Manager, CORBA::ULong MAX> ACE_INLINE void
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::freebuf (T* *seq)
+template <class T, CORBA::ULong MAX> ACE_INLINE void
+TAO_Bounded_Object_Sequence<T,MAX>::freebuf (T* *seq)
{
delete []seq;
}
-template <class T, class Manager, CORBA::ULong MAX> ACE_INLINE
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::TAO_Bounded_Managed_Sequence (void)
+template <class T, CORBA::ULong MAX> ACE_INLINE
+TAO_Bounded_Object_Sequence<T,MAX>::TAO_Bounded_Object_Sequence (void)
{}
// constructor from data buffer
-template <class T, class Manager, CORBA::ULong MAX> ACE_INLINE
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::TAO_Bounded_Managed_Sequence
+template <class T, CORBA::ULong MAX> ACE_INLINE
+TAO_Bounded_Object_Sequence<T,MAX>::TAO_Bounded_Object_Sequence
(CORBA::ULong length, T* *value, CORBA::Boolean release)
: TAO_Bounded_Base_Sequence (MAX, length, value, release)
{
}
-template <class T, class Manager, CORBA::ULong MAX> ACE_INLINE Manager
-TAO_Bounded_Managed_Sequence<T,Manager,MAX>::operator[] (CORBA::ULong index) const
+template <class T, CORBA::ULong MAX> ACE_INLINE TAO_Object_Manager<T>
+TAO_Bounded_Object_Sequence<T,MAX>::operator[] (CORBA::ULong index) const
{
ACE_ASSERT (index < this->maximum_);
T* tmp = ACE_reinterpret_cast (T*, this->buffer_);
diff --git a/TAO/tests/Cubit/TAO/MT_Cubit/server.cpp b/TAO/tests/Cubit/TAO/MT_Cubit/server.cpp
index fa2e4687412..d21f6c81194 100644
--- a/TAO/tests/Cubit/TAO/MT_Cubit/server.cpp
+++ b/TAO/tests/Cubit/TAO/MT_Cubit/server.cpp
@@ -130,14 +130,18 @@ Cubit_Task::create_servants ()
"implementation object&d\n",
i), 2);
- CORBA::OctetSeq obj_key;
-
- obj_key.buffer = (CORBA::Octet *) obj_str;
- obj_key.length = obj_key.maximum = ACE_OS::strlen (obj_str);
+ TAO_opaque obj_key (ACE_OS::strlen (obj_str));
+ for (CORBA::ULong i = 0;
+ i < obj_key.maximum ();
+ ++i)
+ {
+ obj_key[i] = obj_str[i];
+ }
+ obj_key.length (obj_key.maximum ());
CORBA::Object_ptr obj = 0;
- if (oa_ptr_->find (obj_key, obj) == -1)
+ if (this->oa_ptr_->find (obj_key, obj) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
" (%P|%t) Unable to locate object with key '%s', %p\n",
key),