General IRI utilities
threadserver.cpp
1 // Copyright (C) 2009-2010 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
2 // Author Sergi Hernandez (shernand@iri.upc.edu)
3 // All rights reserved.
4 //
5 // This file is part of iriutils
6 // iriutils is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 #include "threadserver.h"
20 #include "threadexceptions.h"
21 
22 CThreadServer *CThreadServer::pinstance=NULL;
23 
25 {
26 }
27 
29 {
30 }
31 
33 {
34  return *this->pinstance;
35 }
36 
37 std::list<CThread>::iterator CThreadServer::search_thread(const std::string& thread_id)
38 {
39  std::string id;
40  std::list<CThread>::iterator it;
41 
42  if(thread_id.size()==0)
43  {
44  /* handle exception */
45  throw CThreadServerException(_HERE_,"Invalid thread id","NULL pointer");
46  }
47  else
48  {
49  for(it=this->thread_list.begin();it!=this->thread_list.end();it++)
50  {
51  id=it->get_id();
52  if(thread_id==id)
53  {
54  return it;
55  }
56  }
57  return (std::list<CThread>::iterator)NULL;
58  }
59  return (std::list<CThread>::iterator)NULL;
60 }
61 
63 {
64  if (CThreadServer::pinstance == NULL) // ¿Es la primera llamada?
65  {
66  CThreadServer::pinstance = new CThreadServer(); // Creamos la instancia
67  }
68  return CThreadServer::pinstance; // Retornamos la dirección de la instancia
69 }
70 
71 void CThreadServer::create_thread(const std::string& thread_id)
72 {
73  CThread *new_thread;
74  std::list<CThread>::iterator old_thread;
75 
76  this->access_threads.enter();
77  if((old_thread=this->search_thread(thread_id))==(std::list<CThread>::iterator)NULL)
78  {
79  new_thread=new CThread(thread_id);
80  this->thread_list.push_back(*new_thread);
81  this->access_threads.exit();
82  }
83  else
84  {
85  this->access_threads.exit();
86  /* handle exceptions */
87  throw CThreadServerException(_HERE_,"Thread already exists",thread_id);
88  }
89 }
90 
91 void CThreadServer::delete_thread(const std::string& thread_id)
92 {
93  std::list<CThread>::iterator old_thread;
94 
95  this->access_threads.enter();
96  if((old_thread=this->search_thread(thread_id))==(std::list<CThread>::iterator)NULL)
97  {
98  this->access_threads.exit();
99  /* handle exceptions */
100  throw CThreadServerException(_HERE_,"Unknown thread",thread_id);
101  }
102  else
103  {
104  this->thread_list.erase(old_thread);
105  this->access_threads.exit();
106  }
107 }
108 
109 void CThreadServer::attach_thread(const std::string& thread_id,void *(*user_thread_function)(void *param),void *param)
110 {
111  std::list<CThread>::iterator thread;
112 
113  this->access_threads.enter();
114  if((thread=this->search_thread(thread_id))==(std::list<CThread>::iterator)NULL)
115  {
116  this->access_threads.exit();
117  /* handle exception */
118  throw CThreadServerException(_HERE_,"Unknown thread",thread_id);
119  }
120  else
121  {
122  this->access_threads.exit();
123  thread->attach(user_thread_function,param);
124  }
125 }
126 
127 void CThreadServer::start_thread(const std::string& thread_id)
128 {
129  std::list<CThread>::iterator thread;
130 
131  this->access_threads.enter();
132  if((thread=this->search_thread(thread_id))==(std::list<CThread>::iterator)NULL)
133  {
134  this->access_threads.exit();
135  /* handle exceptions */
136  throw CThreadServerException(_HERE_,"Unknown thread",thread_id);
137  }
138  else
139  {
140  this->access_threads.exit();
141  thread->start();
142  }
143 }
144 
145 void CThreadServer::end_thread(const std::string& thread_id)
146 {
147  std::list<CThread>::iterator thread;
148 
149  this->access_threads.enter();
150  if((thread=this->search_thread(thread_id))==(std::list<CThread>::iterator)NULL)
151  {
152  this->access_threads.exit();
153  /* handle exceptions */
154  throw CThreadServerException(_HERE_,"Unknown thread",thread_id);
155  }
156  else
157  {
158  this->access_threads.exit();
159  thread->end();
160  }
161 }
162 
163 void CThreadServer::kill_thread(const std::string& thread_id)
164 {
165  std::list<CThread>::iterator thread;
166 
167  this->access_threads.enter();
168  if((thread=this->search_thread(thread_id))==(std::list<CThread>::iterator)NULL)
169  {
170  this->access_threads.exit();
171  /* handle exceptions */
172  throw CThreadServerException(_HERE_,"Unknown thread",thread_id);
173  }
174  else
175  {
176  this->access_threads.exit();
177  thread->kill();
178  }
179 }
180 
181 void CThreadServer::detach_thread(const std::string& thread_id)
182 {
183  std::list<CThread>::iterator thread;
184 
185  this->access_threads.enter();
186  if((thread=this->search_thread(thread_id))==(std::list<CThread>::iterator)NULL)
187  {
188  this->access_threads.exit();
189  /* handle exceptions */
190  throw CThreadServerException(_HERE_,"Unknown thread",thread_id);
191  }
192  else
193  {
194  this->access_threads.exit();
195  thread->detach();
196  }
197 }
198 
199 int CThreadServer::get_thread_state(const std::string &thread_id)
200 {
201  std::list<CThread>::iterator thread;
202 
203  this->access_threads.enter();
204  if((thread=this->search_thread(thread_id))==(std::list<CThread>::iterator)NULL)
205  {
206  this->access_threads.exit();
207  /* handle exceptions */
208  throw CThreadServerException(_HERE_,"Unknown thread",thread_id);
209  }
210  else
211  {
212  this->access_threads.exit();
213  return thread->get_state();
214  }
215 }
Thread server exception class.
void create_thread(const std::string &thread_id)
Function to create a new thread.
void start_thread(const std::string &thread_id)
Function to start a thread.
Implementation of a parallel thread of execution.
Definition: thread.h:76
std::list< CThread >::iterator search_thread(const std::string &thread_id)
Function to search for an specific thread.
void kill_thread(const std::string &thread_id)
Function to immediately terminate a thread.
void end_thread(const std::string &thread_id)
Function to request the termination of a thread.
CThreadServer & operator=(const CThreadServer &object)
assign operator overloading
void delete_thread(const std::string &thread_id)
Function to delete an existing thread.
void attach_thread(const std::string &thread_id, void *(*user_thread_function)(void *param), void *param)
Function to attach a function to a thread.
CThreadServer()
Default constructor.
void exit(void)
function to release the critical section
Definition: mutex.cpp:64
void enter(void)
function to request access to the critical section
Definition: mutex.cpp:35
void detach_thread(const std::string &thread_id)
Function to detach a function from a thread.
Global thread server.
Definition: threadserver.h:57
static CThreadServer * instance(void)
Function to get a reference to the unique instance.