Skip to content

Commit dd9550a

Browse files
authored
Prevent 503s from IIS after IISNativeApplication gets finalized (#59910)
1 parent fe21c9a commit dd9550a

File tree

2 files changed

+16
-17
lines changed

2 files changed

+16
-17
lines changed

src/Servers/IIS/IIS/src/Core/IISHttpServer.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public void Dispose()
132132
_disposed = true;
133133

134134
// Block any more calls into managed from native as we are unloading.
135-
_nativeApplication.StopCallsIntoManaged();
135+
_nativeApplication.Stop();
136136
_shutdownSignal.TrySetResult();
137137

138138
if (_httpServerHandle.IsAllocated)
@@ -141,7 +141,6 @@ public void Dispose()
141141
}
142142

143143
_memoryPool.Dispose();
144-
_nativeApplication.Dispose();
145144
}
146145

147146
[UnmanagedCallersOnly]
@@ -261,7 +260,7 @@ private static void OnRequestsDrained(IntPtr serverContext)
261260
return;
262261
}
263262

264-
server._nativeApplication.StopCallsIntoManaged();
263+
server._nativeApplication.Stop();
265264
server._shutdownSignal.TrySetResult();
266265
server._cancellationTokenRegistration.Dispose();
267266
}

src/Servers/IIS/IIS/src/Core/IISNativeApplication.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core;
66
internal sealed class IISNativeApplication
77
{
88
private readonly NativeSafeHandle _nativeApplication;
9+
private bool _hasRegisteredCallbacks;
910
private readonly object _sync = new object();
1011

1112
public IISNativeApplication(NativeSafeHandle nativeApplication)
@@ -24,14 +25,22 @@ public void StopIncomingRequests()
2425
}
2526
}
2627

27-
public void StopCallsIntoManaged()
28+
public void Stop()
2829
{
2930
lock (_sync)
3031
{
31-
if (!_nativeApplication.IsInvalid)
32+
if (_nativeApplication.IsInvalid)
33+
{
34+
return;
35+
}
36+
37+
if (_hasRegisteredCallbacks)
3238
{
3339
NativeMethods.HttpStopCallsIntoManaged(_nativeApplication);
3440
}
41+
42+
_nativeApplication.Dispose();
43+
GC.SuppressFinalize(this);
3544
}
3645
}
3746

@@ -44,6 +53,8 @@ public unsafe void RegisterCallbacks(
4453
IntPtr pvRequestContext,
4554
IntPtr pvShutdownContext)
4655
{
56+
_hasRegisteredCallbacks = true;
57+
4758
NativeMethods.HttpRegisterCallbacks(
4859
_nativeApplication,
4960
requestCallback,
@@ -55,20 +66,9 @@ public unsafe void RegisterCallbacks(
5566
pvShutdownContext);
5667
}
5768

58-
public void Dispose()
59-
{
60-
lock (_sync)
61-
{
62-
GC.SuppressFinalize(this);
63-
64-
// Don't need to await here because pinvokes should never been called after disposing the safe handle.
65-
_nativeApplication.Dispose();
66-
}
67-
}
68-
6969
~IISNativeApplication()
7070
{
7171
// If this finalize is invoked, try our best to block all calls into managed.
72-
StopCallsIntoManaged();
72+
Stop();
7373
}
7474
}

0 commit comments

Comments
 (0)