From 9c34d27a8bc724722e9cae203e0c455573c3d5f1 Mon Sep 17 00:00:00 2001
From: Alexander Sulfrian <alexander@sulfrian.net>
Date: Wed, 5 Sep 2012 18:30:34 +0200
Subject: menu: use boost::shared_mutex

Use everywhere a mutable boost::shared_mutex to enable locking during
const getter and the multiple reader and single writer pattern.
---
 src/menu/drawable_control.cpp       | 30 +++++++++++++++++++-----------
 src/menu/drawable_control.hpp       | 10 +++++-----
 src/menu/event_manager.cpp          |  8 ++++----
 src/menu/event_manager.hpp          |  4 ++--
 src/menu/software_mouse_pointer.hpp |  1 -
 src/menu/text.cpp                   | 19 ++++++++++++++-----
 src/menu/text.hpp                   |  4 ++--
 7 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/src/menu/drawable_control.cpp b/src/menu/drawable_control.cpp
index e67b4002..4d0d9c3c 100644
--- a/src/menu/drawable_control.cpp
+++ b/src/menu/drawable_control.cpp
@@ -62,18 +62,19 @@ namespace usdx
 
 	bool DrawableControl::get_clipping_required(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(clipping_required_mutex);
 		return clipping_required;
 	}
 
 	void DrawableControl::set_clipping_required(const bool value)
 	{
-		boost::mutex::scoped_lock lock(clipping_required_mutex);
+		boost::unique_lock<boost::shared_mutex> lock(clipping_required_mutex);
 		clipping_required = value;
 	}
 
 	void DrawableControl::draw(void)
 	{
-		boost::mutex::scoped_lock lock(background_mutex);
+		boost::shared_lock<boost::shared_mutex> lock(background_mutex);
 		if (background) {
 			background->repaint();
 		}
@@ -82,16 +83,16 @@ namespace usdx
 	void DrawableControl::repaint(void)
 	{
 		{
-			// position
-			boost::mutex::scoped_lock lock(position_mutex);
+			boost::shared_lock<boost::shared_mutex> lock(position_mutex);
 			glTranslatef(position.get_x(), position.get_y(), 0.0f);
 		}
 
-		boost::mutex::scoped_lock clipping_lock(clipping_required_mutex);
+		boost::shared_lock<boost::shared_mutex> clipping_lock(clipping_required_mutex);
 		if (clipping_required) {
 			clipping_lock.unlock();
 
-			boost::mutex::scoped_lock lock(size_mutex);
+			boost::shared_lock<boost::shared_mutex> size_lock(size_mutex);
+			boost::shared_lock<boost::shared_mutex> position_lock(position_mutex);
 			ClippingHelper clipping(parent, Rectangle<int>(position, size));
 			Drawable::repaint();
 		}
@@ -103,58 +104,64 @@ namespace usdx
 
 	void DrawableControl::set_position(const Point<int>& position)
 	{
-		boost::mutex::scoped_lock lock(position_mutex);
+		boost::unique_lock<boost::shared_mutex> lock(position_mutex);
 		this->position = position;
 	}
 
 	void DrawableControl::set_position(int left, int top)
 	{
-		boost::mutex::scoped_lock lock(position_mutex);
+		boost::unique_lock<boost::shared_mutex> lock(position_mutex);
 		this->position = Point<int>(left, top);
 	}
 
 
 	const Point<int>& DrawableControl::get_position(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(position_mutex);
 		return position;
 	}
 
 	int DrawableControl::get_left(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(position_mutex);
 		return position.get_x();
 	}
 
 	int DrawableControl::get_top(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(position_mutex);
 		return position.get_y();
 	}
 
 
 	void DrawableControl::set_size(const Dimension<int> &size)
 	{
-		boost::mutex::scoped_lock lock(size_mutex);
+		boost::unique_lock<boost::shared_mutex> lock(size_mutex);
 		this->size = size;
 	}
 
 	void DrawableControl::set_size(int width, int height)
 	{
-		boost::mutex::scoped_lock lock(size_mutex);
+		boost::unique_lock<boost::shared_mutex> lock(size_mutex);
 		this->size = Dimension<int>(width, height);
 	}
 
 
 	const Dimension<int>& DrawableControl::get_size(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(size_mutex);
 		return size;
 	}
 
 	int DrawableControl::get_width(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(size_mutex);
 		return size.get_width();
 	}
 
 	int DrawableControl::get_height(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(size_mutex);
 		return size.get_height();
 	}
 
@@ -180,7 +187,7 @@ namespace usdx
 
 	void DrawableControl::set_background(Background* background)
 	{
-		boost::mutex::scoped_lock lock(background_mutex);
+		boost::unique_lock<boost::shared_mutex> lock(background_mutex);
 		if (this->background) {
 			delete this->background;
 		}
@@ -190,6 +197,7 @@ namespace usdx
 
 	const Background* DrawableControl::get_background(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(background_mutex);
 		return background;
 	}
 };
diff --git a/src/menu/drawable_control.hpp b/src/menu/drawable_control.hpp
index 5d2aee27..ecee373d 100644
--- a/src/menu/drawable_control.hpp
+++ b/src/menu/drawable_control.hpp
@@ -26,7 +26,7 @@
 #define DRAWABLE_CONTROL_HPP
 
 #include <SDL/SDL.h>
-#include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
 #include <log4cpp/Category.hh>
 
 #include "drawable.hpp"
@@ -51,10 +51,10 @@ namespace usdx
 
 		Background* background;
 
-		boost::mutex position_mutex;
-		boost::mutex size_mutex;
-		boost::mutex clipping_required_mutex;
-		boost::mutex background_mutex;
+		mutable boost::shared_mutex position_mutex;
+		mutable boost::shared_mutex size_mutex;
+		mutable boost::shared_mutex clipping_required_mutex;
+		mutable boost::shared_mutex background_mutex;
 
 	protected:
 		Container* parent;
diff --git a/src/menu/event_manager.cpp b/src/menu/event_manager.cpp
index 83aee360..bc7168af 100644
--- a/src/menu/event_manager.cpp
+++ b/src/menu/event_manager.cpp
@@ -37,7 +37,7 @@ namespace usdx
 
 	EventManager::~EventManager(void)
 	{
-		boost::mutex::scoped_lock lock(mutex);
+		boost::unique_lock<boost::shared_mutex> lock(mutex);
 
 		while (waiting > 0) {
 			--waiting;
@@ -57,7 +57,7 @@ namespace usdx
 
 	void EventManager::add_event(const SDL_Event& event)
 	{
-		boost::mutex::scoped_lock lock(mutex);
+		boost::unique_lock<boost::shared_mutex> lock(mutex);
 
 		not_full.wait(lock, boost::bind(&EventManager::is_not_full, this));
 
@@ -70,7 +70,7 @@ namespace usdx
 
 	void EventManager::get_next_event(SDL_Event& event)
 	{
-		boost::mutex::scoped_lock lock(mutex);
+		boost::unique_lock<boost::shared_mutex> lock(mutex);
 
 		not_empty.wait(lock, boost::bind(&EventManager::is_not_empty, this));
 
@@ -84,7 +84,7 @@ namespace usdx
 
 	bool EventManager::available(void)
 	{
-		boost::mutex::scoped_lock lock(mutex);
+		boost::shared_lock<boost::shared_mutex> lock(mutex);
 		return waiting < buffer.capacity();
 	}
 
diff --git a/src/menu/event_manager.hpp b/src/menu/event_manager.hpp
index db588b9f..6fd37c1a 100644
--- a/src/menu/event_manager.hpp
+++ b/src/menu/event_manager.hpp
@@ -32,7 +32,7 @@
 #include <boost/progress.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/thread/condition.hpp>
-#include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
 #include <boost/thread/thread.hpp>
 #include <boost/signals2.hpp>
 
@@ -74,7 +74,7 @@ namespace usdx
 		 * Mutex to guaranty the mutual exclusion between the multiple
 		 * threads.
 		 */
-		boost::mutex mutex;
+		mutable boost::shared_mutex mutex;
 
 		boost::condition not_empty;
 		boost::condition not_full;
diff --git a/src/menu/software_mouse_pointer.hpp b/src/menu/software_mouse_pointer.hpp
index da6d7601..29bc2995 100644
--- a/src/menu/software_mouse_pointer.hpp
+++ b/src/menu/software_mouse_pointer.hpp
@@ -32,7 +32,6 @@
 #include "timer.hpp"
 
 #include <boost/signals2.hpp>
-#include <boost/thread/mutex.hpp>
 #include <GL/gl.h>
 
 namespace usdx
diff --git a/src/menu/text.cpp b/src/menu/text.cpp
index 88af9076..9cfc8218 100644
--- a/src/menu/text.cpp
+++ b/src/menu/text.cpp
@@ -69,6 +69,7 @@ namespace usdx
 
 	void Text::realign(void)
 	{
+		boost::shared_lock<boost::shared_mutex> lock(font_mutex);
 		Rectangle<int> bbox = makeRect(font->BBox(text.c_str()));
 		bbox.get_point1().set_y(font->Ascender());
 		bbox.get_point2().set_y(font->Descender());
@@ -79,7 +80,7 @@ namespace usdx
 	{
 		DrawableControl::draw();
 
-		boost::mutex::scoped_lock lock(font_mutex);
+		boost::shared_lock<boost::shared_mutex> lock(font_mutex);
 		glTranslatef(offset.get_x(), offset.get_y(), 0.0f);
 
 		// invert y axis, text is drawn using window orientation (origin is
@@ -90,25 +91,33 @@ namespace usdx
 
 	void Text::set_font_size(unsigned int value)
 	{
-		boost::mutex::scoped_lock lock(font_mutex);
-		font->FaceSize(value);
+		{
+			boost::unique_lock<boost::shared_mutex> lock(font_mutex);
+			font->FaceSize(value);
+		}
+
 		realign();
 	}
 
 	unsigned int Text::get_font_size(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(font_mutex);
 		return font->FaceSize();
 	}
 
 	void Text::set_text(const std::string value)
 	{
-		boost::mutex::scoped_lock lock(font_mutex);
-		text = value;
+		{
+			boost::unique_lock<boost::shared_mutex> lock(font_mutex);
+			text = value;
+		}
+
 		realign();
 	}
 
 	std::string Text::get_text(void) const
 	{
+		boost::shared_lock<boost::shared_mutex> lock(font_mutex);
 		return text;
 	}
 
diff --git a/src/menu/text.hpp b/src/menu/text.hpp
index 064763e3..d32a2523 100644
--- a/src/menu/text.hpp
+++ b/src/menu/text.hpp
@@ -27,7 +27,7 @@
 
 #include <string>
 #include <ftgl.h>
-#include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
 #include <log4cpp/Category.hh>
 
 #include "drawable_control.hpp"
@@ -70,7 +70,7 @@ namespace usdx
 		FTFont *font;
 		const VerticalTextAlignment *valign;
 
-		boost::mutex font_mutex;
+		mutable boost::shared_mutex font_mutex;
 
 		/**
 		 * This function is used to recalculate the offset of the drawn
-- 
cgit v1.2.3