First commit
[anna.git] / include / anna / core / mt / Thread.hpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_core_mt_Thread_hpp
38 #define anna_core_mt_Thread_hpp
39
40 #include <pthread.h>
41 #include <unistd.h>
42
43 #include <anna/core/RuntimeException.hpp>
44 #include <anna/core/mt/Mutex.hpp>
45 #include <anna/core/Allocator.hpp>
46
47 namespace anna {
48
49 class Semaphore;
50 class Runnable;
51 class ThreadManager;
52
53 /**
54    Recubrimiento para acceder a las funciones de threads de POSIX.
55
56    La funcionalidad de �ta clase slo estar�disponible en aplicaciones multithread aunque el
57    interfaz se mantiene constante de cualquier forma.
58 */
59 class Thread {
60 public:
61   /**
62    * Flags que puede ajuster el funcionamiento del thread.
63    * \see Thread
64    */
65   struct Flag {
66     enum { None = 0, Joinable = 1 };
67   };
68
69   /**
70      Constructor.
71   */
72   Thread() : a_id((pthread_t) - 1), a_manager(NULL), a_flags(Flag::None) {;}
73
74   /**
75     Destructor.
76   */
77   virtual ~Thread();
78
79   // Accesores
80   /**
81     @return El identificador de este thread a nivel de sistema operativo.
82   */
83   pthread_t getId() const throw() { return a_id; }
84
85   /**
86    * Establece los flags que configuran el comportamiento de este thread.
87    * \param flag Una combinación de los valores definidos por Thread::Flags::_v.
88    * \warning Los flags deben establecerse antes de invocar al método #start.
89    */
90   void setFlags(const int flags) throw() { a_flags = flags; }
91
92   /**
93    * Devuelve el indicador que informa sobre si se podría aplicar el método #join sobre este thread
94    */
95   bool isJoinable() const throw() { return (a_flags & Flag::Joinable) != 0; }
96
97   /**
98      Devuelve el estado de ejecucion de �te thread.
99      \return El estado de ejecucion de �te thread \em true si est�en ejecucion o \em false en otro
100      caso.
101   */
102   bool isRunning() const throw() { return (a_id != (pthread_t) - 1); }
103
104   // Metodos
105   /**
106     Comienza la ejecucion de este threads siempre y cuando el thread no est�ejecutandose
107     actualmente.
108   *
109     Invoca al m�odo  anna::Runnable::run del runnable recibido como par�etro.
110
111     @param runnable Instancia del objeto que va a ser ejecutado en el nuevo thread.
112   */
113   void start(Runnable& runnable) throw(RuntimeException);
114
115   /**
116     Introduce un nuevo punto de cancelacin. Esto slo sera necesario en caso de que el proceso
117     que implementa nuestro thread no haga ninguna llamada al sistema.
118   */
119   void testCancel() throw() { pthread_testcancel(); }
120
121   /**
122     Suspende la ejecución del thread que invoca a este método hasta que termine la ejecución
123     del thread sobre el que aplica.
124
125     \code
126
127      try {
128         B.start ();
129         A.start ();
130
131         cout << "Esperando a B." << endl;
132         B.join ();
133         cout << "B terminado." << endl;
134
135         A.cancel ();
136      }
137      catch (Exception& e) {
138         ....
139      }
140     \endcode
141     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
142     thread B y una vez hecho esto termina la ejecucion del thread A.
143   */
144   void join() throw(RuntimeException);
145
146   /**
147      Devuelve una cadena con la informacin referente a �te thread.
148      \return Una cadena con la informacin referente a �te thread.
149   */
150   virtual std::string asString() const throw();
151
152 private:
153   struct Data {
154     Runnable* runnable;
155     Thread* thread;
156   };
157
158   pthread_t a_id;
159   Data a_data;
160   ThreadManager* a_manager;
161   int a_flags;
162
163   Thread(const Thread& other);
164
165   static void* exec(void* arg);
166
167   friend class Allocator <Thread>;
168   friend class ThreadManager;
169 };
170
171 } //namespace anna
172
173 #endif
174