Browse Source

Channel:push now returns an id value. Added Channel:hasRead(id), which returns true if the value that the id represents has already been popped, demanded, or cleared from the Channel. Resolves issue #1104.

--HG--
branch : minor
Alex Szpakowski 9 years ago
parent
commit
140faf0cae
3 changed files with 29 additions and 35 deletions
  1. 11 29
      src/modules/thread/Channel.cpp
  2. 6 4
      src/modules/thread/Channel.h
  3. 12 2
      src/modules/thread/wrap_Channel.cpp

+ 11 - 29
src/modules/thread/Channel.cpp

@@ -22,34 +22,11 @@
 #include <map>
 #include <map>
 #include <string>
 #include <string>
 
 
-namespace
-{
-union uslong
-{
-	unsigned long u;
-	long i;
-};
-
-// target <= current, but semi-wrapsafe, one wrap, anyway
-inline bool past(unsigned int target, unsigned int current)
-{
-	if (target > current)
-		return false;
-	if (target == current)
-		return true;
-
-	uslong t, c;
-	t.u = target;
-	c.u = current;
-
-	return !(t.i < 0 && c.i > 0);
-}
-}
-
 namespace love
 namespace love
 {
 {
 namespace thread
 namespace thread
 {
 {
+
 static std::map<std::string, Channel *> namedChannels;
 static std::map<std::string, Channel *> namedChannels;
 static Mutex *namedChannelMutex;
 static Mutex *namedChannelMutex;
 
 
@@ -61,7 +38,6 @@ Channel *Channel::getChannel(const std::string &name)
 	Lock lock(namedChannelMutex);
 	Lock lock(namedChannelMutex);
 
 
 	auto it = namedChannels.find(name);
 	auto it = namedChannels.find(name);
-
 	if (it != namedChannels.end())
 	if (it != namedChannels.end())
 	{
 	{
 		it->second->retain();
 		it->second->retain();
@@ -96,7 +72,7 @@ Channel::~Channel()
 	}
 	}
 }
 }
 
 
-unsigned long Channel::push(const Variant &var)
+uint64 Channel::push(const Variant &var)
 {
 {
 	Lock l(mutex);
 	Lock l(mutex);
 
 
@@ -114,9 +90,9 @@ unsigned long Channel::push(const Variant &var)
 void Channel::supply(const Variant &var)
 void Channel::supply(const Variant &var)
 {
 {
 	Lock l(mutex);
 	Lock l(mutex);
-	unsigned long id = push(var);
+	uint64 id = push(var);
 
 
-	while (!past(id, received))
+	while (received < id)
 		cond->wait(mutex);
 		cond->wait(mutex);
 }
 }
 
 
@@ -160,12 +136,18 @@ bool Channel::peek(Variant *var)
 	return true;
 	return true;
 }
 }
 
 
-int Channel::getCount()
+int Channel::getCount() const
 {
 {
 	Lock l(mutex);
 	Lock l(mutex);
 	return (int) queue.size();
 	return (int) queue.size();
 }
 }
 
 
+bool Channel::hasRead(uint64 id) const
+{
+	Lock l(mutex);
+	return received >= id;
+}
+
 void Channel::clear()
 void Channel::clear()
 {
 {
 	Lock l(mutex);
 	Lock l(mutex);

+ 6 - 4
src/modules/thread/Channel.h

@@ -27,6 +27,7 @@
 
 
 // LOVE
 // LOVE
 #include "common/Variant.h"
 #include "common/Variant.h"
+#include "common/int.h"
 #include "threads.h"
 #include "threads.h"
 
 
 namespace love
 namespace love
@@ -46,12 +47,13 @@ public:
 
 
 	static Channel *getChannel(const std::string &name);
 	static Channel *getChannel(const std::string &name);
 
 
-	unsigned long push(const Variant &var);
+	uint64 push(const Variant &var);
 	void supply(const Variant &var); // blocking push
 	void supply(const Variant &var); // blocking push
 	bool pop(Variant *var);
 	bool pop(Variant *var);
 	void demand(Variant *var); // blocking pop
 	void demand(Variant *var); // blocking pop
 	bool peek(Variant *var);
 	bool peek(Variant *var);
-	int getCount();
+	int getCount() const;
+	bool hasRead(uint64 id) const;
 	void clear();
 	void clear();
 
 
 private:
 private:
@@ -66,8 +68,8 @@ private:
 	bool named;
 	bool named;
 	std::string name;
 	std::string name;
 
 
-	unsigned long sent;
-	unsigned long received;
+	uint64 sent;
+	uint64 received;
 
 
 }; // Channel
 }; // Channel
 
 

+ 12 - 2
src/modules/thread/wrap_Channel.cpp

@@ -36,8 +36,9 @@ int w_Channel_push(lua_State *L)
 	Variant var;
 	Variant var;
 	if (!Variant::fromLua(L, 2, &var))
 	if (!Variant::fromLua(L, 2, &var))
 		return luaL_argerror(L, 2, "boolean, number, string, love type, or flat table expected");
 		return luaL_argerror(L, 2, "boolean, number, string, love type, or flat table expected");
-	c->push(var);
-	return 0;
+	uint64 id = c->push(var);
+	lua_pushnumber(L, (lua_Number) id);
+	return 1;
 }
 }
 
 
 int w_Channel_supply(lua_State *L)
 int w_Channel_supply(lua_State *L)
@@ -88,6 +89,14 @@ int w_Channel_getCount(lua_State *L)
 	return 1;
 	return 1;
 }
 }
 
 
+int w_Channel_hasRead(lua_State *L)
+{
+	Channel *c = luax_checkchannel(L, 1);
+	uint64 id = (uint64) luaL_checknumber(L, 2);
+	luax_pushboolean(L, c->hasRead(id));
+	return 1;
+}
+
 int w_Channel_clear(lua_State *L)
 int w_Channel_clear(lua_State *L)
 {
 {
 	Channel *c = luax_checkchannel(L, 1);
 	Channel *c = luax_checkchannel(L, 1);
@@ -130,6 +139,7 @@ static const luaL_Reg w_Channel_functions[] =
 	{ "demand", w_Channel_demand },
 	{ "demand", w_Channel_demand },
 	{ "peek", w_Channel_peek },
 	{ "peek", w_Channel_peek },
 	{ "getCount", w_Channel_getCount },
 	{ "getCount", w_Channel_getCount },
+	{ "hasRead", w_Channel_hasRead },
 	{ "clear", w_Channel_clear },
 	{ "clear", w_Channel_clear },
 	{ "performAtomic", w_Channel_performAtomic },
 	{ "performAtomic", w_Channel_performAtomic },
 	{ 0, 0 }
 	{ 0, 0 }