Listing 3: Adding a mutex to FunData to synchronize thread creation

class Mutex {
  public:
    Mutex ()        { pthread_mutex_init (&mutex, 0); };
    ~Mutex ()       { pthread_mutex_destroy (&mutex); };
    void acquire () { pthread_mutex_lock(&mutex); };
    void release () { pthread_mutex_unlock(&mutex); };
  private:
    pthread_mutex_t mutex;
};

struct FunData {
    typedef void * (*ThreadEntryPoint) (void *);

    FunData (const ThreadEntryPoint tep)
            : thread_entry_point (tep)
      { lock.acquire (); };
    
    mutable Mutex lock;    
    ThreadEntryPoint thread_entry_point;
};


template <typename Arg1> class FunWrapper1 {
                                     // ...
    Thread operator() (Arg1 arg1) {
      Data data(fun_ptr, arg1);
      Thread t = do_spawn (data);
      data.lock.acquire ();
      return t;
    };
};


template <typename Arg1>
void * FunWrapper1<Arg1>::Data::thread_entry_point (void *arg) {
  const Data *fun_data = reinterpret_cast<const Data*> (arg);
  FunPtr fun_ptr = fun_data->fun_ptr;
  Arg1   arg1    = fun_data->arg1;

  fun_data->lock.release ();

  (*fun_ptr)(arg1);
  
  return 0;
}

— End of Listing —