diff options
Diffstat (limited to 'client/windows/events_loop_p.cpp')
-rw-r--r-- | client/windows/events_loop_p.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/client/windows/events_loop_p.cpp b/client/windows/events_loop_p.cpp new file mode 100644 index 00000000..7329d161 --- /dev/null +++ b/client/windows/events_loop_p.cpp @@ -0,0 +1,158 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "common.h" +#include "events_loop.h" +#include "debug.h" +#include "utils.h" + + +EventsLoop::EventsLoop() +{ +} + +EventsLoop::~EventsLoop() +{ +} + +void EventsLoop::run() +{ + for (;;) { + run_once(); + } +} + +void EventsLoop::run_once(int timeout_milli) +{ + DWORD wait_res = WaitForMultipleObjects(_handles.size(), &_handles[0], FALSE, timeout_milli); + if (wait_res == WAIT_FAILED) { + THROW("wait failed"); + } + int event_index = wait_res - WAIT_OBJECT_0; + if (event_index < 0 || event_index >= (int)_events.size()) { + THROW("invalid event id"); + } + _events[event_index]->action(); +} + +void EventsLoop::add_socket(Socket& socket) +{ + HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!event) { + THROW("create event failed"); + } + if (WSAEventSelect(socket.get_socket(), event, FD_READ | FD_WRITE | FD_CLOSE) == SOCKET_ERROR) { + CloseHandle(event); + THROW("event select failed"); + } + int size = _events.size(); + _events.resize(size + 1); + _handles.resize(size + 1); + _events[size] = &socket; + _handles[size] = event; +} + +void EventsLoop::remove_socket(Socket& socket) +{ + int size = _events.size(); + for (int i = 0; i < size; i++) { + if (_events[i] == &socket) { + if (WSAEventSelect(socket.get_socket(), NULL, 0) == SOCKET_ERROR) { + THROW("event select failed"); + } + u_long arg = 0; + if (ioctlsocket(socket.get_socket(), FIONBIO, &arg) == SOCKET_ERROR) { + THROW("set blocking mode failed"); + } + CloseHandle(_handles[i]); + for (i++; i < size; i++) { + _events[i - 1] = _events[i]; + _handles[i - 1] = _handles[i]; + } + _events.resize(size - 1); + _handles.resize(size - 1); + return; + } + } + THROW("socket not found"); +} + +void EventsLoop::add_trigger(Trigger& trigger) +{ + int size = _events.size(); + _events.resize(size + 1); + _handles.resize(size + 1); + _events[size] = &trigger; + _handles[size] = trigger.get_handle(); +} + +void EventsLoop::remove_trigger(Trigger& trigger) +{ + int size = _events.size(); + for (int i = 0; i < size; i++) { + if (_events[i] == &trigger) { + for (i++; i < size; i++) { + _events[i - 1] = _events[i]; + _handles[i - 1] = _handles[i]; + } + _events.resize(size - 1); + _handles.resize(size - 1); + return; + } + } + THROW("trigger not found"); +} + +EventsLoop::Trigger::Trigger() +{ + if (!(event = CreateEvent(NULL, FALSE, FALSE, NULL))) { + THROW("create event failed"); + } +} + +EventsLoop::Trigger::~Trigger() +{ + CloseHandle(event); +} + +void EventsLoop::Trigger::trigger() +{ + if (!SetEvent(event)) { + THROW("set event failed"); + } +} + +void EventsLoop::Trigger::reset() +{ + if (!ResetEvent(event)) { + THROW("set event failed"); + } +} + +void EventsLoop::Trigger::action() +{ + on_event(); +} + +void EventsLoop::add_file(File& file) +{ +} + +void EventsLoop::remove_file(File& file) +{ +} + |