[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Potential spiped 1.6.1 release -- please test



On Sun, Feb 09, 2020 at 03:39:07AM +0200, Peter Pentchev wrote:
> So what do you think about the attached patch that addresses both your
> questions: a minimal test case for the kernel/libc maintainers (but see
> below) and a -DPOSIXFAIL_PTHREAD_CANCEL test for spiped?

Thanks for digging into this further!  The minimal test case was extremely
valuable.  I think that we'll hold off on POSIXFAIL_PTHREAD_CANCEL until we've
investigated a bit more.

As far as I understand it now, the crux of the matter is "what's the lifetime
of a POSIX thread?".  Namely, what happens if the thread finishes quickly?

- the page about pthread_cancel says, in the "rationale" (informative)
  section:
    If an implementation detects use of a thread ID after the end of its
    lifetime, it is recommended that the function should fail and report an
    [ESRCH] error.
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cancel.html

Ok, so perhaps we should *expect* to see ESRCH in the test case?

- well, pthread_join has exactly the same text in the rationale section:
    If an implementation detects use of a thread ID after the end of its
    lifetime, it is recommended that the function should fail and report an
    [ESRCH] error.
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html

To be fair, the description of pthread_join() states:
    The pthread_join() function shall suspend execution of the calling thread
    until the target thread terminates, unless the target thread has already
    terminated.
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html

I imagine that the "[non-informative] description" text superceedes the
"rationale" text?  It's certainly the case that pthread_join() seems to be
perfectly happy handling a thread ID which has finish, whereas pthread_cancel
is not.

At the moment I'm leaning towards ignoring any ESRCH errors in the test suite,
but let's see what Colin says about the attached test case (a modified version
of the test case that Peter already produced).

Cheers,
- Graham
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

/* Random value that we'll increment to check if the thread did anything. */
#define TOKEN_INIT 4   // chosen by fair dice roll.
                       // guaranteed to be random.

static void *
workthread(void * restrict cookie)
{
	int *token = cookie;

	/* Increment the token so that we'll know that it worked. */
	(*token)++;
	return NULL;
}

int
main(void)
{
	pthread_t thrid;
	int rc;
	int token = TOKEN_INIT;	/* value that we'll try to recognize. */

	/* Create thread. */
	if ((rc = pthread_create(&thrid, NULL, workthread, &token)) != 0) {
		fprintf(stderr, "pthread_create(): %s\n", strerror(rc));
		return 1;
	}

	/* Wait. */
	sleep(1);

#if 0
	/* Problem: cancel instead of joining. */
	if ((rc = pthread_cancel(thrid)) != 0) {
		fprintf(stderr, "pthread_cancel(): %s\n", strerror(rc));
		return 1;
	}
#endif

	/* Join the thread. */
	if ((rc = pthread_join(thrid, NULL)) != 0) {
		fprintf(stderr, "pthread_join(): %s\n", strerror(rc));
		return 1;
	}

	/* Does the token have the expected value? */
	if (token != TOKEN_INIT + 1)
		fprintf(stdout, "Bad token value: %i\n", token);

	return 0;
}