[Mono-devel-list] marshal.c assertion failed.
Scott Mohekey
scott.mohekey at telogis.com
Wed Feb 23 21:02:27 EST 2005
Attached is a patch to keep the reference to the delegates. Also an
improvement on the former patch which only changes domains when needed.
Scott
Scott Mohekey wrote:
> It seems I spoke too soon.
>
> Now I get the following assertion:
>
> Unmanaged code called delegate of type
> System.Drawing.GDIPlus/GdiPlusStreamHelper.StreamPutBytesImpl which
> was already garbage collected.
> See http://www.go-mono.com/delegate.html for an explanation and ways
> to fix this.
> aborting...
>
> However, I think this could be due to GdiPlusStreamHelper in
> gdipFunctions.cs not keeping references to the delegates. I'll check
> this now.
>
> Scott.
>
Index: mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs
===================================================================
--- mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs
(revision 41126)
+++ mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs (working
copy)
@@ -1493,6 +1493,11 @@
internal class GdiPlusStreamHelper
{
public Stream stream;
+ private StreamGetBytesDelegate getBytesDelegate
= null;
+ private StreamSeekDelegate seekDelegate = null;
+ private StreamPutBytesDelegate putBytesDelegate
= null;
+ private StreamCloseDelegate closeDelegate = null;
+ private StreamSizeDelegate sizeDelegate = null;
public GdiPlusStreamHelper (Stream s)
{
@@ -1536,8 +1541,13 @@
public StreamGetBytesDelegate GetBytesDelegate {
get {
- if (stream != null &&
stream.CanRead)
- return new
StreamGetBytesDelegate (StreamGetBytesImpl);
+ if (stream != null &&
stream.CanRead) {
+ lock (this) {
+ if (null ==
getBytesDelegate)
+
getBytesDelegate = new StreamGetBytesDelegate (StreamGetBytesImpl);
+ }
+ return getBytesDelegate;
+ }
return null;
}
}
@@ -1560,8 +1570,13 @@
public StreamSeekDelegate SeekDelegate {
get {
- if (stream != null &&
stream.CanSeek)
- return new
StreamSeekDelegate (StreamSeekImpl);
+ if (stream != null &&
stream.CanSeek) {
+ lock (this) {
+ if (null ==
seekDelegate)
+
seekDelegate = new StreamSeekDelegate (StreamSeekImpl);
+ }
+ return seekDelegate;
+ }
return null;
}
}
@@ -1576,8 +1591,13 @@
public StreamPutBytesDelegate PutBytesDelegate {
get {
- if (stream != null &&
stream.CanWrite)
- return new
StreamPutBytesDelegate (StreamPutBytesImpl);
+ if (stream != null &&
stream.CanWrite) {
+ lock (this) {
+ if (null ==
putBytesDelegate)
+
putBytesDelegate = new StreamPutBytesDelegate (StreamPutBytesImpl);
+ }
+ return putBytesDelegate;
+ }
return null;
}
}
@@ -1589,8 +1609,13 @@
public StreamCloseDelegate CloseDelegate {
get {
- if (stream != null)
- return new
StreamCloseDelegate (StreamCloseImpl);
+ if (stream != null) {
+ lock (this) {
+ if (null ==
closeDelegate)
+
closeDelegate = new StreamCloseDelegate (StreamCloseImpl);
+ }
+ return closeDelegate;
+ }
return null;
}
}
@@ -1602,8 +1627,13 @@
public StreamSizeDelegate SizeDelegate {
get {
- if (stream != null)
- return new
StreamSizeDelegate (StreamSizeImpl);
+ if (stream != null) {
+ lock (this) {
+ if (null ==
sizeDelegate)
+
sizeDelegate = new StreamSizeDelegate (StreamSizeImpl);
+ }
+ return sizeDelegate;
+ }
return null;
}
}
Index: mcs/class/System.Drawing/System.Drawing/Image.cs
===================================================================
--- mcs/class/System.Drawing/System.Drawing/Image.cs (revision 41126)
+++ mcs/class/System.Drawing/System.Drawing/Image.cs (working copy)
@@ -55,8 +55,8 @@
internal IntPtr nativeObject = IntPtr.Zero;
ColorPalette colorPalette;
+ private GDIPlus.GdiPlusStreamHelper sh;
-
// constructor
internal Image()
{
@@ -198,7 +198,7 @@
// We use a custom API for this, because there's
no easy way
// to get the Stream down to libgdiplus. So, we
wrap the stream
// with a set of delegates.
- GDIPlus.GdiPlusStreamHelper sh = new
GDIPlus.GdiPlusStreamHelper (stream);
+ sh = new GDIPlus.GdiPlusStreamHelper (stream);
IntPtr imagePtr;
Status st =
GDIPlus.GdipLoadImageFromDelegate_linux (sh.GetBytesDelegate,
sh.PutBytesDelegate,
Index: mono/mono/metadata/gc.c
===================================================================
--- mono/mono/metadata/gc.c (revision 41118)
+++ mono/mono/metadata/gc.c (working copy)
@@ -81,8 +81,19 @@
*/
if (o->vtable->klass->delegate) {
MonoDelegate* del = (MonoDelegate*)o;
- if (del->delegate_trampoline)
+ MonoDomain* domain = mono_domain_get ();
+
+ if (del->delegate_trampoline) {
+ if (domain != o->vtable->domain) {
+ mono_domain_set_internal
(o->vtable->domain);
+ }
+
mono_delegate_free_ftnptr ((MonoDelegate*)o);
+
+ if (domain != o->vtable->domain) {
+ mono_domain_set_internal (domain);
+ }
+ }
return;
}
if (o->vtable->klass == mono_get_thread_class ())
More information about the Mono-devel-list
mailing list