@@ -3272,15 +3272,57 @@ nc_client_monitoring_get_session_fd(struct nc_session *session)
32723272 return fd ;
32733273}
32743274
3275+ /**
3276+ * @brief Lock the client monitoring data.
3277+ *
3278+ * @param[in] timeout Timeout in msec to use.
3279+ *
3280+ * @return 1 on success;
3281+ * @return 0 on timeout;
3282+ * @return -1 on error.
3283+ */
3284+ static int
3285+ nc_client_monitoring_lock (int timeout )
3286+ {
3287+ int r ;
3288+ struct timespec ts ;
3289+
3290+ if (timeout > 0 ) {
3291+ nc_timeouttime_get (& ts , timeout );
3292+ r = pthread_mutex_clocklock (& client_opts .monitoring_thread_data .lock , COMPAT_CLOCK_ID , & ts );
3293+ } else if (!timeout ) {
3294+ r = pthread_mutex_trylock (& client_opts .monitoring_thread_data .lock );
3295+ } else {
3296+ r = pthread_mutex_lock (& client_opts .monitoring_thread_data .lock );
3297+ }
3298+
3299+ if (r ) {
3300+ ERR (NULL , "Failed to lock the client monitoring data lock (%s)." , strerror (r ));
3301+
3302+ if ((r == EBUSY ) || (r == ETIMEDOUT )) {
3303+ /* timeout */
3304+ return 0 ;
3305+ }
3306+
3307+ /* error */
3308+ return -1 ;
3309+ }
3310+
3311+ return 1 ;
3312+ }
3313+
32753314int
32763315nc_client_monitoring_session_start (struct nc_session * session )
32773316{
3278- int ret = 0 , fd ;
3317+ int ret = 0 , fd , r ;
32793318 struct nc_client_monitoring_thread_arg * mtarg ;
32803319 void * tmp , * tmp2 ;
32813320
32823321 /* LOCK */
3283- pthread_mutex_lock (& client_opts .monitoring_thread_data .lock );
3322+ r = nc_client_monitoring_lock (NC_CLIENT_MONITORING_LOCK_TIMEOUT );
3323+ if (r < 1 ) {
3324+ return 1 ;
3325+ }
32843326
32853327 /* check if the monitoring thread is running */
32863328 if (!client_opts .monitoring_thread_data .thread_running ) {
@@ -3314,19 +3356,22 @@ nc_client_monitoring_session_start(struct nc_session *session)
33143356
33153357cleanup :
33163358 /* UNLOCK */
3317- pthread_mutex_unlock (& mtarg -> lock );
3359+ pthread_mutex_unlock (& client_opts . monitoring_thread_data . lock );
33183360 return ret ;
33193361}
33203362
33213363void
33223364nc_client_monitoring_session_stop (struct nc_session * session , int lock )
33233365{
3324- int i ;
3366+ int i , r ;
33253367 struct nc_client_monitoring_thread_arg * mtarg ;
33263368
33273369 if (lock ) {
33283370 /* LOCK */
3329- pthread_mutex_lock (& client_opts .monitoring_thread_data .lock );
3371+ r = nc_client_monitoring_lock (NC_CLIENT_MONITORING_LOCK_TIMEOUT );
3372+ if (r < 1 ) {
3373+ return ;
3374+ }
33303375 }
33313376
33323377 mtarg = & client_opts .monitoring_thread_data ;
@@ -3379,7 +3424,7 @@ nc_client_monitoring_session_stop(struct nc_session *session, int lock)
33793424static void *
33803425nc_client_monitoring_thread (void * arg )
33813426{
3382- int r ;
3427+ int r , locked = 0 ;
33833428 struct nc_client_monitoring_thread_arg * mtarg ;
33843429 nfds_t i ;
33853430 struct nc_session * session = NULL ;
@@ -3388,7 +3433,11 @@ nc_client_monitoring_thread(void *arg)
33883433 nc_client_set_thread_context (arg );
33893434
33903435 /* LOCK */
3391- pthread_mutex_lock (& client_opts .monitoring_thread_data .lock );
3436+ r = nc_client_monitoring_lock (NC_CLIENT_MONITORING_LOCK_TIMEOUT );
3437+ if (r < 1 ) {
3438+ goto cleanup ;
3439+ }
3440+ locked = 1 ;
33923441
33933442 mtarg = & client_opts .monitoring_thread_data ;
33943443
@@ -3425,6 +3474,7 @@ nc_client_monitoring_thread(void *arg)
34253474next_iter :
34263475 /* UNLOCK */
34273476 pthread_mutex_unlock (& mtarg -> lock );
3477+ locked = 0 ;
34283478
34293479 /* if an event occurred, call the callback */
34303480 if (session ) {
@@ -3435,12 +3485,18 @@ nc_client_monitoring_thread(void *arg)
34353485 usleep (NC_CLIENT_MONITORING_BACKOFF * 1000 );
34363486
34373487 /* LOCK */
3438- pthread_mutex_lock (& mtarg -> lock );
3488+ r = nc_client_monitoring_lock (NC_CLIENT_MONITORING_LOCK_TIMEOUT );
3489+ if (r < 1 ) {
3490+ goto cleanup ;
3491+ }
3492+ locked = 1 ;
34393493 }
34403494
34413495cleanup :
3442- /* UNLOCK */
3443- pthread_mutex_unlock (& mtarg -> lock );
3496+ if (locked ) {
3497+ /* UNLOCK */
3498+ pthread_mutex_unlock (& mtarg -> lock );
3499+ }
34443500 VRB (NULL , "Client monitoring thread exit." );
34453501 return NULL ;
34463502}
@@ -3454,7 +3510,11 @@ nc_client_monitoring_thread_start(nc_client_monitoring_clb monitoring_clb, void
34543510 NC_CHECK_ARG_RET (NULL , monitoring_clb , 1 );
34553511
34563512 /* LOCK */
3457- pthread_mutex_lock (& client_opts .monitoring_thread_data .lock );
3513+ r = nc_client_monitoring_lock (NC_CLIENT_MONITORING_LOCK_TIMEOUT );
3514+ if (r < 1 ) {
3515+ return 1 ;
3516+ }
3517+
34583518 if (client_opts .monitoring_thread_data .thread_running ) {
34593519 ERR (NULL , "Client monitoring thread is already running." );
34603520 ret = 1 ;
@@ -3497,7 +3557,11 @@ nc_client_monitoring_thread_stop(void)
34973557 struct nc_client_monitoring_thread_arg * mtarg ;
34983558
34993559 /* LOCK */
3500- pthread_mutex_lock (& client_opts .monitoring_thread_data .lock );
3560+ r = nc_client_monitoring_lock (NC_CLIENT_MONITORING_LOCK_TIMEOUT );
3561+ if (r < 1 ) {
3562+ return ;
3563+ }
3564+
35013565 if (!client_opts .monitoring_thread_data .thread_running ) {
35023566 ERR (NULL , "Client monitoring thread is not running." );
35033567
@@ -3525,7 +3589,10 @@ nc_client_monitoring_thread_stop(void)
35253589 }
35263590
35273591 /* LOCK */
3528- pthread_mutex_lock (& mtarg -> lock );
3592+ r = nc_client_monitoring_lock (NC_CLIENT_MONITORING_LOCK_TIMEOUT );
3593+ if (r < 1 ) {
3594+ return ;
3595+ }
35293596
35303597 if (mtarg -> clb_free_data ) {
35313598 mtarg -> clb_free_data (mtarg -> clb_data );
0 commit comments