From 9ee5a79830011cb9cf9b09d388becb59a88a5c20 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 18 Jun 2015 14:22:10 +0200 Subject: [PATCH] virNetSocket: Fix @watch corner case 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 --- src/rpc/virnetsocket.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 48107ffad1..3d7508110e 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -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); } -- 2.47.2