Fix local server for multiple applications
[anna.git] / mt / Thread.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_core_mt_Thread_hpp
10 #define anna_core_mt_Thread_hpp
11
12 #include <pthread.h>
13 #include <unistd.h>
14
15 #include <anna/core/RuntimeException.hpp>
16 #include <anna/core/mt/Mutex.hpp>
17 #include <anna/core/Allocator.hpp>
18
19 namespace anna {
20
21 class Semaphore;
22 class Runnable;
23 class ThreadManager;
24
25 /**
26    Recubrimiento para acceder a las funciones de threads de POSIX.
27
28    La funcionalidad de �ta clase slo estar�disponible en aplicaciones multithread aunque el
29    interfaz se mantiene constante de cualquier forma.
30 */
31 class Thread {
32 public:
33   /**
34    * Flags que puede ajuster el funcionamiento del thread.
35    * \see Thread
36    */
37   struct Flag {
38     enum { None = 0, Joinable = 1 };
39   };
40
41   /**
42      Constructor.
43   */
44   Thread() : a_id((pthread_t) - 1), a_manager(NULL), a_flags(Flag::None) {;}
45
46   /**
47     Destructor.
48   */
49   virtual ~Thread();
50
51   // Accesores
52   /**
53     @return El identificador de este thread a nivel de sistema operativo.
54   */
55   pthread_t getId() const throw() { return a_id; }
56
57   /**
58    * Establece los flags que configuran el comportamiento de este thread.
59    * \param flag Una combinación de los valores definidos por Thread::Flags::_v.
60    * \warning Los flags deben establecerse antes de invocar al método #start.
61    */
62   void setFlags(const int flags) throw() { a_flags = flags; }
63
64   /**
65    * Devuelve el indicador que informa sobre si se podría aplicar el método #join sobre este thread
66    */
67   bool isJoinable() const throw() { return (a_flags & Flag::Joinable) != 0; }
68
69   /**
70      Devuelve el estado de ejecucion de �te thread.
71      \return El estado de ejecucion de �te thread \em true si est�en ejecucion o \em false en otro
72      caso.
73   */
74   bool isRunning() const throw() { return (a_id != (pthread_t) - 1); }
75
76   // Metodos
77   /**
78     Comienza la ejecucion de este threads siempre y cuando el thread no est�ejecutandose
79     actualmente.
80   *
81     Invoca al m�odo  anna::Runnable::run del runnable recibido como par�etro.
82
83     @param runnable Instancia del objeto que va a ser ejecutado en el nuevo thread.
84   */
85   void start(Runnable& runnable) throw(RuntimeException);
86
87   /**
88     Introduce un nuevo punto de cancelacin. Esto slo sera necesario en caso de que el proceso
89     que implementa nuestro thread no haga ninguna llamada al sistema.
90   */
91   void testCancel() throw() { pthread_testcancel(); }
92
93   /**
94     Suspende la ejecución del thread que invoca a este método hasta que termine la ejecución
95     del thread sobre el que aplica.
96
97     \code
98
99      try {
100         B.start ();
101         A.start ();
102
103         cout << "Esperando a B." << endl;
104         B.join ();
105         cout << "B terminado." << endl;
106
107         A.cancel ();
108      }
109      catch (Exception& e) {
110         ....
111      }
112     \endcode
113     Con esto desde el thread C hemos lanzado los threads A y B; C quedar�bloqueado a la espera de que termine la ejecucion del
114     thread B y una vez hecho esto termina la ejecucion del thread A.
115   */
116   void join() throw(RuntimeException);
117
118   /**
119      Devuelve una cadena con la informacin referente a �te thread.
120      \return Una cadena con la informacin referente a �te thread.
121   */
122   virtual std::string asString() const throw();
123
124 private:
125   struct Data {
126     Runnable* runnable;
127     Thread* thread;
128   };
129
130   pthread_t a_id;
131   Data a_data;
132   ThreadManager* a_manager;
133   int a_flags;
134
135   Thread(const Thread& other);
136
137   static void* exec(void* arg);
138
139   friend class Allocator <Thread>;
140   friend class ThreadManager;
141 };
142
143 } //namespace anna
144
145 #endif
146