Queued_Data.cpp

Go to the documentation of this file.
00001 #include "tao/Queued_Data.h"
00002 #include "tao/debug.h"
00003 
00004 #include "ace/Log_Msg.h"
00005 #include "ace/Malloc_Base.h"
00006 
00007 
00008 #if !defined (__ACE_INLINE__)
00009 # include "tao/Queued_Data.inl"
00010 #endif /* __ACE_INLINE__ */
00011 
00012 
00013 ACE_RCSID (tao,
00014            Queued_Data,
00015            "$Id: Queued_Data.cpp 79169 2007-08-02 08:41:23Z johnnyw $")
00016 
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018 
00019 /*!
00020  * @brief Allocate and return a new empty message block of size \a span_size
00021  * mimicking parameters of \a mb.
00022  *
00023  * This function allocates a new aligned message block using the same
00024  * allocators and flags as found in \a mb.  The size of the new message
00025  * block is at least \a span_size; the size may be adjusted up in order
00026  * to accomodate alignment requirements and still fit \a span_size bytes
00027  * into the aligned buffer.
00028  *
00029  * @param mb message block whose parameters should be mimicked
00030  * @param span_size size of the new message block (will be adjusted for proper
00031  * alignment)
00032  * @return an aligned message block with rd_ptr sitting at correct
00033  * alignment spot, 0 on failure
00034  */
00035 static ACE_Message_Block*
00036 clone_mb_nocopy_size (ACE_Message_Block *mb, size_t span_size)
00037 {
00038   // Calculate the required size of the cloned block with alignment
00039   size_t const aligned_size = ACE_CDR::first_size (span_size + ACE_CDR::MAX_ALIGNMENT);
00040 
00041   // Get the allocators
00042   ACE_Allocator *data_allocator = 0;
00043   ACE_Allocator *data_block_allocator = 0;
00044   ACE_Allocator *message_block_allocator = 0;
00045   mb->access_allocators (data_allocator,
00046                          data_block_allocator,
00047                          message_block_allocator);
00048 
00049   // Create a new Message Block
00050   ACE_Message_Block *nb = 0;
00051   ACE_NEW_MALLOC_RETURN (nb,
00052                          static_cast<ACE_Message_Block*> (
00053                                          message_block_allocator->malloc (
00054                                            sizeof (ACE_Message_Block))),
00055                          ACE_Message_Block(aligned_size,
00056                                            mb->msg_type(),
00057                                            mb->cont(),
00058                                            0, //we want the data block created
00059                                            data_allocator,
00060                                            mb->locking_strategy(),
00061                                            mb->msg_priority(),
00062                                            mb->msg_execution_time (),
00063                                            mb->msg_deadline_time (),
00064                                            data_block_allocator,
00065                                            message_block_allocator),
00066                          0);
00067 
00068   ACE_CDR::mb_align (nb);
00069 
00070   // Copy the flags over, but be SURE to clear the DONT_DELETE flag, since
00071   // we just dynamically allocated the two things.
00072   nb->set_flags (mb->flags());
00073   nb->clr_flags (ACE_Message_Block::DONT_DELETE);
00074 
00075   return nb;
00076 }
00077 
00078 /*static*/
00079 TAO_Queued_Data *
00080 TAO_Queued_Data::make_queued_data (ACE_Allocator *message_buffer_alloc,
00081                                    ACE_Allocator *input_cdr_alloc,
00082                                    ACE_Data_Block *db)
00083 {
00084   // Get a node for the queue..
00085   TAO_Queued_Data *qd = 0;
00086 
00087   if (message_buffer_alloc)
00088     {
00089       ACE_NEW_MALLOC_RETURN (qd,
00090                              static_cast<TAO_Queued_Data *> (
00091                                message_buffer_alloc->malloc (sizeof (TAO_Queued_Data))),
00092                              TAO_Queued_Data (message_buffer_alloc),
00093                              0);
00094 
00095     }
00096   else
00097     {
00098       // No allocator, so use the global pool!
00099       ACE_NEW_RETURN (qd,
00100                       TAO_Queued_Data,
00101                       0);
00102     }
00103 
00104   // Providing an ACE_Data_Block indicates that the caller wants
00105   // an aligned ACE_Message_Block added to the TAO_Queued_Data.
00106   if (db != 0)
00107     {
00108       // If this allocation fails, the TAO_Queued_Data will be leaked.
00109       if (input_cdr_alloc == 0)
00110         ACE_NEW_RETURN (qd->msg_block_,
00111                         ACE_Message_Block (db,
00112                                            0,
00113                                            input_cdr_alloc),
00114                         0);
00115       else
00116         ACE_NEW_MALLOC_RETURN (qd->msg_block_,
00117                                static_cast<ACE_Message_Block*> (
00118                                  input_cdr_alloc->malloc (sizeof (ACE_Message_Block))),
00119                                ACE_Message_Block (db,
00120                                                   0,
00121                                                   input_cdr_alloc),
00122                                0);
00123 
00124       ACE_CDR::mb_align (qd->msg_block_);
00125     }
00126 
00127   return qd;
00128 }
00129 
00130 /*static*/
00131 void
00132 TAO_Queued_Data::release (TAO_Queued_Data *qd)
00133 {
00134   //// TODO
00135   ACE_Message_Block::release (qd->msg_block_);
00136 
00137   if (qd->allocator_)
00138     {
00139       ACE_DES_FREE (qd,
00140                     qd->allocator_->free,
00141                     TAO_Queued_Data);
00142 
00143       return;
00144     }
00145 
00146   // @todo: Need to be removed at some point of time!
00147   if (TAO_debug_level == 4)
00148     {
00149       // This debug is for testing purposes!
00150       ACE_DEBUG ((LM_DEBUG,
00151                   "TAO (%P|%t) - Queued_Data[%d]::release\n",
00152                   "Using global pool for releasing \n"));
00153     }
00154   delete qd;
00155 
00156 }
00157 
00158 
00159 TAO_Queued_Data *
00160 TAO_Queued_Data::duplicate (TAO_Queued_Data &sqd)
00161 {
00162   // Check to see if the underlying block is on the stack. If not it
00163   // is fine. If the datablock is on stack, try to make a copy of that
00164   // before doing a duplicate.
00165   // @@ todo: Theoretically this should be within the Message Block,
00166   // but we dont have much scope to do this in that mess. Probably in
00167   // the next stage of MB rewrite we should be okay
00168   ACE_Message_Block::Message_Flags fl =
00169     sqd.msg_block_->self_flags ();
00170 
00171   if (ACE_BIT_ENABLED (fl,
00172                        ACE_Message_Block::DONT_DELETE))
00173     (void) TAO_Queued_Data::replace_data_block (*sqd.msg_block_);
00174 
00175 
00176   TAO_Queued_Data *qd = 0;
00177 
00178   if (sqd.allocator_)
00179     {
00180       ACE_NEW_MALLOC_RETURN (qd,
00181                              static_cast<TAO_Queued_Data *> (
00182                                sqd.allocator_->malloc (sizeof (TAO_Queued_Data))),
00183                              TAO_Queued_Data (sqd),
00184                              0);
00185 
00186       return qd;
00187     }
00188 
00189   // No allocator, so use the global pool!
00190   // @@ TODO: We should be removing this at some point of time!
00191   if (TAO_debug_level == 4)
00192     {
00193       // This debug is for testing purposes!
00194       ACE_DEBUG ((LM_DEBUG,
00195                   "TAO (%P|%t) - Queued_Data[%d]::duplicate\n",
00196                   "Using global pool for allocation \n"));
00197     }
00198 
00199   ACE_NEW_RETURN (qd,
00200                   TAO_Queued_Data (sqd),
00201                   0);
00202 
00203   return qd;
00204 }
00205 
00206 int
00207 TAO_Queued_Data::consolidate (void)
00208 {
00209   // Is this a chain of fragments?
00210   if (this->state_.more_fragments () && this->msg_block_->cont () != 0)
00211     {
00212       // Create a message block big enough to hold the entire chain
00213       ACE_Message_Block *dest = clone_mb_nocopy_size (
00214                                       this->msg_block_,
00215                                       this->msg_block_->total_length ());
00216 
00217       if (0 == dest)
00218         {
00219           // out of memory
00220           return -1;
00221         }
00222       // Memory allocation succeeded, the new message block can hold the consolidated
00223       // message. The following code just copies all the data into this new message block.
00224       // No further memory allocation will take place.
00225 
00226       // Reset the cont() parameter.  We have cloned the message
00227       // block but not the chain as we will no longer have chain.
00228       dest->cont (0);
00229 
00230       // Use ACE_CDR to consolidate the chain for us
00231       ACE_CDR::consolidate (dest, this->msg_block_);
00232 
00233       // free the original message block chain
00234       this->msg_block_->release ();
00235 
00236       // Set the message block to the new consolidated message block
00237       this->msg_block_ = dest;
00238       this->state_.more_fragments (0);
00239     }
00240 
00241   return 0;
00242 }
00243 
00244 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:07:36 2008 for TAO by doxygen 1.3.6