Message_Block.cpp

Go to the documentation of this file.
00001 #include "ace/Message_Block.h"
00002 
00003 #if !defined (__ACE_INLINE__)
00004 #include "ace/Message_Block.inl"
00005 #endif /* __ACE_INLINE__ */
00006 
00007 #include "ace/Guard_T.h"
00008 #include "ace/Log_Msg.h"
00009 #include "ace/Malloc_Base.h"
00010 #include "ace/OS_NS_string.h"
00011 
00012 //#define ACE_ENABLE_TIMEPROBES
00013 #include "ace/Timeprobe.h"
00014 
00015 ACE_RCSID (ace,
00016            Message_Block,
00017            "$Id: Message_Block.cpp 80826 2008-03-04 14:51:23Z wotte $")
00018 
00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 ACE_ALLOC_HOOK_DEFINE (ACE_Message_Block)
00022 
00023 #if defined (ACE_ENABLE_TIMEPROBES)
00024 
00025 static const char *ACE_MB_Timeprobe_Description[] =
00026 {
00027   "Message_Block::init_i - enter",
00028   "Message_Block::init_i - leave",
00029   "Message_Block::init_i - db alloc",
00030   "Message_Block::init_i - db ctor",
00031   "Data_Block::ctor[1] - enter",
00032   "Data_Block::ctor[1] - leave",
00033   "Data_Block::ctor[2] - enter",
00034   "Data_Block::ctor[2] - leave",
00035   "Data_Block::clone - enter",
00036   "Data_Block::clone - leave"
00037 };
00038 
00039 enum
00040 {
00041   ACE_MESSAGE_BLOCK_INIT_I_ENTER = 3000,
00042   ACE_MESSAGE_BLOCK_INIT_I_LEAVE,
00043   ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC,
00044   ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR,
00045   ACE_DATA_BLOCK_CTOR1_ENTER,
00046   ACE_DATA_BLOCK_CTOR1_LEAVE,
00047   ACE_DATA_BLOCK_CTOR2_ENTER,
00048   ACE_DATA_BLOCK_CTOR2_LEAVE,
00049   ACE_DATA_BLOCK_CLONE_ENTER,
00050   ACE_DATA_BLOCK_CLONE_LEAVE
00051 };
00052 
00053 
00054 // Setup Timeprobes
00055 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (ACE_MB_Timeprobe_Description,
00056                                   ACE_MESSAGE_BLOCK_INIT_I_ENTER);
00057 
00058 #endif /* ACE_ENABLE_TIMEPROBES */
00059 
00060 void
00061 ACE_Message_Block::data_block (ACE_Data_Block *db)
00062 {
00063   ACE_TRACE ("ACE_Message_Block::data_block");
00064   if (ACE_BIT_DISABLED (this->flags_,
00065                         ACE_Message_Block::DONT_DELETE)
00066       && this->data_block_ != 0)
00067     this->data_block_->release ();
00068 
00069   this->data_block_ = db;
00070 
00071   // Set the read and write pointers in the <Message_Block> to point
00072   // to the buffer in the <ACE_Data_Block>.
00073   this->rd_ptr (this->data_block ()->base ());
00074   this->wr_ptr (this->data_block ()->base ());
00075 }
00076 
00077 int
00078 ACE_Message_Block::copy (const char *buf, size_t n)
00079 {
00080   ACE_TRACE ("ACE_Message_Block::copy");
00081 
00082   /*size_t len = static_cast<size_t> (this->end () - this->wr_ptr ());*/
00083   // Note that for this to work correct, end () *must* be >= mark ().
00084   size_t len = this->space ();
00085 
00086   if (len < n)
00087     {
00088       errno = ENOSPC;
00089       return -1;
00090     }
00091   else
00092     {
00093       (void) ACE_OS::memcpy (this->wr_ptr (),
00094                              buf,
00095                              n);
00096       this->wr_ptr (n);
00097       return 0;
00098     }
00099 }
00100 
00101 int
00102 ACE_Message_Block::copy (const char *buf)
00103 {
00104   ACE_TRACE ("ACE_Message_Block::copy");
00105 
00106   /* size_t len = static_cast<size_t> (this->end () - this->wr_ptr ()); */
00107   // Note that for this to work correct, end() *must* be >= wr_ptr().
00108   size_t len = this->space ();
00109 
00110   size_t buflen = ACE_OS::strlen (buf) + 1;
00111 
00112   if (len < buflen)
00113     {
00114       errno = ENOSPC;
00115       return -1;
00116     }
00117   else
00118     {
00119       (void) ACE_OS::memcpy (this->wr_ptr (),
00120                              buf,
00121                              buflen);
00122       this->wr_ptr (buflen);
00123       return 0;
00124     }
00125 }
00126 
00127 int
00128 ACE_Message_Block::crunch (void)
00129 {
00130   if (this->rd_ptr_ != 0)
00131     {
00132       if (this->rd_ptr_ > this->wr_ptr_)
00133         return -1;
00134 
00135       size_t const len = this->length ();
00136       (void) ACE_OS::memmove (this->base (),
00137                               this->rd_ptr (),
00138                               len);
00139       this->rd_ptr (this->base ());
00140       this->wr_ptr (this->base () + len);
00141     }
00142   return 0;
00143 }
00144 
00145 void
00146 ACE_Data_Block::dump (void) const
00147 {
00148 #if defined (ACE_HAS_DUMP)
00149   ACE_TRACE ("ACE_Data_Block::dump");
00150   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00151   ACE_DEBUG ((LM_DEBUG,
00152               ACE_TEXT ("-----( Data Block )-----\n")
00153               ACE_TEXT ("type_ = %d\n")
00154               ACE_TEXT ("cur_size_ = %u\n")
00155               ACE_TEXT ("max_size_ = %u\n")
00156               ACE_TEXT ("flags_ = %u\n")
00157               ACE_TEXT ("base_ = %u\n")
00158               ACE_TEXT ("locking_strategy_ = %u\n")
00159               ACE_TEXT ("reference_count_ = %u\n")
00160               ACE_TEXT ("---------------------------\n"),
00161               this->type_,
00162               this->cur_size_,
00163               this->max_size_,
00164               this->flags_,
00165               this->base_,
00166               this->locking_strategy_,
00167               this->reference_count_));
00168   this->allocator_strategy_->dump ();
00169   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00170 #endif /* ACE_HAS_DUMP */
00171 }
00172 
00173 void
00174 ACE_Message_Block::dump (void) const
00175 {
00176 #if defined (ACE_HAS_DUMP)
00177   ACE_TRACE ("ACE_Message_Block::dump");
00178   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00179   ACE_DEBUG ((LM_DEBUG,
00180               ACE_TEXT ("-----( Message Block )-----\n")
00181               ACE_TEXT ("priority_ = %d\n")
00182               ACE_TEXT ("next_ = %u\n")
00183               ACE_TEXT ("prev_ = %u\n")
00184               ACE_TEXT ("cont_ = %u\n")
00185               ACE_TEXT ("rd_ptr_ = %u\n")
00186               ACE_TEXT ("wr_ptr_ = %u\n")
00187               ACE_TEXT ("---------------------------\n"),
00188               this->priority_,
00189               this->next_,
00190               this->prev_,
00191               this->cont_,
00192               this->rd_ptr_,
00193               this->wr_ptr_));
00194   this->data_block ()->dump ();
00195   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00196 #endif /* ACE_HAS_DUMP */
00197 }
00198 
00199 int
00200 ACE_Data_Block::reference_count (void) const
00201 {
00202   if (this->locking_strategy_)
00203     {
00204       // We need to acquire the lock before retrieving the count
00205       ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->locking_strategy_, 0);
00206 
00207       return this->reference_count_i ();
00208     }
00209 
00210   return this->reference_count_i ();
00211 }
00212 
00213 int
00214 ACE_Data_Block::size (size_t length)
00215 {
00216   ACE_TRACE ("ACE_Data_Block::size");
00217 
00218   if (length <= this->max_size_)
00219     this->cur_size_ = length;
00220   else
00221     {
00222       // We need to resize!
00223       char *buf = 0;
00224       ACE_ALLOCATOR_RETURN (buf,
00225                             (char *) this->allocator_strategy_->malloc (length),
00226                             -1);
00227 
00228       ACE_OS::memcpy (buf,
00229                       this->base_,
00230                       this->cur_size_);
00231       if (ACE_BIT_DISABLED (this->flags_,
00232                             ACE_Message_Block::DONT_DELETE))
00233         this->allocator_strategy_->free ((void *) this->base_);
00234       else
00235         // We now assume ownership.
00236         ACE_CLR_BITS (this->flags_,
00237                       ACE_Message_Block::DONT_DELETE);
00238       this->max_size_ = length;
00239       this->cur_size_ = length;
00240       this->base_ = buf;
00241     }
00242   return 0;
00243 }
00244 
00245 int
00246 ACE_Message_Block::size (size_t length)
00247 {
00248   ACE_TRACE ("ACE_Message_Block::size");
00249 
00250   // Resize the underlying <ACE_Data_Block>.
00251   if (this->data_block ()->size (length) == -1)
00252     return -1;
00253 
00254   return 0;
00255 }
00256 
00257 void
00258 ACE_Message_Block::total_size_and_length (size_t &mb_size,
00259                                           size_t &mb_length) const
00260 {
00261   ACE_TRACE ("ACE_Message_Block::total_size_and_length");
00262 
00263   for (const ACE_Message_Block *i = this;
00264        i != 0;
00265        i = i->cont ())
00266     {
00267       mb_size += i->size ();
00268       mb_length += i->length ();
00269     }
00270 }
00271 
00272 size_t
00273 ACE_Message_Block::total_size (void) const
00274 {
00275   ACE_TRACE ("ACE_Message_Block::total_size");
00276 
00277   size_t size = 0;
00278   for (const ACE_Message_Block *i = this;
00279        i != 0;
00280        i = i->cont ())
00281     size += i->size ();
00282 
00283   return size;
00284 }
00285 
00286 size_t
00287 ACE_Message_Block::total_length (void) const
00288 {
00289   ACE_TRACE ("ACE_Message_Block::total_length");
00290 
00291   size_t length = 0;
00292   for (const ACE_Message_Block *i = this;
00293        i != 0;
00294        i = i->cont ())
00295     length += i->length ();
00296 
00297   return length;
00298 }
00299 
00300 size_t
00301 ACE_Message_Block::total_capacity (void) const
00302 {
00303   ACE_TRACE ("ACE_Message_Block::total_capacity");
00304 
00305   size_t size = 0;
00306 
00307   for (const ACE_Message_Block *i = this;
00308        i != 0;
00309        i = i->cont ())
00310     size += i->capacity ();
00311 
00312   return size;
00313 }
00314 
00315 ACE_Data_Block::ACE_Data_Block (void)
00316   : type_ (ACE_Message_Block::MB_DATA),
00317     cur_size_ (0),
00318     max_size_ (0),
00319     flags_ (ACE_Message_Block::DONT_DELETE),
00320     base_ (0),
00321     allocator_strategy_ (0),
00322     locking_strategy_ (0),
00323     reference_count_ (1),
00324     data_block_allocator_ (0)
00325 {
00326   ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
00327   ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR1_ENTER);
00328 
00329   ACE_ALLOCATOR (this->allocator_strategy_,
00330                  ACE_Allocator::instance ());
00331 
00332   ACE_ALLOCATOR (this->data_block_allocator_,
00333                  ACE_Allocator::instance ());
00334 }
00335 
00336 ACE_Data_Block::ACE_Data_Block (size_t size,
00337                                 ACE_Message_Block::ACE_Message_Type msg_type,
00338                                 const char *msg_data,
00339                                 ACE_Allocator *allocator_strategy,
00340                                 ACE_Lock *locking_strategy,
00341                                 ACE_Message_Block::Message_Flags flags,
00342                                 ACE_Allocator *data_block_allocator)
00343   : type_ (msg_type),
00344     cur_size_ (0),          // Reset later if memory alloc'd ok
00345     max_size_ (0),
00346     flags_ (flags),
00347     base_ (const_cast <char *> (msg_data)),
00348     allocator_strategy_ (allocator_strategy),
00349     locking_strategy_ (locking_strategy),
00350     reference_count_ (1),
00351     data_block_allocator_ (data_block_allocator)
00352 {
00353   ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
00354   ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR2_ENTER);
00355 
00356   // If the user didn't pass one in, let's use the
00357   // <ACE_Allocator::instance>.
00358   if (this->allocator_strategy_ == 0)
00359     ACE_ALLOCATOR (this->allocator_strategy_,
00360                    ACE_Allocator::instance ());
00361 
00362   if (this->data_block_allocator_ == 0)
00363     ACE_ALLOCATOR (this->data_block_allocator_,
00364                    ACE_Allocator::instance ());
00365 
00366   if (msg_data == 0)
00367     {
00368       ACE_ALLOCATOR (this->base_,
00369                      (char *) this->allocator_strategy_->malloc (size));
00370 #if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE)
00371       (void) ACE_OS::memset (this->base_,
00372                              '\0',
00373                              size);
00374 #endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */
00375     }
00376 
00377   // ACE_ALLOCATOR returns on alloc failure but we cant throw, so setting
00378   // the size to 0 (i.e. "bad bit") ...
00379   if (this->base_ == 0)
00380     {
00381       size = 0;
00382     }
00383 
00384   // The memory is legit, whether passed in or allocated, so set
00385   // the size.
00386   this->cur_size_ = this->max_size_ = size;
00387 }
00388 
00389 ACE_Message_Block::ACE_Message_Block (const char *data,
00390                                       size_t size,
00391                                       unsigned long priority)
00392   : flags_ (0),
00393     data_block_ (0)
00394 {
00395   ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
00396 
00397   if (this->init_i (size,    // size
00398                     MB_DATA, // type
00399                     0,       // cont
00400                     data,    // data
00401                     0,       // allocator
00402                     0,       // locking strategy
00403                     ACE_Message_Block::DONT_DELETE, // flags
00404                     priority, // priority
00405                     ACE_Time_Value::zero,     // execution time
00406                     ACE_Time_Value::max_time, // absolute time of deadline
00407                     0,  // data block
00408                     0,  // data_block allocator
00409                     0) == -1) // message_block allocator
00410     ACE_ERROR ((LM_ERROR,
00411                 ACE_TEXT ("ACE_Message_Block")));
00412 }
00413 
00414 ACE_Message_Block::ACE_Message_Block (ACE_Allocator *message_block_allocator)
00415   : flags_ (0),
00416     data_block_ (0)
00417 {
00418   ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
00419 
00420   if (this->init_i (0,       // size
00421                     MB_DATA, // type
00422                     0,       // cont
00423                     0,       // data
00424                     0,       // allocator
00425                     0,       // locking strategy
00426                     ACE_Message_Block::DONT_DELETE, // flags
00427                     0, // priority
00428                     ACE_Time_Value::zero,     // execution time
00429                     ACE_Time_Value::max_time, // absolute time of deadline
00430                     0, // data block
00431                     0, // data_block allocator
00432                     message_block_allocator) == -1) // message_block allocator
00433     ACE_ERROR ((LM_ERROR,
00434                 ACE_TEXT ("ACE_Message_Block")));
00435 }
00436 
00437 ACE_Message_Block::ACE_Message_Block (size_t size,
00438                                       ACE_Message_Type msg_type,
00439                                       ACE_Message_Block *msg_cont,
00440                                       const char *msg_data,
00441                                       ACE_Allocator *allocator_strategy,
00442                                       ACE_Lock *locking_strategy,
00443                                       unsigned long priority,
00444                                       const ACE_Time_Value &execution_time,
00445                                       const ACE_Time_Value &deadline_time,
00446                                       ACE_Allocator *data_block_allocator,
00447                                       ACE_Allocator *message_block_allocator)
00448   :flags_ (0),
00449    data_block_ (0)
00450 {
00451   ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
00452 
00453   if (this->init_i (size,
00454                     msg_type,
00455                     msg_cont,
00456                     msg_data,
00457                     allocator_strategy,
00458                     locking_strategy,
00459                     msg_data ? ACE_Message_Block::DONT_DELETE : 0,
00460                     priority,
00461                     execution_time,
00462                     deadline_time,
00463                     0, // data block
00464                     data_block_allocator,
00465                     message_block_allocator) == -1)
00466     ACE_ERROR ((LM_ERROR,
00467                 ACE_TEXT ("ACE_Message_Block")));
00468 }
00469 
00470 int
00471 ACE_Message_Block::init (size_t size,
00472                          ACE_Message_Type msg_type,
00473                          ACE_Message_Block *msg_cont,
00474                          const char *msg_data,
00475                          ACE_Allocator *allocator_strategy,
00476                          ACE_Lock *locking_strategy,
00477                          unsigned long priority,
00478                          const ACE_Time_Value &execution_time,
00479                          const ACE_Time_Value &deadline_time,
00480                          ACE_Allocator *data_block_allocator,
00481                          ACE_Allocator *message_block_allocator)
00482 {
00483   ACE_TRACE ("ACE_Message_Block::init");
00484 
00485   return this->init_i (size,
00486                        msg_type,
00487                        msg_cont,
00488                        msg_data,
00489                        allocator_strategy,
00490                        locking_strategy,
00491                        msg_data ? ACE_Message_Block::DONT_DELETE : 0,
00492                        priority,
00493                        execution_time,
00494                        deadline_time,
00495                        0,  // data block
00496                        data_block_allocator,
00497                        message_block_allocator);
00498 }
00499 
00500 int
00501 ACE_Message_Block::init (const char *data,
00502                          size_t size)
00503 {
00504   ACE_TRACE ("ACE_Message_Block::init");
00505   // Should we also initialize all the other fields, as well?
00506 
00507   return this->init_i (size,    // size
00508                        MB_DATA, // type
00509                        0,       // cont
00510                        data,    // data
00511                        0,       // allocator
00512                        0,       // locking strategy
00513                        ACE_Message_Block::DONT_DELETE,  // flags
00514                        0,  // priority
00515                        ACE_Time_Value::zero,     // execution time
00516                        ACE_Time_Value::max_time, // absolute time of deadline
00517                        0,  // data block
00518                        0,  // data_block allocator
00519                        0); // message_block allocator
00520 }
00521 
00522 ACE_Message_Block::ACE_Message_Block (size_t size,
00523                                       ACE_Message_Type msg_type,
00524                                       ACE_Message_Block *msg_cont,
00525                                       const char *msg_data,
00526                                       ACE_Allocator *allocator_strategy,
00527                                       ACE_Lock *locking_strategy,
00528                                       Message_Flags flags,
00529                                       unsigned long priority,
00530                                       const ACE_Time_Value &execution_time,
00531                                       const ACE_Time_Value &deadline_time,
00532                                       ACE_Data_Block *db,
00533                                       ACE_Allocator *data_block_allocator,
00534                                       ACE_Allocator *message_block_allocator)
00535   : flags_ (0),
00536     data_block_ (0)
00537 {
00538   ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
00539 
00540   if (this->init_i (size,
00541                     msg_type,
00542                     msg_cont,
00543                     msg_data,
00544                     allocator_strategy,
00545                     locking_strategy,
00546                     flags,
00547                     priority,
00548                     execution_time,
00549                     deadline_time,
00550                     db,
00551                     data_block_allocator,
00552                     message_block_allocator) == -1)
00553     ACE_ERROR ((LM_ERROR,
00554                 ACE_TEXT ("ACE_Message_Block")));
00555 }
00556 
00557 ACE_Message_Block::ACE_Message_Block (ACE_Data_Block *data_block,
00558                                       ACE_Message_Block::Message_Flags flags,
00559                                       ACE_Allocator *message_block_allocator)
00560   : flags_ (flags),
00561     data_block_ (0)
00562 {
00563   ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
00564 
00565   if (this->init_i (0,         // size
00566                     MB_NORMAL, // type
00567                     0,         // cont
00568                     0,         // data
00569                     0,         // allocator
00570                     0,         // locking strategy
00571                     0,         // flags
00572                     0,         // priority
00573                     ACE_Time_Value::zero,     // execution time
00574                     ACE_Time_Value::max_time, // absolute time of deadline
00575                     data_block, // data block
00576                     data_block->data_block_allocator (),
00577                     message_block_allocator) == -1)
00578     ACE_ERROR ((LM_ERROR,
00579                 ACE_TEXT ("ACE_Message_Block")));
00580 }
00581 
00582 ACE_Message_Block::ACE_Message_Block (const ACE_Message_Block &mb,
00583                                       size_t align)
00584   :flags_ (0),
00585    data_block_ (0)
00586 {
00587   ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
00588 
00589   if (ACE_BIT_DISABLED (mb.flags_,
00590                         ACE_Message_Block::DONT_DELETE))
00591     {
00592       if (this->init_i (0,         // size
00593                         MB_NORMAL, // type
00594                         0,         // cont
00595                         0,         // data
00596                         0,         // allocator
00597                         0,         // locking strategy
00598                         0,         // flags
00599                         0,         // priority
00600                         ACE_Time_Value::zero,     // execution time
00601                         ACE_Time_Value::max_time, // absolute time of deadline
00602                         mb.data_block ()->duplicate (), // data block
00603                         mb.data_block ()->data_block_allocator (),
00604                         mb.message_block_allocator_) == -1)
00605         ACE_ERROR ((LM_ERROR,
00606                     ACE_TEXT ("ACE_Message_Block")));
00607 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00608       // Align ourselves
00609       char *start = ACE_ptr_align_binary (this->base (),
00610                                           align);
00611 #else
00612       char *start = this->base ();
00613 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00614 
00615       // Set our rd & wr pointers
00616       this->rd_ptr (start);
00617       this->wr_ptr (start);
00618 
00619     }
00620   else
00621     {
00622       if (this->init_i (0,         // size
00623                         MB_NORMAL, // type
00624                         0,         // cont
00625                         0,         // data
00626                         0,         // allocator
00627                         0,         // locking strategy
00628                         0,         // flags
00629                         0,         // priority
00630                         ACE_Time_Value::zero,     // execution time
00631                         ACE_Time_Value::max_time, // absolute time of deadline
00632                         mb.data_block ()->clone_nocopy (),// data block
00633                         mb.data_block ()->data_block_allocator (),
00634                         mb.message_block_allocator_) == -1)
00635         ACE_ERROR ((LM_ERROR,
00636                     ACE_TEXT ("ACE_Message_Block")));
00637 
00638 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00639       // Align ourselves
00640       char *start = ACE_ptr_align_binary (this->base (),
00641                                           align);
00642 #else
00643       char *start = this->base ();
00644 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00645 
00646       // Set our rd & wr pointers
00647       this->rd_ptr (start);
00648       this->wr_ptr (start);
00649 
00650 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00651       // Get the alignment offset of the incoming ACE_Message_Block
00652       start = ACE_ptr_align_binary (mb.base (),
00653                                     align);
00654 #else
00655       start = mb.base ();
00656 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00657 
00658       // Actual offset for the incoming message block assuming that it
00659       // is also aligned to the same "align" byte
00660       size_t const wr_offset = mb.wr_ptr_ - (start - mb.base ());
00661 
00662       // Copy wr_offset amount of data in to <this->data_block>
00663       (void) ACE_OS::memcpy (this->wr_ptr (),
00664                              start,
00665                              wr_offset);
00666 
00667       // Dont move the write pointer, just leave it to the application
00668       // to do what it wants
00669 
00670     }
00671 #if defined (ACE_LACKS_CDR_ALIGNMENT)
00672   ACE_UNUSED_ARG (align);
00673 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00674 }
00675 
00676 int
00677 ACE_Message_Block::init_i (size_t size,
00678                            ACE_Message_Type msg_type,
00679                            ACE_Message_Block *msg_cont,
00680                            const char *msg_data,
00681                            ACE_Allocator *allocator_strategy,
00682                            ACE_Lock *locking_strategy,
00683                            Message_Flags flags,
00684                            unsigned long priority,
00685                            const ACE_Time_Value &execution_time,
00686                            const ACE_Time_Value &deadline_time,
00687                            ACE_Data_Block *db,
00688                            ACE_Allocator *data_block_allocator,
00689                            ACE_Allocator *message_block_allocator)
00690 {
00691   ACE_TRACE ("ACE_Message_Block::init_i");
00692   ACE_FUNCTION_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_ENTER);
00693 
00694   this->rd_ptr_ = 0;
00695   this->wr_ptr_ = 0;
00696   this->priority_ = priority;
00697 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
00698   this->execution_time_ = execution_time;
00699   this->deadline_time_ = deadline_time;
00700 #else
00701   ACE_UNUSED_ARG (execution_time);
00702   ACE_UNUSED_ARG (deadline_time);
00703 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
00704   this->cont_ = msg_cont;
00705   this->next_ = 0;
00706   this->prev_ = 0;
00707 
00708   this->message_block_allocator_ = message_block_allocator;
00709 
00710   if (this->data_block_ != 0)
00711     {
00712       this->data_block_->release ();
00713       this->data_block_ = 0;
00714     }
00715 
00716   if (db == 0)
00717     {
00718       if (data_block_allocator == 0)
00719         ACE_ALLOCATOR_RETURN (data_block_allocator,
00720                               ACE_Allocator::instance (),
00721                               -1);
00722 
00723       ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC);
00724 
00725       // Allocate the <ACE_Data_Block> portion, which is reference
00726       // counted.
00727       ACE_NEW_MALLOC_RETURN (db,
00728                              static_cast<ACE_Data_Block *> (
00729                                data_block_allocator->malloc (sizeof (ACE_Data_Block))),
00730                              ACE_Data_Block (size,
00731                                              msg_type,
00732                                              msg_data,
00733                                              allocator_strategy,
00734                                              locking_strategy,
00735                                              flags,
00736                                              data_block_allocator),
00737                              -1);
00738       ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR);
00739 
00740       // Message block initialization may fail, while the construction
00741       // succeds.  Since ACE may throw no exceptions, we have to do a
00742       // separate check and clean up, like this:
00743       if (db != 0 && db->size () < size)
00744         {
00745           db->ACE_Data_Block::~ACE_Data_Block();  // placement destructor ...
00746           data_block_allocator->free (db); // free ...
00747           errno = ENOMEM;
00748           return -1;
00749         }
00750     }
00751 
00752   // Reset the data_block_ pointer.
00753   this->data_block (db);
00754 
00755   return 0;
00756 }
00757 
00758 ACE_Data_Block::~ACE_Data_Block (void)
00759 {
00760   // Sanity check...
00761   ACE_ASSERT (this->reference_count_ <= 1);
00762 
00763   // Just to be safe...
00764   this->reference_count_ = 0;
00765 
00766   if (ACE_BIT_DISABLED (this->flags_,
00767                         ACE_Message_Block::DONT_DELETE))
00768     {
00769       this->allocator_strategy_->free ((void *) this->base_);
00770       this->base_ = 0;
00771     }
00772 }
00773 
00774 ACE_Data_Block *
00775 ACE_Data_Block::release_i (void)
00776 {
00777   ACE_TRACE ("ACE_Data_Block::release_i");
00778 
00779   ACE_ASSERT (this->reference_count_ > 0);
00780 
00781   ACE_Data_Block *result = 0;
00782 
00783   // decrement reference count
00784   --this->reference_count_;
00785 
00786   if (this->reference_count_ == 0)
00787     // this will cause deletion of this
00788     result = 0;
00789   else
00790     result = this;
00791 
00792   return result;
00793 }
00794 
00795 ACE_Data_Block *
00796 ACE_Data_Block::release_no_delete (ACE_Lock *lock)
00797 {
00798   ACE_TRACE ("ACE_Data_Block::release_no_delete");
00799 
00800   ACE_Data_Block *result = 0;
00801   ACE_Lock *lock_to_be_used = 0;
00802 
00803   // Check if we were passed in a lock
00804   if (lock != 0)
00805     {
00806       // Make sure that the lock passed in and our lock are the same
00807       if (lock == this->locking_strategy_)
00808         // In this case no locking is required.
00809         lock_to_be_used = 0;
00810 
00811       // The lock passed in does not match our lock
00812       else
00813         // Lock to be used is our lock
00814         lock_to_be_used = this->locking_strategy_;
00815     }
00816   // This is the case when no lock was passed in
00817   else
00818     // Lock to be used is our lock
00819     lock_to_be_used = this->locking_strategy_;
00820 
00821   // If there's a locking strategy then we need to acquire the lock
00822   // before decrementing the count.
00823   if (lock_to_be_used != 0)
00824     {
00825       ACE_GUARD_RETURN (ACE_Lock, ace_mon, *lock_to_be_used, 0);
00826 
00827       result = this->release_i ();
00828     }
00829   else
00830     result = this->release_i ();
00831 
00832   return result;
00833 }
00834 
00835 ACE_Data_Block *
00836 ACE_Data_Block::release (ACE_Lock *lock)
00837 {
00838   ACE_TRACE ("ACE_Data_Block::release");
00839 
00840   ACE_Allocator *allocator = this->data_block_allocator_;
00841 
00842   ACE_Data_Block *result = this->release_no_delete (lock);
00843 
00844   // We must delete this outside the scope of the locking_strategy_
00845   // since otherwise we'd be trying to "release" through a deleted
00846   // pointer!
00847   if (result == 0)
00848     ACE_DES_FREE (this,
00849                   allocator->free,
00850                   ACE_Data_Block);
00851   return result;
00852 }
00853 
00854 ACE_Message_Block *
00855 ACE_Message_Block::release (void)
00856 {
00857   ACE_TRACE ("ACE_Message_Block::release");
00858 
00859   // We want to hold the data block in a temporary variable because we
00860   // invoked "delete this;" at some point, so using this->data_block_
00861   // could be a bad idea.
00862   ACE_Data_Block *tmp = this->data_block ();
00863 
00864   // This flag is set to 1 when we have to destroy the data_block
00865   int destroy_dblock = 0;
00866 
00867   ACE_Lock *lock = 0;
00868 
00869   // Do we have a valid data block
00870   if (this->data_block ())
00871     {
00872       // Grab the lock that belongs to my data block
00873       lock = this->data_block ()->locking_strategy ();
00874 
00875       // if we have a lock
00876       if (lock != 0)
00877         {
00878           // One guard for all
00879           ACE_GUARD_RETURN (ACE_Lock, ace_mon, *lock, 0);
00880 
00881           // Call non-guarded release with <lock>
00882           destroy_dblock = this->release_i (lock);
00883         }
00884       // This is the case when we have a valid data block but no lock
00885       else
00886         // Call non-guarded release with no lock
00887         destroy_dblock = this->release_i (0);
00888     }
00889   else
00890     // This is the case when we don't even have a valid data block
00891     destroy_dblock = this->release_i (0);
00892 
00893   if (destroy_dblock != 0)
00894     {
00895       ACE_Allocator *allocator = tmp->data_block_allocator ();
00896       ACE_DES_FREE (tmp,
00897                     allocator->free,
00898                     ACE_Data_Block);
00899     }
00900 
00901   return 0;
00902 }
00903 
00904 int
00905 ACE_Message_Block::release_i (ACE_Lock *lock)
00906 {
00907   ACE_TRACE ("ACE_Message_Block::release_i");
00908 
00909   // Free up all the continuation messages.
00910   if (this->cont_)
00911     {
00912       ACE_Message_Block *mb = this->cont_;
00913       ACE_Message_Block *tmp = 0;
00914 
00915       do
00916         {
00917           tmp = mb;
00918           mb = mb->cont_;
00919           tmp->cont_ = 0;
00920 
00921           ACE_Data_Block *db = tmp->data_block ();
00922           if (tmp->release_i (lock) != 0)
00923             {
00924               ACE_Allocator *allocator = db->data_block_allocator ();
00925               ACE_DES_FREE (db,
00926                             allocator->free,
00927                             ACE_Data_Block);
00928             }
00929         }
00930       while (mb);
00931 
00932       this->cont_ = 0;
00933     }
00934 
00935   int result = 0;
00936 
00937   if (ACE_BIT_DISABLED (this->flags_,
00938                         ACE_Message_Block::DONT_DELETE) &&
00939       this->data_block ())
00940     {
00941       if (this->data_block ()->release_no_delete (lock) == 0)
00942         result = 1;
00943       this->data_block_ = 0;
00944     }
00945 
00946   // We will now commit suicide: this object *must* have come from the
00947   // allocator given.
00948   if (this->message_block_allocator_ == 0)
00949     delete this;
00950   else
00951     {
00952       ACE_Allocator *allocator = this->message_block_allocator_;
00953       ACE_DES_FREE (this,
00954                     allocator->free,
00955                     ACE_Message_Block);
00956     }
00957 
00958   return result;
00959 }
00960 
00961 /* static */ ACE_Message_Block *
00962 ACE_Message_Block::release (ACE_Message_Block *mb)
00963 {
00964   ACE_TRACE ("ACE_Message_Block::release");
00965 
00966   if (mb != 0)
00967     return mb->release ();
00968   else
00969     return 0;
00970 }
00971 
00972 ACE_Message_Block::~ACE_Message_Block (void)
00973 {
00974   ACE_TRACE ("ACE_Message_Block::~ACE_Message_Block");
00975 
00976   if (ACE_BIT_DISABLED (this->flags_,
00977                         ACE_Message_Block::DONT_DELETE)&&
00978       this->data_block ())
00979     this->data_block ()->release ();
00980 
00981   this->prev_ = 0;
00982   this->next_ = 0;
00983 }
00984 
00985 ACE_Data_Block *
00986 ACE_Data_Block::duplicate (void)
00987 {
00988   ACE_TRACE ("ACE_Data_Block::duplicate");
00989 
00990   // Create a new <ACE_Message_Block>, but share the <base_> pointer
00991   // data (i.e., don't copy that).
00992   if (this->locking_strategy_)
00993     {
00994       // We need to acquire the lock before incrementing the count.
00995       ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->locking_strategy_, 0);
00996       ++this->reference_count_;
00997     }
00998   else
00999     ++this->reference_count_;
01000 
01001   return this;
01002 }
01003 
01004 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
01005 #define ACE_EXECUTION_TIME this->execution_time_
01006 #define ACE_DEADLINE_TIME this->deadline_time_
01007 #else
01008 #define ACE_EXECUTION_TIME ACE_Time_Value::zero
01009 #define ACE_DEADLINE_TIME ACE_Time_Value::max_time
01010 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
01011 
01012 ACE_Message_Block *
01013 ACE_Message_Block::duplicate (void) const
01014 {
01015   ACE_TRACE ("ACE_Message_Block::duplicate");
01016 
01017   ACE_Message_Block *nb = 0;
01018 
01019   // Create a new <ACE_Message_Block> that contains unique copies of
01020   // the message block fields, but a reference counted duplicate of
01021   // the <ACE_Data_Block>.
01022 
01023   // If there is no allocator, use the standard new and delete calls.
01024   if (this->message_block_allocator_ == 0)
01025     ACE_NEW_RETURN (nb,
01026                     ACE_Message_Block (0, // size
01027                                        ACE_Message_Type (0), // type
01028                                        0, // cont
01029                                        0, // data
01030                                        0, // allocator
01031                                        0, // locking strategy
01032                                        0, // flags
01033                                        this->priority_, // priority
01034                                        ACE_EXECUTION_TIME,
01035                                        ACE_DEADLINE_TIME,
01036                                        // Get a pointer to a
01037                                        // "duplicated" <ACE_Data_Block>
01038                                        // (will simply increment the
01039                                        // reference count).
01040                                        this->data_block ()->duplicate  (),
01041                                        this->data_block ()->data_block_allocator (),
01042                                        this->message_block_allocator_),
01043                   0);
01044   else // Otherwise, use the message_block_allocator passed in.
01045     ACE_NEW_MALLOC_RETURN (nb,
01046                            static_cast<ACE_Message_Block*> (
01047                              message_block_allocator_->malloc (sizeof (ACE_Message_Block))),
01048                            ACE_Message_Block (0, // size
01049                                               ACE_Message_Type (0), // type
01050                                               0, // cont
01051                                               0, // data
01052                                               0, // allocator
01053                                               0, // locking strategy
01054                                               0, // flags
01055                                               this->priority_, // priority
01056                                               ACE_EXECUTION_TIME,
01057                                               ACE_DEADLINE_TIME,
01058                                               // Get a pointer to a
01059                                               // "duplicated" <ACE_Data_Block>
01060                                               // (will simply increment the
01061                                               // reference count).
01062                                               this->data_block ()->duplicate  (),
01063                                               this->data_block ()->data_block_allocator (),
01064                                               this->message_block_allocator_),
01065                            0);
01066 
01067   // Set the read and write pointers in the new <Message_Block> to the
01068   // same relative offset as in the existing <Message_Block>.  Note
01069   // that we are assuming that the data_block()->base() pointer
01070   // doesn't change when it's duplicated.
01071   nb->rd_ptr (this->rd_ptr_);
01072   nb->wr_ptr (this->wr_ptr_);
01073 
01074   // Increment the reference counts of all the continuation messages.
01075   if (this->cont_)
01076     {
01077       nb->cont_ = this->cont_->duplicate ();
01078 
01079       // If things go wrong, release all of our resources and return
01080       // 0.
01081       if (nb->cont_ == 0)
01082         {
01083           nb->release ();
01084           nb = 0;
01085         }
01086     }
01087 
01088   return nb;
01089 }
01090 
01091 ACE_Message_Block *
01092 ACE_Message_Block::duplicate (const ACE_Message_Block *mb)
01093 {
01094   ACE_TRACE ("ACE_Message_Block::duplicate");
01095   if (mb == 0)
01096     return 0;
01097   else
01098     return mb->duplicate ();
01099 }
01100 
01101 ACE_Data_Block *
01102 ACE_Data_Block::clone (ACE_Message_Block::Message_Flags mask) const
01103 {
01104   ACE_TRACE ("ACE_Data_Block::clone");
01105 
01106   ACE_Data_Block *nb = this->clone_nocopy (mask);
01107 
01108   // Copy all of the payload memory into the new object. The new block
01109   // was allocated with max_size_ (and, thus, it's cur_size_ is the same
01110   // as max_size_). Maintain the same "has been written" boundary in the
01111   // new block by only copying cur_size_ bytes.
01112   if (nb != 0)
01113     {
01114       ACE_OS::memcpy (nb->base_,
01115                       this->base_,
01116                       this->cur_size_);
01117     }
01118 
01119   return nb;
01120 }
01121 
01122 ACE_Data_Block *
01123 ACE_Data_Block::clone_nocopy (ACE_Message_Block::Message_Flags mask,
01124                               size_t max_size) const
01125 {
01126   ACE_FUNCTION_TIMEPROBE(ACE_DATA_BLOCK_CLONE_ENTER);
01127 
01128   ACE_TRACE ("ACE_Data_Block::clone_nocopy");
01129 
01130   // You always want to clear this one to prevent memory leaks but you
01131   // might add some others later.
01132   const ACE_Message_Block::Message_Flags always_clear =
01133     ACE_Message_Block::DONT_DELETE;
01134 
01135   const size_t newsize =
01136     max_size == 0 ? this->max_size_ : max_size;
01137 
01138   ACE_Data_Block *nb = 0;
01139 
01140   ACE_NEW_MALLOC_RETURN (nb,
01141                          static_cast<ACE_Data_Block*> (
01142                            this->data_block_allocator_->malloc (sizeof (ACE_Data_Block))),
01143                          ACE_Data_Block (newsize, // size
01144                                          this->type_,     // type
01145                                          0,               // data
01146                                          this->allocator_strategy_, // allocator
01147                                          this->locking_strategy_, // locking strategy
01148                                          this->flags_,  // flags
01149                                          this->data_block_allocator_),
01150                          0);
01151 
01152   // Message block initialization may fail while the construction
01153   // succeds.  Since as a matter of policy, ACE may throw no
01154   // exceptions, we have to do a separate check like this.
01155   if (nb != 0 && nb->size () < newsize)
01156     {
01157       nb->ACE_Data_Block::~ACE_Data_Block();  // placement destructor ...
01158       this->data_block_allocator_->free (nb); // free ...
01159       errno = ENOMEM;
01160       return 0;
01161     }
01162 
01163 
01164   // Set new flags minus the mask...
01165   nb->clr_flags (mask | always_clear);
01166   return nb;
01167 }
01168 
01169 ACE_Message_Block *
01170 ACE_Message_Block::clone (Message_Flags mask) const
01171 {
01172   ACE_TRACE ("ACE_Message_Block::clone");
01173 
01174   // Get a pointer to a "cloned" <ACE_Data_Block> (will copy the
01175   // values rather than increment the reference count).
01176   ACE_Data_Block *db = this->data_block ()->clone (mask);
01177 
01178   if (db == 0)
01179     return 0;
01180 
01181   ACE_Message_Block *nb = 0;
01182 
01183   if(message_block_allocator_ == 0)
01184     {
01185       ACE_NEW_RETURN (nb,
01186                       ACE_Message_Block (0, // size
01187                                          ACE_Message_Type (0), // type
01188                                          0, // cont
01189                                          0, // data
01190                                          0, // allocator
01191                                          0, // locking strategy
01192                                          0, // flags
01193                                          this->priority_, // priority
01194                                          ACE_EXECUTION_TIME, // execution time
01195                                          ACE_DEADLINE_TIME, // absolute time to deadline
01196                                          // Get a pointer to a
01197                                          // "duplicated" <ACE_Data_Block>
01198                                          // (will simply increment the
01199                                          // reference count).
01200                                          db,
01201                                          db->data_block_allocator (),
01202                                          this->message_block_allocator_),
01203                       0);
01204     }
01205   else
01206     {
01207       // This is the ACE_NEW_MALLOC macro with the return check removed.
01208       // We need to do it this way because if it fails we need to release
01209       // the cloned data block that was created above.  If we used
01210       // ACE_NEW_MALLOC_RETURN, there would be a memory leak because the
01211       // above db pointer would be left dangling.
01212       nb = static_cast<ACE_Message_Block*> (message_block_allocator_->malloc (sizeof (ACE_Message_Block)));
01213       if(nb != 0)
01214         new (nb) ACE_Message_Block (0, // size
01215                                     ACE_Message_Type (0), // type
01216                                     0, // cont
01217                                     0, // data
01218                                     0, // allocator
01219                                     0, // locking strategy
01220                                     0, // flags
01221                                     this->priority_, // priority
01222                                     ACE_EXECUTION_TIME, // execution time
01223                                     ACE_DEADLINE_TIME, // absolute time to deadline
01224                                     db,
01225                                     db->data_block_allocator (),
01226                                     this->message_block_allocator_);
01227     }
01228 
01229   if (nb == 0)
01230     {
01231       db->release ();
01232       return 0;
01233     }
01234 
01235   // Set the read and write pointers in the new <Message_Block> to the
01236   // same relative offset as in the existing <Message_Block>.
01237   nb->rd_ptr (this->rd_ptr_);
01238   nb->wr_ptr (this->wr_ptr_);
01239 
01240   // Clone all the continuation messages if necessary.
01241   if (this->cont () != 0
01242       && (nb->cont_ = this->cont ()->clone (mask)) == 0)
01243     {
01244       nb->release ();
01245       return 0;
01246     }
01247   return nb;
01248 }
01249 
01250 // This is private.
01251 ACE_Message_Block &
01252 ACE_Message_Block::operator= (const ACE_Message_Block &)
01253 {
01254   ACE_TRACE ("ACE_Message_Block::operator=");
01255   return *this;
01256 }
01257 
01258 void
01259 ACE_Data_Block::base (char *msg_data,
01260                       size_t msg_length,
01261                       ACE_Message_Block::Message_Flags msg_flags)
01262 {
01263   if (ACE_BIT_DISABLED (this->flags_,
01264                         ACE_Message_Block::DONT_DELETE))
01265     this->allocator_strategy_->free (this->base_);
01266 
01267   this->max_size_ = msg_length;
01268   this->cur_size_ = msg_length;
01269   this->base_ = msg_data;
01270   this->flags_ = msg_flags;
01271 }
01272 
01273 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:40 2010 for ACE by  doxygen 1.4.7