[Spice-devel] [PATCH vdagent-win 2/3] vdagent: release clipboard ownership on agent stop & desktop switch rhbz#731628
Alon Levy
alevy at redhat.com
Wed Nov 16 03:53:00 PST 2011
On Wed, Nov 16, 2011 at 12:16:36PM +0200, Arnon Gilboa wrote:
> -use event queue for agent stop & desktop switch
> -exit gracefully on session end
ACK
> ---
> vdagent/vdagent.cpp | 86 ++++++++++++++++++++++++++++++++++++++------------
> 1 files changed, 65 insertions(+), 21 deletions(-)
>
> diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
> index 646afed..f0f5243 100644
> --- a/vdagent/vdagent.cpp
> +++ b/vdagent/vdagent.cpp
> @@ -20,6 +20,7 @@
> #include "display_setting.h"
> #include "ximage.h"
> #include <lmcons.h>
> +#include <queue>
> #include <set>
>
> #define VD_AGENT_LOG_PATH TEXT("%svdagent.log")
> @@ -88,6 +89,9 @@ 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 };
> + void set_control_event(int control_command);
> + void handle_control_event();
> uint8_t* write_lock(DWORD bytes = 0);
> void write_unlock(DWORD bytes = 0);
> bool write_message(uint32_t type, uint32_t size, void* data);
> @@ -109,7 +113,7 @@ private:
> LONG _mouse_y;
> INPUT _input;
> DWORD _input_time;
> - HANDLE _desktop_switch_event;
> + HANDLE _control_event;
> HANDLE _clipboard_event;
> VDAgentMessage* _in_msg;
> uint32_t _in_msg_pos;
> @@ -119,10 +123,13 @@ private:
> bool _pending_input;
> bool _pending_write;
> bool _running;
> + bool _desktop_switch;
> DesktopLayout* _desktop_layout;
> DisplaySetting _display_setting;
> VDPipeState _pipe_state;
> mutex_t _write_mutex;
> + mutex_t _control_mutex;
> + std::queue<int> _control_queue;
>
> bool _logon_desktop;
> bool _display_setting_initialized;
> @@ -154,7 +161,7 @@ VDAgent::VDAgent()
> , _mouse_x (0)
> , _mouse_y (0)
> , _input_time (0)
> - , _desktop_switch_event (NULL)
> + , _control_event (NULL)
> , _clipboard_event (NULL)
> , _in_msg (NULL)
> , _in_msg_pos (0)
> @@ -164,6 +171,7 @@ VDAgent::VDAgent()
> , _pending_input (false)
> , _pending_write (false)
> , _running (false)
> + , _desktop_switch (false)
> , _desktop_layout (NULL)
> , _display_setting (VD_AGENT_REGISTRY_KEY)
> , _logon_desktop (false)
> @@ -182,6 +190,7 @@ VDAgent::VDAgent()
> ZeroMemory(&_input, sizeof(INPUT));
> ZeroMemory(&_pipe_state, sizeof(VDPipeState));
> MUTEX_INIT(_write_mutex);
> + MUTEX_INIT(_control_mutex);
>
> _singleton = this;
> }
> @@ -203,7 +212,7 @@ DWORD WINAPI VDAgent::event_thread_proc(LPVOID param)
> DWORD wait_ret = WaitForSingleObject(desktop_event, INFINITE);
> switch (wait_ret) {
> case WAIT_OBJECT_0:
> - SetEvent((HANDLE)param);
> + _singleton->set_control_event(CONTROL_DESKTOP_SWITCH);
> break;
> case WAIT_TIMEOUT:
> default:
> @@ -233,9 +242,9 @@ bool VDAgent::run()
> if (!SetProcessShutdownParameters(0x100, 0)) {
> vd_printf("SetProcessShutdownParameters failed %u", GetLastError());
> }
> - _desktop_switch_event = CreateEvent(NULL, FALSE, FALSE, NULL);
> + _control_event = CreateEvent(NULL, FALSE, FALSE, NULL);
> _clipboard_event = CreateEvent(NULL, FALSE, FALSE, NULL);
> - if (!_desktop_switch_event || !_clipboard_event) {
> + if (!_control_event || !_clipboard_event) {
> vd_printf("CreateEvent() failed: %d", GetLastError());
> cleanup();
> return false;
> @@ -257,8 +266,7 @@ bool VDAgent::run()
> return false;
> }
> _running = true;
> - event_thread = CreateThread(NULL, 0, event_thread_proc, _desktop_switch_event, 0,
> - &event_thread_id);
> + event_thread = CreateThread(NULL, 0, event_thread_proc, NULL, 0, &event_thread_id);
> if (!event_thread) {
> vd_printf("CreateThread() failed: %d", GetLastError());
> cleanup();
> @@ -268,6 +276,9 @@ bool VDAgent::run()
> read_completion(0, 0, &_pipe_state.read.overlap);
> while (_running) {
> input_desktop_message_loop();
> + if (_clipboard_owner == owner_guest) {
> + set_clipboard_owner(owner_none);
> + }
> }
> vd_printf("Agent stopped");
> CloseHandle(event_thread);
> @@ -277,15 +288,45 @@ bool VDAgent::run()
>
> void VDAgent::cleanup()
> {
> - CloseHandle(_desktop_switch_event);
> + CloseHandle(_control_event);
> CloseHandle(_clipboard_event);
> CloseHandle(_pipe_state.pipe);
> delete _desktop_layout;
> }
>
> +void VDAgent::set_control_event(int control_command)
> +{
> + MUTEX_LOCK(_control_mutex);
> + _control_queue.push(control_command);
> + if (_control_event && !SetEvent(_control_event)) {
> + vd_printf("SetEvent() failed: %u", GetLastError());
> + }
> + MUTEX_UNLOCK(_control_mutex);
> +}
> +
> +void VDAgent::handle_control_event()
> +{
> + MUTEX_LOCK(_control_mutex);
> + while (_control_queue.size()) {
> + int control_command = _control_queue.front();
> + _control_queue.pop();
> + vd_printf("Control command %d", control_command);
> + switch (control_command) {
> + case CONTROL_STOP:
> + _running = false;
> + break;
> + case CONTROL_DESKTOP_SWITCH:
> + _desktop_switch = true;
> + break;
> + default:
> + vd_printf("Unsupported control command %u", control_command);
> + }
> + }
> + MUTEX_UNLOCK(_control_mutex);
> +}
> +
> void VDAgent::input_desktop_message_loop()
> {
> - bool desktop_switch = false;
> TCHAR desktop_name[MAX_PATH];
> DWORD wait_ret;
> HDESK hdesk;
> @@ -333,13 +374,12 @@ void VDAgent::input_desktop_message_loop()
> return;
> }
> _hwnd_next_viewer = SetClipboardViewer(_hwnd);
> - while (_running && !desktop_switch) {
> - wait_ret = MsgWaitForMultipleObjectsEx(1, &_desktop_switch_event, INFINITE, QS_ALLINPUT,
> + while (_running && !_desktop_switch) {
> + wait_ret = MsgWaitForMultipleObjectsEx(1, &_control_event, INFINITE, QS_ALLINPUT,
> MWMO_ALERTABLE);
> switch (wait_ret) {
> case WAIT_OBJECT_0:
> - vd_printf("WinSta0_DesktopSwitch");
> - desktop_switch = true;
> + handle_control_event();
> break;
> case WAIT_OBJECT_0 + 1:
> while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
> @@ -354,6 +394,7 @@ void VDAgent::input_desktop_message_loop()
> vd_printf("MsgWaitForMultipleObjectsEx(): %u", wait_ret);
> }
> }
> + _desktop_switch = false;
> if (_pending_input) {
> KillTimer(_hwnd, VD_TIMER_ID);
> _pending_input = false;
> @@ -901,7 +942,7 @@ bool VDAgent::handle_clipboard_grab(VDAgentClipboardGrab* clipboard_grab, uint32
>
> _grab_types.clear();
> for (uint32_t i = 0; i < size / sizeof(clipboard_grab->types[0]); i++) {
> - vd_printf("grab %u", clipboard_grab->types[i]);
> + vd_printf("grab type %u", clipboard_grab->types[i]);
> uint32_t format = get_clipboard_format(clipboard_grab->types[i]);
> //On first supported type, open and empty the clipboard
> if (format && grab_formats.empty()) {
> @@ -1154,7 +1195,7 @@ VOID CALLBACK VDAgent::read_completion(DWORD err, DWORD bytes, LPOVERLAPPED over
> return;
> }
> if (err) {
> - vd_printf("error %u", err);
> + vd_printf("vdservice disconnected (%u)", err);
> a->_running = false;
> return;
> }
> @@ -1225,7 +1266,7 @@ VOID CALLBACK VDAgent::write_completion(DWORD err, DWORD bytes, LPOVERLAPPED ove
> return;
> }
> if (err) {
> - vd_printf("error %u", err);
> + vd_printf("vdservice disconnected (%u)", err);
> a->_running = false;
> return;
> }
> @@ -1297,11 +1338,14 @@ LRESULT CALLBACK VDAgent::wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARA
> case WM_RENDERFORMAT:
> a->on_clipboard_request((UINT)wparam);
> break;
> - case WM_RENDERALLFORMATS:
> - vd_printf("WM_RENDERALLFORMATS");
> - break;
> - case WM_DESTROYCLIPBOARD:
> - vd_printf("WM_DESTROYCLIPBOARD");
> + case WM_ENDSESSION:
> + if (wparam) {
> + vd_printf("Session ended");
> + if (a->_clipboard_owner == owner_guest) {
> + a->set_clipboard_owner(owner_none);
> + }
> + a->set_control_event(CONTROL_STOP);
> + }
> break;
> default:
> return DefWindowProc(hwnd, message, wparam, lparam);
> --
> 1.7.4.1
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
More information about the Spice-devel
mailing list