Skip to content

Commit 6a905db

Browse files
committed
add WOLFSENTRY_SUCCESS_ID_NO_WAITING;
fix return codes in wolfsentry_get_thread_deadline(); fix wolfsentry_get_deadline_rel() to handle WOLFSENTRY_DEADLINE_NOW and return positive rel_when when deadline is unexpired; fix thread->deadline checks in lock functions to handle WOLFSENTRY_DEADLINE_NOW; add unit tests for wolfsentry_set_deadline_rel(), wolfsentry_set_deadline_rel_usecs(), wolfsentry_get_deadline_rel(), wolfsentry_get_deadline_rel_usecs(), wolfsentry_clear_deadline(), wolfsentry_set_thread_readonly(), and wolfsentry_set_thread_readwrite().
1 parent 8f3a6dc commit 6a905db

File tree

4 files changed

+62
-14
lines changed

4 files changed

+62
-14
lines changed

src/wolfsentry_util.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ WOLFSENTRY_API const char *wolfsentry_errcode_error_string(wolfsentry_errcode_t
217217
return "Supplied object has no deadline";
218218
case WOLFSENTRY_SUCCESS_ID_EXPIRED:
219219
return "Deadline on supplied object has passed";
220+
case WOLFSENTRY_SUCCESS_ID_NO_WAITING:
221+
return "Supplied object is non-blocking";
220222
case WOLFSENTRY_ERROR_ID_USER_BASE:
221223
case WOLFSENTRY_SUCCESS_ID_USER_BASE:
222224
break;
@@ -298,6 +300,7 @@ WOLFSENTRY_API const char *wolfsentry_errcode_error_name(wolfsentry_errcode_t e)
298300
_SUCNAME_TO_STRING(DEFERRED);
299301
_SUCNAME_TO_STRING(NO_DEADLINE);
300302
_SUCNAME_TO_STRING(EXPIRED);
303+
_SUCNAME_TO_STRING(NO_WAITING);
301304
#undef _SUCNAME_TO_STRING
302305

303306
case WOLFSENTRY_SUCCESS_ID_USER_BASE:
@@ -854,9 +857,11 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_get_thread_deadline(struct wolfse
854857
if (! (thread->current_thread_flags & WOLFSENTRY_THREAD_FLAG_DEADLINE)) {
855858
deadline->tv_sec = WOLFSENTRY_DEADLINE_NEVER;
856859
deadline->tv_nsec = WOLFSENTRY_DEADLINE_NEVER;
857-
} else
860+
WOLFSENTRY_SUCCESS_RETURN(NO_DEADLINE);
861+
} else {
858862
*deadline = thread->deadline;
859-
WOLFSENTRY_RETURN_OK;
863+
WOLFSENTRY_RETURN_OK;
864+
}
860865
}
861866

