ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gclib/GThreads.cpp
(Generate patch)
# Line 166 | Line 166
166  
167   /// Information to pass to the new thread (what to run).
168   struct _thread_start_info {
169 <  void (*mFunction)(void *, GThread*); ///< Pointer to the function to be executed.
169 >  /*
170    void * mArg;               ///< Function argument for the thread function.
171    GThread * mThread;          ///< Pointer to the thread object.
172 +  */
173 +  GThreadData threadData;
174 +  //void (*mFunction)(void *, GThread*);
175 +  void (*mFunction)(void *); ///< Pointer to the function to be executed.
176 +  void (*gtFunction)(GThreadData&); //custom variant, passing GThreadData
177 +  //handy constructors:
178 +  _thread_start_info():threadData() {
179 +      mFunction=NULL;
180 +      gtFunction=NULL;
181 +      }
182 +  _thread_start_info(GThread* t, void (*aFunc)(void *), void* udata):
183 +    threadData(udata, t) {
184 +       mFunction=aFunc;
185 +       gtFunction=NULL;
186 +       }
187 +  _thread_start_info(GThread* t, void (*gtFunc)(GThreadData &), void* udata):
188 +    threadData(udata, t) {
189 +       mFunction=NULL;
190 +       gtFunction=gtFunc;
191 +       }
192   };
193  
194   // Thread wrapper function.
# Line 190 | Line 210
210    catch(...)
211    {
212      // Uncaught exceptions will terminate the application (default behavior
213 <    // according to the C++0x draft)
213 >    // according to the C++11)
214      std::terminate();
215    }
216   */
217 <  ti->mFunction(ti->mArg, ti->mThread);
217 >  //ti->mFunction(ti->mArg, ti->mThread);
218    
219 +  //cheap trick to pass current GThread pointer
220 +  //when the user doesn't pass anything
221 +  if (ti->gtFunction) {
222 +    ti->gtFunction(ti->threadData);
223 +  }
224 +  else {
225 +    if (ti->threadData.udata) {
226 +      ti->mFunction(ti->threadData.udata);
227 +    }
228 +    else {
229 +      ti->mFunction(ti->threadData.thread);
230 +    }
231 +  }
232    // The thread is no longer executing
233 <  GLockGuard<GMutex> guard(ti->mThread->mDataMutex);
234 <  ti->mThread->mNotAThread = true;
235 <  GThread::update_counter(-1, ti->mThread);
233 >  GLockGuard<GMutex> guard(ti->threadData.thread->mDataMutex);
234 >  ti->threadData.thread->mNotAThread = true;
235 >  GThread::update_counter(-1, ti->threadData.thread);
236    // The thread is responsible for freeing the startup information
237    delete ti;
238  
239    return 0;
240   }
241  
209 GThread::GThread(void (*aFunction)(void *, GThread*), void * aArg)
210 {
211  // Serialize access to this thread structure
212  GLockGuard<GMutex> guard(mDataMutex);
242  
243 <  // Fill out the thread startup information (passed to the thread wrapper,
244 <  // which will eventually free it)
245 <  _thread_start_info * ti = new _thread_start_info;
217 <  ti->mFunction = aFunction;
243 > void GThread::initStart(void* tidata) {
244 > _thread_start_info * ti = (_thread_start_info *) tidata;
245 >   /*ti->mFunction = aFunction;
246    ti->mArg = aArg;
247 <  ti->mThread = this;
247 >  ti->mThread = this;*/
248  
249    // The thread is now alive
250    mNotAThread = false;
# Line 238 | Line 266
266     else GThread::update_counter(1, this);
267   }
268  
269 + //GThread::GThread(void (*aFunction)(void *, GThread*), void * aArg)
270 + GThread::GThread(void (*aFunction)(void *), void * aArg): mId(0), mHandle(0), mNotAThread(true)
271 + #if defined(_GTHREADS_WIN32_)
272 +    , mWin32ThreadID(0)
273 + #endif
274 +    {
275 +  kickStart(aFunction, aArg);
276 + }
277 +
278 + void GThread::kickStart(void (*aFunction)(void *), void * aArg) {
279 +  // Serialize access to this thread structure
280 +  GLockGuard<GMutex> guard(mDataMutex);
281 +  // Fill out the thread startup information (passed to the thread wrapper,
282 +  // which will eventually free it)
283 +  _thread_start_info * ti = new _thread_start_info(this, aFunction, aArg);
284 +  initStart(ti);
285 + }
286 +
287 + //custom alternate constructor (non-C++11 compatible), passing GThreadData back to the
288 + //user function in order to easily retrieve current GThread object
289 + //(better alternative to this_thread)
290 + GThread::GThread(void (*gFunction)(GThreadData& thread_data), void * aArg) {
291 +        kickStart(gFunction, aArg);
292 + }
293 +
294 + void GThread::kickStart(void (*gFunction)(GThreadData& thread_data), void * aArg) {
295 +  // Serialize access to this thread structure
296 +  GLockGuard<GMutex> guard(mDataMutex);
297 +
298 +  // Fill out the thread startup information (passed to the thread wrapper,
299 +  // which will eventually free it)
300 +  _thread_start_info * ti = new _thread_start_info(this, gFunction, aArg);
301 +  initStart(ti);
302 + }
303 +
304   GThread::~GThread()
305   {
306    if(joinable()) {
307 <    //std::terminate();
307 >    //std::terminate(); -- why??
308      GThread::update_counter(-1, this);
309 +    mDataMutex.lock();
310 + #if defined(_TTHREAD_WIN32_)
311 +    CloseHandle(mHandle);
312 + #elif defined(_TTHREAD_POSIX_)
313 +    pthread_detach(mHandle);
314 + #endif
315 +    mDataMutex.unlock();
316      }
317   }
318  
# Line 252 | Line 322
322    {
323   #if defined(_GTHREADS_WIN32_)
324      WaitForSingleObject(mHandle, INFINITE);
325 +    CloseHandle(mHandle);
326   #elif defined(_GTHREADS_POSIX_)
327      pthread_join(mHandle, NULL);
328   #endif
329    }
330   }
331  
332 +
333 + void GThread::detach()
334 + {
335 +  mDataMutex.lock();
336 +  if(!mNotAThread)
337 +  {
338 + #if defined(_TTHREAD_WIN32_)
339 +    CloseHandle(mHandle);
340 + #elif defined(_TTHREAD_POSIX_)
341 +    pthread_detach(mHandle);
342 + #endif
343 +    mNotAThread = true;
344 +  }
345 +  mDataMutex.unlock();
346 + }
347 +
348   void GThread::wait_all() {
349    while (GThread::num_running()>0)
350 <        this_thread::sleep_for(chrono::milliseconds(2));
350 >        this_thread::sleep_for(chrono::milliseconds(4));
351   }
352  
353  
# Line 276 | Line 363
363   {
364    if(!joinable())
365      //return id();
366 <    return 0; //FIXME
366 >    return 0; //FIXME: don't use this
367     else
368       return mId;
369   /*      

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines