@@ -3336,6 +3336,11 @@ nc_client_monitoring_session_stop(struct nc_session *session, int lock)
33363336 pthread_mutex_lock (& mtarg -> lock );
33373337 }
33383338
3339+ /* session is no longer monitored (is being freed) */
3340+ if (!(session -> flags & NC_SESSION_CLIENT_MONITORED )) {
3341+ goto cleanup ;
3342+ }
3343+
33393344 /* find the session */
33403345 for (i = 0 ; i < mtarg -> session_count ; i ++ ) {
33413346 if (mtarg -> sessions [i ] == session ) {
@@ -3344,7 +3349,7 @@ nc_client_monitoring_session_stop(struct nc_session *session, int lock)
33443349 }
33453350 if (i == mtarg -> session_count ) {
33463351 /* not found */
3347- ERR ( session , "Session is not being monitored." ) ;
3352+ ERRINT ;
33483353 goto cleanup ;
33493354 }
33503355
@@ -3382,7 +3387,7 @@ nc_client_monitoring_thread(void *arg)
33823387 int r ;
33833388 struct nc_client_monitoring_thread_arg * mtarg ;
33843389 nfds_t i ;
3385- struct nc_session * session ;
3390+ struct nc_session * session = NULL ;
33863391
33873392 /* set this thread's context to the one from the thread that started the monitoring thread */
33883393 nc_client_set_thread_context (arg );
@@ -3416,52 +3421,36 @@ nc_client_monitoring_thread(void *arg)
34163421 goto next_iter ;
34173422 }
34183423
3419- /* check the events */
3420- i = 0 ;
3421- while (i < mtarg -> pfd_count ) {
3424+ for (i = 0 ; i < mtarg -> pfd_count ; i ++ ) {
34223425 if (mtarg -> pfds [i ].revents & (POLLHUP | POLLNVAL )) {
3423- /* call the callback and free the session */
3426+ /* save the session and stop monitoring it, callback will be called outside of the lock */
34243427 session = mtarg -> sessions [i ];
34253428 session -> status = NC_STATUS_INVALID ;
34263429 session -> term_reason = NC_SESSION_TERM_DROPPED ;
3427- mtarg -> clb (session , mtarg -> clb_data );
3428-
3429- /* session will be removed from the list, continue from the same index */
34303430 nc_client_monitoring_session_stop (session , 0 );
3431- nc_session_free (session , NULL );
3432- } else {
3433- i ++ ;
3431+ break ;
34343432 }
34353433 }
34363434
34373435next_iter :
34383436 /* UNLOCK */
34393437 pthread_mutex_unlock (& mtarg -> lock );
34403438
3439+ /* if an event occurred, call the callback */
3440+ if (session ) {
3441+ mtarg -> clb (session , mtarg -> clb_data );
3442+ }
3443+ session = NULL ;
3444+
34413445 usleep (NC_CLIENT_MONITORING_BACKOFF * 1000 );
34423446
34433447 /* LOCK */
34443448 pthread_mutex_lock (& mtarg -> lock );
34453449 }
34463450
34473451cleanup :
3448- client_opts .monitoring_thread_data = NULL ;
3449-
34503452 /* UNLOCK */
34513453 pthread_mutex_unlock (& mtarg -> lock );
3452-
3453- if (mtarg -> clb_free_data ) {
3454- mtarg -> clb_free_data (mtarg -> clb_data );
3455- }
3456- for (i = 0 ; i < mtarg -> session_count ; i ++ ) {
3457- mtarg -> sessions [i ]-> flags &= ~NC_SESSION_CLIENT_MONITORED ;
3458- }
3459- free (mtarg -> sessions );
3460- free (mtarg -> pfds );
3461- pthread_mutex_destroy (& mtarg -> lock );
3462-
3463- free (mtarg );
3464-
34653454 VRB (NULL , "Client monitoring thread exit." );
34663455 return NULL ;
34673456}
@@ -3518,7 +3507,7 @@ nc_client_monitoring_thread_start(nc_client_monitoring_clb monitoring_clb, void
35183507API void
35193508nc_client_monitoring_thread_stop (void )
35203509{
3521- int r ;
3510+ int r , i ;
35223511 pthread_t tid ;
35233512 struct nc_client_monitoring_thread_arg * mtarg ;
35243513
@@ -3534,6 +3523,12 @@ nc_client_monitoring_thread_stop(void)
35343523
35353524 mtarg -> thread_running = 0 ;
35363525 tid = mtarg -> tid ;
3526+ client_opts .monitoring_thread_data = NULL ;
3527+
3528+ /* remove the flag from the session while the lock is held */
3529+ for (i = 0 ; i < mtarg -> session_count ; i ++ ) {
3530+ mtarg -> sessions [i ]-> flags &= ~NC_SESSION_CLIENT_MONITORED ;
3531+ }
35373532
35383533 /* UNLOCK */
35393534 pthread_mutex_unlock (& mtarg -> lock );
@@ -3542,6 +3537,15 @@ nc_client_monitoring_thread_stop(void)
35423537 if (r ) {
35433538 ERR (NULL , "Failed to join the client monitoring thread (%s)." , strerror (r ));
35443539 }
3540+
3541+ if (mtarg -> clb_free_data ) {
3542+ mtarg -> clb_free_data (mtarg -> clb_data );
3543+ }
3544+ free (mtarg -> sessions );
3545+ free (mtarg -> pfds );
3546+ pthread_mutex_destroy (& mtarg -> lock );
3547+
3548+ free (mtarg );
35453549}
35463550
35473551API void
0 commit comments