Skip to content

Commit df68e7e

Browse files
committed
session BUGFIX thread-safe var access
Fixes #371
1 parent ef7d3e3 commit df68e7e

3 files changed

Lines changed: 31 additions & 6 deletions

File tree

src/session.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ nc_new_session(NC_SIDE side, int shared_ti)
189189
sess->side = side;
190190

191191
if (side == NC_SERVER) {
192+
pthread_mutex_init(&sess->opts.server.ntf_status_lock, NULL);
192193
pthread_mutex_init(&sess->opts.server.rpc_lock, NULL);
193194
pthread_cond_init(&sess->opts.server.rpc_cond, NULL);
194-
sess->opts.server.rpc_inuse = 0;
195195

196196
pthread_mutex_init(&sess->opts.server.ch_lock, NULL);
197197
pthread_cond_init(&sess->opts.server.ch_cond, NULL);
@@ -894,6 +894,7 @@ nc_session_free(struct nc_session *session, void (*data_free)(void *))
894894

895895
/* final cleanup */
896896
if (session->side == NC_SERVER) {
897+
pthread_mutex_destroy(&session->opts.server.ntf_status_lock);
897898
if (rpc_locked) {
898899
nc_session_rpc_unlock(session, NC_SESSION_LOCK_TIMEOUT, __func__);
899900
}

src/session_p.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,9 @@ struct nc_session {
453453
/* server side only data */
454454
time_t session_start; /**< real time the session was created */
455455
time_t last_rpc; /**< monotonic time (seconds) the last RPC was received on this session */
456-
int ntf_status; /**< flag (count) whether the session is subscribed to notifications */
456+
457+
pthread_mutex_t ntf_status_lock; /**< lock for ntf_status */
458+
uint32_t ntf_status; /**< flag (count) whether the session is subscribed to notifications */
457459

458460
pthread_mutex_t rpc_lock; /**< lock indicating RPC processing, this lock is always locked before io_lock!! */
459461
pthread_cond_t rpc_cond; /**< RPC condition (tied with rpc_lock and rpc_inuse) */

src/session_server.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,7 @@ nc_server_notif_send(struct nc_session *session, struct nc_server_notif *notif,
13961396
NC_MSG_TYPE ret;
13971397

13981398
/* check parameters */
1399-
if (!session || (session->side != NC_SERVER) || !session->opts.server.ntf_status) {
1399+
if (!session || (session->side != NC_SERVER) || !nc_session_get_notif_status(session)) {
14001400
ERRARG("session");
14011401
return NC_MSG_ERROR;
14021402
} else if (!notif || !notif->ntf || !notif->eventtime) {
@@ -1505,7 +1505,7 @@ nc_ps_poll_session_io(struct nc_session *session, int io_timeout, time_t now_mon
15051505
#endif
15061506

15071507
/* check timeout first */
1508-
if (!(session->flags & NC_SESSION_CALLHOME) && !session->opts.server.ntf_status && server_opts.idle_timeout &&
1508+
if (!(session->flags & NC_SESSION_CALLHOME) && !nc_session_get_notif_status(session) && server_opts.idle_timeout &&
15091509
(now_mono >= session->opts.server.last_rpc + server_opts.idle_timeout)) {
15101510
sprintf(msg, "session idle timeout elapsed");
15111511
session->status = NC_STATUS_INVALID;
@@ -3443,7 +3443,7 @@ nc_server_ch_client_thread_session_cond_wait(struct nc_session *session, struct
34433443
}
34443444

34453445
nc_gettimespec_mono(&ts);
3446-
if (!session->opts.server.ntf_status && idle_timeout && (ts.tv_sec >= session->opts.server.last_rpc + idle_timeout)) {
3446+
if (!nc_session_get_notif_status(session) && idle_timeout && (ts.tv_sec >= session->opts.server.last_rpc + idle_timeout)) {
34473447
VRB(session, "Call Home client \"%s\": session idle timeout elapsed.", client->name);
34483448
session->status = NC_STATUS_INVALID;
34493449
session->term_reason = NC_SESSION_TERM_TIMEOUT;
@@ -3690,7 +3690,13 @@ nc_session_inc_notif_status(struct nc_session *session)
36903690
return;
36913691
}
36923692

3693+
/* NTF STATUS LOCK */
3694+
pthread_mutex_lock(&session->opts.server.ntf_status_lock);
3695+
36933696
++session->opts.server.ntf_status;
3697+
3698+
/* NTF STATUS UNLOCK */
3699+
pthread_mutex_unlock(&session->opts.server.ntf_status_lock);
36943700
}
36953701

36963702
API void
@@ -3701,20 +3707,36 @@ nc_session_dec_notif_status(struct nc_session *session)
37013707
return;
37023708
}
37033709

3710+
/* NTF STATUS LOCK */
3711+
pthread_mutex_lock(&session->opts.server.ntf_status_lock);
3712+
37043713
if (session->opts.server.ntf_status) {
37053714
--session->opts.server.ntf_status;
37063715
}
3716+
3717+
/* NTF STATUS UNLOCK */
3718+
pthread_mutex_unlock(&session->opts.server.ntf_status_lock);
37073719
}
37083720

37093721
API int
37103722
nc_session_get_notif_status(const struct nc_session *session)
37113723
{
3724+
uint32_t ntf_status;
3725+
37123726
if (!session || (session->side != NC_SERVER)) {
37133727
ERRARG("session");
37143728
return 0;
37153729
}
37163730

3717-
return session->opts.server.ntf_status;
3731+
/* NTF STATUS LOCK */
3732+
pthread_mutex_lock(&((struct nc_session *)session)->opts.server.ntf_status_lock);
3733+
3734+
ntf_status = session->opts.server.ntf_status;
3735+
3736+
/* NTF STATUS UNLOCK */
3737+
pthread_mutex_unlock(&((struct nc_session *)session)->opts.server.ntf_status_lock);
3738+
3739+
return ntf_status;
37183740
}
37193741

37203742
API int

0 commit comments

Comments
 (0)