pthread.h: typo in #define pthread_cleanup_push/pthread_cleanup_pop

Mark Andrews marka at isc.org
Tue Nov 24 22:30:25 UTC 2009


In message <Pine.GSO.4.64.0911241718490.5810 at sea.ntplx.net>, Daniel Eischen wri
tes:
> On Wed, 25 Nov 2009, Mark Andrews wrote:
> 
> >
> > In message <20091124153422.GT2331 at deviant.kiev.zoral.com.ua>, Kostik Belous
> ov write
> > s:
> >>
> >> --i616tqyc3hrkKsk2
> >> Content-Type: text/plain; charset=us-ascii
> >> Content-Disposition: inline
> >> Content-Transfer-Encoding: quoted-printable
> >>
> >> On Tue, Nov 24, 2009 at 05:18:29PM +0200, Mikolaj Golub wrote:
> >>
> >> pthread_cleanup_push/pop are supposed to be used from the common
> >> lexical scope. Citation from SUSv4:
> >>
> >> These functions may be implemented as macros. The application shall
> >> ensure that they appear as statements, and in pairs within the same
> >> lexical scope (that is, the pthread_cleanup_push() macro may be
> >> thought to expand to a token list whose first token is '{' with
> >> pthread_cleanup_pop() expanding to a token list whose last token is the
> >> corresponding '}' ).
> >>
> >> Your change is wrong.
> >>
> >> Basically, the code should do
> >> 	pthread_cleanup_push(some_func, arh);
> >> 	something ...
> >> 	pthread_cleanup_pop(1);
> >> (1 denotes that some_func should be called).
> >
> > The problem is that that expands to C code that can only be used
> > with newer C compilers.  This expansion should be usable with all
> > C compilers.
> >
> > #define         pthread_cleanup_push(cleanup_routine, cleanup_arg)         
> \
> > 		{                                                          \
> > 	        	struct _pthread_cleanup_info __cleanup_info__;     \
> >                        __pthread_cleanup_push_imp(cleanup_routine, cleanup 
> _arg,\
> > 						   &__cleanup_info__)
> >
> > #define         pthread_cleanup_pop(execute)                               
> \
> >                       __pthread_cleanup_pop_imp(execute);                \
> >                } ((void)0)
> 
> Hmm, agreed.  But note that Solaris 10 does it this way:
> 
> #define	pthread_cleanup_push(routine, args) { \
>  	_cleanup_t _cleanup_info; \
>  	__pthread_cleanup_push((_Voidfp)(routine), (void *)(args), \
>  				(caddr_t)_getfp(), &_cleanup_info);
> 
> #define	pthread_cleanup_pop(ex) \
>  	__pthread_cleanup_pop(ex, &_cleanup_info); \
> }

Writing portable macros that don't generate compiler warnings is fun. :-)

Tricks like "do { <body> } while (0)" and  "{ <body> } ((void)0)" absorb
the pesky semi-colon.
 
> -- 
> DE
-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: marka at isc.org


More information about the freebsd-stable mailing list