summaryrefslogtreecommitdiffstats
path: root/client/windows/event_sources_p.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'client/windows/event_sources_p.cpp')
-rw-r--r--client/windows/event_sources_p.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/client/windows/event_sources_p.cpp b/client/windows/event_sources_p.cpp
new file mode 100644
index 00000000..4a11b779
--- /dev/null
+++ b/client/windows/event_sources_p.cpp
@@ -0,0 +1,209 @@
+/*
+ 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 "event_sources.h"
+#include "debug.h"
+#include "utils.h"
+
+bool EventSources_p::process_system_events()
+{
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+
+ if (msg.message == WM_QUIT) {
+ return true;
+ }
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ return false;
+}
+
+void EventSources_p::add_event(HANDLE event, EventSource* source)
+{
+ int size = _events.size();
+ _events.resize(size + 1);
+ _handles.resize(size + 1);
+ _events[size] = source;
+ _handles[size] = event;
+}
+
+void EventSources_p::remove_event(EventSource* source)
+{
+ int size = _events.size();
+ for (int i = 0; i < size; i++) {
+ if (_events[i] == source) {
+ 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("event not found");
+}
+
+EventSources::EventSources()
+{
+}
+
+EventSources::~EventSources()
+{
+}
+
+bool EventSources::wait_events(int timeout_ms)
+{
+ if (_handles.empty()) {
+ if (WaitMessage()) {
+ return process_system_events();
+ } else {
+ THROW("wait failed %d", GetLastError());
+ }
+ }
+
+ DWORD wait_res = MsgWaitForMultipleObjectsEx(_handles.size(), &_handles[0], timeout_ms,
+ QS_ALLINPUT, 0);
+ if (wait_res == WAIT_TIMEOUT) {
+ return false;
+ }
+
+ if (wait_res == WAIT_FAILED) {
+ THROW("wait failed %d", GetLastError());
+ }
+
+ int event_index = wait_res - WAIT_OBJECT_0;
+ if (event_index == _handles.size()) {
+ return process_system_events();
+ } else if ((event_index >= 0) && (event_index < (int)_handles.size())) {
+ _events[event_index]->action();
+ return false;
+ } else {
+ THROW("invalid event id");
+ }
+}
+
+void EventSources::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");
+ }
+ add_event(event, &socket);
+}
+
+void EventSources::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 EventSources::add_handle(Handle& handle)
+{
+ add_event(handle.get_handle(), &handle);
+}
+
+void EventSources::remove_handle(Handle& handle)
+{
+ remove_event(&handle);
+}
+
+Handle_p::Handle_p()
+{
+ if (!(_event = CreateEvent(NULL, FALSE, FALSE, NULL))) {
+ THROW("create event failed");
+ }
+}
+
+Handle_p::~Handle_p()
+{
+ CloseHandle(_event);
+}
+
+void EventSources::add_trigger(Trigger& trigger)
+{
+ add_event(trigger.get_handle(), &trigger);
+}
+
+void EventSources::remove_trigger(Trigger& trigger)
+{
+ remove_event(&trigger);
+}
+
+
+EventSources::Trigger::Trigger()
+{
+}
+
+EventSources::Trigger::~Trigger()
+{
+}
+
+
+void EventSources::Trigger::trigger()
+{
+ if (!SetEvent(_event)) {
+ THROW("set event failed");
+ }
+}
+
+void EventSources::Trigger::reset()
+{
+ if (!ResetEvent(_event)) {
+ THROW("set event failed");
+ }
+}
+
+void EventSources::Trigger::action()
+{
+ on_event();
+}
+
+void EventSources::add_file(File& file)
+{
+}
+
+void EventSources::remove_file(File& file)
+{
+}
+