diff options
author | Arnon Gilboa <agilboa@redhat.com> | 2012-11-07 14:38:20 +0200 |
---|---|---|
committer | Arnon Gilboa <agilboa@redhat.com> | 2012-11-14 10:50:52 +0200 |
commit | a69af07da34b3206f8354ac3879177483d5956ce (patch) | |
tree | 11c7937b033be4e9ee026c43c959d35bd016e2bb /vdagent/vdagent.cpp | |
parent | f71197330c7e11b0956e598a4d571f388b9dc088 (diff) |
vdagent: set timeout for next clipboard chunk instead of complete reception
currently:
-handling client disconnect during clipboard data trasfer is buggy
-agent also timeouts on large paste from client (>10sec)
therfore:
-reduce VD_CLIPBOARD_TIMEOUT_MS to 3sec from previous clipboard chunk
-remove _clipboard_event and use _control_event(CONTROL_CLIPBOARD) instead
-use _clipboard_tick for clipboard timeout, updated on each clipboard chunk
-use cleanup_in_msg() to reset incoming message state
rhbz#833835
Diffstat (limited to 'vdagent/vdagent.cpp')
-rw-r--r-- | vdagent/vdagent.cpp | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp index 7495826..9537b90 100644 --- a/vdagent/vdagent.cpp +++ b/vdagent/vdagent.cpp @@ -32,7 +32,7 @@ #define VD_AGENT_WINCLASS_NAME TEXT("VDAGENT") #define VD_INPUT_INTERVAL_MS 20 #define VD_TIMER_ID 1 -#define VD_CLIPBOARD_TIMEOUT_MS 10000 +#define VD_CLIPBOARD_TIMEOUT_MS 3000 #define VD_CLIPBOARD_FORMAT_MAX_TYPES 16 //FIXME: extract format/type stuff to win_vdagent_common for use by windows\platform.cpp as well @@ -107,7 +107,7 @@ private: DWORD get_cximage_format(uint32_t type); enum { owner_none, owner_guest, owner_client }; void set_clipboard_owner(int new_owner); - enum { CONTROL_STOP, CONTROL_DESKTOP_SWITCH, CONTROL_LOGON }; + enum { CONTROL_STOP, CONTROL_DESKTOP_SWITCH, CONTROL_LOGON, CONTROL_CLIPBOARD }; void set_control_event(int control_command); void handle_control_event(); VDIChunk* new_chunk(DWORD bytes = 0); @@ -119,6 +119,7 @@ private: void set_display_depth(uint32_t depth); void load_display_setting(); bool send_announce_capabilities(bool request); + void cleanup_in_msg(); void cleanup(); private: @@ -126,13 +127,13 @@ private: HWND _hwnd; HWND _hwnd_next_viewer; int _clipboard_owner; + DWORD _clipboard_tick; DWORD _buttons_state; ULONG _mouse_x; ULONG _mouse_y; INPUT _input; DWORD _input_time; HANDLE _control_event; - HANDLE _clipboard_event; HANDLE* _events; VDAgentMessage* _in_msg; uint32_t _in_msg_pos; @@ -174,12 +175,12 @@ VDAgent::VDAgent() : _hwnd (NULL) , _hwnd_next_viewer (NULL) , _clipboard_owner (owner_none) + , _clipboard_tick (0) , _buttons_state (0) , _mouse_x (0) , _mouse_y (0) , _input_time (0) , _control_event (NULL) - , _clipboard_event (NULL) , _events (NULL) , _in_msg (NULL) , _in_msg_pos (0) @@ -259,8 +260,7 @@ bool VDAgent::run() vd_printf("SetProcessShutdownParameters failed %lu", GetLastError()); } _control_event = CreateEvent(NULL, FALSE, FALSE, NULL); - _clipboard_event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (!_control_event || !_clipboard_event) { + if (!_control_event) { vd_printf("CreateEvent() failed: %lu", GetLastError()); cleanup(); return false; @@ -313,7 +313,6 @@ bool VDAgent::run() void VDAgent::cleanup() { CloseHandle(_control_event); - CloseHandle(_clipboard_event); delete _vdi_port; delete _desktop_layout; } @@ -353,6 +352,9 @@ void VDAgent::handle_control_event() _logon_occured = true; } break; + case CONTROL_CLIPBOARD: + _clipboard_tick = 0; + break; default: vd_printf("Unsupported control command %u", control_command); } @@ -641,11 +643,11 @@ bool VDAgent::handle_clipboard(VDAgentClipboard* clipboard, uint32_t size) if (_clipboard_owner != owner_client) { vd_printf("Received clipboard data from client while clipboard is not owned by client"); - SetEvent(_clipboard_event); + set_control_event(CONTROL_CLIPBOARD); return false; } if (clipboard->type == VD_AGENT_CLIPBOARD_NONE) { - SetEvent(_clipboard_event); + set_control_event(CONTROL_CLIPBOARD); return false; } switch (clipboard->type) { @@ -666,7 +668,7 @@ bool VDAgent::handle_clipboard(VDAgentClipboard* clipboard, uint32_t size) } format = get_clipboard_format(clipboard->type); if (SetClipboardData(format, clip_data)) { - SetEvent(_clipboard_event); + set_control_event(CONTROL_CLIPBOARD); return true; } // We retry clipboard open-empty-set-close only when there is a timeout in on_clipboard_request() @@ -942,26 +944,16 @@ void VDAgent::on_clipboard_request(UINT format) return; } - // next clipboard event will be considered a reply to this request - ResetEvent(_clipboard_event); - - DWORD start_tick = GetTickCount(); - do { - DWORD wait_result = WaitForSingleObjectEx(_clipboard_event, 1000, TRUE); - - switch (wait_result) { - case WAIT_OBJECT_0: - return; - case WAIT_IO_COMPLETION: - case WAIT_TIMEOUT: - break; - default: - vd_printf("Wait error (%lu)\n", GetLastError()); - return; - } - } while (GetTickCount() < start_tick + VD_CLIPBOARD_TIMEOUT_MS); + _clipboard_tick = GetTickCount(); + while (_running && _clipboard_tick && + GetTickCount() < _clipboard_tick + VD_CLIPBOARD_TIMEOUT_MS) { + event_dispatcher(VD_CLIPBOARD_TIMEOUT_MS, 0); + } - vd_printf("wait timeout.. "); + cleanup_in_msg(); + if (_clipboard_tick) { + vd_printf("Clipboard wait timeout"); + } } void VDAgent::on_clipboard_release() @@ -1096,7 +1088,7 @@ void VDAgent::handle_clipboard_release() vd_printf("Received clipboard release from client while clipboard is not owned by client"); return; } - SetEvent(_clipboard_event); + set_control_event(CONTROL_CLIPBOARD); set_clipboard_owner(owner_none); } @@ -1277,15 +1269,24 @@ void VDAgent::handle_chunk(VDIChunk* chunk) } else { memcpy((uint8_t*)_in_msg + _in_msg_pos, chunk->data, chunk->hdr.size); _in_msg_pos += chunk->hdr.size; + // update clipboard tick on each clipboard chunk for timeout setting + if (_in_msg->type == VD_AGENT_CLIPBOARD) { + _clipboard_tick = GetTickCount(); + } if (_in_msg_pos == sizeof(VDAgentMessage) + _in_msg->size) { dispatch_message(_in_msg, 0); - _in_msg_pos = 0; - delete[] (uint8_t *)_in_msg; - _in_msg = NULL; + cleanup_in_msg(); } } } +void VDAgent::cleanup_in_msg() +{ + _in_msg_pos = 0; + delete[] (uint8_t *)_in_msg; + _in_msg = NULL; +} + void VDAgent::handle_port_out() { MUTEX_LOCK(_message_mutex); |