Lunchbox  1.8.0
perThread.h
1 
2 /* Copyright (c) 2005-2013, Stefan Eilemann <eile@equalizergraphics.com>
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License version 2.1 as published
6  * by the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11  * details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this library; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  */
17 
18 #ifndef LUNCHBOX_PERTHREAD_H
19 #define LUNCHBOX_PERTHREAD_H
20 
21 #include <lunchbox/tls.h> // member
22 
23 namespace lunchbox
24 {
25 namespace detail { class PerThread; }
26 
28 template< class T > void perThreadDelete( T* object ) { delete object; }
29 
31 template< class T > void perThreadNoDelete( T* object ) {}
32 
41 template< class T, void (*D)( T* ) = &perThreadDelete< T > >
42 class PerThread : public NonCopyable
43 {
44 public:
46  PerThread();
48  ~PerThread();
49 
51  PerThread<T, D>& operator = ( const T* data );
54 
56  T* get();
58  const T* get() const;
60  T* operator->();
62  const T* operator->() const;
63 
65  T& operator*()
66  { LBASSERTINFO( get(), className( this )); return *get(); }
68  const T& operator*() const
69  { LBASSERTINFO( get(), className( this )); return *get(); }
70 
75  bool operator == ( const PerThread& rhs ) const
76  { return ( get() == rhs.get( )); }
77 
82  bool operator == ( const T* rhs ) const { return ( get()==rhs ); }
83 
88  bool operator != ( const T* rhs ) const { return ( get()!=rhs ); }
89 
94  bool operator ! () const;
95 
100  bool isValid() const;
101 
102 private:
103  TLS tls_;
104 };
105 
106 template< class T, void (*D)( T* ) > PerThread<T, D>::PerThread()
107  : tls_( (TLS::ThreadDestructor_t)D )
108 {}
109 
110 template< class T, void (*D)( T* ) > PerThread<T, D>::~PerThread()
111 {}
112 
113 template< class T, void (*D)( T* ) >
115 {
116  tls_.set( static_cast< const void* >( data ));
117  return *this;
118 }
119 
120 template< class T, void (*D)( T* ) >
122 {
123  tls_.set( rhs.tls_.get( ));
124  return *this;
125 }
126 
127 template< class T, void (*D)( T* ) > T* PerThread<T, D>::get()
128 {
129  return static_cast< T* >( tls_.get( ));
130 }
131 
132 template< class T, void (*D)( T* ) > const T* PerThread<T, D>::get() const
133 {
134  return static_cast< const T* >( tls_.get( ));
135 }
136 
137 template< class T, void (*D)( T* ) > T* PerThread<T, D>::operator->()
138 {
139  return static_cast< T* >( tls_.get( ));
140 }
141 
142 template< class T, void (*D)( T* ) >
144 {
145  return static_cast< T* >( tls_.get( ));
146 }
147 
148 template< class T, void (*D)( T* ) > bool PerThread<T, D>::operator ! () const
149 {
150  return tls_.get() == 0;
151 }
152 
153 template< class T, void (*D)( T* ) > bool PerThread<T, D>::isValid() const
154 {
155  return tls_.get() != 0;
156 }
157 
158 }
159 #endif //LUNCHBOX_PERTHREAD_H