Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita4bb82d

Browse files
committed
Add pending marker
1 parentf836ffa commita4bb82d

File tree

1 file changed

+60
-6
lines changed

1 file changed

+60
-6
lines changed

‎src/runtime/finalizer.cs

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
usingSystem;
22
usingSystem.Collections.Concurrent;
33
usingSystem.Collections.Generic;
4+
usingSystem.Diagnostics;
45
usingSystem.Linq;
56
usingSystem.Runtime.InteropServices;
67
usingSystem.Threading;
@@ -24,16 +25,23 @@ public class ErrorArgs : EventArgs
2425
publiceventEventHandler<CollectArgs>CollectOnce;
2526
publiceventEventHandler<ErrorArgs>ErrorHandler;
2627

27-
privateConcurrentQueue<IDisposable>_objQueue=newConcurrentQueue<IDisposable>();
28+
publicintThreshold{get;set;}
29+
publicboolEnable{get;set;}
30+
31+
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
32+
structPendingArgs
33+
{
34+
publicboolcancelled;
35+
}
2836

2937
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
3038
privatedelegateintPendingCall(IntPtrarg);
3139
privatereadonlyPendingCall_collectAction;
3240

41+
privateConcurrentQueue<IDisposable>_objQueue=newConcurrentQueue<IDisposable>();
3342
privatebool_pending=false;
3443
privatereadonlyobject_collectingLock=newobject();
35-
publicintThreshold{get;set;}
36-
publicboolEnable{get;set;}
44+
privateIntPtr_pendingArgs;
3745

3846
privateFinalizer()
3947
{
@@ -92,6 +100,23 @@ internal static void Shutdown()
92100
return;
93101
}
94102
Instance.DisposeAll();
103+
if(Thread.CurrentThread.ManagedThreadId!=Runtime.MainManagedThreadId)
104+
{
105+
if(Instance._pendingArgs==IntPtr.Zero)
106+
{
107+
Instance.ResetPending();
108+
return;
109+
}
110+
// Not in main thread just cancel the pending operation to avoid error in different domain
111+
// It will make a memory leak
112+
unsafe
113+
{
114+
PendingArgs*args=(PendingArgs*)Instance._pendingArgs;
115+
args->cancelled=true;
116+
}
117+
Instance.ResetPending();
118+
return;
119+
}
95120
Instance.CallPendingFinalizers();
96121
}
97122

@@ -108,8 +133,12 @@ private void AddPendingCollect()
108133
return;
109134
}
110135
_pending=true;
136+
varargs=newPendingArgs(){cancelled=false};
137+
IntPtrp=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PendingArgs)));
138+
Marshal.StructureToPtr(args,p,false);
139+
_pendingArgs=p;
111140
IntPtrfunc=Marshal.GetFunctionPointerForDelegate(_collectAction);
112-
if(Runtime.Py_AddPendingCall(func,IntPtr.Zero)!=0)
141+
if(Runtime.Py_AddPendingCall(func,p)!=0)
113142
{
114143
// Full queue, append next time
115144
_pending=false;
@@ -119,8 +148,24 @@ private void AddPendingCollect()
119148

120149
privatestaticintOnPendingCollect(IntPtrarg)
121150
{
122-
Instance.DisposeAll();
123-
Instance._pending=false;
151+
Debug.Assert(arg==Instance._pendingArgs);
152+
try
153+
{
154+
unsafe
155+
{
156+
PendingArgs*pendingArgs=(PendingArgs*)arg;
157+
if(pendingArgs->cancelled)
158+
{
159+
return0;
160+
}
161+
}
162+
Instance.DisposeAll();
163+
}
164+
finally
165+
{
166+
Instance.ResetPending();
167+
Marshal.FreeHGlobal(arg);
168+
}
124169
return0;
125170
}
126171

@@ -148,5 +193,14 @@ private void DisposeAll()
148193
}
149194
}
150195
}
196+
197+
privatevoidResetPending()
198+
{
199+
lock(_collectingLock)
200+
{
201+
_pending=false;
202+
_pendingArgs=IntPtr.Zero;
203+
}
204+
}
151205
}
152206
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp