aboutsummaryrefslogtreecommitdiff
path: root/xW
diff options
context:
space:
mode:
Diffstat (limited to 'xW')
-rw-r--r--xW/xW.cpp62
1 files 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<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;
}