[libvirt] [PATCH 1/2] qemu: simplify monitor callbacks
Eric Blake
eblake at redhat.com
Tue Mar 22 23:19:36 UTC 2011
On 03/19/2011 08:06 AM, Matthias Bolte wrote:
> 2011/3/18 Eric Blake <eblake at redhat.com>:
>> The next patch will change reference counting idioms; consolidating
>> this pattern now makes the next patch smaller (touch only the new
>> macro rather than every caller).
>>
>> * src/qemu/qemu_monitor.c (QEMU_MONITOR_CALLBACK): New helper.
>> (qemuMonitorGetDiskSecret, qemuMonitorEmitShutdown)
>> (qemuMonitorEmitReset, qemuMonitorEmitPowerdown)
>> (qemuMonitorEmitStop, qemuMonitorEmitRTCChange)
>> (qemuMonitorEmitWatchdog, qemuMonitorEmitIOError)
>> (qemuMonitorEmitGraphics): Use it to reduce duplication.
>> ---
>>
>>
>> +/* Ensure proper locking around callbacks; assumes mon and ret are in
>> + * scope. */
>> +#define QEMU_MONITOR_CALLBACK(callback, ...) \
>> + qemuMonitorRef(mon); \
>> + qemuMonitorUnlock(mon); \
>> + if (mon->cb && mon->cb->callback) \
>> + ret = (mon->cb->callback)(mon, __VA_ARGS__); \
>> + qemuMonitorLock(mon); \
>> + qemuMonitorUnref(mon)
>>
>
> Shouldn't this be
>
> #define QEMU_MONITOR_CALLBACK(callback, ...) \
> do { \
> ... \
> } while (0)
>
> just to ensure that doing things like
>
> if (...)
> QEMU_MONITOR_CALLBACK(domainWatchdog, mon->vm, action);
>
> is safe? Because this one will break with the current form of
> QEMU_MONITOR_CALLBACK.
It would break, but none of the current callers used this macro from
inside a conditional, so that's theoretical for now. Still, I agree
that preventative programming can be worthwhile if it's not too tough.
>
> Another nit on readability. The macro hides the conditional assignment
> of ret, but turning it into ret = QEMU_MONITOR_CALLBACK(...) is not
> that simple.
Yeah, so I decided to make mon and ret explicit parameters. Still not
quite a true function (the macro uses a field name of the callback
function, which is not your typical l- or rvalue of a real function
call), but at least not as magic.
>
> ACK, with that do {} while (0) problem addressed.
Here's what I squashed in, before pushing. Anyone want to review 2/2 of
this series?
diff --git i/src/qemu/qemu_monitor.c w/src/qemu/qemu_monitor.c
index 5c409af..0c740ab 100644
--- i/src/qemu/qemu_monitor.c
+++ w/src/qemu/qemu_monitor.c
@@ -755,15 +755,16 @@ int qemuMonitorHMPCommandWithFd(qemuMonitorPtr mon,
return qemuMonitorTextCommandWithFd(mon, cmd, scm_fd, reply);
}
-/* Ensure proper locking around callbacks; assumes mon and ret are in
- * scope. */
-#define QEMU_MONITOR_CALLBACK(callback, ...) \
- qemuMonitorRef(mon); \
- qemuMonitorUnlock(mon); \
- if (mon->cb && mon->cb->callback) \
- ret = (mon->cb->callback)(mon, __VA_ARGS__); \
- qemuMonitorLock(mon); \
- qemuMonitorUnref(mon)
+/* Ensure proper locking around callbacks. */
+#define QEMU_MONITOR_CALLBACK(mon, ret, callback, ...) \
+ do { \
+ qemuMonitorRef(mon); \
+ qemuMonitorUnlock(mon); \
+ if ((mon)->cb && (mon)->cb->callback) \
+ (ret) = ((mon)->cb->callback)(mon, __VA_ARGS__); \
+ qemuMonitorLock(mon); \
+ qemuMonitorUnref(mon); \
+ } while (0)
int qemuMonitorGetDiskSecret(qemuMonitorPtr mon,
virConnectPtr conn,
@@ -775,7 +776,7 @@ int qemuMonitorGetDiskSecret(qemuMonitorPtr mon,
*secret = NULL;
*secretLen = 0;
- QEMU_MONITOR_CALLBACK(diskSecretLookup, conn, mon->vm,
+ QEMU_MONITOR_CALLBACK(mon, ret, diskSecretLookup, conn, mon->vm,
path, secret, secretLen);
return ret;
}
@@ -786,7 +787,7 @@ int qemuMonitorEmitShutdown(qemuMonitorPtr mon)
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(domainShutdown, mon->vm);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainShutdown, mon->vm);
return ret;
}
@@ -796,7 +797,7 @@ int qemuMonitorEmitReset(qemuMonitorPtr mon)
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(domainReset, mon->vm);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm);
return ret;
}
@@ -806,7 +807,7 @@ int qemuMonitorEmitPowerdown(qemuMonitorPtr mon)
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(domainPowerdown, mon->vm);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainPowerdown, mon->vm);
return ret;
}
@@ -816,7 +817,7 @@ int qemuMonitorEmitStop(qemuMonitorPtr mon)
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(domainStop, mon->vm);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainStop, mon->vm);
return ret;
}
@@ -826,7 +827,7 @@ int qemuMonitorEmitRTCChange(qemuMonitorPtr mon,
long long offset)
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(domainRTCChange, mon->vm, offset);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainRTCChange, mon->vm, offset);
return ret;
}
@@ -836,7 +837,7 @@ int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int
action)
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(domainWatchdog, mon->vm, action);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainWatchdog, mon->vm, action);
return ret;
}
@@ -849,7 +850,8 @@ int qemuMonitorEmitIOError(qemuMonitorPtr mon,
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(domainIOError, mon->vm, diskAlias, action,
reason);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainIOError, mon->vm,
+ diskAlias, action, reason);
return ret;
}
@@ -869,7 +871,7 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(domainGraphics, mon->vm, phase,
+ QEMU_MONITOR_CALLBACK(mon, ret, domainGraphics, mon->vm, phase,
localFamily, localNode, localService,
remoteFamily, remoteNode, remoteService,
authScheme, x509dname, saslUsername);
--
Eric Blake eblake at redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 619 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20110322/c483a910/attachment-0001.sig>
More information about the libvir-list
mailing list