diff --git a/cfg.mk b/cfg.mk index 64af1ee74b..c0457e7fb8 100644 --- a/cfg.mk +++ b/cfg.mk @@ -145,9 +145,6 @@ useless_free_options = \ --name=virJSONValueFree \ --name=virLastErrFreeData \ --name=virNetMessageFree \ - --name=virNetClientFree \ - --name=virNetClientProgramFree \ - --name=virNetClientStreamFree \ --name=virNetServerMDNSFree \ --name=virNetServerMDNSEntryFree \ --name=virNetServerMDNSGroupFree \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0543005b0f..79b4a183ce 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1304,7 +1304,6 @@ virNetClientAddProgram; virNetClientAddStream; virNetClientClose; virNetClientDupFD; -virNetClientFree; virNetClientGetFD; virNetClientGetTLSKeySize; virNetClientHasPassFD; @@ -1318,7 +1317,6 @@ virNetClientNewExternal; virNetClientNewSSH; virNetClientNewTCP; virNetClientNewUNIX; -virNetClientRef; virNetClientRemoteAddrString; virNetClientRemoveStream; virNetClientSendNoReply; @@ -1333,12 +1331,10 @@ virNetClientSetTLSSession; # virnetclientprogram.h virNetClientProgramCall; virNetClientProgramDispatch; -virNetClientProgramFree; virNetClientProgramGetProgram; virNetClientProgramGetVersion; virNetClientProgramMatches; virNetClientProgramNew; -virNetClientProgramRef; # virnetclientstream.h @@ -1346,13 +1342,11 @@ virNetClientStreamEOF; virNetClientStreamEventAddCallback; virNetClientStreamEventRemoveCallback; virNetClientStreamEventUpdateCallback; -virNetClientStreamFree; virNetClientStreamMatches; virNetClientStreamNew; virNetClientStreamQueuePacket; virNetClientStreamRaiseError; virNetClientStreamRecvPacket; -virNetClientStreamRef; virNetClientStreamSendPacket; virNetClientStreamSetError; diff --git a/src/libvirt_probes.d b/src/libvirt_probes.d index 27f4e9a788..9343fa40bb 100644 --- a/src/libvirt_probes.d +++ b/src/libvirt_probes.d @@ -40,9 +40,7 @@ provider libvirt { # file: src/rpc/virnetclient.c # prefix: rpc - probe rpc_client_new(void *client, int refs, void *sock); - probe rpc_client_ref(void *client, int refs); - probe rpc_client_free(void *client, int refs); + probe rpc_client_new(void *client, void *sock); probe rpc_client_msg_tx_queue(void *client, int len, int prog, int vers, int proc, int type, int status, int serial); probe rpc_client_msg_rx(void *client, int len, int prog, int vers, int proc, int type, int status, int serial); diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c index a2a25995f6..a81d0f7778 100644 --- a/src/lxc/lxc_monitor.c +++ b/src/lxc/lxc_monitor.c @@ -170,7 +170,7 @@ static void virLXCMonitorFree(virLXCMonitorPtr mon) if (mon->cb && mon->cb->destroy) (mon->cb->destroy)(mon, mon->vm); virMutexDestroy(&mon->lock); - virNetClientProgramFree(mon->program); + virObjectUnref(mon->program); VIR_FREE(mon); } @@ -199,7 +199,7 @@ void virLXCMonitorClose(virLXCMonitorPtr mon) { if (mon->client) { virNetClientClose(mon->client); - virNetClientFree(mon->client); + virObjectUnref(mon->client); mon->client = NULL; } } diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 38b11e1a37..353a1536c0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -792,10 +792,10 @@ doRemoteOpen (virConnectPtr conn, virReportOOMError(); failed: - virNetClientProgramFree(priv->remoteProgram); - virNetClientProgramFree(priv->qemuProgram); + virObjectUnref(priv->remoteProgram); + virObjectUnref(priv->qemuProgram); virNetClientClose(priv->client); - virNetClientFree(priv->client); + virObjectUnref(priv->client); priv->client = NULL; VIR_FREE(priv->hostname); @@ -946,10 +946,10 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv) virObjectUnref(priv->tls); priv->tls = NULL; virNetClientClose(priv->client); - virNetClientFree(priv->client); + virObjectUnref(priv->client); priv->client = NULL; - virNetClientProgramFree(priv->remoteProgram); - virNetClientProgramFree(priv->qemuProgram); + virObjectUnref(priv->remoteProgram); + virObjectUnref(priv->qemuProgram); priv->remoteProgram = priv->qemuProgram = NULL; /* Free hostname copy */ @@ -4171,7 +4171,7 @@ remoteStreamFinish(virStreamPtr st) cleanup: virNetClientRemoveStream(priv->client, privst); - virNetClientStreamFree(privst); + virObjectUnref(privst); st->privateData = NULL; st->driver = NULL; @@ -4206,7 +4206,7 @@ remoteStreamAbort(virStreamPtr st) cleanup: virNetClientRemoveStream(priv->client, privst); - virNetClientStreamFree(privst); + virObjectUnref(privst); st->privateData = NULL; st->driver = NULL; @@ -4507,7 +4507,7 @@ remoteDomainMigratePrepareTunnel3(virConnectPtr dconn, goto done; if (virNetClientAddStream(priv->client, netst) < 0) { - virNetClientStreamFree(netst); + virObjectUnref(netst); goto done; } @@ -4525,7 +4525,7 @@ remoteDomainMigratePrepareTunnel3(virConnectPtr dconn, (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_args, (char *) &args, (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_ret, (char *) &ret) == -1) { virNetClientRemoveStream(priv->client, netst); - virNetClientStreamFree(netst); + virObjectUnref(netst); goto done; } diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index 3a6644565e..12023e98cf 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -1450,7 +1450,7 @@ elsif ($opt_k) { print " goto done;\n"; print "\n"; print " if (virNetClientAddStream(priv->client, netst) < 0) {\n"; - print " virNetClientStreamFree(netst);\n"; + print " virObjectUnref(netst);\n"; print " goto done;\n"; print " }"; print "\n"; @@ -1526,7 +1526,7 @@ elsif ($opt_k) { if ($call->{streamflag} ne "none") { print " virNetClientRemoveStream(priv->client, netst);\n"; - print " virNetClientStreamFree(netst);\n"; + print " virObjectUnref(netst);\n"; print " st->driver = NULL;\n"; print " st->privateData = NULL;\n"; } diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 9025221789..2530ffaecf 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -63,7 +63,7 @@ struct _virNetClientCall { struct _virNetClient { - int refs; + virObject object; virMutex lock; @@ -109,6 +109,21 @@ struct _virNetClient { }; +static virClassPtr virNetClientClass; +static void virNetClientDispose(void *obj); + +static int virNetClientOnceInit(void) +{ + if (!(virNetClientClass = virClassNew("virNetClient", + sizeof(virNetClient), + virNetClientDispose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virNetClient) + static void virNetClientIOEventLoopPassTheBuck(virNetClientPtr client, virNetClientCallPtr thiscall); static int virNetClientQueueNonBlocking(virNetClientPtr client, @@ -237,13 +252,6 @@ static bool virNetClientCallMatchPredicate(virNetClientCallPtr head, } -static void virNetClientEventFree(void *opaque) -{ - virNetClientPtr client = opaque; - - virNetClientFree(client); -} - bool virNetClientKeepAliveIsSupported(virNetClientPtr client) { @@ -303,20 +311,23 @@ static virNetClientPtr virNetClientNew(virNetSocketPtr sock, int wakeupFD[2] = { -1, -1 }; virKeepAlivePtr ka = NULL; + if (virNetClientInitialize() < 0) + return NULL; + if (pipe2(wakeupFD, O_CLOEXEC) < 0) { virReportSystemError(errno, "%s", _("unable to make pipe")); goto error; } - if (VIR_ALLOC(client) < 0) - goto no_memory; - - client->refs = 1; - - if (virMutexInit(&client->lock) < 0) + if (!(client = virObjectNew(virNetClientClass))) goto error; + if (virMutexInit(&client->lock) < 0) { + VIR_FREE(client); + goto error; + } + client->sock = sock; client->wakeupReadFD = wakeupFD[0]; client->wakeupSendFD = wakeupFD[1]; @@ -327,13 +338,13 @@ static virNetClientPtr virNetClientNew(virNetSocketPtr sock, goto no_memory; /* Set up a callback to listen on the socket data */ - client->refs++; + virObjectRef(client); if (virNetSocketAddIOCallback(client->sock, VIR_EVENT_HANDLE_READABLE, virNetClientIncomingEvent, client, - virNetClientEventFree) < 0) { - client->refs--; + virObjectFreeCallback) < 0) { + virObjectUnref(client); VIR_DEBUG("Failed to add event watch, disabling events and support for" " keepalive messages"); } else { @@ -342,16 +353,16 @@ static virNetClientPtr virNetClientNew(virNetSocketPtr sock, if (!(ka = virKeepAliveNew(-1, 0, client, virNetClientKeepAliveSendCB, virNetClientKeepAliveDeadCB, - virNetClientEventFree))) + virObjectFreeCallback))) goto error; /* keepalive object has a reference to client */ - client->refs++; + virObjectRef(client); } client->keepalive = ka; PROBE(RPC_CLIENT_NEW, - "client=%p refs=%d sock=%p", - client, client->refs, client->sock); + "client=%p sock=%p", + client, client->sock); return client; no_memory: @@ -363,7 +374,7 @@ error: virKeepAliveStop(ka); virObjectUnref(ka); } - virNetClientFree(client); + virObjectUnref(client); return NULL; } @@ -422,17 +433,6 @@ virNetClientPtr virNetClientNewExternal(const char **cmdargv) } -void virNetClientRef(virNetClientPtr client) -{ - virNetClientLock(client); - client->refs++; - PROBE(RPC_CLIENT_REF, - "client=%p refs=%d", - client, client->refs); - virNetClientUnlock(client); -} - - int virNetClientGetFD(virNetClientPtr client) { int fd; @@ -463,28 +463,16 @@ bool virNetClientHasPassFD(virNetClientPtr client) } -void virNetClientFree(virNetClientPtr client) +void virNetClientDispose(void *obj) { + virNetClientPtr client = obj; int i; - if (!client) - return; - - virNetClientLock(client); - PROBE(RPC_CLIENT_FREE, - "client=%p refs=%d", - client, client->refs); - client->refs--; - if (client->refs > 0) { - virNetClientUnlock(client); - return; - } - if (client->closeFf) client->closeFf(client->closeOpaque); for (i = 0 ; i < client->nprograms ; i++) - virNetClientProgramFree(client->programs[i]); + virObjectUnref(client->programs[i]); VIR_FREE(client->programs); VIR_FORCE_CLOSE(client->wakeupSendFD); @@ -504,8 +492,6 @@ void virNetClientFree(virNetClientPtr client) virNetClientUnlock(client); virMutexDestroy(&client->lock); - - VIR_FREE(client); } @@ -546,7 +532,7 @@ virNetClientCloseLocked(virNetClientPtr client) virNetClientCloseFunc closeCb = client->closeCb; void *closeOpaque = client->closeOpaque; int closeReason = client->closeReason; - client->refs++; + virObjectRef(client); virNetClientUnlock(client); if (ka) { @@ -557,7 +543,7 @@ virNetClientCloseLocked(virNetClientPtr client) closeCb(client, closeReason, closeOpaque); virNetClientLock(client); - client->refs--; + virObjectUnref(client); } } @@ -754,8 +740,7 @@ int virNetClientAddProgram(virNetClientPtr client, if (VIR_EXPAND_N(client->programs, client->nprograms, 1) < 0) goto no_memory; - client->programs[client->nprograms-1] = prog; - virNetClientProgramRef(prog); + client->programs[client->nprograms-1] = virObjectRef(prog); virNetClientUnlock(client); return 0; @@ -775,8 +760,7 @@ int virNetClientAddStream(virNetClientPtr client, if (VIR_EXPAND_N(client->streams, client->nstreams, 1) < 0) goto no_memory; - client->streams[client->nstreams-1] = st; - virNetClientStreamRef(st); + client->streams[client->nstreams-1] = virObjectRef(st); virNetClientUnlock(client); return 0; @@ -810,7 +794,7 @@ void virNetClientRemoveStream(virNetClientPtr client, VIR_FREE(client->streams); client->nstreams = 0; } - virNetClientStreamFree(st); + virObjectUnref(st); cleanup: virNetClientUnlock(client); diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h index c939475ffe..d6b9b3c1d6 100644 --- a/src/rpc/virnetclient.h +++ b/src/rpc/virnetclient.h @@ -30,6 +30,7 @@ # endif # include "virnetclientprogram.h" # include "virnetclientstream.h" +# include "virobject.h" virNetClientPtr virNetClientNewUNIX(const char *path, @@ -60,8 +61,6 @@ void virNetClientSetCloseCallback(virNetClientPtr client, void *opaque, virFreeCallback ff); -void virNetClientRef(virNetClientPtr client); - int virNetClientGetFD(virNetClientPtr client); int virNetClientDupFD(virNetClientPtr client, bool cloexec); @@ -105,7 +104,6 @@ const char *virNetClientRemoteAddrString(virNetClientPtr client); int virNetClientGetTLSKeySize(virNetClientPtr client); -void virNetClientFree(virNetClientPtr client); void virNetClientClose(virNetClientPtr client); bool virNetClientKeepAliveIsSupported(virNetClientPtr client); diff --git a/src/rpc/virnetclientprogram.c b/src/rpc/virnetclientprogram.c index c7d2409718..320b7d46ac 100644 --- a/src/rpc/virnetclientprogram.c +++ b/src/rpc/virnetclientprogram.c @@ -33,11 +33,12 @@ #include "logging.h" #include "util.h" #include "virfile.h" +#include "threads.h" #define VIR_FROM_THIS VIR_FROM_RPC struct _virNetClientProgram { - int refs; + virObject object; unsigned program; unsigned version; @@ -46,6 +47,22 @@ struct _virNetClientProgram { void *eventOpaque; }; +static virClassPtr virNetClientProgramClass; +static void virNetClientProgramDispose(void *obj); + +static int virNetClientProgramOnceInit(void) +{ + if (!(virNetClientProgramClass = virClassNew("virNetClientProgram", + sizeof(virNetClientProgram), + virNetClientProgramDispose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virNetClientProgram) + + virNetClientProgramPtr virNetClientProgramNew(unsigned program, unsigned version, virNetClientProgramEventPtr events, @@ -54,12 +71,12 @@ virNetClientProgramPtr virNetClientProgramNew(unsigned program, { virNetClientProgramPtr prog; - if (VIR_ALLOC(prog) < 0) { - virReportOOMError(); + if (virNetClientProgramInitialize() < 0) + return NULL; + + if (!(prog = virObjectNew(virNetClientProgramClass))) return NULL; - } - prog->refs = 1; prog->program = program; prog->version = version; prog->events = events; @@ -70,22 +87,8 @@ virNetClientProgramPtr virNetClientProgramNew(unsigned program, } -void virNetClientProgramRef(virNetClientProgramPtr prog) +void virNetClientProgramDispose(void *obj ATTRIBUTE_UNUSED) { - prog->refs++; -} - - -void virNetClientProgramFree(virNetClientProgramPtr prog) -{ - if (!prog) - return; - - prog->refs--; - if (prog->refs > 0) - return; - - VIR_FREE(prog); } diff --git a/src/rpc/virnetclientprogram.h b/src/rpc/virnetclientprogram.h index f799f2e4aa..9e92a3c1c2 100644 --- a/src/rpc/virnetclientprogram.h +++ b/src/rpc/virnetclientprogram.h @@ -27,6 +27,7 @@ # include # include "virnetmessage.h" +# include "virobject.h" typedef struct _virNetClient virNetClient; typedef virNetClient *virNetClientPtr; @@ -62,10 +63,6 @@ virNetClientProgramPtr virNetClientProgramNew(unsigned program, unsigned virNetClientProgramGetProgram(virNetClientProgramPtr prog); unsigned virNetClientProgramGetVersion(virNetClientProgramPtr prog); -void virNetClientProgramRef(virNetClientProgramPtr prog); - -void virNetClientProgramFree(virNetClientProgramPtr prog); - int virNetClientProgramMatches(virNetClientProgramPtr prog, virNetMessagePtr msg); diff --git a/src/rpc/virnetclientstream.c b/src/rpc/virnetclientstream.c index 8580e39dab..0a2bbead7a 100644 --- a/src/rpc/virnetclientstream.c +++ b/src/rpc/virnetclientstream.c @@ -33,12 +33,13 @@ #define VIR_FROM_THIS VIR_FROM_RPC struct _virNetClientStream { + virObject object; + virMutex lock; virNetClientProgramPtr prog; int proc; unsigned serial; - int refs; virError err; @@ -63,6 +64,22 @@ struct _virNetClientStream { }; +static virClassPtr virNetClientStreamClass; +static void virNetClientStreamDispose(void *obj); + +static int virNetClientStreamOnceInit(void) +{ + if (!(virNetClientStreamClass = virClassNew("virNetClientStream", + sizeof(virNetClientStream), + virNetClientStreamDispose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virNetClientStream) + + static void virNetClientStreamEventTimerUpdate(virNetClientStreamPtr st) { @@ -119,26 +136,18 @@ virNetClientStreamEventTimer(int timer ATTRIBUTE_UNUSED, void *opaque) } -static void -virNetClientStreamEventTimerFree(void *opaque) -{ - virNetClientStreamPtr st = opaque; - virNetClientStreamFree(st); -} - - virNetClientStreamPtr virNetClientStreamNew(virNetClientProgramPtr prog, int proc, unsigned serial) { virNetClientStreamPtr st; - if (VIR_ALLOC(st) < 0) { - virReportOOMError(); + if (virNetClientStreamInitialize() < 0) + return NULL; + + if (!(st = virObjectNew(virNetClientStreamClass))) return NULL; - } - st->refs = 1; st->prog = prog; st->proc = proc; st->serial = serial; @@ -150,35 +159,19 @@ virNetClientStreamPtr virNetClientStreamNew(virNetClientProgramPtr prog, return NULL; } - virNetClientProgramRef(prog); + virObjectRef(prog); return st; } - -void virNetClientStreamRef(virNetClientStreamPtr st) +void virNetClientStreamDispose(void *obj) { - virMutexLock(&st->lock); - st->refs++; - virMutexUnlock(&st->lock); -} - -void virNetClientStreamFree(virNetClientStreamPtr st) -{ - virMutexLock(&st->lock); - st->refs--; - if (st->refs > 0) { - virMutexUnlock(&st->lock); - return; - } - - virMutexUnlock(&st->lock); + virNetClientStreamPtr st = obj; virResetError(&st->err); VIR_FREE(st->incoming); virMutexDestroy(&st->lock); - virNetClientProgramFree(st->prog); - VIR_FREE(st); + virObjectUnref(st->prog); } bool virNetClientStreamMatches(virNetClientStreamPtr st, @@ -454,13 +447,13 @@ int virNetClientStreamEventAddCallback(virNetClientStreamPtr st, goto cleanup; } - st->refs++; + virObjectRef(st); if ((st->cbTimer = virEventAddTimeout(-1, virNetClientStreamEventTimer, st, - virNetClientStreamEventTimerFree)) < 0) { - st->refs--; + virObjectFreeCallback)) < 0) { + virObjectUnref(st); goto cleanup; } diff --git a/src/rpc/virnetclientstream.h b/src/rpc/virnetclientstream.h index 00d598ab64..68a9e999f5 100644 --- a/src/rpc/virnetclientstream.h +++ b/src/rpc/virnetclientstream.h @@ -24,6 +24,7 @@ # define __VIR_NET_CLIENT_STREAM_H__ # include "virnetclientprogram.h" +# include "virobject.h" typedef struct _virNetClientStream virNetClientStream; typedef virNetClientStream *virNetClientStreamPtr; @@ -35,10 +36,6 @@ virNetClientStreamPtr virNetClientStreamNew(virNetClientProgramPtr prog, int proc, unsigned serial); -void virNetClientStreamRef(virNetClientStreamPtr st); - -void virNetClientStreamFree(virNetClientStreamPtr st); - bool virNetClientStreamRaiseError(virNetClientStreamPtr st); int virNetClientStreamSetError(virNetClientStreamPtr st,