2.1. Thread

Start cpp section to pthread/pthread_thread.hpp[1 /1 ]
     1: #line 233 "./lpsrc/flx_pthread.pak"
     2: #ifndef __FLX_THREAD__
     3: #define __FLX_THREAD__
     4: #include <flx_pthread_config.hpp>
     5: 
     6: #ifdef _WIN32
     7: #include <windows.h>
     8: #else
     9: #include <pthread.h>
    10: #endif
    11: 
    12: // auto pthread, because I forget how to deallocate them nicely
    13: // could init in the constructor, but ultimately you don't want the thread
    14: // barging in before you've finished doing other stuff
    15: // Addendum (20051128): doing stdio in turns out to be not very safe.
    16: // I don't know if printf et al are supposed to be thread safe (most impls
    17: // seem to try to be) but I sometimes get deadlocks in ppc64 os x 10.4.2
    18: // with 4.0.1 when printfing to stdout. Nasty.
    19: 
    20: namespace flx { namespace pthread {
    21: 
    22: // ********************************************************
    23: /// Posix Threads. This class simply wraps the creation
    24: /// and joining of threads. It is not safe.
    25: // ********************************************************
    26: 
    27: class PTHREAD_EXTERN flx_detached_thread_t {
    28: #ifdef _WIN32
    29:   HANDLE    thread;
    30: #else
    31:   pthread_t   thr;        ///< the thread
    32: #endif
    33:   flx_detached_thread_t(flx_detached_thread_t const&); // uncopyable
    34:   void operator=(flx_detached_thread_t const&); // uncopyable
    35: public:
    36:   flx_detached_thread_t();
    37:   ~flx_detached_thread_t();
    38: #ifdef _WIN32
    39:   int init(LPTHREAD_START_ROUTINE, LPVOID lParam);
    40: #else
    41:   int init(void* (*start)(void*), void* udat);
    42: #endif
    43: };
    44: 
    45: class PTHREAD_EXTERN flx_thread_t {
    46: #ifdef _WIN32
    47:   HANDLE    thread;
    48: #else
    49:   pthread_t   thr;        ///< the thread
    50: #endif
    51:   flx_thread_t(flx_thread_t const&); // uncopyable
    52:   void operator=(flx_thread_t const&); // uncopyable
    53: public:
    54:   flx_thread_t();
    55:   ~flx_thread_t();
    56: #ifdef _WIN32
    57:   int init(LPTHREAD_START_ROUTINE, LPVOID lParam);
    58: #else
    59:   int init(void* (*start)(void*), void* udat);
    60: #endif
    61:   void join();
    62: };
    63: 
    64: /// RAII wrapper for thread class
    65: class PTHREAD_EXTERN flx_thread_wrapper_t {
    66:   flx_thread_t thread;
    67:   flx_thread_wrapper_t(flx_thread_wrapper_t const&); // uncopyable
    68:   void operator=(flx_thread_wrapper_t const&); // uncopyable
    69: public:
    70:   ~flx_thread_wrapper_t();
    71: #ifndef _WIN32
    72:   flx_thread_wrapper_t(void* (*start)(void*), void* udat);
    73: #else
    74:   flx_thread_wrapper_t(LPTHREAD_START_ROUTINE, LPVOID);
    75: #endif
    76: };
    77: 
    78: }}
    79: #endif
    80: 
End cpp section to pthread/pthread_thread.hpp[1]
Start cpp section to pthread/pthread_posix_thread.cpp[1 /1 ]
     1: #line 314 "./lpsrc/flx_pthread.pak"
     2: #include "pthread_thread.hpp"
     3: #include <stdio.h>
     4: #include <string.h>  // strerror
     5: 
     6: namespace flx { namespace pthread {
     7: 
     8: // ---- detached threads ----------
     9: 
    10: flx_detached_thread_t::flx_detached_thread_t(flx_detached_thread_t const&){} // uncopyable
    11: void flx_detached_thread_t::operator=(flx_detached_thread_t const&){} // uncopyable
    12: 
    13: int
    14: flx_detached_thread_t::init(void* (*start)(void*), void* udat)
    15: {
    16:   pthread_attr_t attr;
    17:   pthread_attr_init(&attr);
    18:   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    19:   int res = pthread_create(&thr, &attr, start, udat);
    20:   if(res)
    21:   {
    22:      fprintf(stderr, "flx_detached_thread_t: pthread_create_failed: %s\n",
    23:        strerror(res));
    24:   }
    25:   pthread_attr_destroy(&attr);
    26:   return res;
    27: }
    28: 
    29: flx_detached_thread_t::~flx_detached_thread_t() { }
    30: flx_detached_thread_t::flx_detached_thread_t() { }
    31: 
    32: // ---- joinable threads ----------
    33: flx_thread_t::flx_thread_t(flx_thread_t const&){} // uncopyable
    34: void flx_thread_t::operator=(flx_thread_t const&){} // uncopyable
    35: 
    36: int
    37: flx_thread_t::init(void* (*start)(void*), void* udat)
    38: {
    39:   int res = pthread_create(&thr, NULL, start, udat);
    40:   if(res)
    41:   {
    42:      fprintf(stderr, "flx_thread_t: pthread_create_failed: %s\n",
    43:        strerror(res));
    44:   }
    45:   return res;
    46: }
    47: 
    48: void flx_thread_t::join() { pthread_join(thr, NULL); }
    49: 
    50: flx_thread_t::~flx_thread_t() { }
    51: flx_thread_t::flx_thread_t() { }
    52: 
    53: // ---- joinable thread wrapper ----------
    54: 
    55: flx_thread_wrapper_t::flx_thread_wrapper_t(flx_thread_wrapper_t const&){} // uncopyable
    56: void flx_thread_wrapper_t::operator=(flx_thread_wrapper_t const&){} // uncopyable
    57: 
    58: flx_thread_wrapper_t::flx_thread_wrapper_t(void* (*start)(void*), void* udat)
    59: {
    60:   thread.init(start,udat);
    61: }
    62: 
    63: flx_thread_wrapper_t::~flx_thread_wrapper_t() { thread.join(); }
    64: 
    65: }}
    66: 
