Skip to content

Swallow ObjectDisposed on SFTP wait handle when receiving late response #1531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Renci.SshNet/Common/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;

using Renci.SshNet.Abstractions;
using Renci.SshNet.Messages;
Expand Down Expand Up @@ -120,6 +121,23 @@ public static byte[] ExportKeyParameter(this BigInteger value, int length)
return target;
}

/// <summary>
/// Sets a wait handle, swallowing any resulting <see cref="ObjectDisposedException"/>.
/// Used in cases where set and dispose may race.
/// </summary>
/// <param name="waitHandle">The wait handle to set.</param>
public static void SetIgnoringObjectDisposed(this EventWaitHandle waitHandle)
{
try
{
_ = waitHandle.Set();
}
catch (ObjectDisposedException)
{
// ODE intentionally ignored.
}
}

/// <summary>
/// Reverses the sequence of the elements in the entire one-dimensional <see cref="Array"/>.
/// </summary>
Expand Down
69 changes: 33 additions & 36 deletions src/Renci.SshNet/Sftp/SftpSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,12 +492,12 @@ public byte[] RequestOpen(string path, Flags flags, bool nullOnError = false)
response =>
{
handle = response.Handle;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -625,7 +625,7 @@ public void RequestClose(byte[] handle)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -825,7 +825,7 @@ public byte[] RequestRead(byte[] handle, ulong offset, uint length)
response =>
{
data = response.Data;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
Expand All @@ -838,7 +838,7 @@ public byte[] RequestRead(byte[] handle, ulong offset, uint length)
data = Array.Empty<byte>();
}

_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -928,10 +928,7 @@ public void RequestWrite(byte[] handle,
writeCompleted?.Invoke(response);

exception = GetSftpException(response);
if (wait != null)
{
_ = wait.Set();
}
wait?.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1011,12 +1008,12 @@ public SftpFileAttributes RequestLStat(string path)
response =>
{
attributes = response.Attributes;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1140,12 +1137,12 @@ public SftpFileAttributes RequestFStat(byte[] handle, bool nullOnError)
response =>
{
attributes = response.Attributes;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1207,7 +1204,7 @@ public void RequestSetStat(string path, SftpFileAttributes attributes)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1239,7 +1236,7 @@ public void RequestFSetStat(byte[] handle, SftpFileAttributes attributes)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1274,12 +1271,12 @@ public byte[] RequestOpenDir(string path, bool nullOnError = false)
response =>
{
handle = response.Handle;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1345,7 +1342,7 @@ public KeyValuePair<string, SftpFileAttributes>[] RequestReadDir(byte[] handle)
response =>
{
result = response.Files;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
Expand All @@ -1354,7 +1351,7 @@ public KeyValuePair<string, SftpFileAttributes>[] RequestReadDir(byte[] handle)
exception = GetSftpException(response);
}

_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1426,7 +1423,7 @@ public void RequestRemove(string path)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1493,7 +1490,7 @@ public void RequestMkDir(string path)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1558,7 +1555,7 @@ public void RequestRmDir(string path)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1625,12 +1622,12 @@ internal KeyValuePair<string, SftpFileAttributes>[] RequestRealPath(string path,
response =>
{
result = response.Files;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1751,12 +1748,12 @@ public SftpFileAttributes RequestStat(string path, bool nullOnError = false)
response =>
{
attributes = response.Attributes;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1849,7 +1846,7 @@ public void RequestRename(string oldPath, string newPath)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1930,12 +1927,12 @@ internal KeyValuePair<string, SftpFileAttributes>[] RequestReadLink(string path,
response =>
{
result = response.Files;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -1975,7 +1972,7 @@ public void RequestSymLink(string linkpath, string targetpath)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

SendRequest(request);
Expand Down Expand Up @@ -2013,7 +2010,7 @@ public void RequestPosixRename(string oldPath, string newPath)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

if (!_supportedExtensions.ContainsKey(request.Name))
Expand Down Expand Up @@ -2060,12 +2057,12 @@ public SftpFileSystemInformation RequestStatVfs(string path, bool nullOnError =
response =>
{
information = response.GetReply<StatVfsReplyInfo>().Information;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

if (!_supportedExtensions.ContainsKey(request.Name))
Expand Down Expand Up @@ -2148,12 +2145,12 @@ internal SftpFileSystemInformation RequestFStatVfs(byte[] handle, bool nullOnErr
response =>
{
information = response.GetReply<StatVfsReplyInfo>().Information;
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
},
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

if (!_supportedExtensions.ContainsKey(request.Name))
Expand Down Expand Up @@ -2197,7 +2194,7 @@ internal void HardLink(string oldPath, string newPath)
response =>
{
exception = GetSftpException(response);
_ = wait.Set();
wait.SetIgnoringObjectDisposed();
});

if (!_supportedExtensions.ContainsKey(request.Name))
Expand Down