ACE_Data_Block * ACE_Data_Block::clone_nocopy (ACE_Message_Block::Message_Flags mask, size_t max_size) const { ACE_FUNCTION_TIMEPROBE(ACE_DATA_BLOCK_CLONE_ENTER); ACE_TRACE ("ACE_Data_Block::clone_nocopy"); // You always want to clear this one to prevent memory leaks but you // might add some others later. const ACE_Message_Block::Message_Flags always_clear = ACE_Message_Block::DONT_DELETE; const size_t newsize = max_size == 0 ? this->max_size_ : max_size; ACE_Data_Block *nb = 0; ACE_NEW_MALLOC_RETURN (nb, static_cast<ACE_Data_Block*> ( this->data_block_allocator_->malloc (sizeof (ACE_Data_Block))), ACE_Data_Block (newsize, // size this->type_, // type 0, // data this->allocator_strategy_, // allocator this->locking_strategy_, // locking strategy this->flags_, // flags this->data_block_allocator_), 0); // Message block initialization may fail while the construction // succeds. Since as a matter of policy, ACE may throw no // exceptions, we have to do a separate check like this. if (nb != 0 && nb->size () < newsize) { nb->ACE_Data_Block::~ACE_Data_Block(); // placement destructor ... this->data_block_allocator_->free (nb); // free ... errno = ENOMEM; return 0; } // Set new flags minus the mask... nb->clr_flags (mask | always_clear); return nb; }
TAO_Queued_Data * TAO_Queued_Data::duplicate (TAO_Queued_Data &sqd) { // Check to see if the underlying block is on the stack. If not it // is fine. If the datablock is on stack, try to make a copy of that // before doing a duplicate. // @@ todo: Theoretically this should be within the Message Block, // but we dont have much scope to do this in that mess. Probably in // the next stage of MB rewrite we should be okay ACE_Message_Block::Message_Flags fl = sqd.msg_block_->self_flags (); if (ACE_BIT_ENABLED (fl, ACE_Message_Block::DONT_DELETE)) (void) TAO_Queued_Data::replace_data_block (*sqd.msg_block_); TAO_Queued_Data *qd = 0; if (sqd.allocator_) { ACE_NEW_MALLOC_RETURN (qd, static_cast<TAO_Queued_Data *> ( sqd.allocator_->malloc (sizeof (TAO_Queued_Data))), TAO_Queued_Data (sqd), 0); return qd; } // No allocator, so use the global pool! // @@ TODO: We should be removing this at some point of time! if (TAO_debug_level == 4) { // This debug is for testing purposes! TAOLIB_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Queued_Data[%d]::duplicate\n", "Using global pool for allocation\n")); } ACE_NEW_RETURN (qd, TAO_Queued_Data (sqd), 0); return qd; }
// Note: The FooDataWriter gives ownership of the marshalled data // to the WriteDataContainer. ACE_Message_Block* FooDataWriterImpl::marshal( const Foo& instance_data, int for_write) { ACE_Message_Block* mb; if (for_write) { ACE_NEW_MALLOC_RETURN (mb, static_cast<ACE_Message_Block*> ( mb_allocator_->malloc ( sizeof (ACE_Message_Block))), ACE_Message_Block( sizeof (Foo), ACE_Message_Block::MB_DATA, 0, //cont 0, //data foo_allocator_, //allocator_strategy 0, //locking_strategy ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY, ACE_Time_Value::zero, ACE_Time_Value::max_time, db_allocator_, mb_allocator_), 0); mb->copy ((const char *)&instance_data, sizeof (Foo)); } else { // Don't use the cached allocator for the registered sample message // block. Foo* register_sample = new Foo(); *register_sample = instance_data; ACE_NEW_RETURN (mb, ACE_Message_Block ((const char*)register_sample, sizeof (Foo)), 0); // Let the PublicationInstance destructor release the Message Block // and delete this register_sample. mb->clr_flags(ACE_Message_Block::DONT_DELETE); } return mb; }
template <class T, class C> int ACE_Unbounded_Set_Ex<T, C>::insert_tail (const T &item) { // ACE_TRACE ("ACE_Unbounded_Set_Ex<T, C>::insert_tail"); NODE *temp = 0; // Insert <item> into the old dummy node location. this->head_->item_ = item; // Create a new dummy node. ACE_NEW_MALLOC_RETURN (temp, static_cast<NODE*> (this->allocator_->malloc (sizeof (NODE))), NODE (this->head_->next_), -1); // Link this pointer into the list. this->head_->next_ = temp; // Point the head to the new dummy node. this->head_ = temp; ++this->cur_size_; return 0; }
int DDS_TEST::run(int num_messages, int msg_size) { VDBG((LM_DEBUG, "(%P|%t) DBG: " "Build the DataSampleElementList\n")); this->num_messages_delivered_ = 0; this->num_messages_sent_ = num_messages; // Set up the SendStateDataSampleList OpenDDS::DCPS::SendStateDataSampleList samples; samples.size_ = num_messages; // Now we can create the DataSampleHeader struct and set its fields. OpenDDS::DCPS::DataSampleHeader header; // The +1 makes the null terminator ('\0') get placed into the block. header.message_id_ = 1; header.publication_id_ = this->pub_id_; OpenDDS::DCPS::DataSampleElement* prev_element = 0; OpenDDS::DCPS::DataSampleElementAllocator allocator(num_messages); Cleanup cleanup(allocator, samples); OpenDDS::DCPS::TransportSendElementAllocator trans_allocator(num_messages, sizeof (OpenDDS::DCPS::TransportSendElement)); std::string data = "Hello World!"; if (msg_size) { data.clear(); for (int j = 1; j <= msg_size; ++j) { data += char(1 + (j % 255)); } } for (int i = 1; i <= num_messages; ++i) { // This is what goes in the "Data Block". std::ostringstream ostr; ostr << data << " [" << i << "]"; std::string data_str = msg_size ? data : ostr.str(); ssize_t num_data_bytes = data_str.length() + 1; header.message_length_ = static_cast<ACE_UINT32>(num_data_bytes); header.sequence_ = i; // The DataSampleHeader is what goes in the "Header Block". ACE_Message_Block* header_block = new ACE_Message_Block(header.max_marshaled_size()); *header_block << header; ACE_Message_Block* data_block = new ACE_Message_Block(num_data_bytes); data_block->copy(data_str.c_str()); // Chain the "Data Block" to the "Header Block" header_block->cont(data_block); // Create the DataSampleElement now. OpenDDS::DCPS::DataSampleElement* element; ACE_NEW_MALLOC_RETURN(element, static_cast<OpenDDS::DCPS::DataSampleElement*>(allocator.malloc(sizeof (OpenDDS::DCPS::DataSampleElement))), OpenDDS::DCPS::DataSampleElement(this->pub_id_, this, 0, &trans_allocator, 0), 1); // The Sample Element will hold on to the chain of blocks (header + data). element->sample_ = header_block; if (prev_element == 0) { samples.head_ = element; } else { prev_element->set_next_send_sample(element); } prev_element = element; samples.tail_ = element; } VDBG((LM_DEBUG, "(%P|%t) DBG: " "Send the SendStateDataSampleList (samples).\n")); ACE_Time_Value start = ACE_OS::gettimeofday(); this->send(samples); ACE_Time_Value finished = ACE_OS::gettimeofday(); ACE_Time_Value total = finished - start; ACE_DEBUG((LM_INFO, "(%P|%t) Publisher total time required was %d.%d seconds.\n", total.sec(), total.usec() % 1000000)); VDBG((LM_DEBUG, "(%P|%t) DBG: " "The Publisher has finished sending the samples.\n")); if (msg_size) { ACE_OS::sleep(15); } return 0; }
int ACE_Message_Block::init_i (size_t size, ACE_Message_Type msg_type, ACE_Message_Block *msg_cont, const char *msg_data, ACE_Allocator *allocator_strategy, ACE_Lock *locking_strategy, Message_Flags flags, unsigned long priority, const ACE_Time_Value &execution_time, const ACE_Time_Value &deadline_time, ACE_Data_Block *db, ACE_Allocator *data_block_allocator, ACE_Allocator *message_block_allocator) { ACE_TRACE ("ACE_Message_Block::init_i"); ACE_FUNCTION_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_ENTER); this->rd_ptr_ = 0; this->wr_ptr_ = 0; this->priority_ = priority; #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS) this->execution_time_ = execution_time; this->deadline_time_ = deadline_time; #else ACE_UNUSED_ARG (execution_time); ACE_UNUSED_ARG (deadline_time); #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */ this->cont_ = msg_cont; this->next_ = 0; this->prev_ = 0; this->message_block_allocator_ = message_block_allocator; if (this->data_block_ != 0) { this->data_block_->release (); this->data_block_ = 0; } if (db == 0) { if (data_block_allocator == 0) ACE_ALLOCATOR_RETURN (data_block_allocator, ACE_Allocator::instance (), -1); ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC); // Allocate the <ACE_Data_Block> portion, which is reference // counted. ACE_NEW_MALLOC_RETURN (db, static_cast<ACE_Data_Block *> ( data_block_allocator->malloc (sizeof (ACE_Data_Block))), ACE_Data_Block (size, msg_type, msg_data, allocator_strategy, locking_strategy, flags, data_block_allocator), -1); ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR); // Message block initialization may fail, while the construction // succeds. Since ACE may throw no exceptions, we have to do a // separate check and clean up, like this: if (db != 0 && db->size () < size) { db->ACE_Data_Block::~ACE_Data_Block(); // placement destructor ... data_block_allocator->free (db); // free ... errno = ENOMEM; return -1; } } // Reset the data_block_ pointer. this->data_block (db); return 0; }
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; }
template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t, ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry) { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i"); // Find the closest matching node, if there is one. RB_SearchResult result = LEFT; ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = find_node (k, result); if (current) { // If the keys match, just return a pointer to the node's item. if (result == EXACT) { entry = current; return 1; } // Otherwise if we're to the left of the insertion // point, insert into the right subtree. else if (result == LEFT) { if (current->right ()) { // If there is already a right subtree, complain. ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("\nright subtree already present in ") ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")), -1); } else { // The right subtree is empty: insert new node there. ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0; ACE_NEW_MALLOC_RETURN (tmp, (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*> (this->allocator_->malloc (sizeof (*tmp)))), (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t), -1); current->right (tmp); // If the node was successfully inserted, set its parent, rebalance // the tree, color the root black, and return a pointer to the // inserted item. entry = current->right (); current->right ()->parent (current); RB_rebalance (current->right ()); this->root_->color (ACE_RB_Tree_Node_Base::BLACK); ++this->current_size_; return 0; } } // Otherwise, we're to the right of the insertion point, so // insert into the left subtree. else // (result == RIGHT) { if (current->left ()) // If there is already a left subtree, complain. ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("\nleft subtree already present in ") ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")), -1); else { // The left subtree is empty: insert new node there. ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0; ACE_NEW_MALLOC_RETURN (tmp, (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*> (this->allocator_->malloc (sizeof (*tmp)))), (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t), -1); current->left (tmp); // If the node was successfully inserted, set its // parent, rebalance the tree, color the root black, and // return a pointer to the inserted item. entry = current->left (); current->left ()->parent (current); RB_rebalance (current->left ()); this->root_->color (ACE_RB_Tree_Node_Base::BLACK); ++this->current_size_; return 0; } } } else { // The tree is empty: insert at the root and color the root black. ACE_NEW_MALLOC_RETURN (this->root_, (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*> (this->allocator_->malloc (sizeof (ACE_RB_Tree_Node<EXT_ID, INT_ID>)))), (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t), -1); this->root_->color (ACE_RB_Tree_Node_Base::BLACK); ++this->current_size_; entry = this->root_; return 0; } }
int SimpleDataWriter::run(SimplePublisher* publisher, unsigned num_messages) { this->num_messages_delivered_ = 0; this->num_messages_sent_ = num_messages; // Set up the DataSampleList TAO::DCPS::DataSampleList samples; samples.head_ = 0; samples.tail_ = 0; samples.size_ = num_messages; // This is what goes in the "Data Block". std::string data = "Hello World!"; // Now we can create the DataSampleHeader struct and set its fields. TAO::DCPS::DataSampleHeader header; header.message_id_ = 1; header.publication_id_ = this->pub_id_; TAO::DCPS::DataSampleListElement* prev_element = 0; TAO::DCPS::DataSampleListElementAllocator allocator(num_messages); TAO::DCPS::TransportSendElementAllocator trans_allocator(num_messages, sizeof (TAO::DCPS::TransportSendElement)); for (unsigned i = 1; i <= num_messages; ++i) { // This is what goes in the "Data Block". std::ostringstream ostr; ostr << data << " [" << i << "]"; std::string data_str = ostr.str(); ssize_t num_data_bytes = data_str.length() + 1; header.message_length_ = num_data_bytes; header.sequence_ = i; // The DataSampleHeader is what goes in the "Header Block". ACE_Message_Block* header_block = new ACE_Message_Block(header.max_marshaled_size()); header_block << header; ACE_Message_Block* data_block = new ACE_Message_Block(num_data_bytes); data_block->copy(data_str.c_str()); // Chain the "Data Block" to the "Header Block" header_block->cont(data_block); // Create the DataSampleListElement now. TAO::DCPS::DataSampleListElement* element; ACE_NEW_MALLOC_RETURN(element, static_cast<TAO::DCPS::DataSampleListElement*> (allocator.malloc(sizeof (TAO::DCPS::DataSampleListElement))), TAO::DCPS::DataSampleListElement(this->pub_id_, this, 0, &trans_allocator), 1); // The Sample Element will hold the chain of blocks (header + data). element->sample_ = header_block; if (prev_element == 0) { samples.head_ = element; } else { prev_element->next_send_sample_ = element; } prev_element = element; samples.tail_ = element; } publisher->send_samples(samples); return 0; }
int SimpleDataWriter::run(SimplePublisher* publisher) { DBG_ENTRY("SimpleDataWriter","run"); VDBG((LM_DEBUG, "(%P|%t) DBG: " "Build the DataSampleElementList to contain one element - " "our 'Hello World' string.\n")); // We just send one message. // This is what goes in the "Data Block". ACE_TString data = "Hello World!"; // Now we can create the DataSampleHeader struct and set its fields. TAO::DCPS::DataSampleHeader header; // The +1 makes the null terminator ('/0') get placed into the block. header.message_length_ = data.length() + 1; header.message_id_ = 1; header.sequence_ = 0; // TMB - Compiler no longer likes the next line... source_timestamp_ is gone. //header.source_timestamp_ = ACE_OS::gettimeofday().msec(); header.publication_id_ = this->pub_id_; // The DataSampleHeader is what goes in the "Header Block". ACE_Message_Block* header_block = new ACE_Message_Block (header.max_marshaled_size()); header_block << header; // The +1 makes the null terminator ('/0') get placed into the block. ACE_Message_Block* data_block = new ACE_Message_Block(data.length() + 1); data_block->copy(data.c_str()); // Chain the "Data Block" to the "Header Block" header_block->cont(data_block); // Create the DataSampleListElement now. TAO::DCPS::DataSampleListElementAllocator allocator(3); TAO::DCPS::TransportSendElementAllocator trans_allocator(3, sizeof (TAO::DCPS::TransportSendElement)); TAO::DCPS::DataSampleListElement* element; ACE_NEW_MALLOC_RETURN(element, static_cast<TAO::DCPS::DataSampleListElement*> (allocator.malloc(sizeof (TAO::DCPS::DataSampleListElement))), TAO::DCPS::DataSampleListElement(this->pub_id_, this, 0, &trans_allocator), 1); // The Sample Element will hold on to the chain of blocks (header + data). element->sample_ = header_block; // Set up the DataSampleList TAO::DCPS::DataSampleList samples; samples.head_ = element; samples.tail_ = element; samples.size_ = 1; VDBG((LM_DEBUG, "(%P|%t) DBG: " "Ask the publisher to send the DataSampleList (samples).\n")); publisher->send_samples(samples); VDBG((LM_DEBUG, "(%P|%t) DBG: " "The Publisher has finished sending the samples.\n")); return 0; }