Skip to content

Commit 1496aa8

Browse files
authored
Merge pull request #435 from IvanMurzak/fix/unity-domain-reload-freeze
Replace SemaphoreSlim with lock for file access
2 parents ed2865c + 3dbd39a commit 1496aa8

File tree

2 files changed

+34
-74
lines changed

2 files changed

+34
-74
lines changed

Unity-MCP-Plugin/Assets/root/Runtime/Unity/Logs/BufferedFileLogStorage.cs

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ public override void Flush()
5353
nameof(Flush));
5454
return;
5555
}
56-
_fileLock.Wait();
57-
try
56+
lock (_fileMutex)
5857
{
5958
// Flush buffered entries to file
6059
if (_logEntriesBufferLength > 0)
@@ -66,21 +65,16 @@ public override void Flush()
6665
}
6766
fileWriteStream?.Flush();
6867
}
69-
finally
70-
{
71-
_fileLock.Release();
72-
}
7368
}
74-
public override async Task FlushAsync()
69+
public override Task FlushAsync()
7570
{
7671
if (_isDisposed.Value)
7772
{
7873
_logger.LogWarning("{method} called but already disposed, ignored.",
7974
nameof(FlushAsync));
80-
return;
75+
return Task.CompletedTask;
8176
}
82-
await _fileLock.WaitAsync();
83-
try
77+
lock (_fileMutex)
8478
{
8579
// Flush buffered entries to file
8680
if (_logEntriesBufferLength > 0)
@@ -90,14 +84,9 @@ public override async Task FlushAsync()
9084
base.AppendInternal(entriesToFlush);
9185
_logEntriesBufferLength = 0;
9286
}
93-
94-
if (fileWriteStream != null)
95-
await fileWriteStream.FlushAsync();
96-
}
97-
finally
98-
{
99-
_fileLock.Release();
87+
fileWriteStream?.Flush();
10088
}
89+
return Task.CompletedTask;
10190
}
10291

10392
protected override void AppendInternal(params LogEntry[] entries)
@@ -137,8 +126,7 @@ public override void Clear()
137126
nameof(Clear));
138127
return;
139128
}
140-
_fileLock.Wait();
141-
try
129+
lock (_fileMutex)
142130
{
143131
fileWriteStream?.Close();
144132
fileWriteStream?.Dispose();
@@ -151,10 +139,6 @@ public override void Clear()
151139
if (File.Exists(filePath))
152140
_logger.LogError("Failed to delete cache file: {file}", filePath);
153141
}
154-
finally
155-
{
156-
_fileLock.Release();
157-
}
158142
}
159143

160144
public override LogEntry[] Query(
@@ -169,15 +153,10 @@ public override LogEntry[] Query(
169153
nameof(Query));
170154
return Array.Empty<LogEntry>();
171155
}
172-
_fileLock.Wait();
173-
try
156+
lock (_fileMutex)
174157
{
175158
return QueryInternal(maxEntries, logTypeFilter, includeStackTrace, lastMinutes);
176159
}
177-
finally
178-
{
179-
_fileLock.Release();
180-
}
181160
}
182161

