X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=liblttng-ust-comm%2Fust-cancelstate.c;fp=liblttng-ust-comm%2Fust-cancelstate.c;h=298ffcbe50f0e52235b020b906200c22b990e4d8;hb=595c15773def8e249145c4dead560ba7329810c7;hp=0000000000000000000000000000000000000000;hpb=1a3b8784434bb597b623100a591aeeb835fccf16;p=deliverable%2Flttng-ust.git diff --git a/liblttng-ust-comm/ust-cancelstate.c b/liblttng-ust-comm/ust-cancelstate.c new file mode 100644 index 00000000..298ffcbe --- /dev/null +++ b/liblttng-ust-comm/ust-cancelstate.c @@ -0,0 +1,60 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (C) 2021 Mathieu Desnoyers + */ + +#include +#include +#include +#include +#include +#include + +struct ust_cancelstate { + int nesting; + int oldstate; /* oldstate for outermost nesting */ +}; + +static DEFINE_URCU_TLS(struct ust_cancelstate, thread_state); + +int lttng_ust_cancelstate_disable_push(void) +{ + struct ust_cancelstate *state = &URCU_TLS(thread_state); + int ret, oldstate; + + if (state->nesting++) + goto end; + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + if (ret) { + ERR("pthread_setcancelstate: %s", strerror(ret)); + return -1; + } + state->oldstate = oldstate; +end: + return 0; +} + +int lttng_ust_cancelstate_disable_pop(void) +{ + struct ust_cancelstate *state = &URCU_TLS(thread_state); + int ret, oldstate; + + if (!state->nesting) + return -1; + if (--state->nesting) + goto end; + ret = pthread_setcancelstate(state->oldstate, &oldstate); + if (ret) { + ERR("pthread_setcancelstate: %s", strerror(ret)); + return -1; + } + if (oldstate != PTHREAD_CANCEL_DISABLE) { + ERR("pthread_setcancelstate: unexpected oldstate"); + return -1; + } +end: + return 0; +} + +