Your message dated Sat, 05 Jan 2008 17:09:30 +0100 with message-id <20080105160930.GB22996@artemis.madism.org> and subject line Bug#459322: libc6-dev: implementation of pthread_cleanup_pop_restore_np(1) is bogus has caused the attached Bug report to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what I am talking about this indicates a serious mail system misconfiguration somewhere. Please contact me immediately.) Debian bug tracking system administrator (administrator, Debian Bugs database)
--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: libc6-dev: implementation of pthread_cleanup_pop_restore_np(1) is bogus
- From: "Peter T. Breuer" <ptb@inv.it.uc3m.es>
- Date: Sat, 05 Jan 2008 15:44:36 +0100
- Message-id: <[🔎] 20080105144436.10169.5086.reportbug@betty.it.uc3m.es>
Package: libc6-dev Version: 2.7-4 Severity: normal pthread_cleanup_pop_restore_np(1) is implemented as .. } while (0); __pthread_unregister_cancel_restore (&__cancel_buf); if (1) __cancel_routine (__cancel_arg); } while (0) and that means the cancel routine may not get executed if the thread dies after the unregister but before the execution of the cancel routine. Thus for example, if pthread_mutex_unlock is the registered cancellation routine, it will never get executed, leaving the thread group's mutex locked, and locking out other threads. This seems to me to contradict what the manual page (for pthread_cleanup_push) says: pthread_cleanup_push_defer_np is a non-portable extension that combines pthread_cleanup_push and pthread_setcanceltype(3). It pushes a cleanup handler just as pthread_cleanup_push does, but also saves the current cancellation type and sets it to deferred cancellation. This ensures that the cleanup mechanism is effective even if the thread was ini- tially in asynchronous cancellation mode. but who knows what jargon like "cancellation type" and "deferred" means. Please use plain english. If you mean "die" by "cancellation" (with slight nuances about whether a condemned thread is dead yet or not), and you mean that it won't wait to join back to the main thread from which it detached by "asynchronous cancellation mode", then maybe there is some universe in which the interpretation of those words means something compatible with the behaviour. But to me, if it dies, it can leave the lock hanging. And in any case, it's all silly the way it is .. even as a macro, you should just set up the data you are saving as a declaration pthread_save_class mydata; and then have your push and pop routines refer to it explicitly pthread_push_whatever(&mydata, myfn, myarg); ... pthread_pop_whatever(&mydata, 1); then we could stop playing with those hidden open and close braces! As it is they are arguably wrongheaded as is, because one has to put the pop in a labelled place at the end of a routine pop: pthread_pop_whatever(1); and that won't work, because we have a label at the end of a block that way, thanks to your do{ /////// } while(0) stuff. One has to put the pop at the end, with goto pop; as one can't lock and unlock mutexes half way through a routine, in a while loop, because of your extra braces. It wrecks the loops. Sigh .. and the man page gets the name of the push routine wrong, at the end: pthread_cleanup_push_restore_np(pthread_mutex_unlock, (void *) &mut); ^^^^^^^^^^^^^ arrgh. pthread_mutex_lock(&mut); /* do some work */ pthread_cleanup_pop_restore_np(1); Arguably, that name would be more sensible! Peter -- System Information: Debian Release: lenny/sid APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Kernel: Linux 2.6.15.3 (PREEMPT) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C) Shell: /bin/sh linked to /bin/bash Versions of packages libc6-dev depends on: ii libc6 2.7-4 GNU C Library: Shared libraries ii linux-libc-dev 2.6.22-6 Linux Kernel Headers for developme Versions of packages libc6-dev recommends: ii gcc [c-compiler] 4:4.2.1-6 The GNU C compiler ii gcc-2.95 [c-compile 1:2.95.4-27 The GNU C compiler ii gcc-3.4 [c-compiler 3.4.6-6 The GNU C compiler ii gcc-4.1 [c-compiler 4.1.2-18 The GNU C compiler ii gcc-4.2 [c-compiler 4.2.2-4 The GNU C compiler ii tcc [c-compiler] 0.9.24~cvs20070502-2 the smallest ANSI C compiler -- no debconf information
--- End Message ---
--- Begin Message ---
- To: "Peter T. Breuer" <ptb@inv.it.uc3m.es>, 459322-done@bugs.debian.org
- Subject: Re: Bug#459322: libc6-dev: implementation of pthread_cleanup_pop_restore_np(1) is bogus
- From: Pierre Habouzit <madcoder@debian.org>
- Date: Sat, 05 Jan 2008 17:09:30 +0100
- Message-id: <20080105160930.GB22996@artemis.madism.org>
- In-reply-to: <[🔎] 20080105144436.10169.5086.reportbug@betty.it.uc3m.es>
- References: <[🔎] 20080105144436.10169.5086.reportbug@betty.it.uc3m.es>
On Sat, Jan 05, 2008 at 02:44:36PM +0000, Peter T. Breuer wrote: > Package: libc6-dev > Version: 2.7-4 > Severity: normal > > > pthread_cleanup_pop_restore_np(1) is implemented as .. > > } while (0); > __pthread_unregister_cancel_restore (&__cancel_buf); > if (1) > __cancel_routine (__cancel_arg); > } while (0) > > > and that means the cancel routine may not get executed if the thread > dies after the unregister but before the execution of the cancel > routine. Wrong, because __pthread_unregister_cancel_restore isn't a cancellation point. > Thus for example, if pthread_mutex_unlock is the registered cancellation > routine, it will never get executed, leaving the thread group's mutex locked, > and locking out other threads. That's wrong. > but who knows what jargon like "cancellation type" and "deferred" means. Well cancellation point, and deferred are specific terms with very precise meanings in the pthread context, please read POSIX about that (I believe manpages-posix-dev or sth like that in non-free has the proper man pages). If you don't get those concepts, you can't understand how pthread_cleanup_pop_restore_np works. And yes, threads are _complex_ you cannot grok it only reading a few manpages. > And in any case, it's all silly the way it is .. even as a macro, you > should just set up the data you are saving as a declaration That's because it works the very same way pthread_cleanup_push and pthread_cleanup_pop work, and those functions are POSIX, and POSIX says that those functions _MUST_ be used at the same context level, and always must be used together. It's how it works, and glibc won't change it, because it's what the norm says about portable code. I'll skip the rest of this bug report that is mostly bogus because you made wrong assumptions. Cheers, -- ·O· Pierre Habouzit ··O madcoder@debian.org OOO http://www.madism.orgAttachment: pgpkz9VSd08r5.pgp
Description: PGP signature
--- End Message ---