views:

445

answers:

1

I'm currently working on a multi-threaded application that would be deployed on arm and ppc architecture. I'm having some problem with pthread_cancel on arm.

pthread_cancel on arm doesn't behave the same with ppc. The thread gets cancelled but the destructor for the thread's local variable isn't being called on arm. I also tried explicitly defining a cancellation cleanup handler routine installed via pthread_cleanup_push. But it isn't being called when the thread is cancelled.

The code works fine with ppc. When a thread is cancelled, local variable's destructor is being called. And when I explicitly defined a cleanup handler, it was called and executed when pthread_cancel was called.

Am I missing something? Some compiler options perhaps?

  • Programming Language: C++
  • Compilers: arm-linux-g++/powerpc-linux-g++
  • OS: Linux

EDIT:

I have found a sort of similar problem logged on this libc bug.

Using gcc instead of g++ and adding -fno-exception compiler option did the trick. But I really want to understand stuff behind this issue. Moreover, the -fno-exception means I won't be able to perform exception handling in my application, not that I'm using it now but I might be in the future.

Thanks.

+2  A: 

Thread cancellation without the help from the application is a bad idea. Just google. It is much better to tell the thread to end itself by setting a flag variable that is periodically checked by the thread.

Actually cancellation is so hard that it has been omitted from the latest C++0x draft. You can search http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html and won't find any mention of cancellation at all. Here's the definition of the proposed thread class (you won't find cancel there):

class thread
{
public:
    // types:
    class id;
    typedef implementation-defined native_handle_type; // See [thread.native]

    // construct/copy/destroy:
    thread();
    template <class F> explicit thread(F f);
    template <class F, class ...Args> thread(F&& f, Args&&... args);
    ~thread();
    thread(const thread&) = delete;
    thread(thread&&);
    thread& operator=(const thread&) = delete;
    thread& operator=(thread&&);

    // members:
    void swap(thread&&);
    bool joinable() const;
    void join();
    void detach();
    id get_id() const;
    native_handle_type native_handle(); // See [thread.native]

    // static members:
    static unsigned hardware_concurrency();
};
lothar
I settled for something like this. I just decided to stay away from pthread_cancel and all the mess it could bring. I just added a flag variable denoting the state of the thread and checked the state on some areas designated as cancellation points. I also sent a SIGINT to break from blocking I/O calls. This way I would have a full control as to the cancellation points and the thread would be able to terminate cleanly and gracefully all the time. Thanks!
teriz