Browse Source

Also mutex lock in Channel::retain

--HG--
branch : minor
Bart van Strien 13 years ago
parent
commit
3dc4e3cdca
2 changed files with 146 additions and 134 deletions
  1. 121 110
      src/modules/thread/Channel.cpp
  2. 25 24
      src/modules/thread/Channel.h

+ 121 - 110
src/modules/thread/Channel.cpp

@@ -26,136 +26,147 @@ namespace love
 {
 namespace thread
 {
-	static std::map<std::string, Channel*> namedChannels;
-	static Mutex *namedChannelMutex;
-	Channel *Channel::getChannel(const std::string &name)
-	{
-		if (!namedChannelMutex)
-			namedChannelMutex = newMutex();
-		Lock l(namedChannelMutex);
-		if (!namedChannels.count(name))
-			namedChannels[name] = new Channel(name);
-		else
-			namedChannels[name]->retain();
-		return namedChannels[name];
-	}
+static std::map<std::string, Channel*> namedChannels;
+static Mutex *namedChannelMutex;
+Channel *Channel::getChannel(const std::string &name)
+{
+	if (!namedChannelMutex)
+		namedChannelMutex = newMutex();
+	Lock l(namedChannelMutex);
+	if (!namedChannels.count(name))
+		namedChannels[name] = new Channel(name);
+	else
+		namedChannels[name]->retain();
+	return namedChannels[name];
+}
+
+Channel::Channel()
+	: named(false)
+{
+	mutex = newMutex();
+	cond = newConditional();
+}
 
-	Channel::Channel()
-		: named(false)
-	{
-		mutex = newMutex();
-		cond = newConditional();
-	}
+Channel::Channel(const std::string &name)
+	: named(true), name(name)
+{
+	mutex = newMutex();
+	cond = newConditional();
+}
 
-	Channel::Channel(const std::string &name)
-		: named(true), name(name)
+Channel::~Channel()
+{
+	while (!queue.empty())
 	{
-		mutex = newMutex();
-		cond = newConditional();
+		queue.front()->release();
+		queue.pop();
 	}
 
-	Channel::~Channel()
-	{
-		while (!queue.empty())
-		{
-			queue.front()->release();
-			queue.pop();
-		}
-
-		delete mutex;
-		delete cond;
-		if (named)
-			namedChannels.erase(name);
-	}
+	delete mutex;
+	delete cond;
+	if (named)
+		namedChannels.erase(name);
+}
+
+void Channel::push(Variant *var)
+{
+	if (!var)
+		return;
+	Lock l(mutex);
+	var->retain();
+	// Keep a reference to ourselves
+	// if we're non-empty and named.
+	if (named && queue.empty())
+		retain();
+	queue.push(var);
+	cond->signal();
+}
+
+Variant *Channel::pop()
+{
+	Lock l(mutex);
+	if (queue.empty())
+		return 0;
 
-	void Channel::push(Variant *var)
+	Variant *var = queue.front();
+	queue.pop();
+
+	// Release our reference to ourselves
+	// if we're empty and named.
+	if (named && queue.empty())
+		release();
+	return var;
+} // NOTE: Returns a retained Variant
+
+Variant *Channel::demand()
+{
+	Variant *var;
+	while (!(var = pop()))
 	{
-		if (!var)
-			return;
-		Lock l(mutex);
-		var->retain();
-		// Keep a reference to ourselves
-		// if we're non-empty and named.
-		if (named && queue.empty())
-			retain();
-		queue.push(var);
-		cond->signal();
+		mutex->lock();
+		cond->wait(mutex);
+		mutex->unlock();
 	}
+	return var;
+}
 
-	Variant *Channel::pop()
-	{
-		Lock l(mutex);
-		if (queue.empty())
-			return 0;
+Variant *Channel::peek()
+{
+	Lock l(mutex);
+	if (queue.empty())
+		return 0;
 
-		Variant *var = queue.front();
-		queue.pop();
+	Variant *var = queue.front();
+	var->retain();
+	return var;
+}
 
-		// Release our reference to ourselves
-		// if we're empty and named.
-		if (named && queue.empty())
-			release();
-		return var;
-	} // NOTE: Returns a retained Variant
+int Channel::count()
+{
+	Lock l(mutex);
+	return queue.size();
+}
+
+void Channel::clear()
+{
+	Lock l(mutex);
 
-	Variant *Channel::demand()
+	// We're already empty.
+	if (queue.empty())
+		return;
+
+	while (!queue.empty())
 	{
-		Variant *var;
-		while (!(var = pop()))
-		{
-			mutex->lock();
-			cond->wait(mutex);
-			mutex->unlock();
-		}
-		return var;
+		queue.front()->release();
+		queue.pop();
 	}
 
-	Variant *Channel::peek()
-	{
-		Lock l(mutex);
-		if (queue.empty())
-			return 0;
+	// Once again, release our own
+	// reference if we're named.
+	if (named)
+		release();
+}
 
-		Variant *var = queue.front();
-		var->retain();
-		return var;
-	}
+void Channel::retain()
+{
+	if (named)
+		namedChannelMutex->lock();
 
-	int Channel::count()
-	{
-		Lock l(mutex);
-		return queue.size();
-	}
+	Object::retain();
 
-	void Channel::clear()
-	{
-		Lock l(mutex);
-
-		// We're already empty.
-		if (queue.empty())
-			return;
-
-		while (!queue.empty())
-		{
-			queue.front()->release();
-			queue.pop();
-		}
-
-		// Once again, release our own
-		// reference if we're named.
-		if (named)
-			release();
-	}
+	if (named)
+		namedChannelMutex->unlock();
+}
 
-	void Channel::release()
-	{
-		if (named)
-			namedChannelMutex->lock();
+void Channel::release()
+{
+	if (named)
+		namedChannelMutex->lock();
 
-		Object::release();
+	Object::release();
 
-		if (named)
-			namedChannelMutex->unlock();
-	}
+	if (named)
+		namedChannelMutex->unlock();
+}
 } // thread
 } // love

+ 25 - 24
src/modules/thread/Channel.h

@@ -33,30 +33,31 @@ namespace love
 {
 namespace thread
 {
-	class Channel : public love::Object
-	{
-	private:
-		Mutex *mutex;
-		Conditional *cond;
-		std::queue<Variant*> queue;
-		bool named;
-		std::string name;
-		Channel(const std::string &name);
-
-	public:
-		Channel();
-		~Channel();
-		static Channel *getChannel(const std::string &name);
-
-		void push(Variant *var);
-		Variant *pop();
-		Variant *demand();
-		Variant *peek();
-		int count();
-		void clear();
-
-		void release();
-	}; // Channel
+class Channel : public love::Object
+{
+private:
+	Mutex *mutex;
+	Conditional *cond;
+	std::queue<Variant*> queue;
+	bool named;
+	std::string name;
+	Channel(const std::string &name);
+
+public:
+	Channel();
+	~Channel();
+	static Channel *getChannel(const std::string &name);
+
+	void push(Variant *var);
+	Variant *pop();
+	Variant *demand();
+	Variant *peek();
+	int count();
+	void clear();
+
+	void retain();
+	void release();
+}; // Channel
 } // thread
 } // love