libeblearntools
/home/rex/ebltrunk/tools/libeblearntools/include/thread.h
00001 /***************************************************************************
00002  *   Copyright (C) 2010 by Pierre Sermanet *
00003  *   pierre.sermanet@gmail.com *
00004  *   All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Redistribution under a license not approved by the Open Source
00014  *       Initiative (http://www.opensource.org) must display the
00015  *       following acknowledgement in all advertising material:
00016  *        This product includes software developed at the Courant
00017  *        Institute of Mathematical Sciences (http://cims.nyu.edu).
00018  *     * The names of the authors may not be used to endorse or promote products
00019  *       derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00024  * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  ***************************************************************************/
00032 
00033 #ifndef THREAD_H_
00034 #define THREAD_H_
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <iostream>
00039 #include "utils.h"
00040 
00041 #ifdef __PTHREAD__
00042 #include <pthread.h>
00043 #endif
00044 
00045 namespace ebl {
00046 
00048   // mutex
00049   
00051   class EXPORT mutex {
00052   public:
00053     mutex();
00054     ~mutex();
00055 
00059     bool trylock();
00060 
00062     void lock();
00063 
00065     void unlock();
00066 
00067   protected:
00068 #ifdef __PTHREAD__
00069 
00070 
00071 
00072 
00073     pthread_mutex_t m;
00074 #endif
00075   };
00076   
00078   // sbuf
00079 
00080   class mutex_ostream;
00081 
00082   // Specialize a stringbuf to handle flushing to unblock mutex.
00083   class EXPORT sbuf : public std::stringbuf {
00084   public:
00085 
00089     sbuf(std::ostream &o, mutex *m = NULL, const char *prefix = NULL);
00090     ~sbuf();
00091     
00092     // When we sync the stream with the output. 
00093     // 1) Output prefix then the buffer
00094     // 2) Reset the buffer
00095     // 3) flush the actual output stream we are using. 
00096     virtual int sync();
00098     virtual streamsize xsputn(const char *s, streamsize n);
00099 
00100     friend class mutex_ostream;
00101     
00102   private:
00103     std::ostream& out;
00104     bool new_line; 
00105     bool own_lock; 
00106     mutex *busy; 
00107     const char *prefix;
00108   };
00109 
00111   // mutex_ostream
00112 
00115   class EXPORT mutex_ostream : public std::ostream {
00116   public:
00120     mutex_ostream(std::ostream &o, mutex *m = NULL, const char *prefix = NULL);
00121     ~mutex_ostream();
00122 
00123   protected:
00124     sbuf buffer;
00125   };
00126   
00128   // thread 
00129   
00131   class EXPORT thread {
00132   public:
00137     thread(mutex *outmutex = NULL, const char *name = "Thread",
00138            bool sync = true);
00139     virtual ~thread();
00141     int start();
00142 
00146     void stop(long wait_seconds = 0);
00147 
00151     void ask_stop();
00152 
00154     bool finished();
00155 
00157     std::string& name();
00158 
00160     std::ostream& get_mout();
00161 
00163     std::ostream& get_merr();
00164 
00165   protected:
00166     void run();
00167     static void* entrypoint(void *pthis);
00168     virtual void execute() = 0;
00169 
00170   protected:    
00171     bool                _stop;
00172     std::string         _name;  
00173     mutex_ostream       mutout; // synchronized cout
00174     mutex_ostream       muterr; // synchronized cerr
00175     ostream             &mout; // may contained synced or standard output
00176     ostream             &merr; // may contained synced or standard err output
00177   private:
00178 #ifdef __PTHREAD__
00179     pthread_t           threadptr;
00180 #endif
00181     mutex               mutex1;
00182     bool                _finished;
00183   };
00184 
00185 } // end namespace ebl
00186 
00187 #endif /* THREAD_H_ */