2 #include "tao/Queued_Data.h"
5 #include "ace/Log_Msg.h"
6 #include "ace/Malloc_Base.h"
8 #if !defined (__ACE_INLINE__)
9 # include "tao/Queued_Data.inl"
10 #endif /* __ACE_INLINE__ */
12 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
15 * @brief Allocate and return a new empty message block of size \a span_size
16 * mimicking parameters of \a mb.
18 * This function allocates a new aligned message block using the same
19 * allocators and flags as found in \a mb. The size of the new message
20 * block is at least \a span_size; the size may be adjusted up in order
21 * to accomodate alignment requirements and still fit \a span_size bytes
22 * into the aligned buffer.
24 * @param mb message block whose parameters should be mimicked
25 * @param span_size size of the new message block (will be adjusted for proper
27 * @return an aligned message block with rd_ptr sitting at correct
28 * alignment spot, 0 on failure
30 static ACE_Message_Block
*
31 clone_mb_nocopy_size (ACE_Message_Block
*mb
, size_t span_size
)
33 // Calculate the required size of the cloned block with alignment
34 size_t const aligned_size
= ACE_CDR::first_size (span_size
+ ACE_CDR::MAX_ALIGNMENT
);
37 ACE_Allocator
*data_allocator
= nullptr;
38 ACE_Allocator
*data_block_allocator
= nullptr;
39 ACE_Allocator
*message_block_allocator
= nullptr;
40 mb
->access_allocators (data_allocator
,
42 message_block_allocator
);
44 // Create a new Message Block
45 ACE_Message_Block
*nb
= nullptr;
46 ACE_NEW_MALLOC_RETURN (nb
,
47 static_cast<ACE_Message_Block
*> (
48 message_block_allocator
->malloc (
49 sizeof (ACE_Message_Block
))),
50 ACE_Message_Block(aligned_size
,
53 nullptr, //we want the data block created
55 mb
->locking_strategy(),
57 mb
->msg_execution_time (),
58 mb
->msg_deadline_time (),
60 message_block_allocator
),
63 ACE_CDR::mb_align (nb
);
65 // Copy the flags over, but be SURE to clear the DONT_DELETE flag, since
66 // we just dynamically allocated the two things.
67 nb
->set_flags (mb
->flags());
68 nb
->clr_flags (ACE_Message_Block::DONT_DELETE
);
75 TAO_Queued_Data::make_queued_data (ACE_Allocator
*message_buffer_alloc
,
76 ACE_Allocator
*input_cdr_alloc
,
79 // Get a node for the queue..
80 TAO_Queued_Data
*qd
= nullptr;
82 if (message_buffer_alloc
)
84 ACE_NEW_MALLOC_RETURN (qd
,
85 static_cast<TAO_Queued_Data
*> (
86 message_buffer_alloc
->malloc (sizeof (TAO_Queued_Data
))),
87 TAO_Queued_Data (message_buffer_alloc
),
92 // No allocator, so use the global pool!
98 // Providing an ACE_Data_Block indicates that the caller wants
99 // an aligned ACE_Message_Block added to the TAO_Queued_Data.
102 // If this allocation fails, the TAO_Queued_Data will be leaked.
103 if (input_cdr_alloc
== nullptr)
104 ACE_NEW_RETURN (qd
->msg_block_
,
105 ACE_Message_Block (db
,
110 ACE_NEW_MALLOC_RETURN (qd
->msg_block_
,
111 static_cast<ACE_Message_Block
*> (
112 input_cdr_alloc
->malloc (sizeof (ACE_Message_Block
))),
113 ACE_Message_Block (db
,
118 ACE_CDR::mb_align (qd
->msg_block_
);
126 TAO_Queued_Data::release (TAO_Queued_Data
*qd
)
129 ACE_Message_Block::release (qd
->msg_block_
);
133 // Store the allocator first on the stack, destructor of
134 // qd will be called first, fixes gcc warning
135 ACE_Allocator
*alloc
= qd
->allocator_
;
142 // @todo: Need to be removed at some point of time!
143 if (TAO_debug_level
== 4)
145 // This debug is for testing purposes!
146 TAOLIB_DEBUG ((LM_DEBUG
,
147 "TAO (%P|%t) - Queued_Data[%d]::release\n",
148 "Using global pool for releasing\n"));
156 TAO_Queued_Data::duplicate (TAO_Queued_Data
&sqd
)
158 // Check to see if the underlying block is on the stack. If not it
159 // is fine. If the datablock is on stack, try to make a copy of that
160 // before doing a duplicate.
161 // @@ todo: Theoretically this should be within the Message Block,
162 // but we dont have much scope to do this in that mess. Probably in
163 // the next stage of MB rewrite we should be okay
164 ACE_Message_Block::Message_Flags fl
=
165 sqd
.msg_block_
->self_flags ();
167 if (ACE_BIT_ENABLED (fl
,
168 ACE_Message_Block::DONT_DELETE
))
169 (void) TAO_Queued_Data::replace_data_block (*sqd
.msg_block_
);
172 TAO_Queued_Data
*qd
= nullptr;
176 ACE_NEW_MALLOC_RETURN (qd
,
177 static_cast<TAO_Queued_Data
*> (
178 sqd
.allocator_
->malloc (sizeof (TAO_Queued_Data
))),
179 TAO_Queued_Data (sqd
),
185 // No allocator, so use the global pool!
186 // @@ TODO: We should be removing this at some point of time!
187 if (TAO_debug_level
== 4)
189 // This debug is for testing purposes!
190 TAOLIB_DEBUG ((LM_DEBUG
,
191 "TAO (%P|%t) - Queued_Data[%d]::duplicate\n",
192 "Using global pool for allocation\n"));
196 TAO_Queued_Data (sqd
),
203 TAO_Queued_Data::consolidate ()
205 // Is this a chain of fragments?
206 if (this->state_
.more_fragments () && this->msg_block_
->cont () != nullptr)
208 // Create a message block big enough to hold the entire chain
209 ACE_Message_Block
*dest
= clone_mb_nocopy_size (
211 this->msg_block_
->total_length ());
218 // Memory allocation succeeded, the new message block can hold the consolidated
219 // message. The following code just copies all the data into this new message block.
220 // No further memory allocation will take place.
222 // Reset the cont() parameter. We have cloned the message
223 // block but not the chain as we will no longer have chain.
224 dest
->cont (nullptr);
226 // Use ACE_CDR to consolidate the chain for us
227 ACE_CDR::consolidate (dest
, this->msg_block_
);
229 // free the original message block chain
230 this->msg_block_
->release ();
232 // Set the message block to the new consolidated message block
233 this->msg_block_
= dest
;
234 this->state_
.more_fragments (false);
240 TAO_END_VERSIONED_NAMESPACE_DECL