static void li_memcached_con_free(liMemcachedCon* con) { if (!con) return; if (-1 != con->con_watcher.fd) { close(con->con_watcher.fd); /* as io has a reference on con, we don't need to stop it here */ ev_io_set(&con->con_watcher, -1, 0); con->fd = -1; } send_queue_reset(&con->out); cancel_all_requests(con); li_buffer_release(con->buf); li_buffer_release(con->line); li_buffer_release(con->remaining); li_buffer_release(con->data); reset_item(&con->curitem); li_sockaddr_clear(&con->addr); g_string_free(con->tmpstr, TRUE); g_clear_error(&con->err); g_slice_free(liMemcachedCon, con); }
static void li_memcached_con_free(liMemcachedCon* con) { if (!con) return; if (-1 != li_event_io_fd(&con->con_watcher)) { close(li_event_io_fd(&con->con_watcher)); li_event_clear(&con->con_watcher); con->fd = -1; } send_queue_reset(&con->out); cancel_all_requests(con); li_buffer_release(con->buf); li_buffer_release(con->line); li_buffer_release(con->remaining); li_buffer_release(con->data); reset_item(&con->curitem); li_sockaddr_clear(&con->addr); g_string_free(con->tmpstr, TRUE); g_clear_error(&con->err); g_slice_free(liMemcachedCon, con); }
void pop_tick(void) { static int last_reset = 0; int nr; if (globs->ticker - last_reset>=RESETTICKER) // reset one character per minute { nr = (globs->ticker / RESETTICKER) % MAXTCHARS; if (nr>0 && nr<MAXTCHARS) // yes, we're paranoid :) { reset_char(nr); } last_reset = globs->ticker; } if (globs->reset_char) { reset_char(globs->reset_char); globs->reset_char = 0; } if (globs->reset_item) { reset_item(globs->reset_item); globs->reset_item = 0; } }
void reset_changed_items(void) { static int changelist[] = {}; int n; for (n = 0; n<sizeof(changelist) / sizeof(int); n++) { reset_item(changelist[n]); } }
static void close_con(liMemcachedCon *con) { if (con->line) con->line->used = 0; if (con->remaining) con->remaining->used = 0; if (con->data) con->data->used = 0; if (con->buf) con->buf->used = 0; reset_item(&con->curitem); send_queue_reset(&con->out); memcached_stop_io(con); close(li_event_io_fd(&con->con_watcher)); con->fd = -1; li_event_io_set_fd(&con->con_watcher, -1); con->cur_req = NULL; cancel_all_requests(con); memcached_connect(con); }
void pop_reset_all(void) { int n; for (n = 1; n<MAXTCHARS; n++) { if (ch_temp[n].used!=USE_EMPTY) { reset_char(n); } } for (n = 1; n<MAXTITEM; n++) { if (it_temp[n].used!=USE_EMPTY && it_temp[n].driver!=36 && it_temp[n].driver!=38) { reset_item(n); } } }
static void handle_read(liMemcachedCon *con) { int_request *cur; if (NULL == (cur = con->cur_req)) { cur = con->cur_req = g_queue_peek_head(&con->req_queue); if (NULL == cur) { /* unexpected read event, perhaps just eof */ g_clear_error(&con->err); g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Connection closed: unexpected read event"); close_con(con); return; } reset_item(&con->curitem); if (con->data) con->data->used = 0; if (con->line) con->line->used = 0; /* init read state */ switch (cur->type) { case REQ_GET: con->get_data_size = 0; con->get_have_header = FALSE; break; case REQ_SET: break; } } switch (cur->type) { case REQ_GET: if (!con->get_have_header) { char *pos, *next; /* wait for header line */ if (!try_read_line(con)) return; con->get_have_header = TRUE; if (3 == con->line->used && 0 == memcmp("END", con->line->addr, 3)) { /* key not found */ if (cur->req.callback) { cur->req.callback(&cur->req, LI_MEMCACHED_NOT_FOUND, NULL, NULL); } con->cur_req = NULL; free_request(con, cur); return; } /* con->line is 0 terminated */ if (0 != strncmp("VALUE ", con->line->addr, 6)) { g_clear_error(&con->err); g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: Unexpected response for GET: '%s'", con->line->addr); close_con(con); return; } /* VALUE <key> <flags> <bytes> [<cas unique>]\r\n */ /* <key> */ pos = con->line->addr + 6; next = strchr(pos, ' '); if (NULL == next) goto req_get_header_error; con->curitem.key = g_string_new_len(pos, next - pos); /* <flags> */ pos = next + 1; con->curitem.flags = strtoul(pos, &next, 10); if (' ' != *next || pos == next) goto req_get_header_error; /* <bytes> */ pos = next + 1; con->get_data_size = g_ascii_strtoll(pos, &next, 10); if (pos == next) goto req_get_header_error; /* [<cas unique>] */ if (' ' == *next) { pos = next + 1; con->curitem.cas = g_ascii_strtoll(pos, &next, 10); if (pos == next) goto req_get_header_error; } if ('\0' != *next) { goto req_get_header_error; } con->line->used = 0; goto req_get_header_done; req_get_header_error: g_clear_error(&con->err); g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: Couldn't parse VALUE respone: '%s'", con->line->addr); close_con(con); return; req_get_header_done: ; } if (NULL == con->data || con->data->used < con->get_data_size) { /* wait for data */ if (!try_read_data(con, con->get_data_size)) return; } /* wait for END\r\n */ if (!try_read_line(con)) return; if (3 == con->line->used && 0 == memcmp("END", con->line->addr, 3)) { /* Move data to item */ con->curitem.data = con->data; con->data = NULL; if (cur->req.callback) { cur->req.callback(&cur->req, LI_MEMCACHED_OK, &con->curitem, NULL); } reset_item(&con->curitem); } else { g_clear_error(&con->err); g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: GET response not terminated with END (got '%s')", con->line->addr); close_con(con); return; } con->cur_req = NULL; free_request(con, cur); return; case REQ_SET: if (!try_read_line(con)) return; if (6 == con->line->used && 0 == memcmp("STORED", con->line->addr, 6)) { if (cur->req.callback) { cur->req.callback(&cur->req, LI_MEMCACHED_OK, NULL, NULL); } } else { g_clear_error(&con->err); g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: unepxected SET response: '%s'", con->line->addr); close_con(con); return; } con->cur_req = NULL; free_request(con, cur); return; } }