xW: improve command sending
This commit is contained in:
parent
b9cdabca5d
commit
2f19e5a733
62
xW/xW.cpp
62
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<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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue