pthread_cleanup_push & pthread_cleanup_pop usage
David Xu
davidxu at freebsd.org
Thu Oct 16 01:44:40 UTC 2008
Daniel Eischen wrote:
> On Tue, 7 Oct 2008, Alfred Perlstein wrote:
>
>> * John Hein <jhein at timing.com> [081007 21:45] wrote:
>>> In June pthread_cleanup_push & pthread_cleanup_pop were changed to
>>> macros
>>> that look like so...
>>
>> Hey John, I found the same problem when working on QNX a while back,
>> however that is really how it's supposed to be set up.
>>
>> I would suggest the following construct to fix the problem,
>> make your own per-thread stack of destructors that are callable
>> as functions and not macros.
>>
>> It's not too hard to do.
>>
>> Just use a pthread_key and pthread_once thingy to write a library
>> to do it, shouldn't take more than a hundred lines of code.
>>
>> FWIW, OS X and QNX have the same set of macros, not sure about
>> other OSes.
>
> Solaris as well.
>
> Just conditionally undef them before you use them.
>
> #ifdef pthread_cleanup_push
> #undef pthread_cleanup_push
> #endif
> #ifdef pthread_cleanup_pop
> #undef pthread_cleanup_pop
> #endif
>
> The library versions are still there (they have to be in order
> to be callable from non-C/C++ languages).
>
One of possible solutions is we define a C++ class in pthread.h:
#ifdef __cplusplus
class __pthread_cleanup_obj {
void (*__f)(void *);
void *__a;
int __execeute;
public:
__pthread_cleanup_obj(void (*__cleanup_routine)(void *), void *__arg) {
f = __cleanup_routine;
a = __arg;
__execute = 0;
}
~__pthread_cleanup_obj()
{
if (__execute)
__f(__a);
}
void __set_execute(int __e)
{
__execute = __e;
}
};
#define pthread_cleanup_push(f, a) { \
__pthread_cleanup_obj __cleanup(f, a); \
{
#define pthread_cleanup_pop(e) \
__cleanup.__set_execute(e); \
} \
}
#endif
but because there is no specification for C++ and threading,
it is unknown which behavior is desired.
David Xu
More information about the freebsd-threads
mailing list