General IRI utilities
event.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 "event.h"
20 #include <string.h>
21 #include <unistd.h>
22 #include <exception>
23 #include <sys/time.h>
24 #include <sys/types.h>
25 #include <sys/select.h>
26 #include "eventexceptions.h"
27 
28 CEvent::CEvent(const std::string& id)
29 {
30  this->pipe_fd[0]=-1;
31  this->pipe_fd[1]=-1;
32  this->event_id=="";
33  this->num_activations=0;
34  if(pipe(this->pipe_fd)==-1)
35  {
36  /* handle exceptions */
37  throw CEventException(_HERE_,"Impossible to create the internal pipe to generate the events",id);
38  }
39  this->set_id(id);
40 }
41 
42 CEvent::CEvent(const std::string& id, bool create_signaled)
43 {
44  this->pipe_fd[0]=-1;
45  this->pipe_fd[1]=-1;
46  this->event_id="";
47  this->num_activations=0;
48  if(pipe(this->pipe_fd)==-1)
49  {
50  /* handle exceptions */
51  throw CEventException(_HERE_,"Impossible to create the internal pipe to generate the events",id);
52  }
53  this->set_id(id);
54  if(create_signaled)
55  this->set();
56 }
57 
58 void CEvent::reset(void)
59 {
60  char event_instance;
61 
62  this->access.enter();
63  if(this->num_activations>0)
64  {
65  if(read(this->pipe_fd[0],&event_instance,1)==-1)
66  {
67  this->access.exit();
68  /* handle exceptions */
69  throw CEventException(_HERE_,"Impossible to read from the internal pipe",this->event_id);
70  }
71  this->num_activations--;
72  }
73  this->access.exit();
74 }
75 
76 void CEvent::set(void)
77 {
78  char event_instance=0x55;
79 
80  this->access.enter();
81  if(write(this->pipe_fd[1],&event_instance,1)==-1)
82  {
83  this->access.exit();
84  /* handle exceptions */
85  throw CEventException(_HERE_,"Impossible to write to the internal pipe",this->event_id);
86  }
87  this->num_activations++;
88  this->access.exit();
89 }
90 
91 void CEvent::wait(int timeout_us)
92 {
93  struct timeval timeout_t;
94  fd_set wait_set;
95  int error;
96 
97  this->access.enter();
98  FD_ZERO(&wait_set);
99  FD_SET(this->pipe_fd[0],&wait_set);
100  if(timeout_us<0)
101  {
102  this->access.exit();
103  error=select(this->pipe_fd[0]+1,&wait_set,NULL,NULL,NULL);
104  }
105  else
106  {
107  timeout_t.tv_sec=0;
108  timeout_t.tv_usec=timeout_us;
109  this->access.exit();
110  error=select(this->pipe_fd[0]+1,&wait_set,NULL,NULL,&timeout_t);
111  }
112  if(error==-1)
113  {
114  /* handle exceptions */
115  throw CEventException(_HERE_,"Unexpected error while waiting the activation of the event",this->event_id);
116  }
117  else if(error==0)
118  {
119  /* handle exceptions */
120  throw CEventTimeoutException(this->event_id);
121  }
122  else
123  {
124  this->reset();
125  }
126 
127 }
128 
129 bool CEvent::is_set(void)
130 {
131  this->access.enter();
132  if(this->num_activations>0)
133  {
134  this->access.exit();
135  return true;
136  }
137  else
138  {
139  this->access.exit();
140  return false;
141  }
142  return false;
143 }
144 
145 void CEvent::set_id(const std::string& id)
146 {
147  if(id.size()==0)
148  {
149  /* handle exceptions */
150  throw CEventException(_HERE_,"Invalid event id","empty string");
151  }
152  else
153  this->event_id=id;
154 }
155 
157 {
158  return this->num_activations;
159 }
160 
161 std::string CEvent::get_id(void)
162 {
163  return this->event_id;
164 }
165 
166 int CEvent::get_fd(void)
167 {
168  return this->pipe_fd[0];
169 }
170 
172 {
173  this->access.enter();
174  if(this->pipe_fd[0]!=-1)
175  close(this->pipe_fd[0]);
176  if(this->pipe_fd[1]!=-1)
177  close(this->pipe_fd[1]);
178  this->num_activations=0;
179  this->access.exit();
180 }
Event exception class.
void wait(int timeout_us)
Function to wait for the activation of the event.
Definition: event.cpp:91
std::string get_id(void)
Function to get the event identifier.
Definition: event.cpp:161
int get_num_activations(void)
Function to get the number of event instances.
Definition: event.cpp:156
Event timeout exception class.
CEvent(const std::string &id)
Constructor with parameters.
Definition: event.cpp:28
virtual ~CEvent()
Destructor.
Definition: event.cpp:171
void reset(void)
Function to reset the event.
Definition: event.cpp:58
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
int get_fd(void)
Function to get the read file descriptor of the pipe.
Definition: event.cpp:166
bool is_set(void)
Function to check the state of the event.
Definition: event.cpp:129
void set(void)
Function to activate the event.
Definition: event.cpp:76
void set_id(const std::string &id)
Function to set the event identifier.
Definition: event.cpp:145