/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks is distributed in the hope that it will be
    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

#ifndef _TBB_tls_H
#define _TBB_tls_H

#if USE_PTHREAD
#include <pthread.h>
#else /* assume USE_WINTHREAD */
#if defined(_XBOX)
    #define NONET
    #define NOD3D
    #include <xtl.h>
#else
#include <windows.h>
#endif
#endif

namespace tbb {

namespace internal {

typedef void (*tls_dtor_t)(void*);

//! Basic cross-platform wrapper class for TLS operations.
template <typename T>
class basic_tls {
#if USE_PTHREAD
    typedef pthread_key_t tls_key_t;
public:
    int  create( tls_dtor_t dtor = NULL ) {
        return pthread_key_create(&my_key, dtor);
    }
    int  destroy()      { return pthread_key_delete(my_key); }
    void set( T value ) { pthread_setspecific(my_key, (void*)value); }
    T    get()          { return (T)pthread_getspecific(my_key); }
#else /* USE_WINTHREAD */
    typedef DWORD tls_key_t;
public:
    int create() {
        tls_key_t tmp = TlsAlloc();
        if( tmp==TLS_OUT_OF_INDEXES )
            return TLS_OUT_OF_INDEXES;
        my_key = tmp;
        return 0;
    }
    int  destroy()      { TlsFree(my_key); my_key=0; return 0; }
    void set( T value ) { TlsSetValue(my_key, (LPVOID)value); }
    T    get()          { return (T)TlsGetValue(my_key); }
#endif
private:
    tls_key_t my_key;
};

//! More advanced TLS support template class.
/** It supports RAII and to some extent mimic __declspec(thread) variables. */
template <typename T>
class tls : public basic_tls<T> {
    typedef basic_tls<T> base;
public:
    tls()  { base::create();  }
    ~tls() { base::destroy(); }
    T operator=(T value) { base::set(value); return value; }
    operator T() { return base::get(); }
};

template <typename T>
class tls<T*> : basic_tls<T*> {
    typedef basic_tls<T*> base;
    static void internal_dtor(void* ptr) {
        if (ptr) delete (T*)ptr;
    }
    T* internal_get() {
        T* result = base::get();
        if (!result) {
            result = new T;
            base::set(result);
        }
        return result;
    }
public:
    tls()  {
#if USE_PTHREAD
        base::create( internal_dtor );
#else
        base::create();
#endif
    }
    ~tls() { base::destroy(); }
    T* operator=(T* value) { base::set(value); return value; }
    operator T*()   { return  internal_get(); }
    T* operator->() { return  internal_get(); }
    T& operator*()  { return *internal_get(); }
};

} // namespace internal

} // namespace tbb

#endif /* _TBB_tls_H */
