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
),
93 // No allocator, so use the global pool!
99 // Providing an ACE_Data_Block indicates that the caller wants
100 // an aligned ACE_Message_Block added to the TAO_Queued_Data.
103 // If this allocation fails, the TAO_Queued_Data will be leaked.
104 if (input_cdr_alloc
== nullptr)
105 ACE_NEW_RETURN (qd
->msg_block_
,
106 ACE_Message_Block (db
,
111 ACE_NEW_MALLOC_RETURN (qd
->msg_block_
,
112 static_cast<ACE_Message_Block
*> (
113 input_cdr_alloc
->malloc (sizeof (ACE_Message_Block
))),
114 ACE_Message_Block (db
,
119 ACE_CDR::mb_align (qd
->msg_block_
);
127 TAO_Queued_Data::release (TAO_Queued_Data
*qd
)
130 ACE_Message_Block::release (qd
->msg_block_
);
134 // Store the allocator first on the stack, destructor of
135 // qd will be called first, fixes gcc warning
136 ACE_Allocator
*alloc
= qd
->allocator_
;
143 // @todo: Need to be removed at some point of time!
144 if (TAO_debug_level
== 4)
146 // This debug is for testing purposes!
147 TAOLIB_DEBUG ((LM_DEBUG
,
148 "TAO (%P|%t) - Queued_Data[%d]::release\n",
149 "Using global pool for releasing\n"));
157 TAO_Queued_Data::duplicate (TAO_Queued_Data
&sqd
)
159 // Check to see if the underlying block is on the stack. If not it
160 // is fine. If the datablock is on stack, try to make a copy of that
161 // before doing a duplicate.
162 // @@ todo: Theoretically this should be within the Message Block,
163 // but we dont have much scope to do this in that mess. Probably in
164 // the next stage of MB rewrite we should be okay
165 ACE_Message_Block::Message_Flags fl
=
166 sqd
.msg_block_
->self_flags ();
168 if (ACE_BIT_ENABLED (fl
,
169 ACE_Message_Block::DONT_DELETE
))
170 (void) TAO_Queued_Data::replace_data_block (*sqd
.msg_block_
);
173 TAO_Queued_Data
*qd
= nullptr;
177 ACE_NEW_MALLOC_RETURN (qd
,
178 static_cast<TAO_Queued_Data
*> (
179 sqd
.allocator_
->malloc (sizeof (TAO_Queued_Data
))),
180 TAO_Queued_Data (sqd
),
186 // No allocator, so use the global pool!
187 // @@ TODO: We should be removing this at some point of time!
188 if (TAO_debug_level
== 4)
190 // This debug is for testing purposes!
191 TAOLIB_DEBUG ((LM_DEBUG
,
192 "TAO (%P|%t) - Queued_Data[%d]::duplicate\n",
193 "Using global pool for allocation\n"));
197 TAO_Queued_Data (sqd
),
204 TAO_Queued_Data::consolidate ()
206 // Is this a chain of fragments?
207 if (this->state_
.more_fragments () && this->msg_block_
->cont () != nullptr)
209 // Create a message block big enough to hold the entire chain
210 ACE_Message_Block
*dest
= clone_mb_nocopy_size (
212 this->msg_block_
->total_length ());
219 // Memory allocation succeeded, the new message block can hold the consolidated
220 // message. The following code just copies all the data into this new message block.
221 // No further memory allocation will take place.
223 // Reset the cont() parameter. We have cloned the message
224 // block but not the chain as we will no longer have chain.
225 dest
->cont (nullptr);
227 // Use ACE_CDR to consolidate the chain for us
228 ACE_CDR::consolidate (dest
, this->msg_block_
);
230 // free the original message block chain
231 this->msg_block_
->release ();
233 // Set the message block to the new consolidated message block
234 this->msg_block_
= dest
;
235 this->state_
.more_fragments (false);
241 TAO_END_VERSIONED_NAMESPACE_DECL