Lines Matching +full:0 +full:- +full:mon

4  * Copyright (c) 2003-2004 Fabrice Bellard
27 #include "chardev/char-io.h"
28 #include "monitor-internal.h"
30 #include "qapi/qapi-commands-control.h"
45 * be pushed onto mon->qmp_requests, and @qmp_dispatcher_co_shutdown may
62 MonitorQMP *mon; member
65 * (exactly one of them is non-null)
74 static bool qmp_oob_enabled(MonitorQMP *mon) in qmp_oob_enabled() argument
76 return mon->capab[QMP_CAPABILITY_OOB]; in qmp_oob_enabled()
79 static void monitor_qmp_caps_reset(MonitorQMP *mon) in monitor_qmp_caps_reset() argument
81 memset(mon->capab_offered, 0, sizeof(mon->capab_offered)); in monitor_qmp_caps_reset()
82 memset(mon->capab, 0, sizeof(mon->capab)); in monitor_qmp_caps_reset()
83 mon->capab_offered[QMP_CAPABILITY_OOB] = mon->common.use_io_thread; in monitor_qmp_caps_reset()
88 qobject_unref(req->req); in qmp_request_free()
89 error_free(req->err); in qmp_request_free()
93 /* Caller must hold mon->qmp.qmp_queue_lock */
94 static void monitor_qmp_cleanup_req_queue_locked(MonitorQMP *mon) in monitor_qmp_cleanup_req_queue_locked() argument
96 while (!g_queue_is_empty(mon->qmp_requests)) { in monitor_qmp_cleanup_req_queue_locked()
97 qmp_request_free(g_queue_pop_head(mon->qmp_requests)); in monitor_qmp_cleanup_req_queue_locked()
101 static void monitor_qmp_cleanup_queue_and_resume(MonitorQMP *mon) in monitor_qmp_cleanup_queue_and_resume() argument
103 QEMU_LOCK_GUARD(&mon->qmp_queue_lock); in monitor_qmp_cleanup_queue_and_resume()
107 * removing an element from the queue (hence no `- 1`). in monitor_qmp_cleanup_queue_and_resume()
111 bool need_resume = (!qmp_oob_enabled(mon) || in monitor_qmp_cleanup_queue_and_resume()
112 mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX) in monitor_qmp_cleanup_queue_and_resume()
113 && !g_queue_is_empty(mon->qmp_requests); in monitor_qmp_cleanup_queue_and_resume()
115 monitor_qmp_cleanup_req_queue_locked(mon); in monitor_qmp_cleanup_queue_and_resume()
127 monitor_resume(&mon->common); in monitor_qmp_cleanup_queue_and_resume()
132 void qmp_send_response(MonitorQMP *mon, const QDict *rsp) in qmp_send_response() argument
137 json = qobject_to_json_pretty(data, mon->pretty); in qmp_send_response()
139 trace_monitor_qmp_respond(mon, json->str); in qmp_send_response()
142 monitor_puts(&mon->common, json->str); in qmp_send_response()
148 * Emit QMP response @rsp to @mon.
152 static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp) in monitor_qmp_respond() argument
155 qmp_send_response(mon, rsp); in monitor_qmp_respond()
163 static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) in monitor_qmp_dispatch() argument
168 rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon), in monitor_qmp_dispatch()
169 &mon->common); in monitor_qmp_dispatch()
171 if (mon->commands == &qmp_cap_negotiation_commands) { in monitor_qmp_dispatch()
183 monitor_qmp_respond(mon, rsp); in monitor_qmp_dispatch()
190 * We are using round-robin fashion to pop the request, to avoid
195 * Note: if the function returned with non-NULL, then the caller will
196 * be with qmp_mon->qmp_queue_lock held, and the caller is responsible
202 Monitor *mon; in monitor_qmp_requests_pop_any_with_lock() local
205 QTAILQ_FOREACH(mon, &mon_list, entry) { in monitor_qmp_requests_pop_any_with_lock()
206 if (!monitor_is_qmp(mon)) { in monitor_qmp_requests_pop_any_with_lock()
210 qmp_mon = container_of(mon, MonitorQMP, common); in monitor_qmp_requests_pop_any_with_lock()
211 qemu_mutex_lock(&qmp_mon->qmp_queue_lock); in monitor_qmp_requests_pop_any_with_lock()
212 req_obj = g_queue_pop_head(qmp_mon->qmp_requests); in monitor_qmp_requests_pop_any_with_lock()
217 qemu_mutex_unlock(&qmp_mon->qmp_queue_lock); in monitor_qmp_requests_pop_any_with_lock()
223 * priority to lowest by re-inserting it to end of queue. in monitor_qmp_requests_pop_any_with_lock()
225 QTAILQ_REMOVE(&mon_list, mon, entry); in monitor_qmp_requests_pop_any_with_lock()
226 QTAILQ_INSERT_TAIL(&mon_list, mon, entry); in monitor_qmp_requests_pop_any_with_lock()
238 * aio_co_wake()-ing it. in monitor_qmp_dispatcher_pop_any()
279 MonitorQMP *mon; in monitor_qmp_dispatcher_co() local
283 req_obj->mon->qmp_requests->length); in monitor_qmp_dispatcher_co()
286 * @req_obj has a request, we hold req_obj->mon->qmp_queue_lock in monitor_qmp_dispatcher_co()
289 mon = req_obj->mon; in monitor_qmp_dispatcher_co()
294 * 1. OOB enabled: mon->qmp_requests has no more space in monitor_qmp_dispatcher_co()
302 oob_enabled = qmp_oob_enabled(mon); in monitor_qmp_dispatcher_co()
304 && mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) { in monitor_qmp_dispatcher_co()
305 monitor_resume(&mon->common); in monitor_qmp_dispatcher_co()
312 qemu_mutex_unlock(&mon->qmp_queue_lock); in monitor_qmp_dispatcher_co()
325 if (req_obj->req) { in monitor_qmp_dispatcher_co()
327 QDict *qdict = qobject_to(QDict, req_obj->req); in monitor_qmp_dispatcher_co()
332 trace_monitor_qmp_cmd_in_band(id_json->str); in monitor_qmp_dispatcher_co()
335 monitor_qmp_dispatch(mon, req_obj->req); in monitor_qmp_dispatcher_co()
337 assert(req_obj->err); in monitor_qmp_dispatcher_co()
338 trace_monitor_qmp_err_in_band(error_get_pretty(req_obj->err)); in monitor_qmp_dispatcher_co()
339 rsp = qmp_error_response(req_obj->err); in monitor_qmp_dispatcher_co()
340 req_obj->err = NULL; in monitor_qmp_dispatcher_co()
341 monitor_qmp_respond(mon, rsp); in monitor_qmp_dispatcher_co()
346 monitor_resume(&mon->common); in monitor_qmp_dispatcher_co()
366 MonitorQMP *mon = opaque; in handle_qmp_command() local
374 trace_handle_qmp_command(mon, req_json->str); in handle_qmp_command()
385 trace_monitor_qmp_cmd_out_of_band(id_json->str); in handle_qmp_command()
388 monitor_qmp_dispatch(mon, req); in handle_qmp_command()
394 req_obj->mon = mon; in handle_qmp_command()
395 req_obj->req = req; in handle_qmp_command()
396 req_obj->err = err; in handle_qmp_command()
399 WITH_QEMU_LOCK_GUARD(&mon->qmp_queue_lock) { in handle_qmp_command()
408 if (!qmp_oob_enabled(mon) || in handle_qmp_command()
409 mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) { in handle_qmp_command()
410 monitor_suspend(&mon->common); in handle_qmp_command()
418 trace_monitor_qmp_in_band_enqueue(req_obj, mon, in handle_qmp_command()
419 mon->qmp_requests->length); in handle_qmp_command()
420 assert(mon->qmp_requests->length < QMP_REQ_QUEUE_LEN_MAX); in handle_qmp_command()
421 g_queue_push_tail(mon->qmp_requests, req_obj); in handle_qmp_command()
430 MonitorQMP *mon = opaque; in monitor_qmp_read() local
432 json_message_parser_feed(&mon->parser, (const char *) buf, size); in monitor_qmp_read()
435 static QDict *qmp_greeting(MonitorQMP *mon) in qmp_greeting() argument
446 for (cap = 0; cap < QMP_CAPABILITY__MAX; cap++) { in qmp_greeting()
447 if (mon->capab_offered[cap]) { in qmp_greeting()
460 MonitorQMP *mon = opaque; in monitor_qmp_event() local
464 mon->commands = &qmp_cap_negotiation_commands; in monitor_qmp_event()
465 monitor_qmp_caps_reset(mon); in monitor_qmp_event()
466 data = qmp_greeting(mon); in monitor_qmp_event()
467 qmp_send_response(mon, data); in monitor_qmp_event()
477 monitor_qmp_cleanup_queue_and_resume(mon); in monitor_qmp_event()
478 json_message_parser_destroy(&mon->parser); in monitor_qmp_event()
479 json_message_parser_init(&mon->parser, handle_qmp_command, in monitor_qmp_event()
480 mon, NULL); in monitor_qmp_event()
491 void monitor_data_destroy_qmp(MonitorQMP *mon) in monitor_data_destroy_qmp() argument
493 json_message_parser_destroy(&mon->parser); in monitor_data_destroy_qmp()
494 qemu_mutex_destroy(&mon->qmp_queue_lock); in monitor_data_destroy_qmp()
495 monitor_qmp_cleanup_req_queue_locked(mon); in monitor_data_destroy_qmp()
496 g_queue_free(mon->qmp_requests); in monitor_data_destroy_qmp()
501 MonitorQMP *mon = opaque; in monitor_qmp_setup_handlers_bh() local
504 assert(mon->common.use_io_thread); in monitor_qmp_setup_handlers_bh()
507 qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read, in monitor_qmp_setup_handlers_bh()
509 NULL, &mon->common, context, true); in monitor_qmp_setup_handlers_bh()
510 monitor_list_append(&mon->common); in monitor_qmp_setup_handlers_bh()
515 MonitorQMP *mon = g_new0(MonitorQMP, 1); in monitor_init_qmp() local
517 if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) { in monitor_init_qmp()
518 g_free(mon); in monitor_init_qmp()
521 qemu_chr_fe_set_echo(&mon->common.chr, true); in monitor_init_qmp()
524 monitor_data_init(&mon->common, true, false, in monitor_init_qmp()
527 mon->pretty = pretty; in monitor_init_qmp()
529 qemu_mutex_init(&mon->qmp_queue_lock); in monitor_init_qmp()
530 mon->qmp_requests = g_queue_new(); in monitor_init_qmp()
532 json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL); in monitor_init_qmp()
533 if (mon->common.use_io_thread) { in monitor_init_qmp()
545 monitor_qmp_setup_handlers_bh, mon); in monitor_init_qmp()
546 /* The bottom half will add @mon to @mon_list */ in monitor_init_qmp()
548 qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read, in monitor_init_qmp()
550 NULL, &mon->common, NULL, true); in monitor_init_qmp()
551 monitor_list_append(&mon->common); in monitor_init_qmp()