00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "precomp.h"
00030 #include "event.h"
00031 #include "exception.h"
00032 #ifndef WIN32
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035 #include <sys/time.h>
00036 #include <sys/types.h>
00037 #include <unistd.h>
00038 #endif
00039
00041
00042
00043 #ifdef WIN32
00044
00045 CL_Event::CL_Event(bool manual_reset, bool initial_state)
00046 : handle(INVALID_HANDLE_VALUE), type(type_native), socket_handler(0)
00047 {
00048 handle = CreateEvent(
00049 0,
00050 manual_reset ? TRUE : FALSE,
00051 initial_state ? TRUE : FALSE,
00052 0);
00053 if (handle == INVALID_HANDLE_VALUE)
00054 throw CL_Exception(TEXT("Unable to create event!"));
00055 }
00056
00057 CL_Event::CL_Event(CL_SocketEventHandler *socket_handler, EventType type)
00058 : type(type), socket_handler(socket_handler)
00059 {
00060 if (type == type_native)
00061 throw CL_Exception(TEXT("Invalid type parameter"));
00062 }
00063
00064 CL_Event::~CL_Event()
00065 {
00066 if (handle != INVALID_HANDLE_VALUE)
00067 CloseHandle(handle);
00068 handle = INVALID_HANDLE_VALUE;
00069 }
00070
00071 #else
00072
00073 CL_Event::CL_Event(bool manual_reset, bool initial_state)
00074 : manual_reset(manual_reset), state(initial_state), type(type_native), socket_handler(0)
00075 {
00076 int result = socketpair(AF_UNIX, SOCK_DGRAM, PF_UNIX, wait_sockets);
00077 if (result == -1)
00078 throw CL_Exception(TEXT("Could not create event waiting socket pair!"));
00079 }
00080
00081 CL_Event::CL_Event(CL_SocketEventHandler *socket_handler, EventType type)
00082 : manual_reset(true), state(false), type(type), socket_handler(socket_handler)
00083 {
00084 if (type == type_native)
00085 throw CL_Exception(TEXT("Invalid type parameter"));
00086 }
00087
00088 CL_Event::~CL_Event()
00089 {
00090 if (type == type_native)
00091 {
00092 close(wait_sockets[0]);
00093 close(wait_sockets[1]);
00094 }
00095 }
00096
00097 #endif
00098
00099
00101
00102
00104
00105
00106 bool CL_Event::wait(int timeout) const
00107 {
00108 #ifdef WIN32
00109 switch (type)
00110 {
00111 case type_native:
00112 {
00113 DWORD result = WaitForSingleObject(handle, (timeout == -1) ? INFINITE : timeout);
00114 return (result != WAIT_TIMEOUT);
00115 }
00116
00117 case type_socket_read:
00118 case type_socket_write:
00119 case type_socket_exception:
00120 {
00121 timeval tv;
00122 tv.tv_sec = timeout / 1000;
00123 tv.tv_usec = (timeout % 1000) * 1000;
00124
00125 fd_set fds;
00126 FD_ZERO(&fds);
00127 FD_SET(socket_handler->socket_handle, &fds);
00128
00129 int result = select((int) socket_handler->socket_handle+1,
00130 (type == type_socket_read) ? &fds : 0,
00131 (type == type_socket_write) ? &fds : 0,
00132 (type == type_socket_exception) ? &fds : 0,
00133 (timeout == -1) ? 0 : &tv);
00134 if (result == -1)
00135 {
00136 throw CL_Exception(TEXT("Event wait failed!"));
00137 }
00138 else if (result == 0)
00139 {
00140 return false;
00141 }
00142 else
00143 {
00144 return true;
00145 }
00146 }
00147 return false;
00148
00149 default:
00150 throw CL_Exception(TEXT("Unknown event type"));
00151 return false;
00152 }
00153 #else
00154
00155
00156
00157
00158
00159
00160 timeval tv;
00161 tv.tv_sec = timeout / 1000;
00162 tv.tv_usec = (timeout % 1000) * 1000;
00163
00164 while (true)
00165 {
00166 fd_set fds;
00167 FD_ZERO(&fds);
00168 if (type == type_native)
00169 FD_SET(wait_sockets[1], &fds);
00170 else
00171 FD_SET(socket_handler->socket_handle, &fds);
00172
00173 int result = select(
00174 (type == type_native) ? wait_sockets[1]+1 : socket_handler->socket_handle+1,
00175 (type == type_native || type == type_socket_read) ? &fds : 0,
00176 (type == type_socket_write) ? &fds : 0,
00177 (type == type_socket_exception) ? &fds : 0,
00178 (timeout == -1) ? 0 : &tv);
00179 if (result == -1)
00180 {
00181 throw CL_Exception(TEXT("Event wait failed!"));
00182 }
00183 else if (result == 0)
00184 {
00185 return false;
00186 }
00187 else
00188 {
00189 if (!manual_reset || type != type_native)
00190 {
00191 return true;
00192 }
00193 else
00194 {
00195
00196
00197 CL_MutexSection mutex_lock(&mutex);
00198 if (state == true)
00199 {
00200 char msg = 0;
00201 recv(wait_sockets[1], &msg, sizeof(char), 0);
00202 state = false;
00203 return true;
00204 }
00205
00206
00207 }
00208 }
00209 }
00210
00211 return false;
00212 #endif
00213 }
00214
00215 int CL_Event::wait(int count, CL_Event const * const * events, int timeout, bool wait_all)
00216 {
00217 #ifdef WIN32
00218 if (count == 0)
00219 {
00220 WaitForMultipleObjects(0, 0, FALSE, (timeout == -1) ? INFINITE : timeout);
00221 return -1;
00222 }
00223
00224 std::vector<HANDLE> handles;
00225 for (int i=0; i<count; i++)
00226 handles.push_back(events[i]->handle);
00227
00228 DWORD result = WaitForMultipleObjects(
00229 count,
00230 &handles[0],
00231 wait_all ? TRUE : FALSE,
00232 (timeout == -1) ? INFINITE : timeout);
00233
00234 if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + count)
00235 return result - WAIT_OBJECT_0;
00236 else if (result >= WAIT_ABANDONED_0 && result < WAIT_ABANDONED_0 + count)
00237 return result - WAIT_ABANDONED_0;
00238 else
00239 return -1;
00240 #else
00241 if (wait_all == true)
00242 throw CL_Exception(TEXT("wait_all not implemented yet for unix target"));
00243
00244
00245
00246
00247
00248
00249
00250 timeval tv;
00251 tv.tv_sec = timeout / 1000;
00252 tv.tv_usec = (timeout % 1000) * 1000;
00253
00254 while (true)
00255 {
00256 bool reads = false;
00257 bool writes = false;
00258 bool exceptions = false;
00259 int highest_fd = -1;
00260 fd_set rfds, wfds, efds;
00261 FD_ZERO(&rfds);
00262 FD_ZERO(&wfds);
00263 FD_ZERO(&efds);
00264 for (int i=0; i<count; i++)
00265 {
00266 switch (events[i]->type)
00267 {
00268 case type_native:
00269 FD_SET(events[i]->wait_sockets[1], &rfds);
00270 if (events[i]->wait_sockets[1] > highest_fd)
00271 highest_fd = events[i]->wait_sockets[1];
00272 reads = true;
00273 break;
00274 case type_socket_read:
00275 FD_SET(events[i]->socket_handler->socket_handle, &rfds);
00276 if (events[i]->socket_handler->socket_handle > highest_fd)
00277 highest_fd = events[i]->socket_handler->socket_handle;
00278 reads = true;
00279 break;
00280 case type_socket_write:
00281 FD_SET(events[i]->socket_handler->socket_handle, &wfds);
00282 if (events[i]->socket_handler->socket_handle > highest_fd)
00283 highest_fd = events[i]->socket_handler->socket_handle;
00284 writes = true;
00285 break;
00286 case type_socket_exception:
00287 FD_SET(events[i]->socket_handler->socket_handle, &efds);
00288 if (events[i]->socket_handler->socket_handle > highest_fd)
00289 highest_fd = events[i]->socket_handler->socket_handle;
00290 exceptions = true;
00291 break;
00292 }
00293 }
00294
00295 int result = select(
00296 highest_fd+1,
00297 reads ? &rfds : 0,
00298 writes ? &wfds : 0,
00299 exceptions ? &efds : 0,
00300 (timeout == -1) ? 0 : &tv);
00301 if (result == -1)
00302 {
00303 throw CL_Exception(TEXT("Event wait failed!"));
00304 }
00305 else if (result == 0)
00306 {
00307 return -1;
00308 }
00309 else
00310 {
00311
00312 for (int i=0; i<count; i++)
00313 {
00314 switch (events[i]->type)
00315 {
00316 case type_native:
00317 if (FD_ISSET(events[i]->wait_sockets[1], &rfds))
00318 {
00319 if (!events[i]->manual_reset)
00320 {
00321 return i;
00322 }
00323 else
00324 {
00325
00326
00327 CL_MutexSection mutex_lock(&events[i]->mutex);
00328 if (events[i]->state == true)
00329 {
00330 char msg = 0;
00331 recv(events[i]->wait_sockets[1], &msg, sizeof(char), 0);
00332 events[i]->state = false;
00333 return i;
00334 }
00335
00336
00337 }
00338 }
00339 break;
00340 case type_socket_read:
00341 if (FD_ISSET(events[i]->socket_handler->socket_handle, &rfds))
00342 return i;
00343 break;
00344 case type_socket_write:
00345 if (FD_ISSET(events[i]->socket_handler->socket_handle, &wfds))
00346 return i;
00347 break;
00348 case type_socket_exception:
00349 if (FD_ISSET(events[i]->socket_handler->socket_handle, &efds))
00350 return i;
00351 break;
00352 }
00353 }
00354 }
00355 }
00356
00357 return -1;
00358 #endif
00359 }
00360
00361 int CL_Event::wait(const std::vector<CL_Event *> &events, int timeout, bool wait_all)
00362 {
00363 if (events.size() > 0)
00364 return wait((int) events.size(), &events[0], timeout, wait_all);
00365 else
00366 return wait(0, 0, timeout, wait_all);
00367 }
00368
00369 void CL_Event::set()
00370 {
00371 if (type != type_native)
00372 throw CL_Exception(TEXT("Changing state on socket events unsupported"));
00373
00374 #ifdef WIN32
00375 BOOL result = SetEvent(handle);
00376 if (result == FALSE)
00377 throw CL_Exception(TEXT("Unable to set event to signalled state!"));
00378 #else
00379 CL_MutexSection mutex_lock(&mutex);
00380 if (state == false)
00381 {
00382 state = true;
00383 char msg = 1;
00384 send(wait_sockets[0], &msg, sizeof(char), 0);
00385 }
00386 #endif
00387 }
00388
00389 void CL_Event::reset()
00390 {
00391 if (type != type_native)
00392 throw CL_Exception(TEXT("Changing state on socket events unsupported"));
00393
00394 #ifdef WIN32
00395 BOOL result = ResetEvent(handle);
00396 if (result == FALSE)
00397 throw CL_Exception(TEXT("Unable to reset event!"));
00398 #else
00399 CL_MutexSection mutex_lock(&mutex);
00400 if (state == true)
00401 {
00402 char msg = 0;
00403 recv(wait_sockets[1], &msg, sizeof(char), 0);
00404 state = false;
00405 }
00406 #endif
00407 }
00408
00410
00411
00412 CL_Event::CL_Event(const CL_Event ©)
00413 {
00414 throw CL_Exception(TEXT("Event class copy construction not supported"));
00415 }
00416
00417 CL_Event &CL_Event::operator =(const CL_Event ©)
00418 {
00419 throw CL_Exception(TEXT("Event class copy construction not supported"));
00420 return *this;
00421 }