diff src/modules/thread/wrap_Channel.cpp @ 1304:ee1448bb9680 minor

Fix race conditions and deadlocks in Channels (hopefully) (issue #554) Also, this is a giant commit because of the official Code Style (tm) was applied.
author Bart van Strien <bart.bes+projects@gmail.com>
date Wed, 30 Jan 2013 17:15:12 +0100
parents 1a59c21cd2f3
children f6ff61fc266f
line wrap: on
line diff
--- a/src/modules/thread/wrap_Channel.cpp	Sun Jan 27 20:04:16 2013 +0100
+++ b/src/modules/thread/wrap_Channel.cpp	Wed Jan 30 17:15:12 2013 +0100
@@ -24,94 +24,108 @@
 {
 namespace thread
 {
-	Channel *luax_checkchannel(lua_State *L, int idx)
-	{
-		return luax_checktype<Channel>(L, idx, "Channel", THREAD_CHANNEL_T);
-	}
+void retainVariant(Channel *c, Variant *v)
+{
+	c->lockMutex();
+	v->retain();
+	c->unlockMutex();
+}
+
+void releaseVariant(Channel *c, Variant *v)
+{
+	c->lockMutex();
+	v->release();
+	c->unlockMutex();
+}
+
+Channel *luax_checkchannel(lua_State *L, int idx)
+{
+	return luax_checktype<Channel>(L, idx, "Channel", THREAD_CHANNEL_T);
+}
 
-	int w_Channel_push(lua_State *L)
-	{
-		Channel *c = luax_checkchannel(L, 1);
-		Variant *var = Variant::fromLua(L, 2);
-		c->push(var);
-		var->release();
-		return 0;
-	}
+int w_Channel_push(lua_State *L)
+{
+	Channel *c = luax_checkchannel(L, 1);
+	Variant *var = Variant::fromLua(L, 2);
+	c->push(var);
+	releaseVariant(c, var);
+	return 0;
+}
 
-	int w_Channel_supply(lua_State *L)
+int w_Channel_supply(lua_State *L)
+{
+	Channel *c = luax_checkchannel(L, 1);
+	Variant *var = Variant::fromLua(L, 2);
+	c->supply(var);
+	releaseVariant(c, var);
+	return 0;
+}
+
+int w_Channel_pop(lua_State *L)
+{
+	Channel *c = luax_checkchannel(L, 1);
+	Variant *var = c->pop();
+	if (var)
 	{
-		Channel *c = luax_checkchannel(L, 1);
-		Variant *var = Variant::fromLua(L, 2);
-		c->supply(var);
-		var->release();
-		return 0;
-	}
-
-	int w_Channel_pop(lua_State *L)
-	{
-		Channel *c = luax_checkchannel(L, 1);
-		Variant *var = c->pop();
-		if (var)
-		{
-			var->toLua(L);
-			var->release();
-		}
-		else
-			lua_pushnil(L);
-		return 1;
-	}
-
-	int w_Channel_demand(lua_State *L)
-	{
-		Channel *c = luax_checkchannel(L, 1);
-		Variant *var = c->demand();
 		var->toLua(L);
-		var->release();
-		return 1;
+		releaseVariant(c, var);
 	}
+	else
+		lua_pushnil(L);
+	return 1;
+}
 
-	int w_Channel_peek(lua_State *L)
+int w_Channel_demand(lua_State *L)
+{
+	Channel *c = luax_checkchannel(L, 1);
+	Variant *var = c->demand();
+	var->toLua(L);
+	releaseVariant(c, var);
+	return 1;
+}
+
+int w_Channel_peek(lua_State *L)
+{
+	Channel *c = luax_checkchannel(L, 1);
+	Variant *var = c->peek();
+	if (var)
 	{
-		Channel *c = luax_checkchannel(L, 1);
-		Variant *var = c->peek();
-		if (var)
-		{
-			var->toLua(L);
-			var->release();
-		}
-		else
-			lua_pushnil(L);
-		return 1;
+		var->toLua(L);
+		releaseVariant(c, var);
 	}
-
-	int w_Channel_count(lua_State *L)
-	{
-		Channel *c = luax_checkchannel(L, 1);
-		lua_pushnumber(L, c->count());
-		return 1;
-	}
+	else
+		lua_pushnil(L);
+	return 1;
+}
 
-	int w_Channel_clear(lua_State *L)
-	{
-		Channel *c = luax_checkchannel(L, 1);
-		c->clear();
-		return 0;
-	}
+int w_Channel_count(lua_State *L)
+{
+	Channel *c = luax_checkchannel(L, 1);
+	lua_pushnumber(L, c->count());
+	return 1;
+}
+
+int w_Channel_clear(lua_State *L)
+{
+	Channel *c = luax_checkchannel(L, 1);
+	c->clear();
+	return 0;
+}
 
-	static const luaL_Reg type_functions[] = {
-		{ "push", w_Channel_push },
-		{ "supply", w_Channel_supply },
-		{ "pop", w_Channel_pop },
-		{ "demand", w_Channel_demand },
-		{ "peek", w_Channel_peek },
-		{ "count", w_Channel_count },
-		{ "clear", w_Channel_clear },
-		{ 0, 0 }
-	};
+static const luaL_Reg type_functions[] = {
+	{ "push", w_Channel_push },
+	{ "supply", w_Channel_supply },
+	{ "pop", w_Channel_pop },
+	{ "demand", w_Channel_demand },
+	{ "peek", w_Channel_peek },
+	{ "count", w_Channel_count },
+	{ "clear", w_Channel_clear },
+	{ 0, 0 }
+};
 
-	extern "C" int luaopen_channel(lua_State *L)
-	{
-		return luax_register_type(L, "Channel", type_functions);
-	}
+extern "C" int luaopen_channel(lua_State *L)
+{
+	return luax_register_type(L, "Channel", type_functions);
 }
 }
+}