You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2018/12/19 17:36:46 UTC
[qpid-dispatch] 01/02: DISPATCH-1214 - Ensure that the delivery
pointer isn't dereferenced after it is dec-ref'ed in case the dec-ref
results in the freeing of the delivery.
This is an automated email from the ASF dual-hosted git repository.
tross pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
commit f1d7cf419a468967ccddef986ca9fba0ec92259a
Author: Ted Ross <tr...@redhat.com>
AuthorDate: Wed Dec 19 12:34:21 2018 -0500
DISPATCH-1214 - Ensure that the delivery pointer isn't dereferenced after it is dec-ref'ed in case the dec-ref results in the freeing of the delivery.
---
src/router_core/transfer.c | 95 +++++++++++++++++++++++-----------------------
1 file changed, 48 insertions(+), 47 deletions(-)
diff --git a/src/router_core/transfer.c b/src/router_core/transfer.c
index 49c1442..f1d7203 100644
--- a/src/router_core/transfer.c
+++ b/src/router_core/transfer.c
@@ -1249,66 +1249,67 @@ static void qdr_deliver_continue_CT(qdr_core_t *core, qdr_action_t *action, bool
qdr_delivery_t *in_dlv = action->args.connection.delivery;
bool more = action->args.connection.more;
- // This decref is for the action reference
- qdr_delivery_decref_CT(core, in_dlv, "qdr_deliver_continue_CT - remove from action");
-
//
// If it is already in the undelivered list, don't try to deliver this again.
//
- if (in_dlv->where == QDR_DELIVERY_IN_UNDELIVERED)
- return;
+ if (in_dlv->where != QDR_DELIVERY_IN_UNDELIVERED) {
+ qdr_deliver_continue_peers_CT(core, in_dlv);
- qdr_deliver_continue_peers_CT(core, in_dlv);
+ qd_message_t *msg = qdr_delivery_message(in_dlv);
- qd_message_t *msg = qdr_delivery_message(in_dlv);
+ if (!more && !qd_message_is_discard(msg)) {
+ //
+ // The entire message has now been received. Check to see if there are in process subscriptions that need to
+ // receive this message. in process subscriptions, at this time, can deal only with full messages.
+ //
+ qdr_subscription_t *sub = DEQ_HEAD(in_dlv->subscriptions);
+ while (sub) {
+ DEQ_REMOVE_HEAD(in_dlv->subscriptions);
+ qdr_forward_on_message_CT(core, sub, in_dlv->link, in_dlv->msg);
+ sub = DEQ_HEAD(in_dlv->subscriptions);
+ }
- if (!more && !qd_message_is_discard(msg)) {
- //
- // The entire message has now been received. Check to see if there are in process subscriptions that need to
- // receive this message. in process subscriptions, at this time, can deal only with full messages.
- //
- qdr_subscription_t *sub = DEQ_HEAD(in_dlv->subscriptions);
- while (sub) {
- DEQ_REMOVE_HEAD(in_dlv->subscriptions);
- qdr_forward_on_message_CT(core, sub, in_dlv->link, in_dlv->msg);
- sub = DEQ_HEAD(in_dlv->subscriptions);
- }
+ // This is a multicast delivery or if this is a presettled multi-frame unicast delivery.
+ if (in_dlv->multicast || in_dlv->settled) {
- // This is a multicast delivery or if this is a presettled multi-frame unicast delivery.
- if (in_dlv->multicast || in_dlv->settled) {
+ //
+ // If a delivery is settled but did not go into one of the lists, that means that it is going nowhere.
+ // We dont want to deal with such deliveries.
+ //
+ if (in_dlv->settled && in_dlv->where == QDR_DELIVERY_NOWHERE) {
+ qdr_delivery_decref_CT(core, in_dlv, "qdr_deliver_continue_CT - remove from action 1");
+ return;
+ }
- //
- // If a delivery is settled but did not go into one of the lists, that means that it is going nowhere.
- // We dont want to deal with such deliveries.
- //
- if (in_dlv->settled && in_dlv->where == QDR_DELIVERY_NOWHERE)
- return;
+ assert(in_dlv->where == QDR_DELIVERY_IN_SETTLED);
+ //
+ // The router will settle on behalf of the receiver in the case of multicast and send out settled
+ // deliveries to the receivers.
+ //
+ in_dlv->disposition = PN_ACCEPTED;
+ qdr_delivery_push_CT(core, in_dlv);
- assert(in_dlv->where == QDR_DELIVERY_IN_SETTLED);
- //
- // The router will settle on behalf of the receiver in the case of multicast and send out settled
- // deliveries to the receivers.
- //
- in_dlv->disposition = PN_ACCEPTED;
- qdr_delivery_push_CT(core, in_dlv);
+ //
+ // The in_dlv has one or more peers. These peers will have to be unlinked.
+ //
+ qdr_delivery_t *peer = qdr_delivery_first_peer_CT(in_dlv);
+ qdr_delivery_t *next_peer = 0;
+ while (peer) {
+ next_peer = qdr_delivery_next_peer_CT(in_dlv);
+ qdr_delivery_unlink_peers_CT(core, in_dlv, peer);
+ peer = next_peer;
+ }
- //
- // The in_dlv has one or more peers. These peers will have to be unlinked.
- //
- qdr_delivery_t *peer = qdr_delivery_first_peer_CT(in_dlv);
- qdr_delivery_t *next_peer = 0;
- while (peer) {
- next_peer = qdr_delivery_next_peer_CT(in_dlv);
- qdr_delivery_unlink_peers_CT(core, in_dlv, peer);
- peer = next_peer;
+ // Remove the delivery from the settled list and decref the in_dlv.
+ in_dlv->where = QDR_DELIVERY_NOWHERE;
+ DEQ_REMOVE(in_dlv->link->settled, in_dlv);
+ qdr_delivery_decref_CT(core, in_dlv, "qdr_deliver_continue_CT - remove from settled list");
}
-
- // Remove the delivery from the settled list and decref the in_dlv.
- in_dlv->where = QDR_DELIVERY_NOWHERE;
- DEQ_REMOVE(in_dlv->link->settled, in_dlv);
- qdr_delivery_decref_CT(core, in_dlv, "qdr_deliver_continue_CT - remove from settled list");
}
}
+
+ // This decref is for the action reference
+ qdr_delivery_decref_CT(core, in_dlv, "qdr_deliver_continue_CT - remove from action 2");
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org