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

Commit885cd3e

Browse files
Fix memory leak in finalizer
- `finalizer` was leaking `_pendingArgs` (global memory) when the callto `Py_AddPendingCall` was unsuccessful.- Changing `lock` for `Monitor.TryEnter` at `AddPendingCollect()` sothreads don't block each other.
1 parentf83c884 commit885cd3e

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

‎src/runtime/finalizer.cs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct PendingArgs
4141
privateConcurrentQueue<IPyDisposable>_objQueue=newConcurrentQueue<IPyDisposable>();
4242
privatebool_pending=false;
4343
privatereadonlyobject_collectingLock=newobject();
44-
privateIntPtr_pendingArgs;
44+
privateIntPtr_pendingArgs=IntPtr.Zero;
4545

4646
#region FINALIZER_CHECK
4747

@@ -128,7 +128,7 @@ internal void AddFinalizedObject(IPyDisposable obj)
128128
_objQueue.Enqueue(obj);
129129
}
130130
GC.ReRegisterForFinalize(obj);
131-
if(_objQueue.Count>=Threshold)
131+
if(!_pending&&_objQueue.Count>=Threshold)
132132
{
133133
AddPendingCollect();
134134
}
@@ -164,26 +164,28 @@ internal static void Shutdown()
164164

165165
privatevoidAddPendingCollect()
166166
{
167-
if(_pending)
167+
if(Monitor.TryEnter(_collectingLock))
168168
{
169-
return;
170-
}
171-
lock(_collectingLock)
172-
{
173-
if(_pending)
169+
try
174170
{
175-
return;
171+
if(!_pending)
172+
{
173+
_pending=true;
174+
varargs=newPendingArgs{cancelled=false};
175+
_pendingArgs=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PendingArgs)));
176+
Marshal.StructureToPtr(args,_pendingArgs,false);
177+
IntPtrfunc=Marshal.GetFunctionPointerForDelegate(_collectAction);
178+
if(Runtime.Py_AddPendingCall(func,_pendingArgs)!=0)
179+
{
180+
// Full queue, append next time
181+
FreePendingArgs();
182+
_pending=false;
183+
}
184+
}
176185
}
177-
_pending=true;
178-
varargs=newPendingArgs(){cancelled=false};
179-
IntPtrp=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PendingArgs)));
180-
Marshal.StructureToPtr(args,p,false);
181-
_pendingArgs=p;
182-
IntPtrfunc=Marshal.GetFunctionPointerForDelegate(_collectAction);
183-
if(Runtime.Py_AddPendingCall(func,p)!=0)
186+
finally
184187
{
185-
// Full queue, append next time
186-
_pending=false;
188+
Monitor.Exit(_collectingLock);
187189
}
188190
}
189191
}
@@ -205,8 +207,8 @@ private static int OnPendingCollect(IntPtr arg)
205207
}
206208
finally
207209
{
210+
Instance.FreePendingArgs();
208211
Instance.ResetPending();
209-
Marshal.FreeHGlobal(arg);
210212
}
211213
return0;
212214
}
@@ -244,12 +246,20 @@ private void DisposeAll()
244246
}
245247
}
246248

249+
privatevoidFreePendingArgs()
250+
{
251+
if(_pendingArgs!=IntPtr.Zero)
252+
{
253+
Marshal.FreeHGlobal(_pendingArgs);
254+
_pendingArgs=IntPtr.Zero;
255+
}
256+
}
257+
247258
privatevoidResetPending()
248259
{
249260
lock(_collectingLock)
250261
{
251262
_pending=false;
252-
_pendingArgs=IntPtr.Zero;
253263
}
254264
}
255265

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp