I use a 3rd-party-library (dcerpc) for my application being a rpc server. Let's say the 3rd party function are in the namespace third.
I call third::listen in a thread, in order to listen for incoming requests.
"Third" provides all the mechanisms to interrupt this listen and properly exit the thread, but either it doesn't work, or I don't do it the correct way. I first try everything with the library tools (demo sample, mail-list, browse the source code to understand...) but with no success.
So I try an alternative: violently kill the listening thread. But third::listen has no cancellation point, I guess.
So this code (I simulate third::listen with listen function above):
void* listen(void*)
{
cout << "listening for calls...." << endl;
while (true) {}
printf ("Server stoppped listening\n");
return 0;
}
int main()
{
pthread_t thread = 0;
int res = pthread_create(&thread, 0, listen, 0);
cout << "pthread_create res: " << res << endl;
sleep(1);
bool isThreadRunning = (pthread_tryjoin_np(thread, 0) != 0);
cout << "Thread is running: " << isThreadRunning << endl;
res = pthread_cancel(thread);
cout << "pthread_cancel res: " << res << endl;
sleep(1);
isThreadRunning = (pthread_tryjoin_np(thread, 0) != 0);
cout << "Thread is running: " << isThreadRunning << endl;
res = pthread_join(thread, 0);
cout << "pthread_join res: " << res << endl;
return 0;
}
will output:
pthread_create res: 0
listening for calls....
Thread is running: 1
pthread_cancel res: 0
Thread is running: 1
and pthread_join(thread, 0) blocks (logic because no cancellation point).
My question: how to kill this thread !!
I tried with signals, but it stops my whole process, not only the thread.
My last try will be to isolate the listening in a dedicated fork process, but in my project context, it's really a pain to fork (that's another story).
Thanks a lot for any help.
Nicolas.
Whether a thread can be cancelled depends on its cancellation state and type. The default state is enabled
. So that's fine. But the default type is deferred
. That means when you send the thread a cancellation request, it's deferred until it reaches a cancellation point. Since your thread doesn't do anything in the empty loop, it doesn't reach a cancellation point at all. Hence, it doesn't respond to pthread_cancel()
.
You can set the cancellation type of the thread to PTHREAD_CANCEL_ASYNCHRONOUS
which will typically make the thread exit. Call
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
before the loop.
Or you can call one of the functions that's a cancellation point. For example, do fflush(stdout);
inside the loop.
POSIX list a number of functions as cancellation point. See cancellation points for such a list.
I can't make any comment on the "3rd party" library that doesn't respond to exiting threads with the limited information you have given.