From 2f19e5a7337fc2058aff665d45798f52b3499db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Sat, 29 Jul 2023 01:59:38 +0200 Subject: xW: improve command sending --- xW/xW.cpp | 62 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/xW/xW.cpp b/xW/xW.cpp index c349d71..6984892 100644 --- a/xW/xW.cpp +++ b/xW/xW.cpp @@ -119,7 +119,8 @@ struct { addrinfoW *addresses; ///< GetAddrInfo() result addrinfoW *addresses_iterator; ///< Currently processed address SOCKET socket; ///< Relay socket - WSAEVENT event; ///< Relay socket event + WSAEVENT socket_event; ///< Relay socket event + HANDLE flush_event; ///< Write buffer has new data std::vector write_buffer; ///< Write buffer std::vector read_buffer; ///< Read buffer @@ -201,6 +202,8 @@ relay_try_read(std::wstring &error) static bool relay_try_write(std::wstring &error) { + ResetEvent(g.flush_event); + auto &w = g.write_buffer; int err = {}; while (!w.empty()) { @@ -235,18 +238,10 @@ relay_send(Relay::CommandData *data, Callback callback = {}) g.write_buffer.insert(g.write_buffer.end(), prefix, prefix + sizeof len); g.write_buffer.insert(g.write_buffer.end(), w.data.begin(), w.data.end()); - // Call relay_try_write() separately. -} - -static void -relay_send_now(Relay::CommandData *data, Callback callback = {}) -{ - relay_send(data, callback); - - // TODO(p): Either tear down here, or run relay_try_write() from a timer. - std::wstring error; - if (!relay_try_write(error)) - show_error_message(error.c_str()); + // There doesn't seem to be a way to cause FD_WRITE without first + // unsuccessfully trying to send some data, but we don't want to + // handle any errors at this level. + SetEvent(g.flush_event); } // --- Buffers ----------------------------------------------------------------- @@ -265,7 +260,7 @@ buffer_activate(const std::wstring &name) { auto activate = new Relay::CommandData_BufferActivate(); activate->buffer_name = name; - relay_send_now(activate); + relay_send(activate); } static void @@ -273,7 +268,7 @@ buffer_toggle_unimportant(const std::wstring &name) { auto toggle = new Relay::CommandData_BufferToggleUnimportant(); toggle->buffer_name = name; - relay_send_now(toggle); + relay_send(toggle); } // --- Current buffer ---------------------------------------------------------- @@ -319,7 +314,7 @@ buffer_toggle_log() auto log = new Relay::CommandData_BufferLog(); log->buffer_name = g.buffer_current; - relay_send_now(log, [name = g.buffer_current](auto error, auto response) { + relay_send(log, [name = g.buffer_current](auto error, auto response) { if (g.buffer_current != name) return; buffer_toggle_log(error, @@ -848,7 +843,7 @@ relay_process_message(const Relay::EventMessage &m) { auto pong = new Relay::CommandData_PingResponse(); pong->event_seq = m.event_seq; - relay_send_now(pong); + relay_send(pong); break; } @@ -1084,8 +1079,8 @@ relay_destroy_socket() { closesocket(g.socket); g.socket = INVALID_SOCKET; - WSACloseEvent(g.event); - g.event = NULL; + WSACloseEvent(g.socket_event); + g.socket_event = NULL; g.read_buffer.clear(); g.write_buffer.clear(); @@ -1106,8 +1101,8 @@ relay_connect_step(std::wstring& error) return false; } - g.event = WSACreateEvent(); - if (WSAEventSelect(g.socket, g.event, + g.socket_event = WSACreateEvent(); + if (WSAEventSelect(g.socket, g.socket_event, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE)) error = format_error_message(WSAGetLastError()); else if (!connect(g.socket, p->ai_addr, (int) p->ai_addrlen)) @@ -1177,7 +1172,7 @@ static bool relay_process_socket_events(std::wstring &error) { WSANETWORKEVENTS wne = {}; - if (WSAEnumNetworkEvents(g.socket, g.event, &wne)) { + if (WSAEnumNetworkEvents(g.socket, g.socket_event, &wne)) { error = format_error_message(WSAGetLastError()); return false; } @@ -1223,7 +1218,7 @@ input_submit() b->history_at = b->history.size(); input_set_contents({}); - relay_send_now(input); + relay_send(input); return true; } @@ -1290,7 +1285,7 @@ input_complete() complete->buffer_name = g.buffer_current; complete->text = state.input; complete->position = utf8.length(); - relay_send_now(complete, [state](auto error, auto response) { + relay_send(complete, [state](auto error, auto response) { auto stamp = input_stamp(); if (std::make_tuple(stamp.start, stamp.end, stamp.input) != std::make_tuple(state.start, state.end, state.input)) @@ -1397,7 +1392,7 @@ input_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, case WM_CHAR: { // This could be implemented more precisely, but it will do. - relay_send_now(new Relay::CommandData_Active()); + relay_send(new Relay::CommandData_Active()); switch (wParam) { case VK_RETURN: @@ -1437,7 +1432,7 @@ bufferlist_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, auto input = new Relay::CommandData_BufferInput(); input->buffer_name = g.buffer_current; input->text = L"/buffer close " + g.buffers.at(index).buffer_name; - relay_send_now(input); + relay_send(input); return 0; } case WM_NCDESTROY: @@ -1959,15 +1954,15 @@ wWinMain(HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance, return 1; } - g.date_change_timer = CreateWaitableTimer(NULL, FALSE, NULL); - if (!g.date_change_timer) { + if (!(g.date_change_timer = CreateWaitableTimer(NULL, FALSE, NULL)) || + !(g.flush_event = CreateEvent(NULL, FALSE, FALSE, NULL))) { show_error_message(format_error_message(GetLastError()).c_str()); return 1; } while (process_messages(accelerators)) { - HANDLE handles[] = {g.date_change_timer, g.event}; - DWORD count = 2 - !handles[1]; + HANDLE handles[] = {g.date_change_timer, g.flush_event, g.socket_event}; + DWORD count = 3 - !handles[2]; DWORD result = MsgWaitForMultipleObjects( count, handles, FALSE, INFINITE, QS_ALLINPUT); if (result == WAIT_FAILED) { @@ -1984,7 +1979,11 @@ wWinMain(HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance, if (to_bottom) buffer_scroll_to_bottom(); } - if (signalled == g.event && !relay_process_socket_events(error)) { + if (signalled == g.flush_event && !relay_try_write(error)) { + show_error_message(error.c_str()); + return 1; + } + if (signalled == g.socket_event && !relay_process_socket_events(error)) { show_error_message(error.c_str()); return 1; } @@ -1992,5 +1991,6 @@ wWinMain(HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance, FreeAddrInfo(g.addresses); WSACleanup(); CloseHandle(g.date_change_timer); + CloseHandle(g.flush_event); return 0; } -- cgit v1.2.3