Undesired handle inheritance (SECURITY_ATTRIBUTES bInheritHandle)
I've noticed that AlphaFS does not include bInheritHandle in its SECURITY_ATTRIBUTES mapping and am wondering whether that results in undefined or undesired behavior.
See the .NET Framework implementation here for comparison: Reference Source.
I suspect that file handles create by AlphaFS result in the bInheritHandle being set to 1 always or randomly.
Can you comment on that suspicion?
I am currently tracking the following behavior:
- Open file for writing:
fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.None) - Start writing data to the stream (in chunks of 4096 bytes) with a
StreamWriter - Create child process via
Process.Starton a different thread (not related to that file operation and working in a different directory) while the file handle is still open. - Finish writing and dispose the
FileStreamandStreamWriter - Observe (in
Process Monitor) that any writes and the close after the child process start don't get executed by Windows until the child process exits. - Also observe that code execution continues (no block on dispose/close) but that the file is locked as subsequent file operations (e.g. read) fail until the child process exits.
- When the child process exits it closes the file handle.
In other words: Any open file handles that are inheritable get passed along to any spawning child processes and result in locking of those files for the duration of the process lifetimes.
From what I gather, applicable handles get inherited by child processes with the .NET process creation. File handles are applicable under some circumstances (See here. While the resulting behavior is strange, it does appear to be the intended behavior (as far as inheritance is concerned).
I'll try switching the code parts to the System.IO classes and see if that fixes the issue and report back.
I can confirm the initial suspicion. The child-process-related file locking went away when switching to the System.IO namespace. I could afford to do that for the affected code parts because of short path lengths and no use of NTFS transactions.
I left in a few usages of AlphaFS in a few less-used parts and just yesterday tracked down the same child-process-related file locking issues in those parts still using AlphaFS.
So for me the conclusion is clear. When using AlphaFS active file handles get passed along to just-spawned child processes (that do things unrelated to those files), which causes locking issues on the files in the main process. When the child process exits, the locking goes away.
When using System.IO that doesn't happen.
As mentioned in my original post, I suspect that this behavior has to do with the bInheritHandle in the SECURITY_ATTRIBUTES.
Thanks for your report. We will investigate this and see if we can find the correct solution. I do recognize this problem, although at the time I was actually using System.IO. But we'll have a look.
Interesting read: When System.Diagnostics.Process creates a process, it inherits inheritable handles from the parent process.
https://github.com/alphaleonis/AlphaFS/blob/2a274554df41b35a1d7d6edb6121f23417bd194c/AlphaFS/Security/SecurityAttributes.cs#L33
The Win32 SECURITY_ATTRIBUTES structure contains: BOOL bInheritHandle, which is
missing in the AlphaFS class.
I think the link posted previously is the same issue and shows that this also happens when using System.IO.
Commit 971bf0d: Added missing SecurityAttributes.InheritHandle property.
Great to see progress on this issue. I'll try to give this is a try soon.
One minor correction: I believe the correct commit is https://github.com/alphaleonis/AlphaFS/commit/927918e826997c7b9f5677216eac7517772e120f
Many thanks!
@tskarman Were you able to test this? Can we close this issue?