ACE_Message_Block * ACE_Message_Block::clone (Message_Flags mask) const { ACE_TRACE ("ACE_Message_Block::clone"); // Get a pointer to a "cloned" <ACE_Data_Block> (will copy the // values rather than increment the reference count). ACE_Data_Block *db = this->data_block ()->clone (mask); if (db == 0) return 0; ACE_Message_Block *nb = 0; if (message_block_allocator_ == 0) { ACE_NEW_RETURN (nb, ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags this->priority_, // priority ACE_EXECUTION_TIME, // execution time ACE_DEADLINE_TIME, // absolute time to deadline // Get a pointer to a // "duplicated" <ACE_Data_Block> // (will simply increment the // reference count). db, db->data_block_allocator (), this->message_block_allocator_), 0); } else { // This is the ACE_NEW_MALLOC macro with the return check removed. // We need to do it this way because if it fails we need to release // the cloned data block that was created above. If we used // ACE_NEW_MALLOC_RETURN, there would be a memory leak because the // above db pointer would be left dangling. nb = static_cast<ACE_Message_Block*> (message_block_allocator_->malloc (sizeof (ACE_Message_Block))); if (nb != 0) new (nb) ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags this->priority_, // priority ACE_EXECUTION_TIME, // execution time ACE_DEADLINE_TIME, // absolute time to deadline db, db->data_block_allocator (), this->message_block_allocator_); } if (nb == 0) { db->release (); return 0; } // Set the read and write pointers in the new <Message_Block> to the // same relative offset as in the existing <Message_Block>. nb->rd_ptr (this->rd_ptr_); nb->wr_ptr (this->wr_ptr_); // Clone all the continuation messages if necessary. if (this->cont () != 0 && (nb->cont_ = this->cont ()->clone (mask)) == 0) { nb->release (); return 0; } return nb; }
ACE_Message_Block * ACE_Message_Block::clone (Message_Flags mask) const { ACE_TRACE ("ACE_Message_Block::clone"); const ACE_Message_Block *old_message_block = this; ACE_Message_Block *new_message_block = 0; ACE_Message_Block *new_previous_message_block = 0; ACE_Message_Block *new_root_message_block = 0; do { // Get a pointer to a "cloned"<ACE_Data_Block> (will copy the // values rather than increment the reference count). ACE_Data_Block *db = old_message_block->data_block ()->clone (mask); if (db == 0) return 0; if(old_message_block->message_block_allocator_ == 0) { ACE_NEW_RETURN (new_message_block, ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags old_message_block->priority_, // priority ACE_EXECUTION_TIME, // execution time ACE_DEADLINE_TIME, // absolute time to deadline // Get a pointer to a // "duplicated"<ACE_Data_Block> // (will simply increment the // reference count). db, db->data_block_allocator (), old_message_block->message_block_allocator_), 0); } else { // This is the ACE_NEW_MALLOC macro with the return check removed. // We need to do it this way because if it fails we need to release // the cloned data block that was created above. If we used // ACE_NEW_MALLOC_RETURN, there would be a memory leak because the // above db pointer would be left dangling. new_message_block = static_cast<ACE_Message_Block*> (old_message_block->message_block_allocator_->malloc (sizeof (ACE_Message_Block))); if (new_message_block != 0) new (new_message_block) ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags old_message_block->priority_, // priority ACE_EXECUTION_TIME, // execution time ACE_DEADLINE_TIME, // absolute time to deadline db, db->data_block_allocator (), old_message_block->message_block_allocator_); } if (new_message_block == 0) { db->release (); return 0; } // Set the read and write pointers in the new <Message_Block> to the // same relative offset as in the existing <Message_Block>. new_message_block->rd_ptr (old_message_block->rd_ptr_); new_message_block->wr_ptr (old_message_block->wr_ptr_); // save the root message block to return if (new_root_message_block == 0) new_root_message_block = new_message_block; if (new_previous_message_block != 0) // we're a continuation of the previous block, add ourself to its chain new_previous_message_block->cont_ = new_message_block; new_previous_message_block = new_message_block; old_message_block = old_message_block->cont (); } while (old_message_block != 0); return new_root_message_block; }
ACE_Message_Block * ACE_Message_Block::duplicate (void) const { ACE_TRACE ("ACE_Message_Block::duplicate"); ACE_Message_Block *nb = 0; // Create a new <ACE_Message_Block> that contains unique copies of // the message block fields, but a reference counted duplicate of // the <ACE_Data_Block>. // If there is no allocator, use the standard new and delete calls. if (this->message_block_allocator_ == 0) ACE_NEW_RETURN (nb, ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags this->priority_, // priority ACE_EXECUTION_TIME, ACE_DEADLINE_TIME, // Get a pointer to a // "duplicated" <ACE_Data_Block> // (will simply increment the // reference count). this->data_block ()->duplicate (), this->data_block ()->data_block_allocator (), this->message_block_allocator_), 0); else // Otherwise, use the message_block_allocator passed in. ACE_NEW_MALLOC_RETURN (nb, static_cast<ACE_Message_Block*> ( message_block_allocator_->malloc (sizeof (ACE_Message_Block))), ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags this->priority_, // priority ACE_EXECUTION_TIME, ACE_DEADLINE_TIME, // Get a pointer to a // "duplicated" <ACE_Data_Block> // (will simply increment the // reference count). this->data_block ()->duplicate (), this->data_block ()->data_block_allocator (), this->message_block_allocator_), 0); // Set the read and write pointers in the new <Message_Block> to the // same relative offset as in the existing <Message_Block>. Note // that we are assuming that the data_block()->base() pointer // doesn't change when it's duplicated. nb->rd_ptr (this->rd_ptr_); nb->wr_ptr (this->wr_ptr_); // Increment the reference counts of all the continuation messages. if (this->cont_) { nb->cont_ = this->cont_->duplicate (); // If things go wrong, release all of our resources and return // 0. if (nb->cont_ == 0) { nb->release (); nb = 0; } } return nb; }
ACE_Message_Block * ACE_Message_Block::duplicate (void) const { ACE_TRACE ("ACE_Message_Block::duplicate"); ACE_Message_Block *nb_top = 0; ACE_Message_Block *nb = 0; const ACE_Message_Block *current = this; // Increment the reference counts of all the continuation messages. while (current) { ACE_Message_Block* cur_dup = 0; // Create a new <ACE_Message_Block> that contains unique copies of // the message block fields, but a reference counted duplicate of // the <ACE_Data_Block>. // If there is no allocator, use the standard new and delete calls. if (current->message_block_allocator_ == 0) ACE_NEW_NORETURN (cur_dup, ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags current->priority_, // priority ACE_EXECUTION_TIME, ACE_DEADLINE_TIME, // Get a pointer to a // "duplicated" <ACE_Data_Block> // (will simply increment the // reference count). current->data_block ()->duplicate (), current->data_block ()->data_block_allocator (), current->message_block_allocator_)); else // Otherwise, use the message_block_allocator passed in. ACE_NEW_MALLOC_NORETURN (cur_dup, static_cast<ACE_Message_Block*> ( current->message_block_allocator_->malloc (sizeof (ACE_Message_Block))), ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags current->priority_, // priority ACE_EXECUTION_TIME, ACE_DEADLINE_TIME, // Get a pointer to a // "duplicated" <ACE_Data_Block> // (will simply increment the // reference count). current->data_block ()->duplicate (), current->data_block ()->data_block_allocator (), current->message_block_allocator_)); // If allocation failed above, release everything done so far and return NULL if (cur_dup == 0) { if (nb_top != 0) { nb_top->release (); } return 0; } // Set the read and write pointers in the new <Message_Block> to the // same relative offset as in the existing <Message_Block>. Note // that we are assuming that the data_block()->base() pointer // doesn't change when it's duplicated. cur_dup->rd_ptr (current->rd_ptr_); cur_dup->wr_ptr (current->wr_ptr_); if (!nb) { /* First in the list: set leading pointers */ nb_top = nb = cur_dup; } else { /* Continuing on: append to nb and walk down the list */ nb->cont_ = cur_dup; nb = nb->cont_; } current = current->cont_; } return nb_top; }