summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-09-24 03:22:30 +0000
committerDavid Robillard <d@drobilla.net>2011-09-24 03:22:30 +0000
commit74a711e0d1cdb5c505a227dc9b1925657f1e778d (patch)
tree78f93b26e4154c76892cb0160414c4effbfc730e /src/server
parent2be10b0b6f2c0f01870208e9d18e5db87e5dfb88 (diff)
downloadingen-74a711e0d1cdb5c505a227dc9b1925657f1e778d.tar.gz
ingen-74a711e0d1cdb5c505a227dc9b1925657f1e778d.tar.bz2
ingen-74a711e0d1cdb5c505a227dc9b1925657f1e778d.zip
Use store lock to avoid race conditions with Get and create/delete events.
Get really shouldn't be reading the store (via ObjectSender) in the post processing thread at all, avoiding that entirely would be a better solution. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@3484 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/server')
-rw-r--r--src/server/events/CreateNode.cpp9
-rw-r--r--src/server/events/CreateNode.hpp9
-rw-r--r--src/server/events/CreatePort.cpp9
-rw-r--r--src/server/events/CreatePort.hpp11
-rw-r--r--src/server/events/Delete.cpp4
-rw-r--r--src/server/events/Delete.hpp2
-rw-r--r--src/server/events/Get.cpp5
-rw-r--r--src/server/events/Get.hpp11
8 files changed, 49 insertions, 11 deletions
diff --git a/src/server/events/CreateNode.cpp b/src/server/events/CreateNode.cpp
index 01d4f285..39d5f86d 100644
--- a/src/server/events/CreateNode.cpp
+++ b/src/server/events/CreateNode.cpp
@@ -57,6 +57,7 @@ CreateNode::CreateNode(
, _node_already_exists(false)
, _polyphonic(false)
, _properties(properties)
+ , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK)
{
const Resource::Properties::const_iterator p = properties.find(
engine.world()->uris()->ingen_polyphonic);
@@ -68,6 +69,8 @@ CreateNode::CreateNode(
void
CreateNode::pre_process()
{
+ _lock.acquire();
+
if (_engine.engine_store()->find_object(_path) != NULL) {
_node_already_exists = true;
QueuedEvent::pre_process();
@@ -117,8 +120,10 @@ CreateNode::execute(ProcessContext& context)
void
CreateNode::post_process()
{
- if (!_request)
+ if (!_request) {
+ _lock.release();
return;
+ }
string msg;
if (_node_already_exists) {
@@ -138,6 +143,8 @@ CreateNode::post_process()
_request->respond_ok();
_engine.broadcaster()->send_object(_node, true); // yes, send ports
}
+
+ _lock.release();
}
} // namespace Server
diff --git a/src/server/events/CreateNode.hpp b/src/server/events/CreateNode.hpp
index bbaf830b..47f86622 100644
--- a/src/server/events/CreateNode.hpp
+++ b/src/server/events/CreateNode.hpp
@@ -19,9 +19,13 @@
#define INGEN_EVENTS_CREATENODE_HPP
#include <string>
-#include "QueuedEvent.hpp"
+
+#include <glibmm/thread.h>
+
#include "ingen/Resource.hpp"
+#include "QueuedEvent.hpp"
+
namespace Ingen {
namespace Server {
@@ -61,7 +65,8 @@ private:
bool _node_already_exists;
bool _polyphonic;
- Resource::Properties _properties;
+ Resource::Properties _properties;
+ Glib::RWLock::WriterLock _lock;
};
} // namespace Server
diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp
index 4541892b..fdf675a6 100644
--- a/src/server/events/CreatePort.cpp
+++ b/src/server/events/CreatePort.cpp
@@ -58,6 +58,7 @@ CreatePort::CreatePort(
, _patch_port(NULL)
, _driver_port(NULL)
, _properties(properties)
+ , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK)
{
/* This is blocking because of the two different sets of Patch ports, the array used in the
* audio thread (inherited from NodeImpl), and the arrays used in the pre processor thread.
@@ -74,6 +75,8 @@ CreatePort::CreatePort(
void
CreatePort::pre_process()
{
+ _lock.acquire();
+
if (_error == UNKNOWN_TYPE || _engine.engine_store()->find_object(_path)) {
QueuedEvent::pre_process();
return;
@@ -161,8 +164,10 @@ CreatePort::execute(ProcessContext& context)
void
CreatePort::post_process()
{
- if (!_request)
+ if (!_request) {
+ _lock.release();
return;
+ }
string msg;
switch (_error) {
@@ -183,6 +188,8 @@ CreatePort::post_process()
_request->respond_error(msg);
break;
}
+
+ _lock.release();
}
} // namespace Server
diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp
index ae44e2f1..e3c13fa1 100644
--- a/src/server/events/CreatePort.hpp
+++ b/src/server/events/CreatePort.hpp
@@ -18,12 +18,16 @@
#ifndef INGEN_EVENTS_CREATEPORT_HPP
#define INGEN_EVENTS_CREATEPORT_HPP
-#include "QueuedEvent.hpp"
-#include "raul/Path.hpp"
+#include <glibmm/thread.h>
+
#include "raul/Array.hpp"
+#include "raul/Path.hpp"
+
#include "ingen/PortType.hpp"
#include "ingen/Resource.hpp"
+#include "QueuedEvent.hpp"
+
namespace Ingen {
namespace Server {
@@ -71,7 +75,8 @@ private:
DriverPort* _driver_port; ///< Driver (eg Jack) port if this is a toplevel port
bool _succeeded;
- Resource::Properties _properties;
+ Resource::Properties _properties;
+ Glib::RWLock::WriterLock _lock;
};
} // namespace Server
diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp
index b1dc1558..4f13cd97 100644
--- a/src/server/events/Delete.cpp
+++ b/src/server/events/Delete.cpp
@@ -50,6 +50,7 @@ Delete::Delete(Engine& engine,
, _ports_array(NULL)
, _compiled_patch(NULL)
, _disconnect_event(NULL)
+ , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK)
{
assert(request);
assert(request->source());
@@ -71,6 +72,8 @@ Delete::pre_process()
return;
}
+ _lock.acquire();
+
_removed_bindings = _engine.control_bindings()->remove(_path);
_store_iterator = _engine.engine_store()->find(_path);
@@ -170,6 +173,7 @@ Delete::execute(ProcessContext& context)
void
Delete::post_process()
{
+ _lock.release();
_removed_bindings.reset();
if (!Raul::Path::is_path(_uri)
diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp
index ba256d87..d865ca11 100644
--- a/src/server/events/Delete.hpp
+++ b/src/server/events/Delete.hpp
@@ -86,6 +86,8 @@ private:
SharedPtr<ControlBindings::Bindings> _removed_bindings;
SharedPtr< Raul::Table<Raul::Path, SharedPtr<GraphObject> > > _removed_table;
+
+ Glib::RWLock::WriterLock _lock;
};
} // namespace Server
diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp
index 058f0b63..61fa6ffc 100644
--- a/src/server/events/Get.cpp
+++ b/src/server/events/Get.cpp
@@ -42,12 +42,15 @@ Get::Get(
, _uri(uri)
, _object(NULL)
, _plugin(NULL)
+ , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK)
{
}
void
Get::pre_process()
{
+ _lock.acquire();
+
if (_uri == "ingen:plugins") {
_plugins = _engine.node_factory()->plugins();
} else if (Path::is_valid(_uri.str())) {
@@ -76,6 +79,8 @@ Get::post_process()
} else {
_request->respond_error("Unable to find client to send object.");
}
+
+ _lock.release();
}
} // namespace Server
diff --git a/src/server/events/Get.hpp b/src/server/events/Get.hpp
index ed68e3c0..b5f1ed4d 100644
--- a/src/server/events/Get.hpp
+++ b/src/server/events/Get.hpp
@@ -18,6 +18,8 @@
#ifndef INGEN_EVENTS_GET_HPP
#define INGEN_EVENTS_GET_HPP
+#include <glibmm/thread.h>
+
#include "QueuedEvent.hpp"
#include "NodeFactory.hpp"
#include "types.hpp"
@@ -47,10 +49,11 @@ public:
void post_process();
private:
- const Raul::URI _uri;
- GraphObjectImpl* _object;
- const PluginImpl* _plugin;
- NodeFactory::Plugins _plugins;
+ const Raul::URI _uri;
+ const GraphObjectImpl* _object;
+ const PluginImpl* _plugin;
+ NodeFactory::Plugins _plugins;
+ Glib::RWLock::ReaderLock _lock;
};
} // namespace Server