2.1. Thread

Start cpp section to pthread/pthread_thread.hpp[1 /1 ]
     1: #line 126 "./lpsrc/flx_pthread.pak"
     2: #ifndef __FLX_PTHREAD_THREAD_H__
     3: #define __FLX_PTHREAD_THREAD_H__
     4: #include <flx_pthread_config.hpp>
     5: 
     6: #if FLX_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: #ifdef _WIN32
    28: typedef HANDLE flx_native_thread_t;
    29: #else
    30: typedef pthread_t flx_native_thread_t;
    31: #endif
    32: 
    33: // a class for threads that can't be joined. upon exit all their resources
    34: // are freed. they just evaporate. probably the best type of thread.
    35: class PTHREAD_EXTERN flx_detached_thread_t {
    36:   flx_native_thread_t thr;        ///< the thread
    37:   flx_detached_thread_t(flx_detached_thread_t const&); // uncopyable
    38:   void operator=(flx_detached_thread_t const&); // uncopyable
    39: public:
    40:   flx_detached_thread_t();
    41:   ~flx_detached_thread_t();
    42:   int init(void (*start)(void*), void* udat);
    43: };
    44: 
    45: // rf: joinable threads. is it an error to not join joinable threads?
    46: class PTHREAD_EXTERN flx_thread_t {
    47:   flx_native_thread_t thr;        ///< the thread
    48:   flx_thread_t(flx_thread_t const&); // uncopyable
    49:   void operator=(flx_thread_t const&); // uncopyable
    50: public:
    51:   flx_thread_t();
    52:   ~flx_thread_t();
    53:   int init(void (*start)(void*), void* udat);
    54:   void join();
    55: };
    56: 
    57: /// RAII wrapper for thread class
    58: class PTHREAD_EXTERN flx_thread_wrapper_t {
    59:   flx_thread_t thread;
    60:   flx_thread_wrapper_t(flx_thread_wrapper_t const&); // uncopyable
    61:   void operator=(flx_thread_wrapper_t const&); // uncopyable
    62: public:
    63:   ~flx_thread_wrapper_t();
    64:   flx_thread_wrapper_t(void (*start)(void*), void* udat);
    65: };
    66: 
    67: }}
    68: #endif
    69: 
End cpp section to pthread/pthread_thread.hpp[1]
Start cpp section to pthread/pthread_posix_thread.cpp[1 /1 ]
     1: #line 196 "./lpsrc/flx_pthread.pak"
     2: #include "pthread_thread.hpp"
     3: #include <stdio.h>
     4: #include <string.h>  // strerror
     5: #include <cstdlib>
     6: 
     7: namespace flx { namespace pthread {
     8: 
     9: struct tstart_t
    10: {
    11:   void (*sr)(void*);
    12:   void *cd;
    13:   tstart_t(void (*s)(void*),void* c) : sr(s), cd(c) {}
    14: };
    15: 
    16: extern "C" void *flx_pthread_start_wrapper(void *e)
    17: {
    18:   tstart_t *ehd = (tstart_t*)e;
    19:   void (*sr)(void*)=ehd->sr;
    20:   void *cd = ehd->cd;
    21:   delete ehd;
    22:   try {
    23:     (*sr)(cd);
    24:   }
    25:   catch (...) {
    26:     fprintf(stderr,"Uncaught exception in thread\n");
    27:     std::exit(1);
    28:   }
    29:   return NULL;
    30: }
    31: 
    32: 
    33: // ---- detached threads ----------
    34: 
    35: flx_detached_thread_t::flx_detached_thread_t(flx_detached_thread_t const&){} // uncopyable
    36: void flx_detached_thread_t::operator=(flx_detached_thread_t const&){} // uncopyable
    37: 
    38: int
    39: flx_detached_thread_t::init(void (*start)(void*), void* udat)
    40: {
    41:   pthread_attr_t attr;
    42:   pthread_attr_init(&attr);
    43:   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    44:   int res = pthread_create(&thr, &attr, flx_pthread_start_wrapper, new tstart_t(start, udat));
    45:   if(res)
    46:   {
    47:      fprintf(stderr, "WARNING: flx_detached_thread_t: pthread_create failed: %s\n",
    48:        strerror(res));
    49:   }
    50:   pthread_attr_destroy(&attr);
    51:   return res;
    52: }
    53: 
    54: flx_detached_thread_t::~flx_detached_thread_t() { }
    55: flx_detached_thread_t::flx_detached_thread_t() { }
    56: 
    57: // ---- joinable threads ----------
    58: flx_thread_t::flx_thread_t(flx_thread_t const&){} // uncopyable
    59: void flx_thread_t::operator=(flx_thread_t const&){} // uncopyable
    60: 
    61: int
    62: flx_thread_t::init(void (*start)(void*), void* udat)
    63: {
    64:   int res = pthread_create(&thr, NULL, flx_pthread_start_wrapper, new tstart_t(start, udat));
    65:   if(res)
    66:   {
    67:      fprintf(stderr, "WARNING: flx_thread_t: pthread_create failed: %s\n",
    68:        strerror(res));
    69:   }
    70:   return res;
    71: }
    72: 
    73: void flx_thread_t::join() {
    74:   int res = pthread_join(thr, NULL);
    75:   if(res)
    76:   {
    77:      fprintf(stderr, "flx_thread_t: FATAL: pthread_join failed: %s\n",
    78:        strerror(res));
    79:      std::exit(1);
    80:   }
    81: }
    82: 
    83: flx_thread_t::~flx_thread_t() { }
    84: flx_thread_t::flx_thread_t() { }
    85: 
    86: // ---- joinable thread wrapper ----------
    87: 
    88: flx_thread_wrapper_t::flx_thread_wrapper_t(flx_thread_wrapper_t const&){} // uncopyable
    89: void flx_thread_wrapper_t::operator=(flx_thread_wrapper_t const&){} // uncopyable
    90: 
    91: flx_thread_wrapper_t::flx_thread_wrapper_t(void (*start)(void*), void* udat)
    92: {
    93:   int res = thread.init(start,udat);
    94:   {
    95:     if(res)
    96:     {
    97:        fprintf(stderr, "FATAL: flx_thread_wapper_t: flx_thread_t.init failed: %s\n",
    98:          strerror(res));
    99:        exit(1);
   100:     }
   101:   }
   102: }
   103: 
   104: flx_thread_wrapper_t::~flx_thread_wrapper_t() { thread.join(); }
   105: 
   106: }}
   107: 
