Пример #1
0
int poller_update_item(struct poller *p, struct poller_item *i) {
	struct poller_item_int *np;

	if (!p || !i)
		return -1;
	if (i->fd < 0)
		return -1;
	if (!i->readable && !i->writeable)
		return -1;
	if (!i->closed)
		return -1;

	mutex_lock(&p->lock);

	if (i->fd >= p->items_size || !(np = p->items[i->fd]))
		return __poller_add_item(p, i, 1);

	obj_hold_o(i->obj);
	obj_put_o(np->item.obj);
	np->item.obj = i->obj;
	np->item.uintp = i->uintp;
	np->item.readable = i->readable;
	np->item.writeable = i->writeable;
	np->item.closed = i->closed;
	/* updating timer is not supported */

	mutex_unlock(&p->lock);

	return 0;
}
Пример #2
0
int udp_listener_init(struct udp_listener *u, struct poller *p, const endpoint_t *ep,
		udp_listener_callback_t func, struct obj *obj)
{
	struct poller_item i;
	struct udp_listener_callback *cb;

	cb = obj_alloc("udp_listener_callback", sizeof(*cb), NULL);
	cb->func = func;
	cb->p = obj_get_o(obj);
	cb->ul = u;

	if (open_socket(&u->sock, SOCK_DGRAM, ep->port, &ep->address))
		goto fail;

	ipv6only(u->sock.fd, 1);

	ZERO(i);
	i.fd = u->sock.fd;
	i.closed = udp_listener_closed;
	i.readable = udp_listener_incoming;
	i.obj = &cb->obj;
	if (poller_add_item(p, &i))
		goto fail;

	return 0;

fail:
	close_socket(&u->sock);
	obj_put_o(obj);
	obj_put(cb);
	return -1;
}
Пример #3
0
/* timers_lock and timers_add_del_lock must be held */
static void poller_timers_mod(struct poller *p) {
	GSList *l, **ll, **kk;
	struct timer_item *ti, *tj;

	ll = &p->timers_add;
	while (*ll) {
		l = *ll;
		*ll = l->next;
		l->next = p->timers;
		p->timers = l;
	}

	ll = &p->timers_del;
	while (*ll) {
		ti = (*ll)->data;
		kk = &p->timers;
		while (*kk) {
			tj = (*kk)->data;
			if (tj->func != ti->func)
				goto next;
			if (tj->obj_ptr != ti->obj_ptr)
				goto next;
			goto found;
next:
			kk = &(*kk)->next;
		}
		/* deleted a timer that wasn't added yet. possible race, otherwise bug */
		ll = &(*ll)->next;
		continue;
found:
		l = *ll;
		*ll = (*ll)->next;
		obj_put_o(l->data);
		g_slist_free_1(l);

		l = *kk;
		*kk = (*kk)->next;
		obj_put_o(l->data);
		g_slist_free_1(l);
	}
}
Пример #4
0
int udp_listener_init(struct udp_listener *u, struct poller *p, struct in6_addr ip, u_int16_t port, udp_listener_callback_t func, struct obj *obj) {
	struct sockaddr_in6 sin;
	struct poller_item i;
	struct udp_listener_callback *cb;

	cb = obj_alloc("udp_listener_callback", sizeof(*cb), NULL);
	cb->func = func;
	cb->p = obj_get_o(obj);

	u->fd = socket(AF_INET6, SOCK_DGRAM, 0);
	if (u->fd == -1)
		goto fail;

	nonblock(u->fd);
	reuseaddr(u->fd);
	ipv6only(u->fd, 0);

	ZERO(sin);
	sin.sin6_family = AF_INET6;
	sin.sin6_addr = ip;
	sin.sin6_port = htons(port);
	if (bind(u->fd, (struct sockaddr *) &sin, sizeof(sin)))
		goto fail;

	ZERO(i);
	i.fd = u->fd;
	i.closed = udp_listener_closed;
	i.readable = udp_listener_incoming;
	i.obj = &cb->obj;
	if (poller_add_item(p, &i))
		goto fail;

	return 0;

fail:
	if (u->fd != -1)
		close(u->fd);
	obj_put_o(obj);
	obj_put(cb);
	return -1;
}
Пример #5
0
static void poller_item_free(void *p) {
	struct poller_item_int *i = p;
	obj_put_o(i->item.obj);
}
Пример #6
0
static void timer_item_free(void *p) {
	struct timer_item *i = p;
	if (i->obj_ptr)
		obj_put_o(i->obj_ptr);
}