Skip to content

Commit 7f1fa3c

Browse files
committed
session BUGFIX use atomics instead of volatile
For notification thread TID. Refs #253
1 parent 308ec81 commit 7f1fa3c

6 files changed

Lines changed: 31 additions & 23 deletions

File tree

src/config.h.in

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,16 @@
3636
# include <stdatomic.h>
3737

3838
# define ATOMIC_UINT32_T atomic_uint_fast32_t
39-
# define ATOMIC_INC(x) atomic_fetch_add(x, 1)
39+
# define ATOMIC_PTR atomic_uintptr_t
40+
# define ATOMIC_STORE(x, val) atomic_store(&(x), (atomic_uintptr_t)(val))
41+
# define ATOMIC_LOAD(x) ((void *)atomic_load(&(x)))
42+
# define ATOMIC_INC(x) atomic_fetch_add(&(x), 1)
4043
#else
4144
# define ATOMIC_UINT32_T uint32_t
42-
# define ATOMIC_INC(x) __sync_add_and_fetch(x, 1)
45+
# define ATOMIC_PTR void *
46+
# define ATOMIC_STORE(x, val) (x) = (void *)(val)
47+
# define ATOMIC_LOAD(x) ((void *)(x))
48+
# define ATOMIC_INC(x) __sync_add_and_fetch(&(x), 1)
4349
#endif
4450