862867
WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_get_thread_flags(struct wolfsentry_thread_context *thread, wolfsentry_thread_flags_t *thread_flags) {
@@ -964,6 +969,9 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_get_deadline_rel(WOLFSENTRY_CONTE
964969

965970
if (! (thread->current_thread_flags & WOLFSENTRY_THREAD_FLAG_DEADLINE)) {
966971
WOLFSENTRY_SUCCESS_RETURN(NO_DEADLINE);
972+
} else if (thread->deadline.tv_nsec == WOLFSENTRY_DEADLINE_NOW) {
973+
*rel_when = 0;
974+
WOLFSENTRY_SUCCESS_RETURN(NO_WAITING);
967975
} else {
968976
wolfsentry_time_t now, deadline;
969977
wolfsentry_errcode_t ret;
@@ -972,7 +980,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_get_deadline_rel(WOLFSENTRY_CONTE
972980
if ((ret = WOLFSENTRY_FROM_EPOCH_TIME(thread->deadline.tv_sec, thread->deadline.tv_nsec, &deadline)) < 0)
973981
WOLFSENTRY_ERROR_RERETURN(ret);
974982
if (rel_when) {
975-
*rel_when = now - deadline;
983+
*rel_when = deadline - now;
976984
if (*rel_when >= 0)
977985
WOLFSENTRY_RETURN_OK;
978986
else
@@ -1004,11 +1012,12 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_set_deadline_abs(WOLFSENTRY_CONTE
10041012

10051013
WOLFSENTRY_THREAD_ASSERT_INITED(thread);
10061014

1007-
if ((epoch_nsecs < 0) || (epoch_nsecs >= 1000000000))
1008-
WOLFSENTRY_ERROR_RETURN(INVALID_ARG);
1009-
if ((epoch_secs == WOLFSENTRY_DEADLINE_NEVER) ||
1010-
(epoch_secs == WOLFSENTRY_DEADLINE_NOW))
1015+
if ((epoch_nsecs < 0) || (epoch_nsecs >= 1000000000) ||
1016+
(epoch_nsecs == WOLFSENTRY_DEADLINE_NEVER) ||
1017+
(epoch_nsecs == WOLFSENTRY_DEADLINE_NOW))
1018+
{
10111019
WOLFSENTRY_ERROR_RETURN(INVALID_ARG);
1020+
}
10121021
thread->deadline.tv_sec = epoch_secs;
10131022
thread->deadline.tv_nsec = epoch_nsecs;
10141023
thread->current_thread_flags |= WOLFSENTRY_THREAD_FLAG_DEADLINE;
@@ -1775,7 +1784,10 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs
17751784
if ((abs_timeout == NULL) &&
17761785
(thread->current_thread_flags & WOLFSENTRY_THREAD_FLAG_DEADLINE))
17771786
{
1778-
abs_timeout = &thread->deadline;
1787+
if (thread->deadline.tv_nsec == timespec_deadline_now.tv_nsec)
1788+
abs_timeout = &timespec_deadline_now;
1789+
else
1790+
abs_timeout = &thread->deadline;
17791791
}
17801792

17811793
/* if shared lock recursion is enabled, and the caller already holds some
@@ -2074,7 +2086,10 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex_abstimed(struct wolfse
20742086
thread &&
20752087
(thread->current_thread_flags & WOLFSENTRY_THREAD_FLAG_DEADLINE))
20762088
{
2077-
abs_timeout = &thread->deadline;
2089+
if (thread->deadline.tv_nsec == timespec_deadline_now.tv_nsec)
2090+
abs_timeout = &timespec_deadline_now;
2091+
else
2092+
abs_timeout = &thread->deadline;
20782093
}
20792094

20802095
if (abs_timeout == NULL) {
@@ -2386,7 +2401,10 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_redeem_abstimed
23862401
if ((abs_timeout == NULL) &&
23872402
(thread->current_thread_flags & WOLFSENTRY_THREAD_FLAG_DEADLINE))
23882403
{
2389-
abs_timeout = &thread->deadline;
2404+
if (thread->deadline.tv_nsec == timespec_deadline_now.tv_nsec)
2405+
abs_timeout = &timespec_deadline_now;
2406+
else
2407+
abs_timeout = &thread->deadline;
23902408
}
23912409

23922410
if (abs_timeout == NULL) {
@@ -2650,7 +2668,10 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_abstimed(struct
26502668
if ((abs_timeout == NULL) &&
26512669
(thread->current_thread_flags & WOLFSENTRY_THREAD_FLAG_DEADLINE))
26522670
{
2653-
abs_timeout = &thread->deadline;
2671+
if (thread->deadline.tv_nsec == timespec_deadline_now.tv_nsec)
2672+
abs_timeout = &timespec_deadline_now;
2673+
else
2674+
abs_timeout = &thread->deadline;
26542675
}
26552676

26562677
if (abs_timeout == NULL) {

tests/unittests.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,10 +981,16 @@ static int test_rw_locks(void) {
981981
TEST_INVALID_ARGS(wolfsentry_free_thread_context(NULL, NULL, 0));
982982
TEST_INVALID_ARGS(wolfsentry_free_thread_context(NULL, &null_thread, 0));
983983
TEST_INVALID_ARGS(wolfsentry_free_thread_context(NULL, &uninited_thread, 0));
984+
TEST_INVALID_ARGS(wolfsentry_set_deadline_rel(wolfsentry, null_thread, 0));
985+
TEST_INVALID_ARGS(wolfsentry_set_deadline_rel(wolfsentry, uninited_thread, 0));
984986
TEST_INVALID_ARGS(wolfsentry_set_deadline_rel_usecs(wolfsentry, null_thread, 0));
985987
TEST_INVALID_ARGS(wolfsentry_set_deadline_rel_usecs(wolfsentry, uninited_thread, 0));
986988
TEST_INVALID_ARGS(wolfsentry_set_deadline_abs(wolfsentry, null_thread, 0, 0));
987989
TEST_INVALID_ARGS(wolfsentry_set_deadline_abs(wolfsentry, uninited_thread, 0, 0));
990+
TEST_INVALID_ARGS(wolfsentry_get_deadline_rel(wolfsentry, null_thread, 0));
991+
TEST_INVALID_ARGS(wolfsentry_get_deadline_rel(wolfsentry, uninited_thread, 0));
992+
TEST_INVALID_ARGS(wolfsentry_get_deadline_rel_usecs(wolfsentry, null_thread, 0));
993+
TEST_INVALID_ARGS(wolfsentry_get_deadline_rel_usecs(wolfsentry, uninited_thread, 0));
988994
TEST_INVALID_ARGS(wolfsentry_clear_deadline(wolfsentry, null_thread));
989995
TEST_INVALID_ARGS(wolfsentry_clear_deadline(wolfsentry, uninited_thread));
990996
TEST_INVALID_ARGS(wolfsentry_set_thread_readonly(null_thread));
@@ -1059,6 +1065,26 @@ static int test_rw_locks(void) {
10591065
TEST_INVALID_ARGS(wolfsentry_lock_get_flags(lock, thread, NULL));
10601066
}
10611067

1068+
{
1069+
long usecs = -1;
1070+
wolfsentry_time_t t = (wolfsentry_time_t)(-1);
1071+
WOLFSENTRY_EXIT_ON_FAILURE(wolfsentry_set_deadline_rel_usecs(WOLFSENTRY_CONTEXT_ARGS_OUT, 0));
1072+
WOLFSENTRY_EXIT_ON_FAILURE(wolfsentry_get_deadline_rel(WOLFSENTRY_CONTEXT_ARGS_OUT, &t));
1073+
WOLFSENTRY_EXIT_ON_FALSE(t == 0);
1074+
WOLFSENTRY_EXIT_UNLESS_EXPECTED_SUCCESS(NO_WAITING, wolfsentry_get_deadline_rel_usecs(WOLFSENTRY_CONTEXT_ARGS_OUT, &usecs));
1075+
WOLFSENTRY_EXIT_ON_FALSE(usecs == 0);
1076+
WOLFSENTRY_EXIT_ON_FAILURE(wolfsentry_clear_deadline(WOLFSENTRY_CONTEXT_ARGS_OUT));
1077+
WOLFSENTRY_EXIT_UNLESS_EXPECTED_SUCCESS(NO_DEADLINE, wolfsentry_get_deadline_rel_usecs(WOLFSENTRY_CONTEXT_ARGS_OUT, &usecs));
1078+
WOLFSENTRY_EXIT_ON_FAILURE(wolfsentry_set_deadline_rel_usecs(WOLFSENTRY_CONTEXT_ARGS_OUT, 1000000));
1079+
WOLFSENTRY_EXIT_ON_FAILURE(wolfsentry_get_deadline_rel_usecs(WOLFSENTRY_CONTEXT_ARGS_OUT, &usecs));
1080+
WOLFSENTRY_EXIT_ON_FALSE(usecs > 100000 && usecs <= 1000000);
1081+
WOLFSENTRY_EXIT_ON_FAILURE(wolfsentry_clear_deadline(WOLFSENTRY_CONTEXT_ARGS_OUT));
1082+
}
1083+
1084+
WOLFSENTRY_EXIT_ON_FAILURE(wolfsentry_set_thread_readonly(thread));
1085+
WOLFSENTRY_EXIT_UNLESS_EXPECTED_FAILURE(NOT_PERMITTED, wolfsentry_lock_mutex_timed(lock, thread, 0, WOLFSENTRY_LOCK_FLAG_NONE));
1086+
WOLFSENTRY_EXIT_ON_FAILURE(wolfsentry_set_thread_readwrite(thread));
1087+
10621088
memset(&thread1_args, 0, sizeof thread1_args);
10631089
thread1_args.wolfsentry = wolfsentry;
10641090
thread1_args.measured_sequence = measured_sequence;

wolfsentry/wolfsentry.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
/*!< \brief Macro for major version number of installed headers. @hideinitializer */
5555
#define WOLFSENTRY_VERSION_MINOR 6
5656
/*!< \brief Macro for minor version number of installed headers. @hideinitializer */
57-
#define WOLFSENTRY_VERSION_TINY 2
57+
#define WOLFSENTRY_VERSION_TINY 3
5858
/*!< \brief Macro for tiny version number of installed headers. @hideinitializer */
5959
#define WOLFSENTRY_VERSION_ENCODE(major, minor, tiny) (((major) << 16U) | ((minor) << 8U) | (tiny))
6060
/*!< \brief Macro to convert a wolfSentry version to a single integer, for comparison to other similarly converted versions. @hideinitializer */
@@ -397,9 +397,9 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_set_deadline_rel(WOLFSENTRY_CONTE
397397
WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_set_deadline_rel_usecs(WOLFSENTRY_CONTEXT_ARGS_IN, long usecs);
398398
/*!< \brief Set the thread deadline to `usecs` in the future. The thread will not wait for a lock beyond that deadline. */
399399
WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_get_deadline_rel(WOLFSENTRY_CONTEXT_ARGS_IN, wolfsentry_time_t *rel_when);
400-
/*!< \brief Get the time remaining until deadline for `thread`, optionally returning the result in `rel_when`, which can be passed as a null pointer. Test for `WOLFSENTRY_ERROR_DECODE_ERROR_CODE(ret) == NO_DEADLINE`, ` == OK`, or ` == EXPIRED`, or `WOLFSENTRY_IS_FAILURE(ret)`, to test (respectively) for no deadline, deadline not reached, deadline passed, or internal error, respectively. */
400+
/*!< \brief Get the time remaining until deadline for `thread`, optionally returning the result in `rel_when`, which can be passed as a null pointer. Test for `WOLFSENTRY_ERROR_DECODE_ERROR_CODE(ret) == NO_DEADLINE`, ` == OK`, ` == NO_WAITING`, or ` == EXPIRED`, or `WOLFSENTRY_IS_FAILURE(ret)`, to test (respectively) for no deadline, deadline not reached, thread is non-blocking, deadline passed, or internal error, respectively. */
401401
WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_get_deadline_rel_usecs(WOLFSENTRY_CONTEXT_ARGS_IN, long *usecs);
402-
/*!< \brief Get the time remaining until deadline for `thread`, optionally returning the result in `usecs`, which can be passed as a null pointer. Test for `WOLFSENTRY_ERROR_DECODE_ERROR_CODE(ret) == NO_DEADLINE`, ` == OK`, or ` == EXPIRED`, or `WOLFSENTRY_IS_FAILURE(ret)`, to test (respectively) for no deadline, deadline not reached, deadline passed, or internal error, respectively. */
402+
/*!< \brief Get the time remaining until deadline for `thread`, optionally returning the result in `usecs`, which can be passed as a null pointer. Same return codes as wolfsentry_get_deadline_rel() */
403403
WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_set_deadline_abs(WOLFSENTRY_CONTEXT_ARGS_IN, time_t epoch_secs, long epoch_nsecs);
404404
/*!< \brief Set the thread deadline to the time identified by `epoch_secs` and `epoch_nsecs`. The thread will not wait for a lock beyond that deadline. */
405405
WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_clear_deadline(WOLFSENTRY_CONTEXT_ARGS_IN);

wolfsentry/wolfsentry_errcodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ enum wolfsentry_error_id {
447447
WOLFSENTRY_SUCCESS_ID_DEFERRED = 8,
448448
WOLFSENTRY_SUCCESS_ID_NO_DEADLINE = 9,
449449
WOLFSENTRY_SUCCESS_ID_EXPIRED = 10,
450+
WOLFSENTRY_SUCCESS_ID_NO_WAITING = 11,
450451
WOLFSENTRY_SUCCESS_ID_USER_BASE = 128
451452
};
452453

0 commit comments

Comments
 (0)