End cpp section to pthread/pthread_posix_thread.cpp[1]
Start cpp section to pthread/pthread_win_thread.cpp[1 /1 ]
     1: #line 381 "./lpsrc/flx_pthread.pak"
     2: #include "pthread_thread.hpp"
     3: #include <stdio.h>
     4: 
     5: namespace flx { namespace pthread {
     6: 
     7: // ---- detached threads ----------
     8: 
     9: flx_detached_thread_t::flx_detached_thread_t(flx_detached_thread_t const&){} // uncopyable
    10: void flx_detached_thread_t::operator=(flx_detached_thread_t const&){} // uncopyable
    11: 
    12: // returns -1 on failure with error in GetLastError, 0 if all good.
    13: int
    14: flx_detached_thread_t::init(LPTHREAD_START_ROUTINE fn, LPVOID lParam)
    15: {
    16:   DWORD thread_id = 0;
    17:   thread = (HANDLE)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)fn, lParam, 0,
    18:     &thread_id);
    19:   if(!thread)
    20:   {
    21:     DWORD err = GetLastError();
    22:     fprintf(stderr, "flx_detached_thread_t: CreateThread failed: %i\n", err);
    23:     return err;
    24:   }
    25:   return 0;
    26: }
    27: 
    28: flx_detached_thread_t::~flx_detached_thread_t() { CloseHandle(thread); }
    29: flx_detached_thread_t::flx_detached_thread_t() { }
    30: 
    31: // ---- joinable threads ----------
    32: flx_thread_t::flx_thread_t(flx_thread_t const&){} // uncopyable
    33: void flx_thread_t::operator=(flx_thread_t const&){} // uncopyable
    34: 
    35: 
    36: flx_thread_t::flx_thread_t() { }
    37: flx_thread_t::~flx_thread_t() { }
    38: 
    39: // this should be idempotent
    40: void
    41: flx_thread_t::join()
    42: {
    43:   // Let's try and wait for the thread to finish, however first I have to
    44:   // tell it to finish up.
    45: 
    46:   DWORD  wait_res = WaitForSingleObject(thread, INFINITE);
    47: 
    48:   // will this give me my return status? how do I get that?
    49:   if(WAIT_FAILED == wait_res)
    50:   {
    51:     fprintf(stderr,"thread wait failed (%li)\n", GetLastError());
    52:   }
    53: 
    54:   // I've already tried waiting on the  thread's exit
    55:   if(!CloseHandle(thread))
    56:   {
    57:     fprintf(stderr,"failed to delete thread (%li)\n", GetLastError());
    58:   }
    59: }
    60: 
    61: // returns -1 on failure with error in GetLastError, 0 if all good.
    62: int
    63: flx_thread_t::init(LPTHREAD_START_ROUTINE fn, LPVOID lParam)
    64: {
    65:   DWORD thread_id = 0;
    66:   thread = (HANDLE)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)fn, lParam, 0,
    67:     &thread_id);
    68: 
    69:   if(!thread)
    70:   {
    71:     DWORD err = GetLastError();
    72:     fprintf(stderr, "flx_thread_t: CreateThread failed: %i\n", err);
    73:     return err;
    74:   }
    75: 
    76:   return 0;
    77: }
    78: 
    79: // ---- joinable thread wrapper ----------
    80: flx_thread_wrapper_t::flx_thread_wrapper_t(LPTHREAD_START_ROUTINE f, LPVOID lParam)
    81: {
    82:   thread.init(f,lParam);
    83: }
    84: flx_thread_wrapper_t::~flx_thread_wrapper_t() { thread.join(); }
    85: 
    86: }}
    87: 
End cpp section to pthread/pthread_win_thread.cpp[1]