Skip to content

Commit 6d6bc7c

Browse files
Improvements on compute_key generated code (#544)
* Refs #23926. Refactor compute_key generated code. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #23926. Synchronize calls to compute_key. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #23926. Avoid unused params warning. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #23926. Use local variable for MD5 context. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #23926. Only generate key buffer when necessary. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #23926. Improve safety against allocation failures. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #23926. Bonus: some linter related improvements. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> --------- Signed-off-by: Miguel Company <miguelcompany@eprosima.com>
1 parent f5c811d commit 6d6bc7c

File tree

7 files changed

+101
-50
lines changed

7 files changed

+101
-50
lines changed

src/main/java/com/eprosima/fastcdr/idl/templates/TypesHeader.stg

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,12 @@ $definition_list$
114114
annotation(ctx, annotation) ::= <<
115115
$if(annotation.enums || annotation.typeDefs || annotation.constDecls)$
116116
namespace $annotation.name$ {
117-
$annotation.enums : { enum | $enum_type(ctx=ctx, parent=annotation, enum=enum)$}; separator="\n"$
118117

119-
$annotation.typeDefs : { typedef | $typedef_decl(ctx=ctx, parent=annotation, typedefs=typedef, typedefs_type="", declarator_type="")$}; separator="\n"$
118+
$annotation.enums : { enum | $enum_type(ctx=ctx, parent=annotation, enum=enum)$}; separator="\n"$
120119

121-
$annotation.constDecls : { const | $const_decl(ctx=ctx, parent=annotation, const=const, const_type="")$}; separator="\n"$
120+
$annotation.typeDefs : { typedef | $typedef_decl(ctx=ctx, parent=annotation, typedefs=typedef, typedefs_type="", declarator_type="")$}; separator="\n"$
121+
122+
$annotation.constDecls : { const | $const_decl(ctx=ctx, parent=annotation, const=const, const_type="")$}; separator="\n"$
122123

123124
} // namespace $annotation.name$
124125
$endif$

src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ $fileHeader(ctx=ctx, file=[ctx.filename, "PubSubTypes.hpp"], description=["This
2323
#ifndef FAST_DDS_GENERATED__$ctx.headerGuardName$_PUBSUBTYPES_HPP
2424
#define FAST_DDS_GENERATED__$ctx.headerGuardName$_PUBSUBTYPES_HPP
2525

26+
#include <mutex>
27+
2628
#include <fastdds/dds/core/policy/QosPolicies.hpp>
2729
$if(ctx.thereIsInterface)$
2830
#include <fastdds/dds/rpc/ServiceTypeSupport.hpp>
@@ -48,10 +50,9 @@ $"\n"$
4850
>>
4951

5052
module(ctx, parent, module, definition_list) ::= <<
51-
namespace $module.name$
52-
{
53-
$definition_list$
54-
} // namespace $module.name$
53+
namespace $module.name$ {
54+
$definition_list$
55+
} // namespace $module.name$
5556
>>
5657

5758
typedef_decl(ctx, parent, typedefs, typedefs_type, declarator_type) ::= <<
@@ -188,8 +189,12 @@ public:
188189

189190
private:
190191

191-
eprosima::fastdds::MD5 md5_;
192-
unsigned char* key_buffer_;
192+
$if(struct.hasKey)$
193+
unsigned char* key_buffer_ = nullptr;
194+
std::mutex compute_key_mtx_;
195+
196+
unsigned char* get_key_buffer_nts();
197+
$endif$
193198

194199
$if(struct.isPlain)$
195200

src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeSource.stg

Lines changed: 76 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ $fileHeader(ctx=ctx, file=[ctx.filename, "PubSubTypes.cpp"], description=["This
2121

2222
#include "$ctx.filename$PubSubTypes.hpp"
2323

24+
#include <algorithm>
25+
#include <mutex>
26+
2427
#include <fastdds/dds/log/Log.hpp>
2528
#include <fastdds/rtps/common/CdrSerialization.hpp>
2629

@@ -34,7 +37,6 @@ using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t;
3437
using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t;
3538

3639
$definitions; separator="\n"$
37-
3840
$if(ctx.thereIsStructOrUnion || ctx.thereIsInterface)$
3941
// Include auxiliary functions like for serializing/deserializing.
4042
#include "$ctx.filename$CdrAux.ipp"
@@ -44,7 +46,7 @@ $endif$
4446

4547
module(ctx, parent, module, definition_list) ::= <<
4648
namespace $module.name$ {
47-
$definition_list$
49+
$definition_list$
4850
} // namespace $module.name$
4951

5052
>>
@@ -58,26 +60,32 @@ $struct.name$PubSubType::$struct.name$PubSubType()
5860
uint32_t type_size = $struct.cScopedname$_max_cdr_typesize;
5961
type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */
6062
max_serialized_type_size = type_size + 4; /*encapsulation*/
61-
is_compute_key_provided = $if(struct.hasKey)$true$else$false$endif$;
62-
uint32_t key_length = $struct.cScopedname$_max_key_cdr_typesize > 16 ? $struct.cScopedname$_max_key_cdr_typesize : 16;
63-
key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length));
64-
memset(key_buffer_, 0, key_length);
63+
$if(struct.hasKey)$
64+
is_compute_key_provided = true;
65+
key_buffer_ = nullptr;
66+
get_key_buffer_nts();
67+
$else$
68+
is_compute_key_provided = false;
69+
$endif$
6570
}
6671

6772
$struct.name$PubSubType::~$struct.name$PubSubType()
6873
{
74+
$if(struct.hasKey)$
6975
if (key_buffer_ != nullptr)
7076
{
7177
free(key_buffer_);
7278
}
79+
$endif$
7380
}
7481

7582
bool $struct.name$PubSubType::serialize(
7683
const void* const data,
7784
SerializedPayload_t& payload,
7885
DataRepresentationId_t data_representation)
7986
{
80-
const ::$struct.scopedname$* p_type = static_cast<const ::$struct.scopedname$*>(data);
87+
const ::$struct.scopedname$* p_type =
88+
static_cast<const ::$struct.scopedname$*>(data);
8189

8290
// Object that manages the raw buffer.
8391
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.max_size);
@@ -97,7 +105,7 @@ bool $struct.name$PubSubType::serialize(
97105
ser.serialize_encapsulation();
98106
// Serialize the object.
99107
ser << *p_type;
100-
ser.set_dds_cdr_options({0,0});
108+
ser.set_dds_cdr_options({0, 0});
101109
}
102110
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
103111
{
@@ -116,7 +124,8 @@ bool $struct.name$PubSubType::deserialize(
116124
try
117125
{
118126
// Convert DATA to pointer of your type
119-
::$struct.scopedname$* p_type = static_cast<::$struct.scopedname$*>(data);
127+
::$struct.scopedname$* p_type =
128+
static_cast<::$struct.scopedname$*>(data);
120129

121130
// Object that manages the raw buffer.
122131
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length);
@@ -149,9 +158,10 @@ uint32_t $struct.name$PubSubType::calculate_serialized_size(
149158
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
150159
eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2);
151160
size_t current_alignment {0};
152-
return static_cast<uint32_t>(calculator.calculate_serialized_size(
153-
*static_cast<const ::$struct.scopedname$*>(data), current_alignment)) +
154-
4u /*encapsulation*/;
161+
const ::$struct.scopedname$* p_type =
162+
static_cast<const ::$struct.scopedname$*>(data);
163+
auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment);
164+
return static_cast<uint32_t>(calc_size) + 4u /*encapsulation*/;
155165
}
156166
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
157167
{
@@ -175,16 +185,17 @@ bool $struct.name$PubSubType::compute_key(
175185
InstanceHandle_t& handle,
176186
bool force_md5)
177187
{
178-
if (!is_compute_key_provided)
179-
{
180-
return false;
181-
}
182-
188+
$if(struct.hasKey)$
183189
::$struct.scopedname$ data;
184190
if (deserialize(payload, static_cast<void*>(&data)))
185191
{
186192
return compute_key(static_cast<void*>(&data), handle, force_md5);
187193
}
194+
$else$
195+
static_cast<void>(payload);
196+
static_cast<void>(handle);
197+
static_cast<void>(force_md5);
198+
$endif$
188199

189200
return false;
190201
}
@@ -194,48 +205,80 @@ bool $struct.name$PubSubType::compute_key(
194205
InstanceHandle_t& handle,
195206
bool force_md5)
196207
{
197-
if (!is_compute_key_provided)
208+
$if(struct.hasKey)$
209+
std::lock_guard<std::mutex> guard(compute_key_mtx_);
210+
const ::$struct.scopedname$* p_type =
211+
static_cast<const ::$struct.scopedname$*>(data);
212+
213+
// Ensure the key buffer is reserved
214+
unsigned char* key_buffer = get_key_buffer_nts();
215+
if (key_buffer == nullptr)
198216
{
199217
return false;
200218
}
201219

202-
const ::$struct.scopedname$* p_type = static_cast<const ::$struct.scopedname$*>(data);
203-
204220
// Object that manages the raw buffer.
205-
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_),
221+
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer),
206222
$struct.cScopedname$_max_key_cdr_typesize);
207223

208224
// Object that serializes the data.
209-
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2);
225+
eprosima::fastcdr::Cdr ser(
226+
fastbuffer,
227+
eprosima::fastcdr::Cdr::BIG_ENDIANNESS,
228+
eprosima::fastcdr::CdrVersion::XCDRv2);
210229
ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2);
211230
eprosima::fastcdr::serialize_key(ser, *p_type);
212231
if (force_md5 || $struct.cScopedname$_max_key_cdr_typesize > 16)
213232
{
214-
md5_.init();
215-
md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length()));
216-
md5_.finalize();
233+
eprosima::fastdds::MD5 md5;
234+
md5.init();
235+
md5.update(key_buffer, static_cast<unsigned int>(ser.get_serialized_data_length()));
236+
md5.finalize();
217237
for (uint8_t i = 0; i < 16; ++i)
218238
{
219-
handle.value[i] = md5_.digest[i];
239+
handle.value[i] = md5.digest[i];
220240
}
221241
}
222242
else
223243
{
224244
for (uint8_t i = 0; i < 16; ++i)
225245
{
226-
handle.value[i] = key_buffer_[i];
246+
handle.value[i] = key_buffer[i];
227247
}
228248
}
229249
return true;
250+
$else$
251+
static_cast<void>(data);
252+
static_cast<void>(handle);
253+
static_cast<void>(force_md5);
254+
255+
return false;
256+
$endif$
230257
}
231258

