Skip to content

Commit 8dde290

Browse files
Roytakmichalvasko
authored andcommitted
session UPDATE add (rw/mut)lock timeout wrapper
1 parent 8d3e2ba commit 8dde290

2 files changed

Lines changed: 180 additions & 0 deletions

File tree

src/session.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,127 @@ nc_session_client_msgs_unlock(struct nc_session *session, const char *func)
530530
return 1;
531531
}
532532

533+
int
534+
nc_rwlock_lock(pthread_rwlock_t *rwlock, enum nc_rwlock_mode mode, int timeout, const char *func_name)
535+
{
536+
int ret;
537+
struct timespec ts_timeout;
538+
539+
if (!rwlock || (mode == NC_RWLOCK_NONE)) {
540+
ERRINT;
541+
return -1;
542+
}
543+
544+
if (timeout > 0) {
545+
/* get absolute time for timeout */
546+
nc_timeouttime_get(&ts_timeout, timeout);
547+
548+
/* acquire lock with timeout based on mode */
549+
if (mode == NC_RWLOCK_READ) {
550+
ret = pthread_rwlock_clockrdlock(rwlock, COMPAT_CLOCK_ID, &ts_timeout);
551+
} else {
552+
ret = pthread_rwlock_clockwrlock(rwlock, COMPAT_CLOCK_ID, &ts_timeout);
553+
}
554+
} else if (!timeout) {
555+
/* try to acquire lock without waiting */
556+
if (mode == NC_RWLOCK_READ) {
557+
ret = pthread_rwlock_tryrdlock(rwlock);
558+
} else {
559+
ret = pthread_rwlock_trywrlock(rwlock);
560+
}
561+
} else {
562+
/* acquire lock without timeout */
563+
if (mode == NC_RWLOCK_READ) {
564+
ret = pthread_rwlock_rdlock(rwlock);
565+
} else {
566+
ret = pthread_rwlock_wrlock(rwlock);
567+
}
568+
}
569+
570+
if (ret) {
571+
if ((ret == EBUSY) || (ret == ETIMEDOUT)) {
572+
/* timeout */
573+
return 0;
574+
}
575+
576+
ERR(NULL, "%s: failed to lock rwlock in %s mode (%s).", func_name,
577+
mode == NC_RWLOCK_READ ? "read" : "write", strerror(ret));
578+
return -1;
579+
}
580+
581+
return 1;
582+
}
583+
584+
void
585+
nc_rwlock_unlock(pthread_rwlock_t *rwlock, const char *func_name)
586+
{
587+
int r;
588+
589+
if (!rwlock) {
590+
ERRINT;
591+
return;
592+
}
593+
594+
r = pthread_rwlock_unlock(rwlock);
595+
if (r) {
596+
ERR(NULL, "%s: failed to unlock rwlock (%s).", func_name, strerror(r));
597+
}
598+
}
599+
600+
int
601+
nc_mutex_lock(pthread_mutex_t *mutex, int timeout, const char *func_name)
602+
{
603+
int ret;
604+
struct timespec ts_timeout;
605+
606+
if (!mutex) {
607+
ERRINT;
608+
return -1;
609+
}
610+
611+
if (timeout > 0) {
612+
/* get absolute time for timeout */
613+
nc_timeouttime_get(&ts_timeout, timeout);
614+
615+
/* acquire lock with timeout */
616+
ret = pthread_mutex_clocklock(mutex, COMPAT_CLOCK_ID, &ts_timeout);
617+
} else if (!timeout) {
618+
/* try to acquire lock without waiting */
619+
ret = pthread_mutex_trylock(mutex);
620+
} else {
621+
/* acquire lock without timeout */
622+
ret = pthread_mutex_lock(mutex);
623+
}
624+
625+
if (ret) {
626+
if ((ret == EBUSY) || (ret == ETIMEDOUT)) {
627+
/* timeout */
628+
return 0;
629+
}
630+
631+
ERR(NULL, "%s: failed to lock mutex (%s).", func_name, strerror(ret));
632+
return -1;
633+
}
634+
635+
return 1;
636+
}
637+
638+
void
639+
nc_mutex_unlock(pthread_mutex_t *mutex, const char *func_name)
640+
{
641+
int r;
642+
643+
if (!mutex) {
644+
ERRINT;
645+
return;
646+
}
647+
648+
r = pthread_mutex_unlock(mutex);
649+
if (r) {
650+
ERR(NULL, "%s: failed to unlock mutex (%s).", func_name, strerror(r));
651+
}
652+
}
653+
533654
API NC_STATUS
534655
nc_session_get_status(const struct nc_session *session)
535656
{

src/session_p.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ enum nc_operation {
133133
NC_OP_REPLACE
134134
};
135135

136+
/**
137+
* @brief Enumeration of rwlock mode.
138+
*/
139+
enum nc_rwlock_mode {
140+
NC_RWLOCK_NONE = 0, /**< Lock not held */
141+
NC_RWLOCK_READ, /**< Read lock mode */
142+
NC_RWLOCK_WRITE /**< Write lock mode */
143+
};
144+
136145
/**
137146
* Enumeration of key or certificate store type.
138147
*/
@@ -1126,6 +1135,56 @@ int nc_session_client_msgs_lock(struct nc_session *session, int *timeout, const
11261135
*/
11271136
int nc_session_client_msgs_unlock(struct nc_session *session, const char *func);
11281137

1138+
/**
1139+
* @brief Lock a pthread_rwlock with timeout support.
1140+
*
1141+
* @param[in] rwlock Lock to be acquired.
1142+
* @param[in] mode Lock mode (NC_RWLOCK_READ for read lock, NC_RWLOCK_WRITE for write lock).
1143+
* @param[in] timeout Timeout in milliseconds:
1144+
* - Positive value: Wait up to this many milliseconds for the lock.
1145+
* - 0: Try to acquire the lock without waiting (trylock).
1146+
* - Negative value: Wait indefinitely for the lock.
1147+
* @param[in] func_name Caller function name for logging purposes.
1148+
* @return 1 on success (lock acquired);
1149+
* @return 0 on timeout;
1150+
* @return -1 on error.
1151+
*/
1152+
int nc_rwlock_lock(pthread_rwlock_t *rwlock, enum nc_rwlock_mode mode, int timeout, const char *func_name);
1153+
1154+
/**
1155+
* @brief Unlock a previously locked pthread_rwlock.
1156+
*
1157+
* This function unlocks a previously locked pthread_rwlock regardless of whether
1158+
* it was locked in read or write mode.
1159+
*
1160+
* @param[in] rwlock Lock to be unlocked.
1161+
* @param[in] func_name Caller function name for logging purposes.
1162+
*/
1163+
void nc_rwlock_unlock(pthread_rwlock_t *rwlock, const char *func_name);
1164+
1165+
/**
1166+
* @brief Lock a pthread_mutex with timeout support.
1167+
*
1168+
* @param[in] mutex Mutex to be acquired.
1169+
* @param[in] timeout Timeout in milliseconds:
1170+
* - Positive value: Wait up to this many milliseconds for the lock.
1171+
* - 0: Try to acquire the lock without waiting (trylock).
1172+
* - Negative value: Wait indefinitely for the lock.
1173+
* @param[in] func_name Caller function name for logging purposes.
1174+
* @return 1 on success (lock acquired);
1175+
* @return 0 on timeout;
1176+
* @return -1 on error.
1177+
*/
1178+
int nc_mutex_lock(pthread_mutex_t *mutex, int timeout, const char *func_name);
1179+
1180+
/**
1181+
* @brief Unlock a previously locked pthread_mutex.
1182+
*
1183+
* @param[in] mutex Mutex to be unlocked.
1184+
* @param[in] func_name Caller function name for logging purposes.
1185+
*/
1186+
void nc_mutex_unlock(pthread_mutex_t *mutex, const char *func_name);
1187+
11291188
int nc_ps_lock(struct nc_pollsession *ps, uint8_t *id, const char *func);
11301189

11311190
int nc_ps_unlock(struct nc_pollsession *ps, uint8_t id, const char *func);

0 commit comments

Comments
 (0)