gcc 4.7 в Linux pthreads - нетривиальный обход нити thread_local с использованием __thread (без повышения)

В C ++ 11 вы можете иметь нетривиальный объект с хранилищем thread_local:

class X { ... }

void f()
{
    thread_local X x = ...;
    ...
}

К сожалению, эта функция еще не реализована в gcc (по состоянию на 4.7).

gcc позволяет вам иметь локальные переменные потока, но только с тривиальными типами.

Я ищу обходной путь:

Вот что у меня так далеко:

#include <iostream>
#include <type_traits>

using namespace std;

class X
{
public:
    X() { cout << "X::X()" << endl; };
    ~X() { cout << "X::~X()" << endl; }
};

typedef aligned_storage<sizeof(X), alignment_of<X>::value>::type XStorage;

inline void placement_delete_x(X* p) { p->~X(); }

void f()
{
        static __thread bool x_allocated = false;
        static __thread XStorage x_storage;

        if (!x_allocated)
        {
                new (&x_storage) X;
                x_allocated = true;

                // TODO: add thread cleanup that
                //     calls placement_delete_x(&x_storage)
        }

        X& x = *((X*) &x_storage);
}

int main()
{
        f();
}

Мне нужна помощь по вызовуplace_delete_x (& amp; x_storage) при выходе из текущего потока. Есть ли механизм в pthreads и / или Linux, который я могу использовать для этого? Мне нужно добавить указатель на функцию и параметр в какой-либо стек очистки pthread?

Update:

Я думаюpthread_cleanup_push может быть то, что я хочу:

http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cleanup_push.3.html

Будет ли это вызывать обработчик очистки в правильных обстоятельствах для этого использования?

Update 2:

Это выглядит какboost::thread_specific_ptr в конце концов звонитpthread_key_create сdestructor параметр, а неpthread_cleanup_push - вызвать его функцию очистки tls:

http://pubs.opengroup.org/onlinepubs/009696799/functions/pthread_key_create.html

Неясно, в чем разница между этими двумя методами, если таковые имеются. ?

Ответы на вопрос(2)

Ваш ответ на вопрос