Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: kostja@tarantool.org
Subject: [tarantool-patches] [PATCH 1/2] fiber: remove fiber local storage
Date: Sat,  9 Jun 2018 20:49:48 +0300	[thread overview]
Message-ID: <fba7c803c220a38b7d9809ebb059c1963bb3088b.1528566238.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1528566238.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1528566238.git.v.shpilevoy@tarantool.org>

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)

  reply	other threads:[~2018-06-09 17:49 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-09 17:49 [tarantool-patches] [PATCH 0/2] Box.session.sync Vladislav Shpilevoy
2018-06-09 17:49 ` Vladislav Shpilevoy [this message]
2018-06-13 21:11   ` [tarantool-patches] Re: [PATCH 1/2] fiber: remove fiber local storage Konstantin Osipov
2018-06-14 17:33     ` Vladislav Shpilevoy
2018-06-09 17:49 ` [tarantool-patches] [PATCH 2/2] session: fix box.session.sync() Vladislav Shpilevoy
2018-06-13 21:13   ` [tarantool-patches] " Konstantin Osipov
2018-06-09 17:58 ` [tarantool-patches] Re: [PATCH 0/2] Box.session.sync Vladislav Shpilevoy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fba7c803c220a38b7d9809ebb059c1963bb3088b.1528566238.git.v.shpilevoy@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=kostja@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [tarantool-patches] [PATCH 1/2] fiber: remove fiber local storage' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox