Repository: qpid-dispatch Updated Branches: refs/heads/master 3b73b03c0 -> 3eae0e137
DISPATCH-553 - Resolve the issue of concurrent access to the message-annotations when fanout is greater than one. Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/bbcfea04 Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/bbcfea04 Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/bbcfea04 Branch: refs/heads/master Commit: bbcfea048643fd382e39f1fb8920ee12d69d2fb0 Parents: 3b73b03 Author: Ted Ross <[email protected]> Authored: Thu Nov 3 10:41:07 2016 -0400 Committer: Ted Ross <[email protected]> Committed: Thu Nov 3 10:41:07 2016 -0400 ---------------------------------------------------------------------- include/qpid/dispatch/ctools.h | 1 + include/qpid/dispatch/parse.h | 8 +++++++ src/message.c | 9 ++++---- src/parse.c | 43 +++++++++++++++++++++++++++++++------ 4 files changed, 51 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/bbcfea04/include/qpid/dispatch/ctools.h ---------------------------------------------------------------------- diff --git a/include/qpid/dispatch/ctools.h b/include/qpid/dispatch/ctools.h index 863033b..1b5d0d3 100644 --- a/include/qpid/dispatch/ctools.h +++ b/include/qpid/dispatch/ctools.h @@ -25,6 +25,7 @@ #include <stdlib.h> #include <assert.h> +#include <memory.h> #define CT_ASSERT(exp) { assert(exp); } http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/bbcfea04/include/qpid/dispatch/parse.h ---------------------------------------------------------------------- diff --git a/include/qpid/dispatch/parse.h b/include/qpid/dispatch/parse.h index d38a5fa..d4fdf42 100644 --- a/include/qpid/dispatch/parse.h +++ b/include/qpid/dispatch/parse.h @@ -50,6 +50,14 @@ qd_parsed_field_t *qd_parse(qd_field_iterator_t *iter); void qd_parse_free(qd_parsed_field_t *field); /** + * Create a duplicate parsed field, referring to the same base data. + * + * @param field A field pointer returned by qd_parse. + * @return A separate field that is a duplicate of the supplied field. + */ +qd_parsed_field_t *qd_parse_dup(const qd_parsed_field_t *field); + +/** * Check to see if the field parse was successful (i.e. the field was * well-formed). * http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/bbcfea04/src/message.c ---------------------------------------------------------------------- diff --git a/src/message.c b/src/message.c index 33f0ea9..03586ee 100644 --- a/src/message.c +++ b/src/message.c @@ -559,8 +559,8 @@ qd_message_t *qd_message() return 0; } - memset(msg->content, 0, sizeof(qd_message_content_t)); - msg->content->lock = sys_mutex(); + ZERO(msg->content); + msg->content->lock = sys_mutex(); sys_atomic_init(&msg->content->ref_count, 1); msg->content->parse_depth = QD_DEPTH_NONE; msg->content->parsed_message_annotations = 0; @@ -796,8 +796,7 @@ static void compose_message_annotations(qd_message_pvt_t *msg, qd_buffer_list_t bool map_started = false; //We will have to add the custom annotations - qd_parsed_field_t *in_ma = msg->content->parsed_message_annotations; - + qd_parsed_field_t *in_ma = qd_parse_dup(msg->content->parsed_message_annotations); if (in_ma) { uint32_t count = qd_parse_sub_count(in_ma); @@ -818,6 +817,8 @@ static void compose_message_annotations(qd_message_pvt_t *msg, qd_buffer_list_t qd_compose_insert_typed_iterator(out_ma, qd_parse_typed(sub_value)); } } + + qd_parse_free(in_ma); } //Add the dispatch router specific annotations only if strip_annotations is false. http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/bbcfea04/src/parse.c ---------------------------------------------------------------------- diff --git a/src/parse.c b/src/parse.c index 091c32e..d185d52 100644 --- a/src/parse.c +++ b/src/parse.c @@ -26,12 +26,12 @@ DEQ_DECLARE(qd_parsed_field_t, qd_parsed_field_list_t); struct qd_parsed_field_t { DEQ_LINKS(qd_parsed_field_t); - qd_parsed_field_t *parent; - qd_parsed_field_list_t children; - uint8_t tag; - qd_field_iterator_t *raw_iter; - qd_field_iterator_t *typed_iter; - const char *parse_error; + const qd_parsed_field_t *parent; + qd_parsed_field_list_t children; + uint8_t tag; + qd_field_iterator_t *raw_iter; + qd_field_iterator_t *typed_iter; + const char *parse_error; }; ALLOC_DECLARE(qd_parsed_field_t); @@ -194,6 +194,37 @@ void qd_parse_free(qd_parsed_field_t *field) } +static qd_parsed_field_t *qd_parse_dup_internal(const qd_parsed_field_t *field, const qd_parsed_field_t *parent) +{ + qd_parsed_field_t *dup = new_qd_parsed_field_t(); + + if (dup == 0) + return 0; + + ZERO(dup); + dup->parent = parent; + dup->tag = field->tag; + dup->raw_iter = qd_field_iterator_dup(field->raw_iter); + dup->typed_iter = qd_field_iterator_dup(field->typed_iter); + dup->parse_error = field->parse_error; + + qd_parsed_field_t *child = DEQ_HEAD(field->children); + while (child) { + qd_parsed_field_t *dup_child = qd_parse_dup_internal(child, field); + DEQ_INSERT_TAIL(dup->children, dup_child); + child = DEQ_NEXT(child); + } + + return dup; +} + + +qd_parsed_field_t *qd_parse_dup(const qd_parsed_field_t *field) +{ + return field ? qd_parse_dup_internal(field, 0) : 0; +} + + int qd_parse_ok(qd_parsed_field_t *field) { return field->parse_error == 0; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
