Tutorial :cancellation handler won't run if pthread_exit called from C source instead of C++ source



Question:

I'm linking a C++ source with a C source and a C++ source. I create a thread with pthread, a cancellation point and then I call pthread_exit either through the C or the C++ source file.

If the pthread_exit call comes from the C source, the cancellation handler does not fire! What may be the reason for this?

b.cc:

#include <cstdio>  #include <cstdlib>  #include <stdbool.h>  #include <pthread.h>      extern "C" void V();  extern "C" void Vpp();  extern "C" void Vs();    #define PTHREAD_EXIT Vs            void cleanup(void*v)  {      fprintf(stderr, "Aadsfasdf\n");      exit(0);  }      void* f(void*p)  {      pthread_cleanup_push(cleanup, NULL);      PTHREAD_EXIT();      pthread_cleanup_pop(true);        return NULL;  }    int main()  {      pthread_t p;      if (pthread_create(&p, NULL, f, NULL))          abort();      for(;;);  }  

vpp.cc:

#include <pthread.h>    extern "C" void Vpp();  void Vpp() {      pthread_exit(0);  }  

v.c:

#include <pthread.h>    void V() {      pthread_exit(0);  }  

vs.s:

.text  Vs: .global Vs      call pthread_exit      spin: jmp spin  

compilation with

g++ -c vpp.cc -g -o vpp.o -Wall  gcc -c v.c -g -o v.o -Wall  as vs.s -o vs.o  g++ b.cc vpp.o v.o vs.o -o b -lpthread -g -Wall  

If PTHREAD_EXIT is Vpp the program displays a message and terminates, if it is V or Vs it doesn't.

the disassembly for V and Vpp is identical, and changing the definition of PTHREAD_EXIT between V and Vpp merely changes between call V and call Vpp in the disassembly.

EDIT: Not reproducible on another computer, so I guess I hit an error in the library or something.


Solution:1

I don't know, but you are giving the cancellation handler C++ linkage. What happens if you use C linkage for that as well?

extern "C"  {    void cleanup(void*v) { ... }  }  


Solution:2

In the "pthread.h" header file installed on my machine, the pthread_cleanup_push() function is not defined the same way for C and C++ (search for __cplusplus).

Could you try to give C linkage for both f() and cleanup()?

You may find the above link interesting: http://www.cs.rit.edu/~afb/20012/cs4/slides/threads-05.html


Solution:3

Inspired by Ch. Vu-Brugier I took a look at pthread.h and found out that I have to add

 #undef __EXCEPTIONS  

before including pthread.h. This is a satisfactory workaround for my current needs.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »