From 7ad81cc5ba73a488044a158b7ee9720bfb55672b Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Thu, 1 Oct 2015 12:28:56 +0300
Subject: [PATCH] gh-1079: deprecate and remove fiber.channel.broadcast()

Remove broadcast(): it din't work as expected and wasn't used
by anyone.
---
 doc/sphinx/reference/fiber-ipc.rst | 12 +-----
 src/ipc.cc                         | 61 ------------------------------
 src/ipc.h                          | 12 ------
 src/lua/ipc.cc                     | 31 ---------------
 test/box/ipc.result                | 22 +----------
 test/box/ipc.test.lua              |  6 +--
 6 files changed, 4 insertions(+), 140 deletions(-)

diff --git a/doc/sphinx/reference/fiber-ipc.rst b/doc/sphinx/reference/fiber-ipc.rst
index 29483f7d6f..1b7cb60301 100644
--- a/doc/sphinx/reference/fiber-ipc.rst
+++ b/doc/sphinx/reference/fiber-ipc.rst
@@ -21,7 +21,7 @@ other Lua object. Use object-oriented syntax, for example
     Create a new communication channel.
 
     :param int capacity: positive integer as great as the maximum number of
-                         slots (spaces for get or put or broadcast messages)
+                         slots (spaces for get or put messages)
                          that might be pending at any given time.
 
     :return: new channel.
@@ -54,17 +54,9 @@ other Lua object. Use object-oriented syntax, for example
 
         :param timeout:
         :return: the value placed on the channel by an earlier
-                ``channel:put()`` or ``channel:broadcast()``.
+                ``channel:put()``
         :rtype:  lua_object
 
-    .. method:: broadcast(message)
-
-        If the channel is empty, ``channel:broadcast()`` is equivalent to
-        ``channel:put()``. Otherwise, ``channel:broadcast()`` sends the
-        message to all readers of the channel.
-
-        :param message:
-
     .. method:: is_empty()
 
         Check whether the specified channel is empty (has no messages).
diff --git a/src/ipc.cc b/src/ipc.cc
index 5b253111d1..9cf5d7ed1f 100644
--- a/src/ipc.cc
+++ b/src/ipc.cc
@@ -58,7 +58,6 @@ ipc_channel_create(struct ipc_channel *ch, unsigned size)
 	ch->beg = ch->count = 0;
 	ch->readonly = ch->closed = false;
 	ch->close = NULL;
-	ch->bcast = NULL;
 	rlist_create(&ch->readers);
 	rlist_create(&ch->writers);
 }
@@ -130,14 +129,6 @@ ipc_channel_get_timeout(struct ipc_channel *ch, ev_tstamp timeout)
 		fiber_yield_timeout(timeout);
 		rlist_del_entry(fiber(), state);
 
-		/* broadcast message wakes us up */
-		if (ch->bcast) {
-			fiber_wakeup(ch->bcast);
-			fiber_testcancel();
-			res = ch->bcast_msg;
-			goto exit;
-		}
-
 		fiber_testcancel();
 
 		timeout -= ev_now(loop()) - started;
@@ -202,8 +193,6 @@ ipc_channel_shutdown(struct ipc_channel *ch)
 		f = rlist_first_entry(&ch->writers, struct fiber, state);
 		ipc_channel_close_waiter(ch, f);
 	}
-	if (ch->bcast)
-		fiber_wakeup(ch->bcast);
 }
 
 void
@@ -216,7 +205,6 @@ ipc_channel_close(struct ipc_channel *ch)
 	assert(ch->count == 0);
 	assert(rlist_empty(&ch->readers));
 	assert(rlist_empty(&ch->writers));
-	assert(ch->bcast == NULL);
 	ch->closed = true;
 }
 
@@ -286,52 +274,3 @@ ipc_channel_put_timeout(struct ipc_channel *ch, void *data,
 	}
 	return res;
 }
-
-int
-ipc_channel_broadcast(struct ipc_channel *ch, void *data)
-{
-	/* do nothing at closed channel */
-	if (ch->readonly)
-		return 0;
-
-	/* broadcast in broadcast: marasmus */
-	if (ch->bcast)
-		return 0;
-
-	/* there is no reader on channel */
-	if (rlist_empty(&ch->readers)) {
-		ipc_channel_put(ch, data);
-		return 1;
-	}
-
-	unsigned readers = 0;
-	struct fiber *f;
-	rlist_foreach_entry(f, &ch->readers, state) {
-		readers++;
-	}
-
-	unsigned cnt = 0;
-	while (!rlist_empty(&ch->readers)) {
-		if (ch->readonly)
-			break;
-		f = rlist_first_entry(&ch->readers, struct fiber, state);
-
-		ch->bcast_msg = data;
-		ch->bcast = fiber();
-		fiber_wakeup(f);
-		fiber_yield();
-		ch->bcast = NULL;
-		rlist_del_entry(fiber(), state);
-		fiber_testcancel();
-		/* if any other reader was added don't wake it up */
-		if (++cnt >= readers)
-			break;
-	}
-
-	if (ch->readonly && ch->close) {
-		fiber_wakeup(ch->close);
-		ch->close = NULL;
-	}
-
-	return cnt;
-}
diff --git a/src/ipc.h b/src/ipc.h
index 312d51c8bc..44027acfcc 100644
--- a/src/ipc.h
+++ b/src/ipc.h
@@ -49,14 +49,12 @@ struct ipc_channel {
 	 * the channel is full.
 	 */
 	struct rlist writers;
-	struct fiber *bcast;		/* broadcast waiter */
 	struct fiber *close;		/* close waiter */
 	bool readonly;			/* channel is read only */
 	bool closed;			/* channel is closed */
 	unsigned size;
 	unsigned beg;
 	unsigned count;
-	void *bcast_msg;
 	void *item[0];
 };
 
