Skip to content

Commit 29f50d6

Browse files
authored
Reduce lock scope in FSDirectory.DeleteFile, apache#1428 (apache#1429)
1 parent 60d9864 commit 29f50d6

1 file changed

Lines changed: 26 additions & 20 deletions

File tree

src/Lucene.Net/Store/FSDirectory.cs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -317,31 +317,37 @@ public override void DeleteFile(string name)
317317
EnsureOpen();
318318
string file = Path.Combine(m_directory.FullName, name);
319319

320-
// LUCENENET Specific: See remarks for m_staleFiles field.
321-
UninterruptableMonitor.Enter(m_syncLock);
322-
try
320+
// LUCENENET specific: We need to explicitly throw when the file has already been deleted,
321+
// since FileInfo doesn't do that for us.
322+
// (An enhancement carried over from Lucene 8.2.0)
323+
if (!File.Exists(file))
323324
{
324-
// LUCENENET specific: We need to explicitly throw when the file has already been deleted,
325-
// since FileInfo doesn't do that for us.
326-
// (An enhancement carried over from Lucene 8.2.0)
327-
if (!File.Exists(file))
328-
{
329-
throw new FileNotFoundException("Cannot delete " + file + " because it doesn't exist.");
330-
}
325+
throw new FileNotFoundException("Cannot delete " + file + " because it doesn't exist.");
326+
}
331327

332-
try
333-
{
334-
File.Delete(file);
335-
if (File.Exists(file))
336-
{
337-
throw new IOException("Cannot delete " + file);
338-
}
339-
}
340-
catch (Exception e)
328+
// LUCENENET NOTE: Do NOT hold m_syncLock while deleting. On a network share (SMB),
329+
// File.Delete can block for a long time (e.g. waiting for the server to break an
330+
// oplock/lease on a file this client still has open). Holding m_syncLock here would
331+
// block every concurrent Sync() and IndexOutput.Dispose() on this directory behind
332+
// a single stalled delete, freezing the whole writer. Only the m_staleFiles
333+
// bookkeeping below needs the lock (see remarks for the m_staleFiles field);
334+
// upstream Java likewise performs the delete without any directory-wide lock.
335+
try
336+
{
337+
File.Delete(file);
338+
if (File.Exists(file))
341339
{
342-
throw new IOException("Cannot delete " + file, e);
340+
throw new IOException("Cannot delete " + file);
343341
}
342+
}
343+
catch (Exception e)
344+
{
345+
throw new IOException("Cannot delete " + file, e);
346+
}
344347

348+
UninterruptableMonitor.Enter(m_syncLock);
349+
try
350+
{
345351
m_staleFiles.Remove(name);
346352
}
347353
finally

0 commit comments

Comments
 (0)