[Spice-devel] [PATCH] vdagent: set timeout for next clipboard chunk instead of complete reception
Arnon Gilboa
agilboa at redhat.com
Wed Nov 7 05:20:46 PST 2012
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
---
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);
--
1.7.4.1
More information about the Spice-devel
mailing list