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; ///< GetAddrInfo() result
|
||||||
addrinfoW *addresses_iterator; ///< Currently processed address
|
addrinfoW *addresses_iterator; ///< Currently processed address
|
||||||
SOCKET socket; ///< Relay socket
|
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> write_buffer; ///< Write buffer
|
||||||
std::vector<uint8_t> read_buffer; ///< Read buffer
|
std::vector<uint8_t> read_buffer; ///< Read buffer
|
||||||
|
|
||||||
|
@ -201,6 +202,8 @@ relay_try_read(std::wstring &error)
|
||||||
static bool
|
static bool
|
||||||
relay_try_write(std::wstring &error)
|
relay_try_write(std::wstring &error)
|
||||||
{
|
{
|
||||||
|
ResetEvent(g.flush_event);
|
||||||
|
|
||||||
auto &w = g.write_buffer;
|
auto &w = g.write_buffer;
|
||||||
int err = {};
|
int err = {};
|
||||||
while (!w.empty()) {
|
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(), prefix, prefix + sizeof len);
|
||||||
g.write_buffer.insert(g.write_buffer.end(), w.data.begin(), w.data.end());
|
g.write_buffer.insert(g.write_buffer.end(), w.data.begin(), w.data.end());
|
||||||
|
|
||||||
// Call relay_try_write() separately.
|
// 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.
|
||||||
static void
|
SetEvent(g.flush_event);
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Buffers -----------------------------------------------------------------
|
// --- Buffers -----------------------------------------------------------------
|
||||||
|
@ -265,7 +260,7 @@ buffer_activate(const std::wstring &name)
|
||||||
{
|
{
|
||||||
auto activate = new Relay::CommandData_BufferActivate();
|
auto activate = new Relay::CommandData_BufferActivate();
|
||||||
activate->buffer_name = name;
|
activate->buffer_name = name;
|
||||||
relay_send_now(activate);
|
relay_send(activate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -273,7 +268,7 @@ buffer_toggle_unimportant(const std::wstring &name)
|
||||||
{
|
{
|
||||||
auto toggle = new Relay::CommandData_BufferToggleUnimportant();
|
auto toggle = new Relay::CommandData_BufferToggleUnimportant();
|
||||||
toggle->buffer_name = name;
|
toggle->buffer_name = name;
|
||||||
relay_send_now(toggle);
|
relay_send(toggle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Current buffer ----------------------------------------------------------
|
// --- Current buffer ----------------------------------------------------------
|
||||||
|
@ -319,7 +314,7 @@ buffer_toggle_log()
|
||||||
|
|
||||||
auto log = new Relay::CommandData_BufferLog();
|
auto log = new Relay::CommandData_BufferLog();
|
||||||
log->buffer_name = g.buffer_current;
|
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)
|
if (g.buffer_current != name)
|
||||||
return;
|
return;
|
||||||
buffer_toggle_log(error,
|
buffer_toggle_log(error,
|
||||||
|
@ -848,7 +843,7 @@ relay_process_message(const Relay::EventMessage &m)
|
||||||
{
|
{
|
||||||
auto pong = new Relay::CommandData_PingResponse();
|
auto pong = new Relay::CommandData_PingResponse();
|
||||||
pong->event_seq = m.event_seq;
|
pong->event_seq = m.event_seq;
|
||||||
relay_send_now(pong);
|
relay_send(pong);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1084,8 +1079,8 @@ relay_destroy_socket()
|
||||||
{
|
{
|
||||||
closesocket(g.socket);
|
closesocket(g.socket);
|
||||||
g.socket = INVALID_SOCKET;
|
g.socket = INVALID_SOCKET;
|
||||||
WSACloseEvent(g.event);
|
WSACloseEvent(g.socket_event);
|
||||||
g.event = NULL;
|
g.socket_event = NULL;
|
||||||
|
|
||||||
g.read_buffer.clear();
|
g.read_buffer.clear();
|
||||||
g.write_buffer.clear();
|
g.write_buffer.clear();
|
||||||
|
@ -1106,8 +1101,8 @@ relay_connect_step(std::wstring& error)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
g.event = WSACreateEvent();
|
g.socket_event = WSACreateEvent();
|
||||||
if (WSAEventSelect(g.socket, g.event,
|
if (WSAEventSelect(g.socket, g.socket_event,
|
||||||
FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE))
|
FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE))
|
||||||
error = format_error_message(WSAGetLastError());
|
error = format_error_message(WSAGetLastError());
|
||||||
else if (!connect(g.socket, p->ai_addr, (int) p->ai_addrlen))
|
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)
|
relay_process_socket_events(std::wstring &error)
|
||||||
{
|
{
|
||||||
WSANETWORKEVENTS wne = {};
|
WSANETWORKEVENTS wne = {};
|
||||||
if (WSAEnumNetworkEvents(g.socket, g.event, &wne)) {
|
if (WSAEnumNetworkEvents(g.socket, g.socket_event, &wne)) {
|
||||||
error = format_error_message(WSAGetLastError());
|
error = format_error_message(WSAGetLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1223,7 +1218,7 @@ input_submit()
|
||||||
b->history_at = b->history.size();
|
b->history_at = b->history.size();
|
||||||
input_set_contents({});
|
input_set_contents({});
|
||||||
|
|
||||||
relay_send_now(input);
|
relay_send(input);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1290,7 +1285,7 @@ input_complete()
|
||||||
complete->buffer_name = g.buffer_current;
|
complete->buffer_name = g.buffer_current;
|
||||||
complete->text = state.input;
|
complete->text = state.input;
|
||||||
complete->position = utf8.length();
|
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();
|
auto stamp = input_stamp();
|
||||||
if (std::make_tuple(stamp.start, stamp.end, stamp.input) !=
|
if (std::make_tuple(stamp.start, stamp.end, stamp.input) !=
|
||||||
std::make_tuple(state.start, state.end, state.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:
|
case WM_CHAR:
|
||||||
{
|
{
|
||||||
// This could be implemented more precisely, but it will do.
|
// 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) {
|
switch (wParam) {
|
||||||
case VK_RETURN:
|
case VK_RETURN:
|
||||||
|
@ -1437,7 +1432,7 @@ bufferlist_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
|
||||||
auto input = new Relay::CommandData_BufferInput();
|
auto input = new Relay::CommandData_BufferInput();
|
||||||
input->buffer_name = g.buffer_current;
|
input->buffer_name = g.buffer_current;
|
||||||
input->text = L"/buffer close " + g.buffers.at(index).buffer_name;
|
input->text = L"/buffer close " + g.buffers.at(index).buffer_name;
|
||||||
relay_send_now(input);
|
relay_send(input);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case WM_NCDESTROY:
|
case WM_NCDESTROY:
|
||||||
|
@ -1959,15 +1954,15 @@ wWinMain(HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
g.date_change_timer = CreateWaitableTimer(NULL, FALSE, NULL);
|
if (!(g.date_change_timer = CreateWaitableTimer(NULL, FALSE, NULL)) ||
|
||||||
if (!g.date_change_timer) {
|
!(g.flush_event = CreateEvent(NULL, FALSE, FALSE, NULL))) {
|
||||||
show_error_message(format_error_message(GetLastError()).c_str());
|
show_error_message(format_error_message(GetLastError()).c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (process_messages(accelerators)) {
|
while (process_messages(accelerators)) {
|
||||||
HANDLE handles[] = {g.date_change_timer, g.event};
|
HANDLE handles[] = {g.date_change_timer, g.flush_event, g.socket_event};
|
||||||
DWORD count = 2 - !handles[1];
|
DWORD count = 3 - !handles[2];
|
||||||
DWORD result = MsgWaitForMultipleObjects(
|
DWORD result = MsgWaitForMultipleObjects(
|
||||||
count, handles, FALSE, INFINITE, QS_ALLINPUT);
|
count, handles, FALSE, INFINITE, QS_ALLINPUT);
|
||||||
if (result == WAIT_FAILED) {
|
if (result == WAIT_FAILED) {
|
||||||
|
@ -1984,7 +1979,11 @@ wWinMain(HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance,
|
||||||
if (to_bottom)
|
if (to_bottom)
|
||||||
buffer_scroll_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());
|
show_error_message(error.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1992,5 +1991,6 @@ wWinMain(HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance,
|
||||||
FreeAddrInfo(g.addresses);
|
FreeAddrInfo(g.addresses);
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
CloseHandle(g.date_change_timer);
|
CloseHandle(g.date_change_timer);
|
||||||
|
CloseHandle(g.flush_event);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue