NetBSD Problem Report #59135

From www@netbsd.org  Wed Mar  5 16:35:36 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 448971A923D
	for <gnats-bugs@gnats.NetBSD.org>; Wed,  5 Mar 2025 16:35:36 +0000 (UTC)
Message-Id: <20250305163534.CA7411A923F@mollari.NetBSD.org>
Date: Wed,  5 Mar 2025 16:35:34 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: PTHREAD_CANCEL_ASYNCHRONOUS doesn't do much
X-Send-Pr-Version: www-1.0

>Number:         59135
>Category:       lib
>Synopsis:       PTHREAD_CANCEL_ASYNCHRONOUS doesn't do much
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Mar 05 16:40:01 +0000 2025
>Originator:     Taylor R Campbell
>Release:        current, 10, 9, ...
>Organization:
The PthreadBSD Foun
>Environment:
>Description:
Under POSIX, when a thread has asynchronous cancellation configured with pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, ...), cancellation should be able to happen at any time, not just at cancellation points:

> Each thread maintains its own cancelability state, which may be encoded in two bits:
>  1. Cancelability-Enable: ...
>  2. Cancelability Type: When cancelability is enabled and the cancelability type is PTHREAD_CANCEL_ASYNCHRONOUS (as defined in <pthread.h>), new or pending cancellation requests may be acted upon at any time. When cancelability is enabled and the cancelability type is PTHREAD_CANCEL_DEFERRED (as defined in <pthread.h>), cancellation requests are held pending until a cancellation point (see below) is reached....

However, NetBSD's libpthread doesn't really do much with PTHREAD_CANCEL_ASYNCHRONOUS.
>How-To-Repeat:
#include <err.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

static void
cleanup(void *cookie)
{
	fprintf(stderr, "cleanup\n");
}

static void *
thread(void *cookie)
{
	pthread_barrier_t *bar = cookie;
	int error;

	error = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
	if (error)
		errc(1, error, "pthread_setcanceltype");
	pthread_cleanup_push(cleanup, NULL);
	fprintf(stderr, "loop forever\n");
	(void)pthread_barrier_wait(bar);
	for (;;) {
		__asm("");
	}
	pthread_cleanup_pop(0);
	return NULL;
}

int
main(void)
{
	pthread_barrier_t bar;
	pthread_t t;
	int error;

	error = pthread_barrier_init(&bar, NULL, 2);
	if (error)
		errc(1, error, "pthread_barrier_init");

	fprintf(stderr, "create thread\n");
	error = pthread_create(&t, NULL, &thread, &bar);
	if (error)
		errc(1, error, "pthread_create");
	(void)pthread_barrier_wait(&bar);
	fprintf(stderr, "cancel\n");
	error = pthread_cancel(t);
	if (error)
		errc(1, error, "pthread_cancel");
	(void)alarm(1);
	error = pthread_join(t, NULL);
	if (error)
		errc(1, error, "pthread_join");
	(void)alarm(0);
	fprintf(stderr, "ok\n");
	return 0;
}
>Fix:
1. Invent a new signal, say SIGCANCEL.
2. Teach libc's signal/sigaction/sigprocmask stubs to pretend it doesn't exist.
3. Teach libpthread to set up a SIGCANCEL handler that does pthread_cancel as appropriate.
4. Shake out all the bugs.
5. Shake out some more bugs.
6. ???
7. Profit!
8. ...just one or two more bugs

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2025 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.