@@ -98,16 +96,6 @@ ipc_channel_new(unsigned size);
 void
 ipc_channel_delete(struct ipc_channel *ch);
 
-/**
- * @brief Wake up all fibers that sleep in ipc_channel_get and
- * send a message to them.
- * @param channel
- * @param data
- * @return count of fibers to which the message was delivered
- */
-int
-ipc_channel_broadcast(struct ipc_channel *ch, void *data);
-
 /**
  * @brief check if channel is empty
  * @param channel
diff --git a/src/lua/ipc.cc b/src/lua/ipc.cc
index ca4d2ba36a..05e352621e 100644
--- a/src/lua/ipc.cc
+++ b/src/lua/ipc.cc
@@ -43,8 +43,6 @@ extern "C" {
 
 static const char channel_lib[]   = "fiber.channel";
 
-#define BROADCAST_MASK	(((size_t)1) << (CHAR_BIT * sizeof(size_t) - 1))
-
 /******************** channel ***************************/
 
 static int
@@ -180,38 +178,11 @@ lbox_ipc_channel_get(struct lua_State *L)
 		lua_pushnil(L);
 		return 1;
 	}
-	if (vref & BROADCAST_MASK) {
-		vref &= ~BROADCAST_MASK;
-		lua_rawgeti(L, LUA_REGISTRYINDEX, vref);
-		return 1;
-	}
 	lua_rawgeti(L, LUA_REGISTRYINDEX, vref);
 	luaL_unref(L, LUA_REGISTRYINDEX, vref);
 	return 1;
 }
 
-static int
-lbox_ipc_channel_broadcast(struct lua_State *L)
-{
-	struct ipc_channel *ch;
-
-	if (lua_gettop(L) != 2)
-		luaL_error(L, "usage: channel:broadcast(variable)");
-
-	ch = lbox_check_channel(L, 1);
-
-	if (!ipc_channel_has_readers(ch))
-		return lbox_ipc_channel_put(L);
-
-
-	lua_pushvalue(L, 2);
-	size_t vref = luaL_ref(L, LUA_REGISTRYINDEX);
-	int count = ipc_channel_broadcast(ch, (void *)(vref | BROADCAST_MASK));
-	luaL_unref(L, LUA_REGISTRYINDEX, vref);
-	lua_pushnumber(L, count);
-	return 1;
-}
-
 static int
 lbox_ipc_channel_has_readers(struct lua_State *L)
 {
@@ -267,7 +238,6 @@ lbox_ipc_channel_close(struct lua_State *L)
 		/* Never yields because channel is not empty */
 		size_t vref = (size_t)ipc_channel_get_timeout(ch, 0);
 		assert(vref);
-		assert((vref & BROADCAST_MASK) == 0);
 		/* Unref lua items */
 		luaL_unref(L, LUA_REGISTRYINDEX, vref);
 	}
@@ -298,7 +268,6 @@ tarantool_lua_ipc_init(struct lua_State *L)
 		{"is_empty",	lbox_ipc_channel_is_empty},
 		{"put",		lbox_ipc_channel_put},
 		{"get",		lbox_ipc_channel_get},
-		{"broadcast",	lbox_ipc_channel_broadcast},
 		{"has_readers",	lbox_ipc_channel_has_readers},
 		{"has_writers",	lbox_ipc_channel_has_writers},
 		{"count",	lbox_ipc_channel_count},
diff --git a/test/box/ipc.result b/test/box/ipc.result
index 4c9b42e59b..6fb1bb2f47 100644
--- a/test/box/ipc.result
+++ b/test/box/ipc.result
@@ -52,7 +52,7 @@ ch:put(234)
 ---
 - true
 ...
-ch:put(345, .5)
+ch:put(345, .1)
 ---
 - false
 ...
@@ -174,18 +174,6 @@ ch:is_empty()
 ---
 - true
 ...
-ch:broadcast()
----
-- error: 'usage: channel:broadcast(variable)'
-...
-ch:broadcast(123)
----
-- true
-...
-ch:get()
----
-- 123
-...
 ch:is_full()
 ---
 - false
@@ -251,10 +239,6 @@ ch:put(5)
 ---
 - true
 ...
-ch:broadcast('broadcast message!')
----
-- 2
-...
 t = {}
 ---
 ...
@@ -287,10 +271,6 @@ buffer
     - '4'
   - - tfbr
     - '5'
-  - - tfbr2
-    - broadcast message!
-  - - tfbr
-    - broadcast message!
   - - tfbr2
     - '35'
   - - tfbr
diff --git a/test/box/ipc.test.lua b/test/box/ipc.test.lua
index 3b60b03be0..4a490a77d1 100644
--- a/test/box/ipc.test.lua
+++ b/test/box/ipc.test.lua
@@ -13,7 +13,7 @@ ch:get()
 ch:get('wrong timeout')
 ch:get(-10)
 ch:put(234)
-ch:put(345, .5)
+ch:put(345, .1)
 ch:count()
 ch:is_full()
 ch:is_empty()
@@ -47,9 +47,6 @@ ch:get(box.info.pid) == box.info.pid
 buffer
 
 ch:is_empty()
-ch:broadcast()
-ch:broadcast(123)
-ch:get()
 
 ch:is_full()
 ch:is_empty()
@@ -82,7 +79,6 @@ ch:put(2)
 ch:put(3)
 ch:put(4)
 ch:put(5)
-ch:broadcast('broadcast message!')
 t = {}
 for i = 35, 45 do table.insert(t, ch:put(i)) end
 t
-- 
GitLab