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

Generated on Tue Feb 2 17:37:52 2010 for TAO by  doxygen 1.4.7