Skip to content

Commit b08e9e3

Browse files
TIHanbaronfel
authored andcommitted
Move Finalize from TcImports to another object (#8251)
* Move Finalize from TcImports to another object responsible for disposing of TcImports resources * Use ResizeArray
1 parent 8c649d8 commit b08e9e3

File tree

1 file changed

+39
-21
lines changed

1 file changed

+39
-21
lines changed

src/fsharp/CompileOps.fs

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3756,6 +3756,38 @@ type TcConfigProvider =
37563756
// TcImports
37573757
//--------------------------------------------------------------------------
37583758

3759+
[<Sealed>]
3760+
type TcImportsSafeDisposal
3761+
(disposeActions: ResizeArray<unit -> unit>,
3762+
#if !NO_EXTENSIONTYPING
3763+
disposeTypeProviderActions: ResizeArray<unit -> unit>,
3764+
#endif
3765+
compilationThread: ICompilationThread) =
3766+
3767+
let mutable isDisposed = false
3768+
3769+
let dispose () =
3770+
// disposing deliberately only closes this tcImports, not the ones up the chain
3771+
isDisposed <- true
3772+
if verbose then
3773+
dprintf "disposing of TcImports, %d binaries\n" disposeActions.Count
3774+
#if !NO_EXTENSIONTYPING
3775+
let actions = disposeTypeProviderActions
3776+
if actions.Count > 0 then
3777+
compilationThread.EnqueueWork (fun _ -> for action in actions do action())
3778+
#endif
3779+
for action in disposeActions do action()
3780+
3781+
override _.Finalize() =
3782+
dispose ()
3783+
3784+
interface IDisposable with
3785+
3786+
member this.Dispose() =
3787+
if not isDisposed then
3788+
GC.SuppressFinalize this
3789+
dispose ()
3790+
37593791
#if !NO_EXTENSIONTYPING
37603792
// These are hacks in order to allow TcImports to be held as a weak reference inside a type provider.
37613793
// The reason is due to older type providers compiled using an older TypeProviderSDK, that SDK used reflection on fields and properties to determine the contract.
@@ -3800,34 +3832,24 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
38003832
let mutable dllTable: NameMap<ImportedBinary> = NameMap.empty
38013833
let mutable ccuInfos: ImportedAssembly list = []
38023834
let mutable ccuTable: NameMap<ImportedAssembly> = NameMap.empty
3803-
let mutable disposeActions = []
3835+
let disposeActions = ResizeArray()
38043836
let mutable disposed = false
38053837
let mutable ilGlobalsOpt = ilGlobalsOpt
38063838
let mutable tcGlobals = None
38073839
#if !NO_EXTENSIONTYPING
3808-
let mutable disposeTypeProviderActions = []
3840+
let disposeTypeProviderActions = ResizeArray()
38093841
let mutable generatedTypeRoots = new System.Collections.Generic.Dictionary<ILTypeRef, int * ProviderGeneratedType>()
38103842
let mutable tcImportsWeak = TcImportsWeakHack (WeakReference<_> this)
38113843
#endif
3844+
3845+
let disposal = new TcImportsSafeDisposal(disposeActions, disposeTypeProviderActions, compilationThread)
38123846

38133847
let CheckDisposed() =
38143848
if disposed then assert false
38153849

38163850
let dispose () =
38173851
CheckDisposed()
3818-
// disposing deliberately only closes this tcImports, not the ones up the chain
3819-
disposed <- true
3820-
if verbose then
3821-
dprintf "disposing of TcImports, %d binaries\n" disposeActions.Length
3822-
#if !NO_EXTENSIONTYPING
3823-
let actions = disposeTypeProviderActions
3824-
disposeTypeProviderActions <- []
3825-
if actions.Length > 0 then
3826-
compilationThread.EnqueueWork (fun _ -> for action in actions do action())
3827-
#endif
3828-
let actions = disposeActions
3829-
disposeActions <- []
3830-
for action in actions do action()
3852+
(disposal :> IDisposable).Dispose()
38313853

38323854
static let ccuHasType (ccu: CcuThunk) (nsname: string list) (tname: string) =
38333855
let matchNameSpace (entityOpt: Entity option) n =
@@ -4043,12 +4065,12 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
40434065

40444066
member private tcImports.AttachDisposeAction action =
40454067
CheckDisposed()
4046-
disposeActions <- action :: disposeActions
4068+
disposeActions.Add action
40474069

40484070
#if !NO_EXTENSIONTYPING
40494071
member private tcImports.AttachDisposeTypeProviderAction action =
40504072
CheckDisposed()
4051-
disposeTypeProviderActions <- action :: disposeTypeProviderActions
4073+
disposeTypeProviderActions.Add action
40524074
#endif
40534075

40544076
// Note: the returned binary reader is associated with the tcImports, i.e. when the tcImports are closed
@@ -4781,9 +4803,6 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
47814803
knownUnresolved
47824804
|> List.map (function UnresolvedAssemblyReference(file, originalReferences) -> file, originalReferences)
47834805
|> List.iter reportAssemblyNotResolved
4784-
4785-
override tcImports.Finalize () =
4786-
dispose ()
47874806

47884807
static member BuildNonFrameworkTcImports (ctok, tcConfigP: TcConfigProvider, tcGlobals: TcGlobals, baseTcImports, nonFrameworkReferences, knownUnresolved) =
47894808
cancellable {
@@ -4809,7 +4828,6 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
48094828
interface System.IDisposable with
48104829
member tcImports.Dispose() =
48114830
dispose ()
4812-
GC.SuppressFinalize tcImports
48134831

48144832
override tcImports.ToString() = "TcImports(...)"
48154833

0 commit comments

Comments
 (0)