[Spice-devel,vdagent-win,2/6] vdservice: use overlap ConnectNamedPipe() in launch_agent()

Submitted by Arnon Gilboa on July 24, 2011, 5:48 p.m.

Details

Message ID 1311504498-31132-3-git-send-email-agilboa@redhat.com
State New, archived
Headers show

Not browsing as part of any series.

Commit Message

Arnon Gilboa July 24, 2011, 5:48 p.m.
passing NULL is buggy when pipe opened with FILE_FLAG_OVERLAPPED
---
 vdservice/vdservice.cpp |   28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index 4d4937f..7ca9db8 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -827,6 +827,7 @@  BOOL create_process_as_user(IN DWORD session_id, IN LPCWSTR application_name,
 bool VDService::launch_agent()
 {
     STARTUPINFO startup_info;
+    OVERLAPPED overlap;
     BOOL ret = FALSE;
 
     ZeroMemory(&startup_info, sizeof(startup_info));
@@ -867,15 +868,30 @@  bool VDService::launch_agent()
         return false;
     }
     vd_printf("Wait for vdagent to connect");
-    if (ConnectNamedPipe(_pipe_state.pipe, NULL) || GetLastError() == ERROR_PIPE_CONNECTED) {
+    ZeroMemory(&overlap, sizeof(overlap));
+    overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+    DWORD err = (ConnectNamedPipe(_pipe_state.pipe, &overlap) ? 0 : GetLastError());
+    if (err = 0 || err == ERROR_PIPE_CONNECTED) {
+        vd_printf("Pipe connected by vdagent without pending");
+    } else if (err = ERROR_IO_PENDING) {
+        DWORD wait_ret = WaitForSingleObject(overlap.hEvent, 3000);
+        if (wait_ret == WAIT_OBJECT_0) {
+            vd_printf("Pipe connected by vdagent");
+        } else {
+            vd_printf("WaitForSingleObject() failed: %u error: %u", wait_ret,
+                wait_ret == WAIT_FAILED ? GetLastError() : 0);
+            ret = FALSE;
+        }
+    } else {
+        vd_printf("ConnectNamedPipe() failed: %u", err);
+        ret = FALSE;
+    }
+    if (ret) {
         _pipe_connected = true;
         _pending_reset = false;
-        vd_printf("Pipe connected by vdagent");
-    } else {
-        vd_printf("ConnectNamedPipe() failed: %u", GetLastError());
-        return false;
     }
-    return true;
+    CloseHandle(overlap.hEvent);
+    return !!ret;
 }
 
 bool VDService::kill_agent()