Skip to content

Commit

Permalink
fix FumenRescue.Rescue() deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
MikiraSora committed Jan 3, 2024
1 parent 370a535 commit 686b806
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 32 deletions.
48 changes: 32 additions & 16 deletions OngekiFumenEditor/AppBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

Expand All @@ -43,7 +44,7 @@ namespace OngekiFumenEditor
public class AppBootstrapper : Gemini.AppBootstrapper
{
#if !DEBUG
public override bool IsPublishSingleFileHandled => true;
public override bool IsPublishSingleFileHandled => true;
#endif

public AppBootstrapper() : this(true)
Expand Down Expand Up @@ -276,12 +277,15 @@ private void InitExceptionCatcher()
{
var recHandle = new HashSet<IntPtr>();

void LogException(object sender, Exception exception)
async void ProcessException(object sender, Exception exception)
{
if (exceptionHandling)
return;
exceptionHandling = true;

foreach (var visual in Application.Current.Windows.OfType<Window>())
visual.Hide();

var sb = new StringBuilder();
void exceptionDump(Exception e, int level = 0)
{
Expand All @@ -302,24 +306,36 @@ void exceptionDump(Exception e, int level = 0)
FileLogOutput.WriteLog(sb.ToString());

Check warning on line 306 in OngekiFumenEditor/AppBootstrapper.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
FileLogOutput.WaitForWriteDone();
#if !DEBUG
var exceptionHandle = Marshal.GetExceptionPointers();
if (exceptionHandle != IntPtr.Zero && !recHandle.Contains(exceptionHandle))
{
DumpFileHelper.WriteMiniDump(exceptionHandle);
recHandle.Add(exceptionHandle);
}

FileLogOutput.WriteLog("FumenRescue.Rescue() Begin");
FumenRescue.Rescue();
FileLogOutput.WriteLog("FumenRescue.Rescue() End");
FileLogOutput.WaitForWriteDone();
var exceptionHandle = Marshal.GetExceptionPointers();
if (exceptionHandle != IntPtr.Zero && !recHandle.Contains(exceptionHandle))
{
DumpFileHelper.WriteMiniDump(exceptionHandle);
recHandle.Add(exceptionHandle);
}

FileLogOutput.WriteLog("FumenRescue.Rescue() Begin");

Check warning on line 316 in OngekiFumenEditor/AppBootstrapper.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
await FumenRescue.Rescue();
FileLogOutput.WriteLog("FumenRescue.Rescue() End");

Check warning on line 318 in OngekiFumenEditor/AppBootstrapper.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
FileLogOutput.WaitForWriteDone();
#endif
exceptionHandling = true;
Environment.Exit(-1);
}

AppDomain.CurrentDomain.UnhandledException += (sender, e) => LogException(sender, e.ExceptionObject as Exception);
Application.Current.DispatcherUnhandledException += (sender, e) => LogException(sender, e.Exception);
TaskScheduler.UnobservedTaskException += (sender, e) => LogException(sender, e.Exception);
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
ProcessException(sender, e.ExceptionObject as Exception);
};
Application.Current.DispatcherUnhandledException += (sender, e) =>
{
ProcessException(sender, e.Exception);
e.Handled = true;
};
TaskScheduler.UnobservedTaskException += (sender, e) =>
{
ProcessException(sender, e.Exception);
e.SetObserved();
};
}

protected override async void OnExit(object sender, EventArgs e)
Expand Down
28 changes: 12 additions & 16 deletions OngekiFumenEditor/Utils/DeadHandler/FumenRescue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
using OngekiFumenEditor.Modules.FumenVisualEditor.Kernel;
using OngekiFumenEditor.Modules.FumenVisualEditor.ViewModels;
using System.IO;
using System.Threading.Tasks;

namespace OngekiFumenEditor.Utils.DeadHandler
{
internal static class FumenRescue
{
public static void Rescue()
public static async Task Rescue()
{
try
{
var editorManager = IoC.Get<IEditorDocumentManager>();
foreach (var editor in editorManager.GetCurrentEditors())
{
if (Rescue(editor, out var savedFolderPath))
{
var savedFolderPath = await Rescue(editor);
if (Directory.Exists(savedFolderPath))
Log.LogInfo($"Rescue fumen/proj file successfully: {savedFolderPath}");
}
}
}
catch
Expand All @@ -27,31 +27,29 @@ public static void Rescue()
}
}

public static bool Rescue(FumenVisualEditorViewModel editor, out string savedPath)
public static async Task<string> Rescue(FumenVisualEditorViewModel editor)
{
var projFilePath = editor.FilePath;
var docName = "NotSavedUnknown-" + RandomHepler.RandomString(10);
if (!string.IsNullOrWhiteSpace(projFilePath))
docName = Path.GetFileNameWithoutExtension(projFilePath);

var rescueFolderPath = TempFileHelper.GetTempFolderPath("Rescue", docName);
savedPath = default;

try
{
//save proj file
var extName = ".nyagekiProj";
if (!string.IsNullOrWhiteSpace(projFilePath))
extName = Path.GetExtension(projFilePath);

var tempProjFile = Path.Combine(rescueFolderPath, docName + extName);
var result = EditorProjectDataUtils.TrySaveProjFileAsync(tempProjFile, editor.EditorProjectData).Result;
var result = await EditorProjectDataUtils.TrySaveProjFileAsync(tempProjFile, editor.EditorProjectData);
if (!result.IsSuccess)
return false;
return string.Empty;
}
catch
{
return false;
return string.Empty;
}

try
Expand All @@ -62,18 +60,16 @@ public static bool Rescue(FumenVisualEditorViewModel editor, out string savedPat
fumenName = RandomHepler.RandomString() + ".ogkr";

var tempFumenFile = Path.Combine(rescueFolderPath, fumenName);
var task = EditorProjectDataUtils.TrySaveFumenFileAsync(tempFumenFile, editor.EditorProjectData);
var result = task.Result;
var result = await EditorProjectDataUtils.TrySaveFumenFileAsync(tempFumenFile, editor.EditorProjectData);
if (!result.IsSuccess)
return false;
return string.Empty;
}
catch
{
return false;
return string.Empty;
}

savedPath = rescueFolderPath;
return true;
return rescueFolderPath;
}
}
}

0 comments on commit 686b806

Please sign in to comment.