--- char-pipe.c	2017-03-24 08:08:13.999237000 +0100
+++ char-pipe_new.c	2017-03-24 10:52:21.441322100 +0100
@@ -35,6 +35,61 @@
 #define MAXCONNECT 1
 #define NTIMEOUT 5000
 
+static DWORD WINAPI win_chr_pipe_thread(LPVOID param)
+{
+    Chardev *chr = CHARDEV(param);
+    WinChardev *s = WIN_CHARDEV(param);
+    DWORD size;
+
+    int ret;
+
+    ZeroMemory(&s->orecv, sizeof(s->orecv));
+    s->orecv.hEvent = s->hrecv;
+	while (1) {
+
+		PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
+		if (size>0) {
+			// Wait for one byte
+			while(!(qemu_chr_be_can_write(chr)));
+			ret = ReadFile(s->hcom, &s->win_pipe_buf, 1, &size, &s->orecv);
+			printf("			%s buf = %c size = %lu\n", __func__, s->win_pipe_buf, size);
+
+			if (!ret) {
+				break;
+			}
+			if (!size) {
+				break;
+			}
+
+			// Some terminal emulator returns \r\n for Enter, just pass \n
+			if (s->win_pipe_buf == '\r') {
+				 continue;
+			}
+
+			// Signal the main thread and wait until the byte was eaten
+			if (!SetEvent(s->hpipeInputReadyEvent)) {
+				 break;
+			}
+			printf("			%s the main thread is signaled\n", __func__);
+			if (WaitForSingleObject(s->hpipeInputDoneEvent, INFINITE) != WAIT_OBJECT_0) {
+				 break;
+			}
+			printf("			%s the byte was eaten\n", __func__);
+		}
+	}
+    qemu_del_wait_object(s->hpipeInputReadyEvent, NULL, NULL);
+    return 0;
+}
+
+static void win_pipe_thread_wait_func(void *opaque)
+{
+    Chardev *chr = CHARDEV(opaque);
+    WinChardev *s = WIN_CHARDEV(opaque);
+
+	qemu_chr_be_write(chr, &s->win_pipe_buf, 1);
+	SetEvent(s->hpipeInputDoneEvent); //force the byte is eaten by the fifo
+	}
+}
 static int win_chr_pipe_init(Chardev *chr, const char *filename,
                              Error **errp)
 {
@@ -94,8 +149,38 @@
         ov.hEvent = NULL;
     }
 
-    qemu_add_polling_cb(win_chr_pipe_poll, chr);
-    return 0;
+     // for interlocking
+    DWORD   dwId;
+
+
+    s->hpipeInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+    s->hpipeInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (s->hpipeInputReadyEvent == INVALID_HANDLE_VALUE
+        || s->hpipeInputDoneEvent == INVALID_HANDLE_VALUE) {
+        error_setg(errp, "cannot create event");
+        goto err2;
+    }
+
+    if (qemu_add_wait_object(s->hpipeInputReadyEvent, win_pipe_thread_wait_func, chr)) {
+        error_setg(errp, "qemu_add_wait_object: failed");
+        goto err2;
+    }
+
+    s->hpipeInputThread = CreateThread(NULL, 0, win_chr_pipe_thread, chr, 0, &dwId);
+    if (s->hpipeInputThread == INVALID_HANDLE_VALUE) {
+        error_setg(errp, "cannot create stdio thread");
+        goto err3;
+    }
+
+     return 0;
+
+err3:
+    qemu_del_wait_object(s->hpipeInputReadyEvent, NULL, NULL);
+    return -1;
+err2:
+    CloseHandle(s->hpipeInputReadyEvent);
+    CloseHandle(s->hpipeInputDoneEvent);
+    return -1;
 
  fail:
     return -1;