259+
$if(struct.hasKey)$
260+
unsigned char* $struct.name$PubSubType::get_key_buffer_nts()
261+
{
262+
// If already reserved, return
263+
if (key_buffer_ != nullptr)
264+
{
265+
return key_buffer_;
266+
}
267+
268+
// Allocate the key buffer
269+
uint32_t key_length = (std::max)($struct.cScopedname$_max_key_cdr_typesize, 16u);
270+
key_buffer_ = reinterpret_cast<unsigned char*>(calloc(key_length, 1u));
271+
return key_buffer_;
272+
}
273+
$endif$
274+
232275
void $struct.name$PubSubType::register_type_object_representation()
233276
{
234277
$if (ctx.generateTypeObjectSupport)$
235278
register_$struct.name$_type_identifier(type_identifiers_);
236279
$else$
237280
EPROSIMA_LOG_WARNING(XTYPES_TYPE_REPRESENTATION,
238-
"TypeObject type representation support disabled in generated code");
281+
"TypeObject type representation support disabled in generated code");
239282
$endif$
240283
}
241284
$endif$
@@ -310,7 +353,7 @@ public:
310353
ser.serialize_encapsulation();
311354
// Serialize the object.
312355
ser << *p_type;
313-
ser.set_dds_cdr_options({0,0});
356+
ser.set_dds_cdr_options({0, 0});
314357
}
315358
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
316359
{
@@ -362,9 +405,9 @@ public:
362405
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
363406
eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2);
364407
size_t current_alignment {0};
365-
return static_cast<uint32_t>(calculator.calculate_serialized_size(
366-
*static_cast<const type*>(data), current_alignment)) +
367-
4u /*encapsulation*/;
408+
const type* p_type = static_cast<const type*>(data);
409+
auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment);
410+
return static_cast<uint32_t>(calc_size) + 4u /*encapsulation*/;
368411
}
369412
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
370413
{
@@ -412,7 +455,7 @@ $if (ctx.generateTypeObjectSupport)$
412455
register_$interface.name$_$suffix$_type_identifier(type_identifiers_);
413456
$else$
414457
EPROSIMA_LOG_WARNING(XTYPES_TYPE_REPRESENTATION,
415-
"TypeObject type representation support disabled in generated code");
458+
"TypeObject type representation support disabled in generated code");
416459
$endif$
417460
}
418461

