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
This commit is contained in:
Alex Szpakowski
2016-03-09 22:04:14 -04:00
parent e515cf076e
commit 140faf0cae
3 changed files with 29 additions and 35 deletions
+11 -29
View File
@@ -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
View File
@@ -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; uint64 sent;
unsigned long received; uint64 received;
}; // Channel }; // Channel
+12 -2
View File
@@ -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); uint64 id = c->push(var);
return 0; 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 }