summaryrefslogtreecommitdiffstats
path: root/client/windows/events_loop_p.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'client/windows/events_loop_p.cpp')
-rw-r--r--client/windows/events_loop_p.cpp158
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)
+{
+}
+