Commit 6e5d4999 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2019-11-19' into staging



Monitor patches for 2019-11-19

# gpg: Signature made Tue 19 Nov 2019 08:50:57 GMT
# gpg:                using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653
# gpg:                issuer "armbru@redhat.com"
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full]
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>" [full]
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867  4E5F 3870 B400 EB91 8653

* remotes/armbru/tags/pull-monitor-2019-11-19:
  monitor/qmp: resume monitor when clearing its queue

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 385e43e6 2895aaa1
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -75,10 +75,35 @@ static void monitor_qmp_cleanup_req_queue_locked(MonitorQMP *mon)
    }
}

static void monitor_qmp_cleanup_queues(MonitorQMP *mon)
static void monitor_qmp_cleanup_queue_and_resume(MonitorQMP *mon)
{
    qemu_mutex_lock(&mon->qmp_queue_lock);

    /*
     * Same condition as in monitor_qmp_bh_dispatcher(), but before
     * removing an element from the queue (hence no `- 1`).
     * Also, the queue should not be empty either, otherwise the
     * monitor hasn't been suspended yet (or was already resumed).
     */
    bool need_resume = (!qmp_oob_enabled(mon) ||
        mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX)
        && !g_queue_is_empty(mon->qmp_requests);

    monitor_qmp_cleanup_req_queue_locked(mon);

    if (need_resume) {
        /*
         * handle_qmp_command() suspended the monitor because the
         * request queue filled up, to be resumed when the queue has
         * space again.  We just emptied it; resume the monitor.
         *
         * Without this, the monitor would remain suspended forever
         * when we get here while the monitor is suspended.  An
         * unfortunately timed CHR_EVENT_CLOSED can do the trick.
         */
        monitor_resume(&mon->common);
    }

    qemu_mutex_unlock(&mon->qmp_queue_lock);
}

@@ -263,9 +288,10 @@ static void handle_qmp_command(void *opaque, QObject *req, Error *err)

    /*
     * Suspend the monitor when we can't queue more requests after
     * this one.  Dequeuing in monitor_qmp_bh_dispatcher() will resume
     * it.  Note that when OOB is disabled, we queue at most one
     * command, for backward compatibility.
     * this one.  Dequeuing in monitor_qmp_bh_dispatcher() or
     * monitor_qmp_cleanup_queue_and_resume() will resume it.
     * Note that when OOB is disabled, we queue at most one command,
     * for backward compatibility.
     */
    if (!qmp_oob_enabled(mon) ||
        mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
@@ -332,7 +358,7 @@ static void monitor_qmp_event(void *opaque, int event)
         * stdio, it's possible that stdout is still open when stdin
         * is closed.
         */
        monitor_qmp_cleanup_queues(mon);
        monitor_qmp_cleanup_queue_and_resume(mon);
        json_message_parser_destroy(&mon->parser);
        json_message_parser_init(&mon->parser, handle_qmp_command,
                                 mon, NULL);