Example #1
0
static gboolean push_request(liMemcachedCon *con, int_request *req, GError **err) {
	UNUSED(err);

	li_memcached_con_acquire(con);

	send_request(con, req);

	req->iter.data = req;
	g_queue_push_tail_link(&con->req_queue, &req->iter);

	memcached_start_io(con);
	li_event_io_set_events(&con->con_watcher, LI_EV_READ | LI_EV_WRITE);

	return TRUE;
}
Example #2
0
static void memcached_io_cb(liEventBase *watcher, int events) {
	liMemcachedCon *con = LI_CONTAINER_OF(li_event_io_from(watcher), liMemcachedCon, con_watcher);

	if (1 == g_atomic_int_get(&con->refcount) && li_event_active(&con->con_watcher)) {
		memcached_stop_io(con);
		return;
	}

	if (-1 == con->fd) {
		memcached_connect(con);
		return;
	}

	li_memcached_con_acquire(con); /* make sure con isn't freed in the middle of something */

	if (events & LI_EV_WRITE) {
		int i;
		ssize_t written, len;
		gchar *data;
		send_item *si;

		si = g_queue_peek_head(&con->out);

		for (i = 0; si && (i < 10); i++) { /* don't send more than 10 chunks */
			data = si->buf->addr + si->pos;
			len = si->len;
			written = write(li_event_io_fd(&con->con_watcher), data, len);
			if (written < 0) {
				switch (errno) {
				case EINTR:
					continue;
				case EAGAIN:
#if EWOULDBLOCK != EAGAIN
				case EWOULDBLOCK:
#endif
					goto write_eagain;
				default: /* Fatal error, connection has to be closed */
					g_clear_error(&con->err);
					g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Couldn't write socket '%s': %s",
						li_sockaddr_to_string(con->addr, con->tmpstr, TRUE)->str,
						g_strerror(errno));
					close_con(con);
					goto out;
				}
			} else {
				si->pos += written;
				si->len -= written;
				if (0 == si->len) {
					send_queue_item_free(si);
					g_queue_pop_head(&con->out);
					si = g_queue_peek_head(&con->out);
				}
			}
		}

write_eagain:
		send_queue_clean(&con->out);
	}

	if (events & LI_EV_READ) {
		do {
			handle_read(con);
		} while (con->remaining && con->remaining->used > 0);
	}

out:
	memcached_update_io(con);
	li_memcached_con_release(con);
}
Example #3
0
static void memcached_start_io(liMemcachedCon *con) {
	if (!li_event_active(&con->con_watcher)) {
		li_memcached_con_acquire(con);
		li_event_start(&con->con_watcher);
	}
}
Example #4
0
static void memcached_start_io(liMemcachedCon *con) {
	if (!((ev_watcher*) &con->con_watcher)->active) {
		li_memcached_con_acquire(con);
		li_ev_safe_unref_and_start(ev_io_start, con->loop, &con->con_watcher);
	}
}