[tarantool-patches] [PATCH 1/2] fiber: remove fiber local storage
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Sat Jun 9 20:49:48 MSK 2018
Replace it with more specific structures and pointers in order to
prepare to add `net` storage.
This allows to make the code working with fiber storage simpler,
remove useless wrappers and casts, and in the next patch - remove
broken session.sync and add fiber sync.
---
src/box/session.cc | 4 +--
src/box/session.h | 14 ++++------
src/box/txn.c | 2 +-
src/box/txn.h | 2 +-
src/fiber.c | 9 ++----
src/fiber.h | 80 +++++++++++++++++++----------------------------------
src/fiber_channel.c | 31 ++++++---------------
src/lua/fiber.c | 19 ++++++-------
8 files changed, 56 insertions(+), 105 deletions(-)
diff --git a/src/box/session.cc b/src/box/session.cc
index 60adc5639..f868e9ecc 100644
--- a/src/box/session.cc
+++ b/src/box/session.cc
@@ -86,10 +86,8 @@ session_on_stop(struct trigger *trigger, void * /* event */)
* after the trigger and its memory is long gone.
*/
trigger_clear(trigger);
- struct session *session = (struct session *)
- fiber_get_key(fiber(), FIBER_KEY_SESSION);
/* Destroy the session */
- session_destroy(session);
+ session_destroy(fiber_get_session(fiber()));
}
struct session *
diff --git a/src/box/session.h b/src/box/session.h
index f4e9b4109..17190ab47 100644
--- a/src/box/session.h
+++ b/src/box/session.h
@@ -154,7 +154,7 @@ extern struct rlist session_on_auth;
static inline struct session *
fiber_get_session(struct fiber *fiber)
{
- return (struct session *) fiber_get_key(fiber, FIBER_KEY_SESSION);
+ return fiber->storage.session;
}
/**
@@ -165,13 +165,13 @@ fiber_get_session(struct fiber *fiber)
static inline void
fiber_set_user(struct fiber *fiber, struct credentials *cr)
{
- fiber_set_key(fiber, FIBER_KEY_USER, cr);
+ fiber->storage.credentials = cr;
}
static inline void
fiber_set_session(struct fiber *fiber, struct session *session)
{
- fiber_set_key(fiber, FIBER_KEY_SESSION, session);
+ fiber->storage.session = session;
}
static inline void
@@ -227,13 +227,11 @@ current_session()
static inline struct credentials *
effective_user()
{
- struct credentials *u =
- (struct credentials *) fiber_get_key(fiber(),
- FIBER_KEY_USER);
+ struct fiber *f = fiber();
+ struct credentials *u = f->storage.credentials;
if (u == NULL) {
session_create_on_demand();
- u = (struct credentials *) fiber_get_key(fiber(),
- FIBER_KEY_USER);
+ u = f->storage.credentials;
}
return u;
}
diff --git a/src/box/txn.c b/src/box/txn.c
index e25c0e0e0..5714d485d 100644
--- a/src/box/txn.c
+++ b/src/box/txn.c
@@ -40,7 +40,7 @@ double too_long_threshold;
static inline void
fiber_set_txn(struct fiber *fiber, struct txn *txn)
{
- fiber_set_key(fiber, FIBER_KEY_TXN, (void *) txn);
+ fiber->storage.txn = txn;
}
static int
diff --git a/src/box/txn.h b/src/box/txn.h
index 4db74dfca..2bec73ec1 100644
--- a/src/box/txn.h
+++ b/src/box/txn.h
@@ -142,7 +142,7 @@ struct txn {
static inline struct txn *
in_txn()
{
- return (struct txn *) fiber_get_key(fiber(), FIBER_KEY_TXN);
+ return fiber()->storage.txn;
}
/**
diff --git a/src/fiber.c b/src/fiber.c
index 9eb7aed50..75a4846d4 100644
--- a/src/fiber.c
+++ b/src/fiber.c
@@ -612,7 +612,8 @@ fiber_recycle(struct fiber *fiber)
fiber_reset(fiber);
fiber->name[0] = '\0';
fiber->f = NULL;
- memset(fiber->fls, 0, sizeof(fiber->fls));
+ fiber->wait_pad = NULL;
+ memset(&fiber->storage, 0, sizeof(fiber->storage));
unregister_fid(fiber);
fiber->fid = 0;
region_free(&fiber->gc);
@@ -682,12 +683,6 @@ fiber_set_name(struct fiber *fiber, const char *name)
snprintf(fiber->name, sizeof(fiber->name), "%s", name);
}
-extern inline void
-fiber_set_key(struct fiber *fiber, enum fiber_key key, void *value);
-
-extern inline void *
-fiber_get_key(struct fiber *fiber, enum fiber_key key);
-
static inline void *
page_align_down(void *ptr)
{
diff --git a/src/fiber.h b/src/fiber.h
index 8231bba24..b7003aeb6 100644
--- a/src/fiber.h
+++ b/src/fiber.h
@@ -92,24 +92,6 @@ enum {
FIBER_DEFAULT_FLAGS = FIBER_IS_CANCELLABLE
};
-/**
- * \brief Pre-defined key for fiber local storage
- */
-enum fiber_key {
- /** box.session */
- FIBER_KEY_SESSION = 0,
- /** Lua fiber.storage */
- FIBER_KEY_LUA_STORAGE = 1,
- /** transaction */
- FIBER_KEY_TXN = 2,
- /** User global privilege and authentication token */
- FIBER_KEY_USER = 3,
- FIBER_KEY_MSG = 4,
- /** Storage for lua stack */
- FIBER_KEY_LUA_STACK = 5,
- FIBER_KEY_MAX = 6
-};
-
/** \cond public */
/**
@@ -349,6 +331,12 @@ struct fiber_attr {
void
fiber_attr_create(struct fiber_attr *fiber_attr);
+struct session;
+struct txn;
+struct credentials;
+struct lua_State;
+struct ipc_wait_pad;
+
struct fiber {
coro_context ctx;
/** Coro stack slab. */
@@ -395,8 +383,28 @@ struct fiber {
fiber_func f;
va_list f_data;
int f_ret;
- /** Fiber local storage */
- void *fls[FIBER_KEY_MAX];
+ /** Fiber local storage. */
+ struct {
+ /**
+ * Current transaction, session and the active
+ * user credentials are shared among multiple
+ * requests and valid even out of a former.
+ */
+ struct session *session;
+ struct credentials *credentials;
+ struct txn *txn;
+ /**
+ * Fields used by a fiber created in Lua: Lua
+ * stack and the optional fiber.storage Lua
+ * reference.
+ */
+ struct {
+ struct lua_State *stack;
+ int ref;
+ } lua;
+ } storage;
+ /** An object to wait for incoming message or a reader. */
+ struct ipc_wait_pad *wait_pad;
/** Exception which caused this fiber's death. */
struct diag diag;
char name[FIBER_NAME_MAX];
@@ -577,44 +585,12 @@ fiber_find(uint32_t fid);
void
fiber_schedule_cb(ev_loop * /* loop */, ev_watcher *watcher, int revents);
-/**
- * \brief Associate \a value with \a key in fiber local storage
- * \param fiber fiber
- * \param key pre-defined key
- * \param value value to set
- */
-inline void
-fiber_set_key(struct fiber *fiber, enum fiber_key key, void *value)
-{
- assert(key < FIBER_KEY_MAX);
- fiber->fls[key] = value;
-}
-
-
static inline bool
fiber_is_dead(struct fiber *f)
{
return f->flags & FIBER_IS_DEAD;
}
-/**
- * \brief Retrieve value by \a key from fiber local storage
- * \param fiber fiber
- * \param key pre-defined key
- * \return value from from fiber local storage
- */
-inline void *
-fiber_get_key(struct fiber *fiber, enum fiber_key key)
-{
- assert(key < FIBER_KEY_MAX);
- return fiber->fls[key];
-}
-
-/**
- * Finalizer callback
- * \sa fiber_key_on_gc()
- */
-typedef void (*fiber_key_gc_cb)(enum fiber_key key, void *arg);
typedef int (*fiber_stat_cb)(struct fiber *f, void *ctx);
int
diff --git a/src/fiber_channel.c b/src/fiber_channel.c
index 99e51a47e..4bbff45c5 100644
--- a/src/fiber_channel.c
+++ b/src/fiber_channel.c
@@ -85,9 +85,7 @@ fiber_channel_has_waiter(struct fiber_channel *ch,
if (rlist_empty(&ch->waiters))
return false;
struct fiber *f = rlist_first_entry(&ch->waiters, struct fiber, state);
- struct ipc_wait_pad *pad = (struct ipc_wait_pad *)
- fiber_get_key(f, FIBER_KEY_MSG);
- return pad->status == status;
+ return f->wait_pad->status == status;
}
bool
@@ -134,14 +132,12 @@ static inline void
fiber_channel_waiter_wakeup(struct fiber *f,
enum fiber_channel_wait_status status)
{
- struct ipc_wait_pad *pad = (struct ipc_wait_pad *)
- fiber_get_key(f, FIBER_KEY_MSG);
/*
* Safe to overwrite the status without looking at it:
* whoever is touching the status, removes the fiber
* from the wait list.
*/
- pad->status = status;
+ f->wait_pad->status = status;
/*
* fiber_channel allows an asynchronous cancel. If a fiber
* is cancelled while waiting on a timeout, it is done via
@@ -317,10 +313,7 @@ fiber_channel_put_msg_timeout(struct fiber_channel *ch,
struct fiber,
state);
/* Place the message on the pad. */
- struct ipc_wait_pad *pad = (struct ipc_wait_pad *)
- fiber_get_key(f, FIBER_KEY_MSG);
-
- pad->msg = msg;
+ f->wait_pad->msg = msg;
fiber_channel_waiter_wakeup(f, FIBER_CHANNEL_WAIT_DONE);
return 0;
@@ -355,7 +348,7 @@ fiber_channel_put_msg_timeout(struct fiber_channel *ch,
struct ipc_wait_pad pad;
pad.status = FIBER_CHANNEL_WAIT_WRITER;
pad.msg = msg;
- fiber_set_key(f, FIBER_KEY_MSG, &pad);
+ f->wait_pad = &pad;
if (first_try) {
rlist_add_tail_entry(&ch->waiters, f, state);
@@ -370,7 +363,7 @@ fiber_channel_put_msg_timeout(struct fiber_channel *ch,
* rlist_del_entry() is a no-op if already done.
*/
rlist_del_entry(f, state);
- fiber_set_key(f, FIBER_KEY_MSG, NULL);
+ f->wait_pad = NULL;
if (pad.status == FIBER_CHANNEL_WAIT_CLOSED) {
/*
@@ -423,10 +416,7 @@ fiber_channel_get_msg_timeout(struct fiber_channel *ch,
f = rlist_first_entry(&ch->waiters,
struct fiber,
state);
- struct ipc_wait_pad *pad =
- (struct ipc_wait_pad *)
- fiber_get_key(f, FIBER_KEY_MSG);
- fiber_channel_buffer_push(ch, pad->msg);
+ fiber_channel_buffer_push(ch, f->wait_pad->msg);
fiber_channel_waiter_wakeup(f,
FIBER_CHANNEL_WAIT_DONE);
}
@@ -445,10 +435,7 @@ fiber_channel_get_msg_timeout(struct fiber_channel *ch,
f = rlist_first_entry(&ch->waiters,
struct fiber,
state);
- struct ipc_wait_pad *pad =
- (struct ipc_wait_pad *)
- fiber_get_key(f, FIBER_KEY_MSG);
- *msg = pad->msg;
+ *msg = f->wait_pad->msg;
fiber_channel_waiter_wakeup(f, FIBER_CHANNEL_WAIT_DONE);
return 0;
}
@@ -461,7 +448,7 @@ fiber_channel_get_msg_timeout(struct fiber_channel *ch,
*/
struct ipc_wait_pad pad;
pad.status = FIBER_CHANNEL_WAIT_READER;
- fiber_set_key(f, FIBER_KEY_MSG, &pad);
+ f->wait_pad = &pad;
if (first_try) {
rlist_add_tail_entry(&ch->waiters, f, state);
first_try = false;
@@ -475,7 +462,7 @@ fiber_channel_get_msg_timeout(struct fiber_channel *ch,
* rlist_del_entry() is a no-op if already done.
*/
rlist_del_entry(f, state);
- fiber_set_key(f, FIBER_KEY_MSG, NULL);
+ f->wait_pad = NULL;
if (pad.status == FIBER_CHANNEL_WAIT_CLOSED) {
diag_set(ChannelIsClosed);
return -1;
diff --git a/src/lua/fiber.c b/src/lua/fiber.c
index 312edd3d5..147add89b 100644
--- a/src/lua/fiber.c
+++ b/src/lua/fiber.c
@@ -294,15 +294,14 @@ static int
lua_fiber_run_f(MAYBE_UNUSED va_list ap)
{
int result;
- struct lua_State *L = (struct lua_State *)
- fiber_get_key(fiber(), FIBER_KEY_LUA_STACK);
+ struct fiber *f = fiber();
+ struct lua_State *L = f->storage.lua.stack;
int coro_ref = lua_tointeger(L, -1);
lua_pop(L, 1);
result = luaT_call(L, lua_gettop(L) - 1, LUA_MULTRET);
/* Destroy local storage */
- int storage_ref = (int)(intptr_t)
- fiber_get_key(fiber(), FIBER_KEY_LUA_STORAGE);
+ int storage_ref = f->storage.lua.ref;
if (storage_ref > 0)
luaL_unref(L, LUA_REGISTRYINDEX, storage_ref);
/*
@@ -310,7 +309,7 @@ lua_fiber_run_f(MAYBE_UNUSED va_list ap)
* We can unref child stack here,
* otherwise we have to unref child stack in join
*/
- if (fiber()->flags & FIBER_IS_JOINABLE)
+ if (f->flags & FIBER_IS_JOINABLE)
lua_pushinteger(L, coro_ref);
else
luaL_unref(L, LUA_REGISTRYINDEX, coro_ref);
@@ -343,7 +342,7 @@ fiber_create(struct lua_State *L)
* At that time we can pop coro_ref from stack
*/
lua_pushinteger(child_L, coro_ref);
- fiber_set_key(f, FIBER_KEY_LUA_STACK, child_L);
+ f->storage.lua.stack = child_L;
return f;
}
@@ -467,13 +466,11 @@ static int
lbox_fiber_storage(struct lua_State *L)
{
struct fiber *f = lbox_checkfiber(L, 1);
- int storage_ref = (int)(intptr_t)
- fiber_get_key(f, FIBER_KEY_LUA_STORAGE);
+ int storage_ref = f->storage.lua.ref;
if (storage_ref <= 0) {
lua_newtable(L); /* create local storage on demand */
storage_ref = luaL_ref(L, LUA_REGISTRYINDEX);
- fiber_set_key(f, FIBER_KEY_LUA_STORAGE,
- (void *)(intptr_t) storage_ref);
+ f->storage.lua.ref = storage_ref;
}
lua_rawgeti(L, LUA_REGISTRYINDEX, storage_ref);
return 1;
@@ -613,7 +610,7 @@ static int
lbox_fiber_join(struct lua_State *L)
{
struct fiber *fiber = lbox_checkfiber(L, 1);
- struct lua_State *child_L = fiber_get_key(fiber, FIBER_KEY_LUA_STACK);
+ struct lua_State *child_L = fiber->storage.lua.stack;
fiber_join(fiber);
struct error *e = NULL;
int num_ret = 0;
--
2.15.1 (Apple Git-101)
More information about the Tarantool-patches
mailing list