Skip to content

Commit 0db3db5

Browse files
committed
session BUGFIX call home flag is protected by lock and cond
1 parent 0a047f0 commit 0db3db5

2 files changed

Lines changed: 18 additions & 15 deletions

File tree

src/session.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ nc_session_free(struct nc_session *session, void (*data_free)(void *))
593593
struct lyxml_elem *rpl, *child;
594594
struct lyd_node *close_rpc;
595595
const struct lys_module *ietfnc;
596+
struct timespec ts;
596597
void *p;
597598

598599
if (!session || (session->status == NC_STATUS_CLOSING)) {
@@ -695,17 +696,20 @@ nc_session_free(struct nc_session *session, void (*data_free)(void *))
695696
if ((session->side == NC_SERVER) && (session->flags & NC_SESSION_CALLHOME)) {
696697
pthread_cond_signal(&session->opts.server.ch_cond);
697698

699+
nc_gettimespec_real(&ts);
700+
nc_addtimespec(&ts, NC_SESSION_FREE_LOCK_TIMEOUT);
701+
702+
/* wait for CH thread to actually wake up and terminate */
703+
r = 0;
704+
while (!r && (session->flags & NC_SESSION_CALLHOME)) {
705+
r = pthread_cond_timedwait(&session->opts.server.ch_cond, &session->opts.server.ch_lock, &ts);
706+
}
707+
698708
/* CH UNLOCK */
699709
pthread_mutex_unlock(&session->opts.server.ch_lock);
700710

701-
/* wait for CH thread to actually wake up */
702-
i = (NC_SESSION_FREE_LOCK_TIMEOUT * 1000) / NC_TIMEOUT_STEP;
703-
while (i && (session->flags & NC_SESSION_CALLHOME)) {
704-
usleep(NC_TIMEOUT_STEP);
705-
--i;
706-
}
707-
if (session->flags & NC_SESSION_CALLHOME) {
708-
ERR("Session %u: Call Home thread failed to wake up in a timely manner, fatal synchronization problem.", session->id);
711+
if (r) {
712+
ERR("Session %u: waiting for Call Home thread failed (%s).", session->id, strerror(r));
709713
}
710714
}
711715

src/session_server.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3275,18 +3275,19 @@ nc_server_ch_client_thread_session_cond_wait(struct nc_session *session, struct
32753275
struct timespec ts;
32763276
struct nc_ch_client *client;
32773277

3278-
session->flags |= NC_SESSION_CALLHOME;
3279-
32803278
/* CH LOCK */
32813279
pthread_mutex_lock(&session->opts.server.ch_lock);
32823280

3281+
session->flags |= NC_SESSION_CALLHOME;
3282+
32833283
/* give the session to the user */
32843284
data->session_clb(data->client_name, session);
32853285

32863286
do {
32873287
nc_gettimespec_real(&ts);
32883288
nc_addtimespec(&ts, NC_CH_NO_ENDPT_WAIT);
32893289

3290+
/* CH COND WAIT */
32903291
r = pthread_cond_timedwait(&session->opts.server.ch_cond, &session->opts.server.ch_lock, &ts);
32913292
if (!r) {
32923293
/* we were woken up, something probably happened */
@@ -3328,14 +3329,12 @@ nc_server_ch_client_thread_session_cond_wait(struct nc_session *session, struct
33283329

33293330
} while (session->status == NC_STATUS_RUNNING);
33303331

3332+
/* signal to nc_session_free() that CH registered this session not being valid anymore */
3333+
session->flags &= ~NC_SESSION_CALLHOME;
3334+
33313335
/* CH UNLOCK */
33323336
pthread_mutex_unlock(&session->opts.server.ch_lock);
33333337

3334-
if (session->status == NC_STATUS_CLOSING) {
3335-
/* signal to nc_session_free() that we registered session being freed, otherwise it matters not */
3336-
session->flags &= ~NC_SESSION_CALLHOME;
3337-
}
3338-
33393338
return ret;
33403339
}
33413340

0 commit comments

Comments
 (0)