Code enhancement: Prevent backup worker thread crash at Notepad++ exit

Use thread safe g_bNppExitFlag and optimize the Notepad_plus::backupDocument worker thread.

Fix: https://github.com/notepad-plus-plus/notepad-plus-plus/pull/15681#issuecomment-2403168094, close #15935
This commit is contained in:
xomx 2024-12-10 16:49:31 +01:00 committed by Don Ho
parent fdf3ed2714
commit dc583bf34e
4 changed files with 19 additions and 9 deletions

View File

@ -8653,23 +8653,22 @@ void Notepad_plus::launchDocumentBackupTask()
DWORD WINAPI Notepad_plus::backupDocument(void * /*param*/)
{
bool isSnapshotMode = true;
while (isSnapshotMode)
{
NppParameters& nppParam = NppParameters::getInstance();
NppGUI& nppGUI = (NppParameters::getInstance()).getNppGUI();
size_t timer = nppParam.getNppGUI()._snapshotBackupTiming;
while (!g_bNppExitFlag.load() && nppGUI.isSnapshotMode())
{
size_t timer = nppGUI._snapshotBackupTiming;
if (timer < 1000)
timer = 1000;
::Sleep(DWORD(timer));
isSnapshotMode = nppParam.getNppGUI().isSnapshotMode();
if (!isSnapshotMode)
if (g_bNppExitFlag.load() || !nppGUI.isSnapshotMode())
break;
::SendMessage(Notepad_plus_Window::gNppHWND, NPPM_INTERNAL_SAVEBACKUP, 0, 0);
}
return ERROR_SUCCESS;
}

View File

@ -46,10 +46,13 @@
#include <vector>
#include <iso646.h>
#include <chrono>
#include <atomic>
extern std::chrono::steady_clock::time_point g_nppStartTimePoint;
extern std::chrono::steady_clock::duration g_pluginsLoadingTime;
extern std::atomic<bool> g_bNppExitFlag;
#define MENU 0x01
#define TOOLBAR 0x02

View File

@ -20,6 +20,7 @@
#include <uxtheme.h> // for EnableThemeDialogTexture
#include <format>
#include <windowsx.h> // for GET_X_LPARAM, GET_Y_LPARAM
#include <atomic>
#include "Notepad_plus_Window.h"
#include "TaskListDlg.h"
#include "ImageListSet.h"
@ -39,6 +40,8 @@ using namespace std;
#define WM_DPICHANGED 0x02E0
#endif
std::atomic<bool> g_bNppExitFlag{ false };
struct SortTaskListPred final
{
@ -2721,6 +2724,11 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
return 0; // abort quitting
}
// from this point on the Notepad++ exit is inevitable
g_bNppExitFlag.store(true); // thread-safe op
// currently it is used only in the Notepad_plus::backupDocument worker thread,
// use it in such a thread like: if (g_bNppExitFlag.load()) -> finish work of & exit the thread
if (_beforeSpecialView._isFullScreen) //closing, return to windowed mode
fullScreenToggle();
if (_beforeSpecialView._isPostIt) //closing, return to windowed mode

View File

@ -1086,7 +1086,7 @@ bool FileManager::backupCurrentBuffer()
{
size_t lengthDoc = _pNotepadPlus->_pEditView->getCurrentDocLen();
char* buf = (char*)_pNotepadPlus->_pEditView->execute(SCI_GETCHARACTERPOINTER); //to get characters directly from Scintilla buffer
boolean isWrittenSuccessful = false;
bool isWrittenSuccessful = false;
if (encoding == -1) //no special encoding; can be handled directly by Utf8_16_Write
{
@ -1248,7 +1248,7 @@ SavingStatus FileManager::saveBuffer(BufferID id, const wchar_t* filename, bool
size_t lengthDoc = _pscratchTilla->getCurrentDocLen();
char* buf = (char*)_pscratchTilla->execute(SCI_GETCHARACTERPOINTER); //to get characters directly from Scintilla buffer
boolean isWrittenSuccessful = false;
bool isWrittenSuccessful = false;
if (encoding == -1) //no special encoding; can be handled directly by Utf8_16_Write
{