src/main/java/com/eprosima/fastdds/idl/templates/InterfaceDetails.stg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ bitset_type(ctx, parent, bitset) ::= <<>>
4343

4444
module(ctx, parent, module, definition_list) ::= <<
4545
namespace $module.name$ {
46-
$definition_list$
46+
$definition_list$
4747
} // namespace $module.name$
4848
>>
4949

src/main/java/com/eprosima/fastdds/idl/templates/SerializationHeader.stg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,6 @@ $endif$
101101

102102
module(ctx, parent, module, definition_list) ::= <<
103103
namespace $module.name$ {
104-
$definition_list$
104+
$definition_list$
105105
} // namespace $module.name$
106106
>>

src/main/java/com/eprosima/fastdds/idl/templates/XTypesTypeObjectHeader.stg

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ $definitions; separator="\n"$
6060
annotation(ctx, annotation) ::= <<
6161

6262
namespace $annotation.name$ {
63-
$annotation.enums : { enum | $enum_type(ctx=ctx, parent=annotation, enum=enum)$}; separator="\n"$
6463

65-
$annotation.typeDefs : { typedef | $typedef_decl(ctx=ctx, parent=annotation, typedefs=typedef, typedefs_type="", declarator_type="")$}; separator="\n"$
64+
$annotation.enums : { enum | $enum_type(ctx=ctx, parent=annotation, enum=enum)$}; separator="\n"$
6665

67-
$annotation.constDecls : { const | $const_decl(ctx=ctx, parent=annotation, const=const, const_type="")$}; separator="\n"$
66+
$annotation.typeDefs : { typedef | $typedef_decl(ctx=ctx, parent=annotation, typedefs=typedef, typedefs_type="", declarator_type="")$}; separator="\n"$
67+
68+
$annotation.constDecls : { const | $const_decl(ctx=ctx, parent=annotation, const=const, const_type="")$}; separator="\n"$
6869

6970
} // namespace $annotation.name$
7071

