time_t last_failed_connect;
char *last_connect_error;
- struct ioloop *ioloop, *prev_ioloop;
struct io_wait_timer *wait_timer;
uint64_t last_timer_switch_usecs;
struct timeout *to_requests;
return FALSE;
}
-static void dict_client_stop_wait(struct client_dict *dict)
-{
- if (dict->prev_ioloop != NULL) {
- current_ioloop = dict->ioloop;
- /* stop client_dict_wait() */
- io_loop_stop(dict->ioloop);
- }
-}
-
-static void dict_pre_api_callback(struct client_dict *dict)
-{
- if (dict->prev_ioloop != NULL) {
- /* Don't let callback see that we've created our
- internal ioloop in case it wants to add some ios
- or timeouts. */
- current_ioloop = dict->prev_ioloop;
- }
-}
-
-static void dict_post_api_callback(struct client_dict *dict)
-{
- dict_client_stop_wait(dict);
-}
-
static bool
dict_cmd_callback_line(struct client_dict_cmd *cmd, const char *const *args)
{
connection_init_client_unix(dict_connections, &dict->conn.conn, path);
dict->uri = i_strdup(dest_uri + 1);
- dict->ioloop = io_loop_create();
+ dict->dict.ioloop = io_loop_create();
dict->wait_timer = io_wait_timer_add();
io_loop_set_current(old_ioloop);
*dict_r = &dict->dict;
i_assert(dict->transactions == NULL);
i_assert(array_count(&dict->cmds) == 0);
- io_loop_set_current(dict->ioloop);
- io_loop_destroy(&dict->ioloop);
+ io_loop_set_current(dict->dict.ioloop);
+ io_loop_destroy(&dict->dict.ioloop);
io_loop_set_current(old_ioloop);
array_free(&dict->cmds);
if (array_count(&dict->cmds) == 0)
return;
- dict->prev_ioloop = current_ioloop;
- io_loop_set_current(dict->ioloop);
+ dict->dict.prev_ioloop = current_ioloop;
+ io_loop_set_current(dict->dict.ioloop);
dict_switch_ioloop(_dict);
while (array_count(&dict->cmds) > 0)
- io_loop_run(dict->ioloop);
+ io_loop_run(dict->dict.ioloop);
- io_loop_set_current(dict->prev_ioloop);
- dict->prev_ioloop = NULL;
+ io_loop_set_current(dict->dict.prev_ioloop);
+ dict->dict.prev_ioloop = NULL;
dict_switch_ioloop(_dict);
}
cmd->query);
}
- dict_pre_api_callback(dict);
+ dict_pre_api_callback(&dict->dict);
cmd->api_callback.lookup(&result, cmd->api_callback.context);
- dict_post_api_callback(dict);
+ dict_post_api_callback(&dict->dict);
}
static void
if (ctx->deinit) {
/* Iterator was already deinitialized. Stop if we're in
client_dict_wait(). */
- dict_client_stop_wait(dict);
+ dict_post_api_callback(&dict->dict);
return;
}
if (ctx->finished) {
}
}
if (ctx->ctx.async_callback != NULL) {
- dict_pre_api_callback(dict);
+ dict_pre_api_callback(&dict->dict);
ctx->ctx.async_callback(ctx->ctx.async_context);
- dict_post_api_callback(dict);
+ dict_post_api_callback(&dict->dict);
} else {
/* synchronous lookup */
- io_loop_stop(dict->ioloop);
+ io_loop_stop(dict->dict.ioloop);
}
}
}
client_dict_transaction_free(&cmd->trans);
- dict_pre_api_callback(dict);
+ dict_pre_api_callback(&dict->dict);
cmd->api_callback.commit(&result, cmd->api_callback.context);
- dict_post_api_callback(dict);
+ dict_post_api_callback(&dict->dict);
}
in_port_t port;
unsigned int timeout_msecs;
- struct ioloop *ioloop, *prev_ioloop;
struct timeout *to;
struct memcached_ascii_connection conn;
const struct dict_commit_result *result)
{
if (reply->callback != NULL) {
- if (dict->prev_ioloop != NULL) {
+ if (dict->dict.prev_ioloop != NULL) {
/* Don't let callback see that we've created our
internal ioloop in case it wants to add some ios
or timeouts. */
- current_ioloop = dict->prev_ioloop;
+ current_ioloop = dict->dict.prev_ioloop;
}
reply->callback(result, reply->context);
- if (dict->prev_ioloop != NULL)
- current_ioloop = dict->ioloop;
+ if (dict->dict.prev_ioloop != NULL)
+ current_ioloop = dict->dict.ioloop;
}
}
const struct memcached_ascii_dict_reply *reply;
connection_disconnect(&conn->conn);
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
array_foreach(&conn->dict->replies, reply)
memcached_ascii_callback(conn->dict, reply, &result);
while ((ret = memcached_ascii_input_reply(conn->dict, &error)) > 0) ;
if (ret < 0)
memcached_ascii_disconnected(conn, error);
- io_loop_stop(conn->dict->ioloop);
+ io_loop_stop(conn->dict->dict.ioloop);
}
static int memcached_ascii_input_wait(struct memcached_ascii_dict *dict,
const char **error_r)
{
- dict->prev_ioloop = current_ioloop;
- io_loop_set_current(dict->ioloop);
+ dict->dict.prev_ioloop = current_ioloop;
+ io_loop_set_current(dict->dict.ioloop);
if (dict->to != NULL)
dict->to = io_loop_move_timeout(&dict->to);
connection_switch_ioloop(&dict->conn.conn);
- io_loop_run(dict->ioloop);
+ io_loop_run(dict->dict.ioloop);
- io_loop_set_current(dict->prev_ioloop);
- dict->prev_ioloop = NULL;
+ io_loop_set_current(dict->dict.prev_ioloop);
+ dict->dict.prev_ioloop = NULL;
if (dict->to != NULL)
dict->to = io_loop_move_timeout(&dict->to);
i_error("memcached_ascii: connect(%s, %u) failed: %m",
net_ip2addr(&conn->dict->ip), conn->dict->port);
}
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
}
static const struct connection_settings memcached_ascii_conn_set = {
i_array_init(&dict->input_states, 4);
i_array_init(&dict->replies, 4);
- dict->ioloop = io_loop_create();
+ dict->dict.ioloop = io_loop_create();
io_loop_set_current(old_ioloop);
*dict_r = &dict->dict;
return 0;
}
connection_deinit(&dict->conn.conn);
- io_loop_set_current(dict->ioloop);
- io_loop_destroy(&dict->ioloop);
+ io_loop_set_current(dict->dict.ioloop);
+ io_loop_destroy(&dict->dict.ioloop);
io_loop_set_current(old_ioloop);
str_free(&dict->conn.reply_str);
in_port_t port;
unsigned int timeout_msecs;
- struct ioloop *ioloop;
struct memcached_connection conn;
bool connected;
conn->dict->connected = FALSE;
connection_disconnect(_conn);
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
}
static int memcached_input_get(struct memcached_connection *conn)
i_stream_skip(conn->conn.input, body_len);
conn->reply.reply_received = TRUE;
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
return 1;
}
} else {
conn->dict->connected = TRUE;
}
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
}
static const struct connection_settings memcached_conn_set = {
{
i_error("memcached: Lookup timed out in %u.%03u secs",
dict->timeout_msecs/1000, dict->timeout_msecs%1000);
- io_loop_stop(dict->ioloop);
+ io_loop_stop(dict->dict.ioloop);
}
static void memcached_add_header(buffer_t *buf, unsigned int key_len)
return -1;
}
- i_assert(dict->ioloop == NULL);
+ i_assert(dict->dict.ioloop == NULL);
- dict->ioloop = io_loop_create();
+ dict->dict.ioloop = io_loop_create();
connection_switch_ioloop(&dict->conn.conn);
if (dict->conn.conn.fd_in == -1 &&
memcached_dict_lookup_timeout, dict);
if (!dict->connected) {
/* wait for connection */
- io_loop_run(dict->ioloop);
+ io_loop_run(dict->dict.ioloop);
}
if (dict->connected) {
dict->conn.cmd->used);
i_zero(&dict->conn.reply);
- io_loop_run(dict->ioloop);
+ io_loop_run(dict->dict.ioloop);
}
timeout_remove(&to);
}
io_loop_set_current(prev_ioloop);
connection_switch_ioloop(&dict->conn.conn);
- io_loop_set_current(dict->ioloop);
- io_loop_destroy(&dict->ioloop);
+ io_loop_set_current(dict->dict.ioloop);
+ io_loop_destroy(&dict->dict.ioloop);
if (!dict->conn.reply.reply_received) {
/* we failed in some way. make sure we disconnect since the
#include <time.h>
#include "dict.h"
+struct ioloop;
+
struct dict_vfuncs {
int (*init)(struct dict *dict_driver, const char *uri,
const struct dict_settings *set,
unsigned int iter_count;
unsigned int transaction_count;
struct dict_transaction_context *transactions;
+ struct ioloop *ioloop, *prev_ioloop;
};
struct dict_iterate_context {
extern struct dict_iterate_context dict_iter_unsupported;
extern struct dict_transaction_context dict_transaction_unsupported;
+void dict_pre_api_callback(struct dict *dict);
+void dict_post_api_callback(struct dict *dict);
+
#endif
char *username, *password, *key_prefix, *expire_value;
unsigned int timeout_msecs, db_id;
- struct ioloop *ioloop, *prev_ioloop;
struct redis_connection conn;
ARRAY(enum redis_input_state) input_states;
const struct dict_commit_result *result)
{
if (reply->callback != NULL) {
- if (dict->prev_ioloop != NULL) {
- /* Don't let callback see that we've created our
- internal ioloop in case it wants to add some ios
- or timeouts. */
- current_ioloop = dict->prev_ioloop;
- }
+ dict_pre_api_callback(&dict->dict);
reply->callback(result, reply->context);
- if (dict->prev_ioloop != NULL)
- current_ioloop = dict->ioloop;
+ dict_post_api_callback(&dict->dict);
}
}
array_clear(&conn->dict->replies);
array_clear(&conn->dict->input_states);
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
}
static void redis_conn_destroy(struct connection *_conn)
{
struct timeout *to;
- i_assert(dict->ioloop == NULL);
+ i_assert(dict->dict.ioloop == NULL);
- dict->prev_ioloop = current_ioloop;
- dict->ioloop = io_loop_create();
+ dict->dict.prev_ioloop = current_ioloop;
+ dict->dict.ioloop = io_loop_create();
to = timeout_add(dict->timeout_msecs, redis_dict_wait_timeout, dict);
connection_switch_ioloop(&dict->conn.conn);
do {
- io_loop_run(dict->ioloop);
+ io_loop_run(dict->dict.ioloop);
} while (array_count(&dict->input_states) > 0);
timeout_remove(&to);
- io_loop_set_current(dict->prev_ioloop);
+ io_loop_set_current(dict->dict.prev_ioloop);
connection_switch_ioloop(&dict->conn.conn);
- io_loop_set_current(dict->ioloop);
- io_loop_destroy(&dict->ioloop);
- dict->prev_ioloop = NULL;
+ io_loop_set_current(dict->dict.ioloop);
+ io_loop_destroy(&dict->dict.ioloop);
+ dict->dict.prev_ioloop = NULL;
}
static int redis_input_get(struct redis_connection *conn, const char **error_r)
if (strcmp(line, "$-1") == 0) {
conn->value_received = TRUE;
conn->value_not_found = TRUE;
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
redis_input_state_remove(conn->dict);
return 1;
}
conn->value_received = TRUE;
str_truncate(conn->last_reply, str_len(conn->last_reply)-2);
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
redis_input_state_remove(conn->dict);
return 1;
}
/* if we're running in a dict-ioloop, we're handling a
synchronous commit and need to stop now */
if (array_count(&dict->replies) == 0 &&
- conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
}
return 1;
}
} else {
conn->dict->connected = TRUE;
}
- if (conn->dict->ioloop != NULL)
- io_loop_stop(conn->dict->ioloop);
+ if (conn->dict->dict.ioloop != NULL)
+ io_loop_stop(conn->dict->dict.ioloop);
}
static const struct connection_settings redis_conn_set = {
dict->conn.value_received = FALSE;
dict->conn.value_not_found = FALSE;
- i_assert(dict->ioloop == NULL);
+ i_assert(dict->dict.ioloop == NULL);
- dict->prev_ioloop = current_ioloop;
- dict->ioloop = io_loop_create();
+ dict->dict.prev_ioloop = current_ioloop;
+ dict->dict.ioloop = io_loop_create();
connection_switch_ioloop(&dict->conn.conn);
if (dict->conn.conn.fd_in == -1 &&
redis_dict_lookup_timeout, dict);
if (!dict->connected) {
/* wait for connection */
- io_loop_run(dict->ioloop);
+ io_loop_run(dict->dict.ioloop);
if (dict->connected)
redis_dict_auth(dict);
}
str_truncate(dict->conn.last_reply, 0);
redis_input_state_add(dict, REDIS_INPUT_STATE_GET);
do {
- io_loop_run(dict->ioloop);
+ io_loop_run(dict->dict.ioloop);
} while (array_count(&dict->input_states) > 0);
}
timeout_remove(&to);
}
- io_loop_set_current(dict->prev_ioloop);
+ io_loop_set_current(dict->dict.prev_ioloop);
connection_switch_ioloop(&dict->conn.conn);
- io_loop_set_current(dict->ioloop);
- io_loop_destroy(&dict->ioloop);
- dict->prev_ioloop = NULL;
+ io_loop_set_current(dict->dict.ioloop);
+ io_loop_destroy(&dict->dict.ioloop);
+ dict->dict.prev_ioloop = NULL;
if (!dict->conn.value_received) {
/* we failed in some way. make sure we disconnect since the
#include "lib.h"
#include "array.h"
#include "llist.h"
+#include "ioloop.h"
#include "str.h"
#include "dict-private.h"
str_begins(key, DICT_PATH_PRIVATE);
}
+void dict_pre_api_callback(struct dict *dict)
+{
+ if (dict->prev_ioloop != NULL) {
+ /* Don't let callback see that we've created our
+ internal ioloop in case it wants to add some ios
+ or timeouts. */
+ io_loop_set_current(dict->prev_ioloop);
+ }
+}
+
+void dict_post_api_callback(struct dict *dict)
+{
+ if (dict->prev_ioloop != NULL) {
+ io_loop_set_current(dict->ioloop);
+ io_loop_stop(dict->ioloop);
+ }
+}
+
+
int dict_lookup(struct dict *dict, pool_t pool, const char *key,
const char **value_r, const char **error_r)
{