xW: improve command sending

This commit is contained in:
Přemysl Eric Janouch 2023-07-29 01:59:38 +02:00
parent b9cdabca5d
commit 2f19e5a733
Signed by: p
GPG Key ID: A0420B94F92B9493

View File

@ -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<uint8_t> write_buffer; ///< Write buffer
std::vector<uint8_t> 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;
}