Terminate agent politely instead of ugly TerminateProcess(), so now VD_AGENT_CLIPBOARD_RELEASE is sent (if guest owned the clipboard), followed by cleanup. rhbz #903379 --- common/vdcommon.h | 1 + vdagent/vdagent.cpp | 16 +++++++++++++++- vdservice/vdservice.cpp | 5 ++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/common/vdcommon.h b/common/vdcommon.h index cc3bd3d..605153d 100644 --- a/common/vdcommon.h +++ b/common/vdcommon.h @@ -33,6 +33,7 @@ typedef CRITICAL_SECTION mutex_t; #define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex) #define VD_AGENT_REGISTRY_KEY "SOFTWARE\\Red Hat\\Spice\\vdagent\\" +#define VD_AGENT_STOP_EVENT TEXT("Global\\vdagent_stop_event") #if defined __GNUC__ #define ALIGN_GCC __attribute__ ((packed)) diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp index 85244c0..722815c 100644 --- a/vdagent/vdagent.cpp +++ b/vdagent/vdagent.cpp @@ -128,6 +128,7 @@ private: INPUT _input; DWORD _input_time; HANDLE _control_event; + HANDLE _stop_event; VDAgentMessage* _in_msg; uint32_t _in_msg_pos; bool _pending_input; @@ -180,6 +181,7 @@ VDAgent::VDAgent() , _mouse_y (0) , _input_time (0) , _control_event (NULL) + , _stop_event (NULL) , _in_msg (NULL) , _in_msg_pos (0) , _pending_input (false) @@ -266,6 +268,12 @@ bool VDAgent::run() cleanup(); return false; } + _stop_event = OpenEvent(SYNCHRONIZE, FALSE, VD_AGENT_STOP_EVENT); + if (!_stop_event) { + vd_printf("OpenEvent() failed: %lu", GetLastError()); + cleanup(); + return false; + } memset(&wcls, 0, sizeof(wcls)); wcls.lpfnWndProc = &VDAgent::wnd_proc; wcls.lpszClassName = VD_AGENT_WINCLASS_NAME; @@ -312,6 +320,7 @@ bool VDAgent::run() void VDAgent::cleanup() { + CloseHandle(_stop_event); CloseHandle(_control_event); CloseHandle(_vio_serial); delete _desktop_layout; @@ -428,15 +437,20 @@ void VDAgent::input_desktop_message_loop() void VDAgent::event_dispatcher(DWORD timeout, DWORD wake_mask) { + HANDLE events[] = {_control_event, _stop_event}; + const DWORD event_count = sizeof(events) / sizeof(events[0]); DWORD wait_ret; MSG msg; - wait_ret = MsgWaitForMultipleObjectsEx(1, &_control_event, timeout, wake_mask, MWMO_ALERTABLE); + wait_ret = MsgWaitForMultipleObjectsEx(event_count, events, timeout, wake_mask, MWMO_ALERTABLE); switch (wait_ret) { case WAIT_OBJECT_0: handle_control_event(); break; case WAIT_OBJECT_0 + 1: + _running = false; + break; + case WAIT_OBJECT_0 + event_count: while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp index a2cf67d..a899ae1 100644 --- a/vdservice/vdservice.cpp +++ b/vdservice/vdservice.cpp @@ -92,6 +92,7 @@ private: SERVICE_STATUS_HANDLE _status_handle; PROCESS_INFORMATION _agent_proc_info; HANDLE _control_event; + HANDLE _agent_stop_event; HANDLE* _events; TCHAR _agent_path[MAX_PATH]; VDControlQueue _control_queue; @@ -157,6 +158,7 @@ VDService::VDService() ZeroMemory(&_agent_proc_info, sizeof(_agent_proc_info)); _system_version = supported_system_version(); _control_event = CreateEvent(NULL, FALSE, FALSE, NULL); + _agent_stop_event = CreateEvent(NULL, FALSE, FALSE, VD_AGENT_STOP_EVENT); _agent_path[0] = wchar_t('\0'); MUTEX_INIT(_agent_mutex); MUTEX_INIT(_control_mutex); @@ -165,6 +167,7 @@ VDService::VDService() VDService::~VDService() { + CloseHandle(_agent_stop_event); CloseHandle(_control_event); delete _events; delete _log; @@ -777,7 +780,7 @@ bool VDService::kill_agent() _agent_alive = false; proc_handle = _agent_proc_info.hProcess; _agent_proc_info.hProcess = 0; - TerminateProcess(proc_handle, 0); + SetEvent(_agent_stop_event); if (GetProcessId(proc_handle)) { wait_ret = WaitForSingleObject(proc_handle, VD_AGENT_TIMEOUT); switch (wait_ret) { -- 1.7.7.6 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel