blockjob: optimize JSON event handler lookup

Probably in the noise, but this will let us scale more efficiently
as we learn to recognize even more qemu events.

* src/qemu/qemu_monitor_json.c (eventHandlers): Sort.
(qemuMonitorEventCompare): New helper function.
(qemuMonitorJSONIOProcessEvent): Optimize event lookup.
This commit is contained in:
Eric Blake 2012-04-11 08:58:09 -06:00
parent a696f8b71a
commit ecb39e9d4b

View File

@ -66,36 +66,46 @@ static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr
static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr data);
static struct { typedef struct {
const char *type; const char *type;
void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data); void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data);
} eventHandlers[] = { } qemuEventHandler;
{ "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
{ "RESET", qemuMonitorJSONHandleReset, }, static qemuEventHandler eventHandlers[] = {
{ "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
{ "STOP", qemuMonitorJSONHandleStop, },
{ "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
{ "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
{ "BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError, }, { "BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError, },
{ "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
{ "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
{ "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
{ "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, }, { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, },
{ "SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect, },
{ "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
{ "SPICE_DISCONNECTED", qemuMonitorJSONHandleSPICEDisconnect, },
{ "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, }, { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
{ "WAKEUP", qemuMonitorJSONHandlePMWakeup, }, { "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
{ "RESET", qemuMonitorJSONHandleReset, },
{ "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
{ "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
{ "SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect, },
{ "SPICE_DISCONNECTED", qemuMonitorJSONHandleSPICEDisconnect, },
{ "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
{ "STOP", qemuMonitorJSONHandleStop, },
{ "SUSPEND", qemuMonitorJSONHandlePMSuspend, }, { "SUSPEND", qemuMonitorJSONHandlePMSuspend, },
{ "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
{ "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
{ "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
{ "WAKEUP", qemuMonitorJSONHandlePMWakeup, },
{ "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
/* We use bsearch, so keep this list sorted. */
}; };
static int
qemuMonitorEventCompare(const void *key, const void *elt)
{
const char *type = key;
const qemuEventHandler *handler = elt;
return strcmp(type, handler->type);
}
static int static int
qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon, qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
virJSONValuePtr obj) virJSONValuePtr obj)
{ {
const char *type; const char *type;
int i; qemuEventHandler *handler;
VIR_DEBUG("mon=%p obj=%p", mon, obj); VIR_DEBUG("mon=%p obj=%p", mon, obj);
type = virJSONValueObjectGetString(obj, "event"); type = virJSONValueObjectGetString(obj, "event");
@ -105,14 +115,13 @@ qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
return -1; return -1;
} }
for (i = 0 ; i < ARRAY_CARDINALITY(eventHandlers) ; i++) { handler = bsearch(type, eventHandlers, ARRAY_CARDINALITY(eventHandlers),
if (STREQ(eventHandlers[i].type, type)) { sizeof(eventHandlers[0]), qemuMonitorEventCompare);
virJSONValuePtr data = virJSONValueObjectGet(obj, "data"); if (handler) {
VIR_DEBUG("handle %s handler=%p data=%p", type, virJSONValuePtr data = virJSONValueObjectGet(obj, "data");
eventHandlers[i].handler, data); VIR_DEBUG("handle %s handler=%p data=%p", type,
(eventHandlers[i].handler)(mon, data); handler->handler, data);
break; (handler->handler)(mon, data);
}
} }
return 0; return 0;
} }