root/juggler/tags/1.0.5/Threads/vjThreadKeyPosix.h

Revision 3930, 7.9 kB (checked in by patrickh, 8 years ago)

Set the thread-specific data pointer to NULL in the constructors. I was
hoping that this would fix a dangling pointer read in the overloaded
operator<< in vjBaseThread.cpp, but it doesn't. :( Still, it shouldn't
hurt anything to initialize the value before it's read.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
2  *
3  * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
4  *
5  * Original Authors:
6  *   Allen Bierbaum, Christopher Just,
7  *   Patrick Hartling, Kevin Meinert,
8  *   Carolina Cruz-Neira, Albert Baker
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  * -----------------------------------------------------------------
26  * File:          $RCSfile$
27  * Date modified: $Date$
28  * Version:       $Revision$
29  * -----------------------------------------------------------------
30  *
31  *************** <auto-copyright.pl END do not edit this line> ***************/
32
33
34 /*
35  * --------------------------------------------------------------------------
36  * NOTES:
37  *    - This file (vjThreadKeyPosix.h) MUST be included by vjThread.h, not
38  *      the other way around.
39  * --------------------------------------------------------------------------
40  */
41
42 #ifndef _VJ_THREAD_KEY_POSIX_H_
43 #define _VJ_THREAD_KEY_POSIX_H_
44
45 #include <vjConfig.h>
46 #include <pthread.h>
47 #include <sys/types.h>
48
49 #include <Threads/vjThreadFunctor.h>
50
51
52 // Key destructor function type.
53 #ifdef _PTHREADS_DRAFT_4
54     typedef pthread_destructor_t        vjKeyDestructor;
55 #else
56     typedef vj_thread_func_t            vjKeyDestructor;
57 #endif
58
59
60 //: Wrapper around POSIX threads thread-specific data.
61
62 class vjThreadKeyPosix {
63 public:
64     // -----------------------------------------------------------------------
65     //: Constructor.
66     // -----------------------------------------------------------------------
67     vjThreadKeyPosix (void) {
68         keycreate(NULL);
69         setspecific(NULL);
70     }
71
72     // -----------------------------------------------------------------------
73     //: Constructor.
74     // -----------------------------------------------------------------------
75     vjThreadKeyPosix (vj_thread_func_t destructor, void* arg) {
76         keycreate(destructor, arg);
77         setspecific(NULL);
78     }
79
80     // -----------------------------------------------------------------------
81     //: Constructor.
82     // -----------------------------------------------------------------------
83     vjThreadKeyPosix (vjBaseThreadFunctor* destructor) {
84         keycreate(destructor);
85         setspecific(NULL);
86     }
87
88     // -----------------------------------------------------------------------
89     //: Destructor.
90     // -----------------------------------------------------------------------
91     ~vjThreadKeyPosix (void) {
92         keyfree();
93     }
94
95     // -----------------------------------------------------------------------
96     //: Allocate a <keyp> that is used to identify data that is specific to
97     //+ each thread in the process, is global to all threads in the process
98     //+ and is destroyed using the spcefied destructor function that takes a
99     //+ single argument.
100     //
101     //! PRE: None.
102     //! POST: A key is created and is associated with the specified
103     //+       destructor function and argument.
104     //
105     //! ARGS: dest_func - The destructor function for the key.  This uses
106     //+                   the functor data structure.
107     //! ARGS: arg - Argument to be passed to destructor (optional).
108     //
109     //! RETURNS:  0 - Successful completion
110     //! RETURNS: -1 - Error
111     //
112     //! NOTE: Use this routine to construct the key destructor function if
113     //+       it requires arguments.  Otherwise, use the two-argument version
114     //+       of keycreate().
115     // -----------------------------------------------------------------------
116     int
117     keycreate (vj_thread_func_t destructor, void* arg) {
118         vjThreadNonMemberFunctor *NonMemFunctor = new vjThreadNonMemberFunctor(destructor, arg);
119
120         return keycreate(NonMemFunctor);
121     }
122
123     // -----------------------------------------------------------------------
124     //: Allocates a <keyp> that is used to identify data that is specific to
125     //+ each thread in the process, is global to all threads in the process
126     //+ and is destroyed by the specified destructor function.
127     //
128     //! PRE: None.
129     //! POST: A key is created and is associated with the specified
130     //+       destructor function.
131     //
132     //! ARGS: desctructor - Procedure to be called to destroy a data value
133     //+                     associated with the key when the thread
134     //+                     terminates.
135     //
136     //! RETURNS:  0 - Successful completion
137     //! RETURNS: -1 - Error
138     // -----------------------------------------------------------------------
139     int
140     keycreate ( vjBaseThreadFunctor* destructor) {
141 #ifdef _PTHREADS_DRAFT_4
142         return pthread_keycreate(&keyID, (vjKeyDestructor) destructor);
143 #else
144         return pthread_key_create(&keyID, (vjKeyDestructor) destructor);
145 #endif
146     }
147
148     // -----------------------------------------------------------------------
149     //: Free up this key so that other threads may reuse it.
150     //
151     //! PRE: This key must have been properly created using the keycreate()
152     //+      member function.
153     //! POST: This key is destroyed using the destructor function previously
154     //+       associated with it, and its resources are freed.
155     //
156     //! RETURNS:  0 - Successful completion
157     //! RETURNS: -1 - Error
158     //
159     //! NOTE: This is not currently supported on HP-UX 10.20.
160     // -----------------------------------------------------------------------
161     int
162     keyfree (void) {
163 #ifdef _PTHREADS_DRAFT_4
164         std::cerr << "keyfree() not supported with this POSIX threads "
165                   << "implementation\n";
166
167         return -1;
168 #else
169         return pthread_key_delete(keyID);
170 #endif
171     }
172
173     // -----------------------------------------------------------------------
174     //: Bind value to the thread-specific data key, <key>, for the calling
175     //+ thread.
176     //
177     //! PRE: The specified key must have been properly created using the
178     //+      keycreate() member function.
179     //! POST: The specified value is associated with the key for the calling
180     //+       thread.
181     //
182     //! ARGS: value - Address containing data to be associated with the
183     //+               specified key for the current thread.
184     //
185     //! RETURNS:  0 - Successful completion
186     //! RETURNS: -1 - Error
187     // -----------------------------------------------------------------------
188     int
189     setspecific (void* value) {
190         return pthread_setspecific(keyID, value);
191     }
192
193     // -----------------------------------------------------------------------
194     //: Stores the current value bound to <key> for the calling thread into
195     //+ the location pointed to by <valuep>.
196     //
197     //! PRE: The specified key must have been properly created using the
198     //+      keycreate() member function.
199     //! POST: The value associated with the key is obtained and stored in the
200     //+       pointer valuep so that the caller may work with it.
201     //
202     //! ARGS: valuep - Address of the current data value associated with the
203     //+                key.
204     //
205     //! RETURNS:  0 - Successful completion
206     //! RETURNS: -1 - Error
207     // -----------------------------------------------------------------------
208     int
209     getspecific (void** valuep) {
210 #ifdef _PTHREADS_DRAFT_4
211         return pthread_getspecific(keyID, valuep);
212 #else
213         *valuep = pthread_getspecific(keyID);
214
215         return 0;
216 #endif
217     }
218
219 private:
220     pthread_key_t keyID;                //: Thread key ID
221 };
222
223 #endif  /* _VJ_THREAD_KEY_POSIX_H_ */
Note: See TracBrowser for help on using the browser.