aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/Data.MySQL/MySQLDataStore.cs129
1 files changed, 64 insertions, 65 deletions
diff --git a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
index 6523105..7ac4bde 100644
--- a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
+++ b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
@@ -50,6 +50,7 @@ namespace OpenSim.Framework.Data.MySQL
50 private const string m_landAccessListSelect = "select * from landaccesslist"; 50 private const string m_landAccessListSelect = "select * from landaccesslist";
51 51
52 private DataSet m_dataSet; 52 private DataSet m_dataSet;
53 private static object DBAccessLock = new object(); // Trying to use a static object because there might be other regions that keep modifying table
53 private MySqlDataAdapter m_primDataAdapter; 54 private MySqlDataAdapter m_primDataAdapter;
54 private MySqlDataAdapter m_shapeDataAdapter; 55 private MySqlDataAdapter m_shapeDataAdapter;
55 private MySqlDataAdapter m_itemsDataAdapter; 56 private MySqlDataAdapter m_itemsDataAdapter;
@@ -103,7 +104,7 @@ namespace OpenSim.Framework.Data.MySQL
103 104
104 TestTables(m_connection); 105 TestTables(m_connection);
105 106
106 lock (m_dataSet) 107 lock (DBAccessLock)
107 { 108 {
108 m_primTable = createPrimTable(); 109 m_primTable = createPrimTable();
109 m_dataSet.Tables.Add(m_primTable); 110 m_dataSet.Tables.Add(m_primTable);
@@ -142,7 +143,7 @@ namespace OpenSim.Framework.Data.MySQL
142 143
143 public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) 144 public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID)
144 { 145 {
145 lock (m_dataSet) 146 lock (DBAccessLock)
146 { 147 {
147 foreach (SceneObjectPart prim in obj.Children.Values) 148 foreach (SceneObjectPart prim in obj.Children.Values)
148 { 149 {
@@ -169,7 +170,7 @@ namespace OpenSim.Framework.Data.MySQL
169 DataTable shapes = m_shapeTable; 170 DataTable shapes = m_shapeTable;
170 171
171 string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'"; 172 string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'";
172 lock (m_dataSet) 173 lock (DBAccessLock)
173 { 174 {
174 DataRow[] primRows = prims.Select(selectExp); 175 DataRow[] primRows = prims.Select(selectExp);
175 foreach (DataRow row in primRows) 176 foreach (DataRow row in primRows)
@@ -225,7 +226,7 @@ namespace OpenSim.Framework.Data.MySQL
225 string byRegion = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'"; 226 string byRegion = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'";
226 string orderByParent = "ParentID ASC"; 227 string orderByParent = "ParentID ASC";
227 228
228 lock (m_dataSet) 229 lock (DBAccessLock)
229 { 230 {
230 DataRow[] primsForRegion = prims.Select(byRegion, orderByParent); 231 DataRow[] primsForRegion = prims.Select(byRegion, orderByParent);
231 MainLog.Instance.Verbose("DATASTORE", 232 MainLog.Instance.Verbose("DATASTORE",
@@ -335,7 +336,7 @@ namespace OpenSim.Framework.Data.MySQL
335 MainLog.Instance.Verbose("DATASTORE", "Storing terrain revision r" + revision.ToString()); 336 MainLog.Instance.Verbose("DATASTORE", "Storing terrain revision r" + revision.ToString());
336 337
337 DataTable terrain = m_dataSet.Tables["terrain"]; 338 DataTable terrain = m_dataSet.Tables["terrain"];
338 lock (m_dataSet) 339 lock (DBAccessLock)
339 { 340 {
340 MySqlCommand cmd = new MySqlCommand("insert into terrain(RegionUUID, Revision, Heightfield)" + 341 MySqlCommand cmd = new MySqlCommand("insert into terrain(RegionUUID, Revision, Heightfield)" +
341 " values(?RegionUUID, ?Revision, ?Heightfield)", m_connection); 342 " values(?RegionUUID, ?Revision, ?Heightfield)", m_connection);
@@ -396,7 +397,7 @@ namespace OpenSim.Framework.Data.MySQL
396 397
397 public void RemoveLandObject(LLUUID globalID) 398 public void RemoveLandObject(LLUUID globalID)
398 { 399 {
399 lock (m_dataSet) 400 lock (DBAccessLock)
400 { 401 {
401 using (MySqlCommand cmd = new MySqlCommand("delete from land where UUID=?UUID", m_connection)) 402 using (MySqlCommand cmd = new MySqlCommand("delete from land where UUID=?UUID", m_connection))
402 { 403 {
@@ -418,62 +419,47 @@ namespace OpenSim.Framework.Data.MySQL
418 { 419 {
419 MainLog.Instance.Verbose("DATASTORE", "Tedds temp fix: Waiting 3 seconds for stuff to catch up. (Someone please fix! :))"); 420 MainLog.Instance.Verbose("DATASTORE", "Tedds temp fix: Waiting 3 seconds for stuff to catch up. (Someone please fix! :))");
420 System.Threading.Thread.Sleep(3000); 421 System.Threading.Thread.Sleep(3000);
421 422
422 int loopCount = 0; 423 lock (DBAccessLock)
423 while (true)
424 { 424 {
425 loopCount++; 425 DataTable land = m_landTable;
426 try 426 DataTable landaccesslist = m_landAccessListTable;
427 {
428 lock (m_dataSet)
429 {
430 DataTable land = m_landTable;
431 DataTable landaccesslist = m_landAccessListTable;
432
433 DataRow landRow = land.Rows.Find(Util.ToRawUuidString(parcel.landData.globalID));
434 if (landRow == null)
435 {
436 landRow = land.NewRow();
437 fillLandRow(landRow, parcel.landData, regionUUID);
438 land.Rows.Add(landRow);
439 }
440 else
441 {
442 fillLandRow(landRow, parcel.landData, regionUUID);
443 }
444 427
445 using ( 428 DataRow landRow = land.Rows.Find(Util.ToRawUuidString(parcel.landData.globalID));
446 MySqlCommand cmd = 429 if (landRow == null)
447 new MySqlCommand("delete from landaccesslist where LandUUID=?LandUUID", m_connection)) 430 {
448 { 431 landRow = land.NewRow();
449 cmd.Parameters.Add( 432 fillLandRow(landRow, parcel.landData, regionUUID);
450 new MySqlParameter("?LandUUID", Util.ToRawUuidString(parcel.landData.globalID))); 433 land.Rows.Add(landRow);
451 cmd.ExecuteNonQuery(); 434 }
452 } 435 else
436 {
437 fillLandRow(landRow, parcel.landData, regionUUID);
438 }
453 439
454 foreach (ParcelManager.ParcelAccessEntry entry in parcel.landData.parcelAccessList) 440 using (
455 { 441 MySqlCommand cmd =
456 DataRow newAccessRow = landaccesslist.NewRow(); 442 new MySqlCommand("delete from landaccesslist where LandUUID=?LandUUID", m_connection))
457 fillLandAccessRow(newAccessRow, entry, parcel.landData.globalID); 443 {
458 landaccesslist.Rows.Add(newAccessRow); 444 cmd.Parameters.Add(new MySqlParameter("?LandUUID", Util.ToRawUuidString(parcel.landData.globalID)));
459 } 445 cmd.ExecuteNonQuery();
460 }
461 Commit();
462 break;
463 } 446 }
464 catch (Exception ex) 447
448 foreach (ParcelManager.ParcelAccessEntry entry in parcel.landData.parcelAccessList)
465 { 449 {
466 System.Console.WriteLine("Tedds temp fix exception, will repeat taks: " + ex.ToString()); 450 DataRow newAccessRow = landaccesslist.NewRow();
467 if (loopCount > 3) 451 fillLandAccessRow(newAccessRow, entry, parcel.landData.globalID);
468 throw (ex); 452 landaccesslist.Rows.Add(newAccessRow);
469 } 453 }
454
455 Commit_NoLock();
470 } 456 }
471 } 457 }
472 458
473 public List<LandData> LoadLandObjects(LLUUID regionUUID) 459 public List<LandData> LoadLandObjects(LLUUID regionUUID)
474 { 460 {
475 List<LandData> landDataForRegion = new List<LandData>(); 461 List<LandData> landDataForRegion = new List<LandData>();
476 lock (m_dataSet) 462 lock (DBAccessLock)
477 { 463 {
478 DataTable land = m_landTable; 464 DataTable land = m_landTable;
479 DataTable landaccesslist = m_landAccessListTable; 465 DataTable landaccesslist = m_landAccessListTable;
@@ -535,24 +521,37 @@ namespace OpenSim.Framework.Data.MySQL
535 m_connection.Open(); 521 m_connection.Open();
536 } 522 }
537 523
538 lock (m_dataSet) 524 lock (DBAccessLock)
539 { 525 {
540 // DisplayDataSet(m_dataSet, "Region DataSet"); 526 // Moved code to own sub that can be called directly by "StoreLandObject".
527 // Problem is that:
528 // - StoreLandObject locks
529 // - Some other function waits for lock
530 // - StoreLandObject releases lock
531 // - Other function obtains lock
532 // - StoreLandObject calls Commit that tries to take lock back
533 // - When StoreLandObject's Commit finally gets lock the table has been changed and we crash
534 Commit_NoLock();
535 }
536 }
541 537
542 m_primDataAdapter.Update(m_primTable); 538 private void Commit_NoLock()
543 m_shapeDataAdapter.Update(m_shapeTable); 539 {
544 540 // DisplayDataSet(m_dataSet, "Region DataSet");
545 if (persistPrimInventories)
546 {
547 m_itemsDataAdapter.Update(m_itemsTable);
548 }
549
550 m_terrainDataAdapter.Update(m_terrainTable);
551 m_landDataAdapter.Update(m_landTable);
552 m_landAccessListDataAdapter.Update(m_landAccessListTable);
553 541
554 m_dataSet.AcceptChanges(); 542 m_primDataAdapter.Update(m_primTable);
543 m_shapeDataAdapter.Update(m_shapeTable);
544
545 if (persistPrimInventories)
546 {
547 m_itemsDataAdapter.Update(m_itemsTable);
555 } 548 }
549
550 m_terrainDataAdapter.Update(m_terrainTable);
551 m_landDataAdapter.Update(m_landTable);
552 m_landAccessListDataAdapter.Update(m_landAccessListTable);
553
554 m_dataSet.AcceptChanges();
556 } 555 }
557 556
558 public void Shutdown() 557 public void Shutdown()
@@ -1230,7 +1229,7 @@ namespace OpenSim.Framework.Data.MySQL
1230 1229
1231 // For now, we're just going to crudely remove all the previous inventory items 1230 // For now, we're just going to crudely remove all the previous inventory items
1232 // no matter whether they have changed or not, and replace them with the current set. 1231 // no matter whether they have changed or not, and replace them with the current set.
1233 lock (m_dataSet) 1232 lock (DBAccessLock)
1234 { 1233 {
1235 RemoveItems(primID); 1234 RemoveItems(primID);
1236 1235