libqmp
qtest_qmp_receive_dict()
/ qmp_fd_receive()
QEMU
QDict *qtest_qmp_receive_dict(QTestState *s)
{
// 通过 s->qmp_fd 来 receive 输出
return qmp_fd_receive(s->qmp_fd);
}
QDict *qmp_fd_receive(int fd)
{
QMPResponseParser qmp;
bool log = getenv("QTEST_LOG") != NULL;
qmp.response = NULL;
json_message_parser_init(&qmp.parser, qmp_response, &qmp, NULL);
while (!qmp.response) {
ssize_t len;
char c;
// 一次接收一个 char
len = recv(fd, &c, 1, 0);
// error handling...
// ...
if (log)
g_assert(write(2, &c, 1) == 1);
// 把接收到的 char feed 到 JsonParser 当中。
// JsonParser 只是一个 parser,并不会存储任何信息。
// 解析完成后存储到了 qmp.response 当中。
json_message_parser_feed(&qmp.parser, &c, 1);
}
if (log)
g_assert(write(2, "\n", 1) == 1);
json_message_parser_destroy(&qmp.parser);
return qmp.response;
}
struct QMPResponseParser
QEMU
typedef struct {
JSONMessageParser parser;
// 注意这是一个 QDict。
QDict *response;
} QMPResponseParser;
qtest_qmp_receive()
QEMU
QDict *qtest_qmp_receive(QTestState *s)
{
while (true) {
QDict *response = qtest_qmp_receive_dict(s);
if (!qdict_get_try_str(response, "event"))
return response;
if (!s->eventCB || !s->eventCB(s, qdict_get_str(response, "event"), response, s->eventData)) {
/* Stash the event for a later consumption */
// 一个关于 QDict 的 list
s->pending_events = g_list_append(s->pending_events, response);
}
}
}
qtest_qmp_event_ref()
QEMU
这个函数是把现在已经 stash 的 pending_events
处理完。
QDict *qtest_qmp_event_ref(QTestState *s, const char *event)
{
while (s->pending_events) {
GList *first = s->pending_events;
QDict *response = (QDict *)first->data;
s->pending_events = g_list_delete_link(s->pending_events, first);
if (!strcmp(qdict_get_str(response, "event"), event))
return response;
qobject_unref(response);
}
return NULL;
}
qtest_qmp_eventwait_ref()
QEMU
QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event)
{
// 先处理已经有的 pending_events
QDict *response = qtest_qmp_event_ref(s, event);
if (response)
return response;
// 继续接收
for (;;) {
response = qtest_qmp_receive_dict(s);
if ((qdict_haskey(response, "event")) &&
(strcmp(qdict_get_str(response, "event"), event) == 0)) {
return response;
}
qobject_unref(response);
}
}
🗞️ Recent Posts