Skip to content

Commit 2f6fe8c

Browse files
committed
fixup: block core activation until after raw conn is active
1 parent af70e0a commit 2f6fe8c

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

src/adaptors/tcp_lite/tcp_lite.c

+35-23
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,9 @@ static void free_connection_IO(void *context)
445445
tcplite_connection_t *conn = (tcplite_connection_t*) context;
446446
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%"PRIu64"] Cleaning up resources", conn->conn_id);
447447

448-
// disable activation via Core thread
448+
// Disable activation via Core thread. The lock needs to be taken to ensure the core thread is not currently
449+
// attempting to activate the connection: after the mutex is unlocked we're guaranteed no further activations can
450+
// take place.
449451
sys_mutex_lock(&conn->activation_lock);
450452
CLEAR_ATOMIC_FLAG(&conn->raw_opened);
451453
sys_mutex_unlock(&conn->activation_lock);
@@ -1208,9 +1210,7 @@ static uint64_t handle_first_outbound_delivery_CSIDE(tcplite_connector_t *cr, qd
12081210
// The raw connection establishment must be the last thing done in this function.
12091211
// After this call, a separate IO thread may immediately be invoked in the context
12101212
// of the new connection to handle raw connection events.
1211-
// ISSUE-1202 - Set the conn->raw_opened flag before calling pn_proactor_raw_connect()
12121213
//
1213-
SET_ATOMIC_FLAG(&conn->raw_opened);
12141214
pn_proactor_raw_connect(tcplite_context->proactor, conn->raw_conn, cr->adaptor_config->host_port);
12151215

12161216
return QD_DELIVERY_MOVED_TO_NEW_LINK;
@@ -1586,14 +1586,15 @@ static void connection_run_LSIDE_IO(tcplite_connection_t *conn)
15861586

15871587
switch (conn->state) {
15881588
case LSIDE_INITIAL:
1589-
// raw connection is active
1590-
if (conn->tls) {
1591-
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%"PRIu64"] LSIDE_IO performing TLS handshake", conn->conn_id);
1592-
set_state_XSIDE_IO(conn, LSIDE_TLS_HANDSHAKE);
1593-
repeat = true;
1594-
} else {
1595-
link_setup_LSIDE_IO(conn);
1596-
set_state_XSIDE_IO(conn, LSIDE_LINK_SETUP);
1589+
if (IS_ATOMIC_FLAG_SET(&conn->raw_opened)) { // raw connection is active
1590+
if (conn->tls) {
1591+
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%"PRIu64"] LSIDE_IO performing TLS handshake", conn->conn_id);
1592+
set_state_XSIDE_IO(conn, LSIDE_TLS_HANDSHAKE);
1593+
repeat = true;
1594+
} else {
1595+
link_setup_LSIDE_IO(conn);
1596+
set_state_XSIDE_IO(conn, LSIDE_LINK_SETUP);
1597+
}
15971598
}
15981599
break;
15991600

@@ -1685,9 +1686,10 @@ static void connection_run_CSIDE_IO(tcplite_connection_t *conn)
16851686

16861687
switch (conn->state) {
16871688
case CSIDE_INITIAL:
1688-
// raw connection is active
1689-
link_setup_CSIDE_IO(conn, conn->outbound_delivery);
1690-
set_state_XSIDE_IO(conn, CSIDE_LINK_SETUP);
1689+
if (IS_ATOMIC_FLAG_SET(&conn->raw_opened)) { // raw connection is active
1690+
link_setup_CSIDE_IO(conn, conn->outbound_delivery);
1691+
set_state_XSIDE_IO(conn, CSIDE_LINK_SETUP);
1692+
}
16911693
break;
16921694

16931695
case CSIDE_LINK_SETUP:
@@ -1835,10 +1837,15 @@ static char *get_tls_negotiated_alpn(qd_message_t *msg)
18351837
static void on_connection_event_LSIDE_IO(pn_event_t *e, qd_server_t *qd_server, void *context)
18361838
{
18371839
SET_THREAD_RAW_IO;
1838-
tcplite_connection_t *conn = (tcplite_connection_t*) context;
1839-
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%"PRIu64"] on_connection_event_LSIDE_IO: %s", conn->conn_id, pn_event_type_name(pn_event_type(e)));
1840-
1841-
if (pn_event_type(e) == PN_RAW_CONNECTION_DISCONNECTED) {
1840+
pn_event_type_t etype = pn_event_type(e);
1841+
tcplite_connection_t *conn = (tcplite_connection_t*) context;
1842+
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%"PRIu64"] on_connection_event_LSIDE_IO: %s", conn->conn_id, pn_event_type_name(etype));
1843+
1844+
if (etype == PN_RAW_CONNECTION_CONNECTED) {
1845+
// it is safe to call pn_raw_connection_wake() now
1846+
assert(!IS_ATOMIC_FLAG_SET(&conn->raw_opened));
1847+
SET_ATOMIC_FLAG(&conn->raw_opened);
1848+
} else if (etype == PN_RAW_CONNECTION_DISCONNECTED) {
18421849
conn->error = !!conn->raw_conn ? pn_raw_connection_condition(conn->raw_conn) : 0;
18431850

18441851
if (!!conn->error) {
@@ -1867,10 +1874,15 @@ static void on_connection_event_LSIDE_IO(pn_event_t *e, qd_server_t *qd_server,
18671874
static void on_connection_event_CSIDE_IO(pn_event_t *e, qd_server_t *qd_server, void *context)
18681875
{
18691876
SET_THREAD_RAW_IO;
1870-
tcplite_connection_t *conn = (tcplite_connection_t*) context;
1871-
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%"PRIu64"] on_connection_event_CSIDE_IO: %s", conn->conn_id, pn_event_type_name(pn_event_type(e)));
1872-
1873-
if (pn_event_type(e) == PN_RAW_CONNECTION_DISCONNECTED) {
1877+
pn_event_type_t etype = pn_event_type(e);
1878+
tcplite_connection_t *conn = (tcplite_connection_t*) context;
1879+
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%"PRIu64"] on_connection_event_CSIDE_IO: %s", conn->conn_id, pn_event_type_name(etype));
1880+
1881+
if (etype == PN_RAW_CONNECTION_CONNECTED) {
1882+
// it is safe to call pn_raw_connection_wake() now
1883+
assert(!IS_ATOMIC_FLAG_SET(&conn->raw_opened));
1884+
SET_ATOMIC_FLAG(&conn->raw_opened);
1885+
} else if (etype == PN_RAW_CONNECTION_DISCONNECTED) {
18741886
conn->error = !!conn->raw_conn ? pn_raw_connection_condition(conn->raw_conn) : 0;
18751887

18761888
if (!!conn->error) {
@@ -1931,7 +1943,7 @@ static void on_accept(qd_adaptor_listener_t *listener, pn_listener_t *pn_listene
19311943

19321944
sys_mutex_init(&conn->activation_lock);
19331945
sys_atomic_init(&conn->core_activation, 0);
1934-
sys_atomic_init(&conn->raw_opened, 1);
1946+
sys_atomic_init(&conn->raw_opened, 0);
19351947

19361948
conn->listener_side = true;
19371949
conn->state = LSIDE_INITIAL;

0 commit comments

Comments
 (0)