@@ -23,6 +23,7 @@ public sealed class FileStream_NET : Stream
23
23
private int _readPos ;
24
24
private int _readLen ;
25
25
26
+ #if false
26
27
public FileStream_NET ( AL_SafeFileHandle handle , FileAccess access , byte [ ] buffer , int bufferSize )
27
28
{
28
29
ValidateHandle ( handle , access ) ;
@@ -45,6 +46,7 @@ public FileStream_NET(AL_SafeFileHandle handle, FileAccess access, byte[] buffer
45
46
46
47
_fileHandle = handle ;
47
48
}
49
+ #endif
48
50
49
51
public FileStream_NET ( string path , FileMode mode , FileAccess access , FileShare share , byte [ ] buffer , int bufferSize )
50
52
: this ( path , mode , access , share , buffer , bufferSize , FileOptions . None )
@@ -56,13 +58,17 @@ public FileStream_NET(string path, FileMode mode, FileAccess access, FileShare s
56
58
{
57
59
}
58
60
61
+ // Disable because we don't need it and we don't want it running when we're in a weird state and _fileHandle
62
+ // could be null etc.
63
+ #if false
59
64
~ FileStream_NET ( )
60
65
{
61
66
// Preserved for compatibility since FileStream has defined a
62
67
// finalizer in past releases and derived classes may depend
63
68
// on Dispose(false) call.
64
69
Dispose ( false ) ;
65
70
}
71
+ #endif
66
72
67
73
private FileStream_NET ( string path , FileMode mode , FileAccess access , FileShare share , byte [ ] buffer , int bufferSize , FileOptions options , long preallocationSize )
68
74
{
@@ -75,10 +81,14 @@ private FileStream_NET(string path, FileMode mode, FileAccess access, FileShare
75
81
76
82
_access = access ;
77
83
78
- _fileHandle = AL_SafeFileHandle . Open ( fullPath , mode , access , share , options , preallocationSize ) ;
79
-
80
84
try
81
85
{
86
+ /*
87
+ IMPORTANT: This MUST go inside the try block as it can throw!
88
+ The modern .NET version, through a complicated chain of logic, avoids this problem, but we don't.
89
+ The finalizer will run and _fileHandle will be null and then we crash the whole app.
90
+ */
91
+ _fileHandle = AL_SafeFileHandle . Open ( fullPath , mode , access , share , options , preallocationSize ) ;
82
92
if ( mode == FileMode . Append && CanSeek )
83
93
{
84
94
_appendStart = _filePosition = GetLengthCore ;
@@ -92,8 +102,12 @@ private FileStream_NET(string path, FileMode mode, FileAccess access, FileShare
92
102
{
93
103
// If anything goes wrong while setting up the stream, make sure we deterministically dispose
94
104
// of the opened handle.
95
- _fileHandle . Dispose ( ) ;
96
- _fileHandle = null ! ;
105
+ _fileHandle ? . Dispose ( ) ;
106
+ // If we want to enable the ctor that takes a file handle, we need to re-enable this and then re-do
107
+ // the logic to expect that this could null in the finalizer if we enable that too.
108
+ #if false
109
+ _fileHandle = null ;
110
+ #endif
97
111
throw ;
98
112
}
99
113
}
0 commit comments