aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-08-22 23:04:17 +0100
committerJustin Clark-Casey (justincc)2012-08-22 23:04:17 +0100
commit1369058280c4cf399d46df1508b80cad99f1247e (patch)
treee6f267cd79312d745f6506e9872c021b4dcb2ff0 /OpenSim/Region
parentBulletSim: update DLLs and SOs to eliminate terrain update crash which manife... (diff)
downloadopensim-SC-1369058280c4cf399d46df1508b80cad99f1247e.zip
opensim-SC-1369058280c4cf399d46df1508b80cad99f1247e.tar.gz
opensim-SC-1369058280c4cf399d46df1508b80cad99f1247e.tar.bz2
opensim-SC-1369058280c4cf399d46df1508b80cad99f1247e.tar.xz
Lock disposal of separate gdi+ objects under different threads since this prevents malloc heap corruption seen under Ubuntu 10.04.1 and 11.04 - probably a libcairo issue
In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously, the native malloc heap can become corrupted, possibly due to a double free(). This may be due to bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed under lock.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs68
1 files changed, 42 insertions, 26 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index ca320e1..c48a703 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -308,36 +308,44 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
308 308
309 try 309 try
310 { 310 {
311 if (alpha == 256) 311 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
312 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); 312 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
313 else 313 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
314 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); 314 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
315 315 // under lock.
316 graph = Graphics.FromImage(bitmap); 316 lock (this)
317
318 // this is really just to save people filling the
319 // background color in their scripts, only do when fully opaque
320 if (alpha >= 255)
321 { 317 {
322 using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) 318 if (alpha == 256)
319 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
320 else
321 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
322
323 graph = Graphics.FromImage(bitmap);
324
325 // this is really just to save people filling the
326 // background color in their scripts, only do when fully opaque
327 if (alpha >= 255)
323 { 328 {
324 graph.FillRectangle(bgFillBrush, 0, 0, width, height); 329 using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
330 {
331 graph.FillRectangle(bgFillBrush, 0, 0, width, height);
332 }
325 } 333 }
326 } 334
327 335 for (int w = 0; w < bitmap.Width; w++)
328 for (int w = 0; w < bitmap.Width; w++)
329 {
330 if (alpha <= 255)
331 { 336 {
332 for (int h = 0; h < bitmap.Height; h++) 337 if (alpha <= 255)
333 { 338 {
334 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); 339 for (int h = 0; h < bitmap.Height; h++)
340 {
341 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
342 }
335 } 343 }
336 } 344 }
345
346 GDIDraw(data, graph, altDataDelim);
337 } 347 }
338 348
339 GDIDraw(data, graph, altDataDelim);
340
341 byte[] imageJ2000 = new byte[0]; 349 byte[] imageJ2000 = new byte[0];
342 350
343 try 351 try
@@ -355,11 +363,19 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
355 } 363 }
356 finally 364 finally
357 { 365 {
358 if (graph != null) 366 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
359 graph.Dispose(); 367 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
360 368 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
361 if (bitmap != null) 369 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
362 bitmap.Dispose(); 370 // under lock.
371 lock (this)
372 {
373 if (graph != null)
374 graph.Dispose();
375
376 if (bitmap != null)
377 bitmap.Dispose();
378 }
363 } 379 }
364 } 380 }
365 381