From da5fd53702ce97d13da2cb50da0753d507e6c11b Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 18:39:23 +0300 Subject: [PATCH] Fixed problem with MySQL: it was possible for one thread to use an incomplete list of column names if another thread was creating the list at the same time. Now this is thread-safe. --- OpenSim/Data/MySQL/MySQLAuthenticationData.cs | 23 ++++++++++----- .../Data/MySQL/MySQLGenericTableHandler.cs | 6 ++-- OpenSim/Data/MySQL/MySQLRegionData.cs | 29 ++++++++++++------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index 8d82f61bda..664ce84f7c 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -79,14 +79,7 @@ namespace OpenSim.Data.MySQL { ret.PrincipalID = principalID; - if (m_ColumnNames == null) - { - m_ColumnNames = new List(); - - DataTable schemaTable = result.GetSchemaTable(); - foreach (DataRow row in schemaTable.Rows) - m_ColumnNames.Add(row["ColumnName"].ToString()); - } + CheckColumnNames(result); foreach (string s in m_ColumnNames) { @@ -105,6 +98,20 @@ namespace OpenSim.Data.MySQL } } + private void CheckColumnNames(IDataReader result) + { + if (m_ColumnNames != null) + return; + + List columnNames = new List(); + + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + columnNames.Add(row["ColumnName"].ToString()); + + m_ColumnNames = columnNames; + } + public bool Store(AuthenticationData data) { if (data.Data.ContainsKey("UUID")) diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 754cf725f0..da8e958b07 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -91,15 +91,17 @@ namespace OpenSim.Data.MySQL if (m_ColumnNames != null) return; - m_ColumnNames = new List(); + List columnNames = new List(); DataTable schemaTable = reader.GetSchemaTable(); foreach (DataRow row in schemaTable.Rows) { if (row["ColumnName"] != null && (!m_Fields.ContainsKey(row["ColumnName"].ToString()))) - m_ColumnNames.Add(row["ColumnName"].ToString()); + columnNames.Add(row["ColumnName"].ToString()); } + + m_ColumnNames = columnNames; } public virtual T[] Get(string field, string key) diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 948cdf330f..d1f1932dd8 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -162,17 +162,7 @@ namespace OpenSim.Data.MySQL ret.sizeX = Convert.ToInt32(result["sizeX"]); ret.sizeY = Convert.ToInt32(result["sizeY"]); - if (m_ColumnNames == null) - { - m_ColumnNames = new List(); - - DataTable schemaTable = result.GetSchemaTable(); - foreach (DataRow row in schemaTable.Rows) - { - if (row["ColumnName"] != null) - m_ColumnNames.Add(row["ColumnName"].ToString()); - } - } + CheckColumnNames(result); foreach (string s in m_ColumnNames) { @@ -202,6 +192,23 @@ namespace OpenSim.Data.MySQL return retList; } + private void CheckColumnNames(IDataReader result) + { + if (m_ColumnNames != null) + return; + + List columnNames = new List(); + + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + { + if (row["ColumnName"] != null) + columnNames.Add(row["ColumnName"].ToString()); + } + + m_ColumnNames = columnNames; + } + public bool Store(RegionData data) { if (data.Data.ContainsKey("uuid"))