Esempio n. 1
0
/* not every context has srv ready, extract from context instead */
static void mc_ctx_release(liServer *_srv, gpointer param) {
	memcached_ctx *ctx = param;
	liServer *srv;
	guint i;
	UNUSED(_srv);

	if (NULL == ctx) return;
	srv = ctx->srv;

	assert(g_atomic_int_get(&ctx->refcount) > 0);
	if (!g_atomic_int_dec_and_test(&ctx->refcount)) return;

	if (ctx->worker_client_ctx) {
		for (i = 0; i < srv->worker_count; i++) {
			li_memcached_con_release(ctx->worker_client_ctx[i]);
		}
		g_slice_free1(sizeof(liMemcachedCon*) * srv->worker_count, ctx->worker_client_ctx);
	}

	li_sockaddr_clear(&ctx->addr);

	li_pattern_free(ctx->pattern);

	li_action_release(srv, ctx->act_found);
	li_action_release(srv, ctx->act_miss);

	if (ctx->mconf_link.data) { /* still in LI_SERVER_INIT */
		memcached_config *mconf = ctx->p->data;
		g_queue_unlink(&mconf->prepare_ctx, &ctx->mconf_link);
		ctx->mconf_link.data = NULL;
	}

	ctx->srv = NULL;
	g_slice_free(memcached_ctx, ctx);
}
Esempio n. 2
0
static void free_request(liMemcachedCon *con, int_request *req) {
	if (!req) return;

	li_memcached_con_release(con);

	if (NULL != req->iter.data) {
		req->iter.data = NULL;
		g_queue_unlink(&con->req_queue, &req->iter);
	}

	switch (req->type) {
	case REQ_GET:
		break;
	case REQ_SET:
		li_buffer_release(req->data);
		req->data = NULL;
		break;
	}

	g_string_free(req->key, TRUE);
	req->key = NULL;

	g_slice_free(int_request, req);
}
Esempio n. 3
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);
}
Esempio n. 4
0
static void memcached_stop_io(liMemcachedCon *con) {
	if (li_event_active(&con->con_watcher)) {
		li_event_stop(&con->con_watcher);
		li_memcached_con_release(con);
	}
}
Esempio n. 5
0
static void memcached_stop_io(liMemcachedCon *con) {
	if (((ev_watcher*) &con->con_watcher)->active) {
		li_ev_safe_ref_and_stop(ev_io_stop, con->loop, &con->con_watcher);
		li_memcached_con_release(con);
	}
}