#include "xmalloc.h"
struct pa_socket_client {
+ int ref;
struct pa_mainloop_api *mainloop;
int fd;
struct pa_io_event *io_event;
assert(m);
c = pa_xmalloc(sizeof(struct pa_socket_client));
+ c->ref = 1;
c->mainloop = m;
c->fd = -1;
c->io_event = NULL;
}
static void do_call(struct pa_socket_client *c) {
- struct pa_iochannel *io;
+ struct pa_iochannel *io = NULL;
int error, lerror;
assert(c && c->callback);
+ pa_socket_client_ref(c);
+
lerror = sizeof(error);
if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &error, &lerror) < 0) {
fprintf(stderr, "getsockopt(): %s\n", strerror(errno));
- goto failed;
+ goto finish;
}
if (lerror != sizeof(error)) {
fprintf(stderr, "getsocktop() returned invalid size.\n");
- goto failed;
+ goto finish;
}
if (error != 0) {
fprintf(stderr, "connect(): %s\n", strerror(error));
- goto failed;
+ goto finish;
}
io = pa_iochannel_new(c->mainloop, c->fd, c->fd);
assert(io);
+
+finish:
+ if (!io)
+ close(c->fd);
c->fd = -1;
+
+ assert(c->callback);
c->callback(c, io, c->userdata);
-
- return;
-failed:
- close(c->fd);
- c->fd = -1;
- c->callback(c, NULL, c->userdata);
- return;
+ pa_socket_client_unref(c);
}
static void connect_fixed_cb(struct pa_mainloop_api *m, struct pa_defer_event *e, void *userdata) {
return c;
fail:
- pa_socket_client_free(c);
+ pa_socket_client_unref(c);
return NULL;
}
return c;
fail:
- pa_socket_client_free(c);
+ pa_socket_client_unref(c);
return NULL;
}
return c;
fail:
- pa_socket_client_free(c);
+ pa_socket_client_unref(c);
return NULL;
}
-void pa_socket_client_free(struct pa_socket_client *c) {
+void socket_client_free(struct pa_socket_client *c) {
assert(c && c->mainloop);
if (c->io_event)
c->mainloop->io_free(c->io_event);
pa_xfree(c);
}
+void pa_socket_client_unref(struct pa_socket_client *c) {
+ assert(c && c->ref >= 1);
+
+ if (!(--(c->ref)))
+ socket_client_free(c);
+}
+
+struct pa_socket_client* pa_socket_client_ref(struct pa_socket_client *c) {
+ assert(c && c->ref >= 1);
+ c->ref++;
+ return c;
+}
+
void pa_socket_client_set_callback(struct pa_socket_client *c, void (*on_connection)(struct pa_socket_client *c, struct pa_iochannel*io, void *userdata), void *userdata) {
assert(c);
c->callback = on_connection;