int events,
void *opaque);
+static void virNetClientEventFree(void *opaque)
+{
+ virNetClientPtr client = opaque;
+
+ virNetClientFree(client);
+}
+
static virNetClientPtr virNetClientNew(virNetSocketPtr sock,
const char *hostname)
{
goto no_memory;
/* Set up a callback to listen on the socket data */
+ client->refs++;
if (virNetSocketAddIOCallback(client->sock,
VIR_EVENT_HANDLE_READABLE,
virNetClientIncomingEvent,
- client) < 0)
+ client,
+ virNetClientEventFree) < 0) {
+ client->refs--;
VIR_DEBUG("Failed to add event watch, disabling events");
+ }
VIR_DEBUG("client=%p refs=%d", client, client->refs);
return client;
return mode;
}
+static void virNetServerClientEventFree(void *opaque)
+{
+ virNetServerClientPtr client = opaque;
+
+ virNetServerClientFree(client);
+}
+
/*
* @server: a locked or unlocked server object
* @client: a locked client object
{
int mode = virNetServerClientCalculateHandleMode(client);
+ client->refs++;
VIR_DEBUG("Registering client event callback %d", mode);
if (virNetSocketAddIOCallback(client->sock,
mode,
virNetServerClientDispatchEvent,
- client) < 0)
+ client,
+ virNetServerClientEventFree) < 0) {
+ client->refs--;
return -1;
+ }
return 0;
}
}
+static void virNetServerServiceEventFree(void *opaque)
+{
+ virNetServerServicePtr svc = opaque;
+
+ virNetServerServiceFree(svc);
+}
+
+
virNetServerServicePtr virNetServerServiceNewTCP(const char *nodename,
const char *service,
int auth,
/* IO callback is initially disabled, until we're ready
* to deal with incoming clients */
+ virNetServerServiceRef(svc);
if (virNetSocketAddIOCallback(svc->socks[i],
0,
virNetServerServiceAccept,
- svc) < 0)
+ svc,
+ virNetServerServiceEventFree) < 0) {
+ virNetServerServiceFree(svc);
goto error;
+ }
}
/* IO callback is initially disabled, until we're ready
* to deal with incoming clients */
+ virNetServerServiceRef(svc);
if (virNetSocketAddIOCallback(svc->socks[i],
0,
virNetServerServiceAccept,
- svc) < 0)
+ svc,
+ virNetServerServiceEventFree) < 0) {
+ virNetServerServiceFree(svc);
goto error;
+ }
}
pid_t pid;
int errfd;
bool client;
+
+ /* Event callback fields */
virNetSocketIOFunc func;
void *opaque;
+ virFreeCallback ff;
+
virSocketAddr localAddr;
virSocketAddr remoteAddr;
char *localAddrStr;
}
+static void virNetSocketEventFree(void *opaque)
+{
+ virNetSocketPtr sock = opaque;
+ virFreeCallback ff;
+ void *eopaque;
+
+ virMutexLock(&sock->lock);
+ ff = sock->ff;
+ eopaque = sock->opaque;
+ sock->func = NULL;
+ sock->ff = NULL;
+ sock->opaque = NULL;
+ virMutexUnlock(&sock->lock);
+
+ if (ff)
+ ff(eopaque);
+
+ virNetSocketFree(sock);
+}
+
int virNetSocketAddIOCallback(virNetSocketPtr sock,
int events,
virNetSocketIOFunc func,
- void *opaque)
+ void *opaque,
+ virFreeCallback ff)
{
int ret = -1;
goto cleanup;
}
+ sock->refs++;
if ((sock->watch = virEventAddHandle(sock->fd,
events,
virNetSocketEventHandle,
sock,
- NULL)) < 0) {
+ virNetSocketEventFree)) < 0) {
VIR_DEBUG("Failed to register watch on socket %p", sock);
+ sock->refs--;
goto cleanup;
}
sock->func = func;
sock->opaque = opaque;
+ sock->ff = ff;
ret = 0;
int virNetSocketAddIOCallback(virNetSocketPtr sock,
int events,
virNetSocketIOFunc func,
- void *opaque);
+ void *opaque,
+ virFreeCallback ff);
void virNetSocketUpdateIOCallback(virNetSocketPtr sock,
int events);