4551
/*

src/session.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,8 @@ nc_session_free(struct nc_session *session, void (*data_free)(void *))
614614
}
615615

616616
/* stop notifications loop if any */
617-
if ((session->side == NC_CLIENT) && session->opts.client.ntf_tid) {
618-
session->opts.client.ntf_tid = NULL;
617+
if ((session->side == NC_CLIENT) && ATOMIC_LOAD(session->opts.client.ntf_tid)) {
618+
ATOMIC_STORE(session->opts.client.ntf_tid, NULL);
619619
/* the thread now knows it should quit */
620620
}
621621

src/session_client.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ get_msg(struct nc_session *session, int timeout, uint64_t msgid, struct lyxml_el
14931493

14941494
/* we read notif, want a rpc-reply */
14951495
if (msgid && (msgtype == NC_MSG_NOTIF)) {
1496-
if (!session->opts.client.ntf_tid) {
1496+
if (!ATOMIC_LOAD(session->opts.client.ntf_tid)) {
14971497
ERR("Session %u: received a <notification> but session is not subscribed.", session->id);
14981498
lyxml_free(session->ctx, xml);
14991499
return NC_MSG_ERROR;
@@ -2059,7 +2059,7 @@ nc_session_ntf_thread_running(const struct nc_session *session)
20592059
return 0;
20602060
}
20612061

2062-
return session->opts.client.ntf_tid ? 1 : 0;
2062+
return ATOMIC_LOAD(session->opts.client.ntf_tid) ? 1 : 0;
20632063
}
20642064

20652065
API void
@@ -2214,9 +2214,9 @@ nc_recv_notif_thread(void *arg)
22142214
free(ntarg);
22152215

22162216
/* remember our allocated tid, we will be freeing it */
2217-
ntf_tid = (pthread_t *)session->opts.client.ntf_tid;
2217+
ntf_tid = ATOMIC_LOAD(session->opts.client.ntf_tid);
22182218

2219-
while (session->opts.client.ntf_tid) {
2219+
while (ATOMIC_LOAD(session->opts.client.ntf_tid)) {
22202220
msgtype = nc_recv_notif(session, NC_CLIENT_NOTIF_THREAD_SLEEP / 1000, &notif);
22212221
if (msgtype == NC_MSG_NOTIF) {
22222222
notif_clb(session, notif);
@@ -2235,7 +2235,7 @@ nc_recv_notif_thread(void *arg)
22352235
}
22362236

22372237
VRB("Session %u: notification thread exit.", session->id);
2238-
session->opts.client.ntf_tid = NULL;
2238+
ATOMIC_STORE(session->opts.client.ntf_tid, NULL);
22392239
free(ntf_tid);
22402240
return NULL;
22412241
}
@@ -2244,6 +2244,7 @@ API int
22442244
nc_recv_notif_dispatch(struct nc_session *session, void (*notif_clb)(struct nc_session *session, const struct nc_notif *notif))
22452245
{
22462246
struct nc_ntf_thread_arg *ntarg;
2247+
pthread_t *tid;
22472248
int ret;
22482249

22492250
if (!session) {
@@ -2255,7 +2256,7 @@ nc_recv_notif_dispatch(struct nc_session *session, void (*notif_clb)(struct nc_s
22552256
} else if ((session->status != NC_STATUS_RUNNING) || (session->side != NC_CLIENT)) {
22562257
ERR("Session %u: invalid session to receive Notifications.", session->id);
22572258
return -1;
2258-
} else if (session->opts.client.ntf_tid) {
2259+
} else if (ATOMIC_LOAD(session->opts.client.ntf_tid)) {
22592260
ERR("Session %u: separate notification thread is already running.", session->id);
22602261
return -1;
22612262
}
@@ -2268,20 +2269,21 @@ nc_recv_notif_dispatch(struct nc_session *session, void (*notif_clb)(struct nc_s
22682269
ntarg->session = session;
22692270
ntarg->notif_clb = notif_clb;
22702271

2271-
/* just so that nc_recv_notif_thread() does not immediately exit, the value does not matter */
2272-
session->opts.client.ntf_tid = malloc(sizeof *session->opts.client.ntf_tid);
2273-
if (!session->opts.client.ntf_tid) {
2272+
tid = malloc(sizeof *tid);
2273+
if (!tid) {
22742274
ERRMEM;
22752275
free(ntarg);
22762276
return -1;
22772277
}
2278+
/* just so that nc_recv_notif_thread() does not immediately exit, the value does not matter */
2279+
ATOMIC_STORE(session->opts.client.ntf_tid, tid);
22782280

2279-
ret = pthread_create((pthread_t *)session->opts.client.ntf_tid, NULL, nc_recv_notif_thread, ntarg);
2281+
ret = pthread_create(tid, NULL, nc_recv_notif_thread, ntarg);
22802282
if (ret) {
22812283
ERR("Session %u: failed to create a new thread (%s).", strerror(errno));
22822284
free(ntarg);
2283-
free((pthread_t *)session->opts.client.ntf_tid);
2284-
session->opts.client.ntf_tid = NULL;
2285+
free(tid);
2286+
ATOMIC_STORE(session->opts.client.ntf_tid, NULL);
22852287
return -1;
22862288
}
22872289

src/session_p.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ struct nc_session {
426426
char **cpblts; /**< list of server's capabilities on client side */
427427
struct nc_msg_cont *replies; /**< queue for RPC replies received instead of notifications */
428428
struct nc_msg_cont *notifs; /**< queue for notifications received instead of RPC reply */
429-
volatile pthread_t *ntf_tid; /**< running notifications receiving thread */
429+
ATOMIC_PTR ntf_tid; /**< running notifications receiving thread */
430430

431431
/* client flags */
432432
/* some server modules failed to load so the data from them will be ignored - not use strict flag for parsing */

src/session_server.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ nc_accept_inout(int fdin, int fdout, const char *username, struct nc_session **s
773773
(*session)->ctx = server_opts.ctx;
774774

775775
/* assign new SID atomically */
776-
(*session)->id = ATOMIC_INC(&server_opts.new_session_id);
776+
(*session)->id = ATOMIC_INC(server_opts.new_session_id);
777777

778778
/* NETCONF handshake */
779779
msgtype = nc_handshake_io(*session);
@@ -2349,7 +2349,7 @@ nc_accept(int timeout, struct nc_session **session)
23492349
pthread_rwlock_unlock(&server_opts.endpt_lock);
23502350

23512351
/* assign new SID atomically */
2352-
(*session)->id = ATOMIC_INC(&server_opts.new_session_id);
2352+
(*session)->id = ATOMIC_INC(server_opts.new_session_id);
23532353

23542354
/* NETCONF handshake */
23552355
msgtype = nc_handshake_io(*session);
@@ -2497,7 +2497,7 @@ nc_server_ch_add_client(const char *name)
24972497
client = &server_opts.ch_clients[server_opts.ch_client_count - 1];
24982498

24992499
client->name = lydict_insert(server_opts.ctx, name, 0);
2500-
client->id = ATOMIC_INC(&server_opts.new_client_id);
2500+
client->id = ATOMIC_INC(server_opts.new_client_id);
25012501
client->ch_endpts = NULL;
25022502
client->ch_endpt_count = 0;
25032503
client->conn_type = 0;
@@ -3134,7 +3134,7 @@ nc_connect_ch_endpt(struct nc_ch_endpt *endpt, struct nc_session **session)
31343134
}
31353135

31363136
/* assign new SID atomically */
3137-
(*session)->id = ATOMIC_INC(&server_opts.new_session_id);
3137+
(*session)->id = ATOMIC_INC(server_opts.new_session_id);
31383138

31393139
/* NETCONF handshake */
31403140
msgtype = nc_handshake_io(*session);

src/session_server_ssh.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,7 @@ nc_session_accept_ssh_channel(struct nc_session *orig_session, struct nc_session
15011501
}
15021502

15031503
/* assign new SID atomically */
1504-
new_session->id = ATOMIC_INC(&server_opts.new_session_id);
1504+
new_session->id = ATOMIC_INC(server_opts.new_session_id);
15051505

15061506
/* NETCONF handshake */
15071507
msgtype = nc_handshake_io(new_session);
@@ -1572,7 +1572,7 @@ nc_ps_accept_ssh_channel(struct nc_pollsession *ps, struct nc_session **session)
15721572
}
15731573

15741574
/* assign new SID atomically */
1575-
new_session->id = ATOMIC_INC(&server_opts.new_session_id);
1575+
new_session->id = ATOMIC_INC(server_opts.new_session_id);
15761576

15771577
/* NETCONF handshake */
15781578
msgtype = nc_handshake_io(new_session);

0 commit comments

Comments
 (0)