src/main/java/com/eprosima/fastdds/idl/templates/XTypesTypeObjectSource.stg

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ $definitions; separator=""$
6060
annotation(ctx, annotation) ::= <<
6161

6262
namespace $annotation.name$ {
63-
$annotation.enums : { enum | $enum_type(ctx=ctx, parent=annotation, enum=enum)$}; separator="\n"$
6463

65-
$annotation.typeDefs : { typedef | $typedef_decl(ctx=ctx, parent=annotation, typedefs=typedef, typedefs_type="", declarator_type="")$}; separator="\n"$
64+
$annotation.enums : { enum | $enum_type(ctx=ctx, parent=annotation, enum=enum)$}; separator="\n"$
6665

67-
$annotation.constDecls : { const | $const_decl(ctx=ctx, parent=annotation, const=const, const_type="")$}; separator="\n"$
66+
$annotation.typeDefs : { typedef | $typedef_decl(ctx=ctx, parent=annotation, typedefs=typedef, typedefs_type="", declarator_type="")$}; separator="\n"$
67+
68+
$annotation.constDecls : { const | $const_decl(ctx=ctx, parent=annotation, const=const, const_type="")$}; separator="\n"$
6869

6970
} // namespace $annotation.name$
7071

0 commit comments

Comments
 (0)