Matan
Matan

Reputation: 179

Is There a Function Like "pthread_getcancelstate"?

The Linux Pthread Library includes 2 functions to set a threads' cancel state and cancel type:

How can I receive those states and types? Is there a function like pthread_getcancelstate or pthread_getcanceltype? I searched on the Internet and I didn't found solutions.

Upvotes: 4

Views: 225

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754710

Since the functions pthread_setcancelstate() and pthread_setcanceltype() return the old state via the argument list, you can call the functions to set the 'safe' state/type (PTHREAD_CANCEL_DISABLE and PTHREAD_CANCEL_DEFERRED, I think), and if the old state/type was not the same, call the function a second time to reinstate the old state/type. There doesn't seem to be a 'no-op' value for the new state/type.

int pthread_getcancelstate(int *oldstate)
{
    int dont_care;
    int rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, oldstate);
    if (rc == 0 && *oldstate != PTHREAD_CANCEL_DISABLE)
        rc = pthread_setcancelstate(*oldstate, &dont_care);
    return rc;
}

int pthread_getcanceltype(int *oldtype)
{
    int dont_care;
    int rc = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, oldtype);
    if (rc == 0 && *oldtype != PTHREAD_CANCEL_DEFERRED)
        rc = pthread_setcanceltype(*oldtype, &dont_care);
    return rc;
}

The other state is PTHREAD_CANCEL_ENABLE and the other type is PTHREAD_CANCEL_ASYNCHRONOUS.

The manual pages for these functions on macOS do say that it is permissible to pass a null pointer for the old state/type, so it would be possible to eliminate the dont_care variable on macOS. However, neither the POSIX specification nor the manual page on (RHEL 7.4) Linux say that a null pointer is permissible. The code above should work safely on both those platforms.

The code is also trespassing on the namespace reserved for use by the implementation — the implementation could choose to add either or both pthread_getcancelstate() or pthread_getcanceltype() (with the same or a different interface) and there'd be no option but to rename the functions shown above. Adding the _np (non-portable) suffix might not help either; the implementation could choose to use the name with the suffix.

Upvotes: 4

Related Questions