On 28/10/2022 06.57, Bin Meng wrote:
Introduce an API for qtest to wait for the QEMU process to terminate.

Suggested-by: Marc-AndrĂ© Lureau <[email protected]>
Signed-off-by: Bin Meng <[email protected]>

---

Changes in v6:
- new patch: "tests/qtest: libqtest: Introduce qtest_wait_qemu()"

  tests/qtest/libqtest.h |  9 ++++++
  tests/qtest/libqtest.c | 63 +++++++++++++++++++++++++-----------------
  2 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index 65c040e504..91a5f7edd9 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -75,6 +75,15 @@ QTestState *qtest_init_without_qmp_handshake(const char 
*extra_args);
   */
  QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd);
+/**
+ * qtest_wait_qemu:
+ * @s: #QTestState instance to operate on.
+ *
+ * Wait for the QEMU process to terminate. It is safe to call this function
+ * multiple times.
+ */
+void qtest_wait_qemu(QTestState *s);
+
  /**
   * qtest_kill_qemu:
   * @s: #QTestState instance to operate on.
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index d12a604d78..e1e2d39a6e 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -156,37 +156,14 @@ void qtest_set_expected_status(QTestState *s, int status)
      s->expected_status = status;
  }
-void qtest_kill_qemu(QTestState *s)
+static void qtest_check_status(QTestState *s)
  {
-    pid_t pid = s->qemu_pid;
-#ifndef _WIN32
-    int wstatus;
-#else
-    DWORD ret;
-#endif
-
-    /* Skip wait if qtest_probe_child already reaped.  */
-    if (pid != -1) {
-#ifndef _WIN32
-        kill(pid, SIGTERM);
-        TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0));
-        assert(pid == s->qemu_pid);
-#else
-        TerminateProcess((HANDLE)pid, s->expected_status);
-        ret = WaitForSingleObject((HANDLE)pid, INFINITE);
-        assert(ret == WAIT_OBJECT_0);
-        GetExitCodeProcess((HANDLE)pid, &s->exit_code);
-        CloseHandle((HANDLE)pid);
-#endif
-        s->qemu_pid = -1;
-    }
-
      /*
       * Check whether qemu exited with expected exit status; anything else is
       * fishy and should be logged with as much detail as possible.
       */
  #ifndef _WIN32
-    wstatus = s->wstatus;
+    int wstatus = s->wstatus;
      if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != s->expected_status) {
          fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU "
                  "process but encountered exit status %d (expected %d)\n",
@@ -212,6 +189,42 @@ void qtest_kill_qemu(QTestState *s)
  #endif
  }
+void qtest_wait_qemu(QTestState *s)
+{
+#ifndef _WIN32
+    pid_t pid;

Should we have a check for  s->qemu_pid != -1 here ?

+    TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0));
+    assert(pid == s->qemu_pid);
+#else
+    DWORD ret;
+
+    ret = WaitForSingleObject((HANDLE)s->qemu_pid, INFINITE);
+    assert(ret == WAIT_OBJECT_0);
+    GetExitCodeProcess((HANDLE)s->qemu_pid, &s->exit_code);
+    CloseHandle((HANDLE)s->qemu_pid);
+#endif
+
+    qtest_check_status(s);
+}
+
+void qtest_kill_qemu(QTestState *s)
+{
+    /* Skip wait if qtest_probe_child() already reaped */
+    if (s->qemu_pid != -1) {
+#ifndef _WIN32
+        kill(s->qemu_pid, SIGTERM);
+#else
+        TerminateProcess((HANDLE)s->qemu_pid, s->expected_status);
+#endif
+        qtest_wait_qemu(s);
+        s->qemu_pid = -1;
+        return;
+    }
+
+    qtest_check_status(s);
+}
+
  static void kill_qemu_hook_func(void *s)
  {
      qtest_kill_qemu(s);

 Thomas


Reply via email to