End cpp section to pthread/pthread_posix_thread.cpp[1]
Start cpp section to pthread/pthread_win_thread.cpp[1 /1 ]
     1: #line 304 "./lpsrc/flx_pthread.pak"
     2: #include "pthread_thread.hpp"
     3: #include <stdio.h>
     4: #include <cstdlib>
     5: 
     6: namespace flx { namespace pthread {
     7: 
     8: struct tstart_t
     9: {
    10:   void (*sr)(void*);
    11:   void *cd;
    12:   tstart_t(void (*s)(void*),void* c) : sr(s), cd(c) {}
    13: };
    14: 
    15: DWORD WINAPI flx_pthread_start_wrapper(LPVOID e)
    16: {
    17:   tstart_t *ehd = (tstart_t*)e;
    18:   void (*sr)(void*)=ehd->sr;
    19:   void *cd = ehd->cd;
    20:   delete ehd;
    21:   try {
    22:     (*sr)(cd);
    23:   }
    24:   catch (...) {
    25:     fprintf(stderr,"Uncaught exception in thread\n");
    26:     std::exit(1);
    27:   }
    28:   return 0;
    29: }
    30: 
    31: 
    32: // ---- detached threads ----------
    33: 
    34: flx_detached_thread_t::flx_detached_thread_t(flx_detached_thread_t const&){} // uncopyable
    35: void flx_detached_thread_t::operator=(flx_detached_thread_t const&){} // uncopyable
    36: 
    37: // returns -1 on failure with error in GetLastError, 0 if all good.
    38: int
    39: flx_detached_thread_t::init(void (*fn)(void*), void *lParam)
    40: {
    41:   DWORD thread_id = 0;
    42:   thr = (HANDLE)CreateThread(NULL, 0,
    43:     (LPTHREAD_START_ROUTINE)flx_pthread_start_wrapper,
    44:     new tstart_t(fn,lParam), 0,
    45:     &thread_id
    46:   );
    47: 
    48:   if(!thr)
    49:   {
    50:     DWORD err = GetLastError();
    51:     fprintf(stderr, "flx_detached_thread_t: CreateThread failed: %i\n", err);
    52:     return err;
    53:   }
    54:   return 0;
    55: }
    56: 
    57: flx_detached_thread_t::~flx_detached_thread_t() { CloseHandle(thr); }
    58: flx_detached_thread_t::flx_detached_thread_t() { }
    59: 
    60: // ---- joinable threads ----------
    61: flx_thread_t::flx_thread_t(flx_thread_t const&){} // uncopyable
    62: void flx_thread_t::operator=(flx_thread_t const&){} // uncopyable
    63: 
    64: 
    65: flx_thread_t::flx_thread_t() { }
    66: flx_thread_t::~flx_thread_t() { }
    67: 
    68: // this should be idempotent
    69: void
    70: flx_thread_t::join()
    71: {
    72:   // Let's try and wait for the thread to finish, however first I have to
    73:   // tell it to finish up.
    74: 
    75:   DWORD  wait_res = WaitForSingleObject(thr, INFINITE);
    76: 
    77:   // will this give me my return status? how do I get that?
    78:   if(WAIT_FAILED == wait_res)
    79:   {
    80:     fprintf(stderr,"WARNING: thread wait failed (%li)\n", GetLastError());
    81:   }
    82: 
    83:   // I've already tried waiting on the  thread's #include <stdlib> exit
    84:   if(!CloseHandle(thr))
    85:   {
    86:     fprintf(stderr,"FATAL: failed to delete thread (%li)\n", GetLastError());
    87:     std::exit(1);
    88:   }
    89: }
    90: 
    91: // returns -1 on failure with error in GetLastError, 0 if all good.
    92: int
    93: flx_thread_t::init(void (*fn)(void*), void *lParam)
    94: {
    95:   DWORD thread_id = 0;
    96:   thr= (HANDLE)CreateThread(NULL, 0,
    97:     (LPTHREAD_START_ROUTINE)flx_pthread_start_wrapper,
    98:     new tstart_t(fn,lParam), 0,
    99:     &thread_id
   100:   );
   101: 
   102:   if(!thr)
   103:   {
   104:     DWORD err = GetLastError();
   105:     fprintf(stderr, "WARNING: flx_thread_t: CreateThread failed: %i\n", err);
   106:     return err;
   107:   }
   108: 
   109:   return 0;
   110: }
   111: 
   112: // ---- joinable thread wrapper ----------
   113: flx_thread_wrapper_t::flx_thread_wrapper_t(void (*f)(void*), void *lParam)
   114: {
   115:   int res = thread.init(f,lParam);
   116:   if(res)
   117:   {
   118:     fprintf(stderr,"flx_thread_wrapper_t: FATAL: flx_thread_t.init failed\n");
   119:     std::exit(1);
   120:   }
   121: }
   122: flx_thread_wrapper_t::~flx_thread_wrapper_t() { thread.join(); }
   123: 
   124: }}
   125: 
End cpp section to pthread/pthread_win_thread.cpp[1]