posix: pthread: allow oldstate & oldtype to be NULL

The POSIX standard doesn't specify if the argument to store
previous state/type in
`pthread_setcancelstate`/`pthread_setcancelstate` can be
`NULL`, but threading implementations in Linux & Apache NuttX
permit the arguments to be `NULL`.

This commit changes Zephyr's implementation to mimic that of
Linux & NuttX, so that user do not get caught off-guard by
NULL pointer dereferencing when porting code over from those
OSes.

Updated test accordingly.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
Yong Cong Sin 2024-01-12 15:02:28 +08:00 committed by Carles Cufí
parent 81d524d081
commit 98a631b5bc
2 changed files with 9 additions and 6 deletions

View file

@ -572,7 +572,9 @@ int pthread_setcancelstate(int state, int *oldstate)
}
key = k_spin_lock(&pthread_pool_lock);
*oldstate = t->cancel_state;
if (oldstate != NULL) {
*oldstate = t->cancel_state;
}
t->cancel_state = state;
cancel_pending = t->cancel_pending;
k_spin_unlock(&pthread_pool_lock, key);
@ -605,7 +607,9 @@ int pthread_setcanceltype(int type, int *oldtype)
}
key = k_spin_lock(&pthread_pool_lock);
*oldtype = t->cancel_type;
if (oldtype != NULL) {
*oldtype = t->cancel_type;
}
t->cancel_type = type;
k_spin_unlock(&pthread_pool_lock, key);

View file

@ -178,7 +178,7 @@ static int barrier_test_done(void)
static void *thread_top_term(void *p1)
{
pthread_t self;
int oldstate, policy, ret;
int policy, ret;
int id = POINTER_TO_INT(p1);
struct sched_param param, getschedparam;
@ -198,7 +198,7 @@ static void *thread_top_term(void *p1)
getschedparam.sched_priority);
if (id % 2) {
ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
zassert_false(ret, "Unable to set cancel state!");
}
@ -309,7 +309,6 @@ ZTEST(pthread, test_pthread_execution)
ZTEST(pthread, test_pthread_termination)
{
int32_t i, ret;
int oldstate;
pthread_t newthread[N_THR_T] = {0};
void *retval;
@ -319,7 +318,7 @@ ZTEST(pthread, test_pthread_termination)
}
/* TESTPOINT: Try setting invalid cancel state to current thread */
ret = pthread_setcancelstate(PTHREAD_CANCEL_INVALID, &oldstate);
ret = pthread_setcancelstate(PTHREAD_CANCEL_INVALID, NULL);
zassert_equal(ret, EINVAL, "invalid cancel state set!");
for (i = 0; i < N_THR_T; i++) {