]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
virNetSocket: Fix @watch corner case
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 18 Jun 2015 12:22:10 +0000 (14:22 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 19 Jun 2015 09:19:49 +0000 (11:19 +0200)
Although highly unlikely, nobody says that virEventAddHandle()
can't return 0 as a handle to socket callback. It can't happen
with our default implementation since all watches will have value
1 or greater, but users can register their own callback functions
(which can re-use unused watch IDs for instance). If this is the
case, weird things may happen.

Also, there's a little bug I'm fixing too, upon
virNetSocketRemoveIOCallback(), the variable holding callback ID
was not reset. Therefore calling AddIOCallback() once again would
fail. Not that we are doing it right now, but we might.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/rpc/virnetsocket.c

index 48107ffad11893fd91d8649ceee538342ee62642..3d7508110ef2a846e1e76ed92c910520a4f7a209 100644 (file)
@@ -245,6 +245,7 @@ static virNetSocketPtr virNetSocketNew(virSocketAddrPtr localAddr,
     sock->fd = fd;
     sock->errfd = errfd;
     sock->pid = pid;
+    sock->watch = -1;
 
     /* Disable nagle for TCP sockets */
     if (sock->localAddr.data.sa.sa_family == AF_INET ||
@@ -1153,7 +1154,7 @@ void virNetSocketDispose(void *obj)
     PROBE(RPC_SOCKET_DISPOSE,
           "sock=%p", sock);
 
-    if (sock->watch > 0) {
+    if (sock->watch >= 0) {
         virEventRemoveHandle(sock->watch);
         sock->watch = -1;
     }
@@ -1941,7 +1942,7 @@ int virNetSocketAddIOCallback(virNetSocketPtr sock,
 
     virObjectRef(sock);
     virObjectLock(sock);
-    if (sock->watch > 0) {
+    if (sock->watch >= 0) {
         VIR_DEBUG("Watch already registered on socket %p", sock);
         goto cleanup;
     }
@@ -1971,7 +1972,7 @@ void virNetSocketUpdateIOCallback(virNetSocketPtr sock,
                                   int events)
 {
     virObjectLock(sock);
-    if (sock->watch <= 0) {
+    if (sock->watch < 0) {
         VIR_DEBUG("Watch not registered on socket %p", sock);
         virObjectUnlock(sock);
         return;
@@ -1986,7 +1987,7 @@ void virNetSocketRemoveIOCallback(virNetSocketPtr sock)
 {
     virObjectLock(sock);
 
-    if (sock->watch <= 0) {
+    if (sock->watch < 0) {
         VIR_DEBUG("Watch not registered on socket %p", sock);
         virObjectUnlock(sock);
         return;
@@ -1994,6 +1995,7 @@ void virNetSocketRemoveIOCallback(virNetSocketPtr sock)
 
     virEventRemoveHandle(sock->watch);
     /* Don't unref @sock, it's done via eventloop callback. */
+    sock->watch = -1;
 
     virObjectUnlock(sock);
 }