183162
protected override LogEntry[] QueryInternal(

Unity-MCP-Plugin/Assets/root/Runtime/Unity/Logs/FileLogStorage.cs

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
using System.Linq;
1616
using System.Text.Json;
1717
using System.Text.Json.Serialization;
18-
using System.Threading;
1918
using System.Threading.Tasks;
2019
using com.IvanMurzak.McpPlugin.Common;
2120
using com.IvanMurzak.ReflectorNet;
@@ -36,7 +35,7 @@ public class FileLogStorage : ILogStorage, IDisposable
3635
protected readonly string _directoryPath;
3736
protected readonly string _requestedFileName;
3837
protected readonly JsonSerializerOptions _jsonOptions;
39-
protected readonly SemaphoreSlim _fileLock = new(1, 1);
38+
protected readonly object _fileMutex = new();
4039
protected readonly int _fileBufferSize;
4140
protected readonly long _maxFileSizeBytes;
4241
protected readonly ThreadSafeBool _isDisposed = new(false);
@@ -140,34 +139,32 @@ public virtual void Flush()
140139
nameof(Flush));
141140
return;
142141
}
143-
_fileLock.Wait();
144-
try
142+
lock (_fileMutex)
145143
{
146144
fileWriteStream?.Flush();
147145
}
148-
finally
149-
{
150-
_fileLock.Release();
151-
}
152146
}
153-
public virtual async Task FlushAsync()
147+
public virtual Task FlushAsync()
154148
{
155149
if (_isDisposed.Value)
156150
{
157151
_logger.LogWarning("{method} called but already disposed, ignored.",
158152
nameof(FlushAsync));
159-
return;
160-
}
161-
await _fileLock.WaitAsync();
162-
try
163-
{
164-
if (fileWriteStream != null)
165-
await fileWriteStream.FlushAsync();
153+
return Task.CompletedTask;
166154
}
167-
finally
155+
return Task.Run(() =>
168156
{
169-
_fileLock.Release();
170-
}
157+
if (_isDisposed.Value)
158+
{
159+
_logger.LogWarning("{method} called but already disposed, ignored.",
160+
nameof(FlushAsync));
161+
return;
162+
}
163+
lock (_fileMutex)
164+
{
165+
fileWriteStream?.Flush();
166+
}
167+
});
171168
}
172169

173170
public virtual Task AppendAsync(params LogEntry[] entries)
@@ -178,16 +175,17 @@ public virtual Task AppendAsync(params LogEntry[] entries)
178175
nameof(AppendAsync));
179176
return Task.CompletedTask;
180177
}
181-
return Task.Run(async () =>
178+
return Task.Run(() =>
182179
{
183-
await _fileLock.WaitAsync();
184-
try
180+
if (_isDisposed.Value)
185181
{
186-
AppendInternal(entries);
182+
_logger.LogWarning("{method} called but already disposed, ignored.",
183+
nameof(AppendAsync));
184+
return;
187185
}
188-
finally
186+
lock (_fileMutex)
189187
{
190-
_fileLock.Release();
188+
AppendInternal(entries);
191189
}
192190
});
193191
}
@@ -200,15 +198,10 @@ public virtual void Append(params LogEntry[] entries)
200198
nameof(Append));
201199
return;
202200
}
203-
_fileLock.Wait();
204-
try
201+
lock (_fileMutex)
205202
{
206203
AppendInternal(entries);
207204
}
208-
finally
209-
{
210-
_fileLock.Release();
211-
}
212205
}
213206

214207
protected virtual void AppendInternal(params LogEntry[] entries)
@@ -272,8 +265,7 @@ public virtual void Clear()
272265
nameof(Clear));
273266
return;
274267
}
275-
_fileLock.Wait();
276-
try
268+
lock (_fileMutex)
277269
{
278270
fileWriteStream?.Dispose();
279271
fileWriteStream = null;
@@ -284,10 +276,6 @@ public virtual void Clear()
284276
if (File.Exists(filePath))
285277
_logger.LogError("Failed to delete cache file: {file}", filePath);
286278
}
287-
finally
288-
{
289-
_fileLock.Release();
290-
}
291279
}
292280

293281
public virtual Task<LogEntry[]> QueryAsync(
@@ -317,15 +305,10 @@ public virtual LogEntry[] Query(
317305
nameof(Query));
318306
return Array.Empty<LogEntry>();
319307
}
320-
_fileLock.Wait();
321-
try
308+
lock (_fileMutex)
322309
{
323310
return QueryInternal(maxEntries, logTypeFilter, includeStackTrace, lastMinutes);
324311
}
325-
finally
326-
{
327-
_fileLock.Release();
328-
}
329312
}
330313

331314
protected virtual LogEntry[] QueryInternal(
@@ -460,8 +443,6 @@ public virtual void Dispose()
460443
fileWriteStream = null;
461444
}
462445

463-
_fileLock.Dispose();
464-
465446
GC.SuppressFinalize(this);
466447
}
467448

0 commit comments

Comments
 (0)