Fix crash bug in Log Monitoring while monitoring a large file

This commit is contained in:
Don Ho 2016-05-11 02:18:04 +02:00
parent 6c4f9a64d2
commit 4268349bf0
8 changed files with 58 additions and 38 deletions

View File

@ -4784,6 +4784,23 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask)
} }
break; break;
} }
case DOC_NEEDRELOAD: // by log monitoring
{
doReload(buffer->getID(), false);
// not only test main view
if (buffer == _mainEditView.getCurrentBuffer())
{
_mainEditView.execute(SCI_GOTOLINE, _mainEditView.execute(SCI_GETLINECOUNT) - 1);
}
// but also test sub-view, because the buffer could be clonned
if (buffer == _subEditView.getCurrentBuffer())
{
_subEditView.execute(SCI_GOTOLINE, _subEditView.execute(SCI_GETLINECOUNT) - 1);
}
break;
}
case DOC_DELETED: //ask for keep case DOC_DELETED: //ask for keep
{ {
SCNotification scnN; SCNotification scnN;

View File

@ -447,7 +447,7 @@ private:
bool reloadLang(); bool reloadLang();
bool loadStyles(); bool loadStyles();
int currentView(){ int currentView() {
return _activeView; return _activeView;
} }
@ -645,11 +645,10 @@ private:
static DWORD WINAPI monitorFileOnChange(void * params); static DWORD WINAPI monitorFileOnChange(void * params);
struct MonitorInfo final { struct MonitorInfo final {
MonitorInfo(Buffer *buf, ScintillaEditView *mainEditorView, ScintillaEditView *subEditorView) : MonitorInfo(Buffer *buf, HWND nppHandle) :
_buffer(buf), _mainEditorView(mainEditorView), _subEditorView(subEditorView) {}; _buffer(buf), _nppHandle(nppHandle) {};
Buffer *_buffer = nullptr; Buffer *_buffer = nullptr;
ScintillaEditView *_mainEditorView = nullptr; HWND _nppHandle = nullptr;
ScintillaEditView *_subEditorView = nullptr;
}; };
}; };

View File

@ -1409,6 +1409,13 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
return FALSE; return FALSE;
} }
case NPPM_INTERNAL_RELOADSCROLLTOEND:
{
Buffer *buf = (Buffer *)wParam;
buf->reload();
return TRUE;
}
case NPPM_INTERNAL_GETCHECKDOCOPT: case NPPM_INTERNAL_GETCHECKDOCOPT:
{ {
return (LRESULT)((NppGUI &)(pNppParam->getNppGUI()))._fileAutoDetection; return (LRESULT)((NppGUI &)(pNppParam->getNppGUI()))._fileAutoDetection;

View File

@ -1781,7 +1781,7 @@ void Notepad_plus::command(int id)
curBuf->startMonitoring(); // monitoring firstly for making monitoring icon curBuf->startMonitoring(); // monitoring firstly for making monitoring icon
curBuf->setUserReadOnly(true); curBuf->setUserReadOnly(true);
MonitorInfo *monitorInfo = new MonitorInfo(curBuf, &_mainEditView, &_subEditView); MonitorInfo *monitorInfo = new MonitorInfo(curBuf, _pPublicInterface->getHSelf());
hThread = ::CreateThread(NULL, 0, monitorFileOnChange, (void *)monitorInfo, 0, NULL); // will be deallocated while quitting thread hThread = ::CreateThread(NULL, 0, monitorFileOnChange, (void *)monitorInfo, 0, NULL); // will be deallocated while quitting thread
checkMenuItem(IDM_VIEW_MONITORING, true); checkMenuItem(IDM_VIEW_MONITORING, true);
_toolBar.setCheck(IDM_VIEW_MONITORING, true); _toolBar.setCheck(IDM_VIEW_MONITORING, true);

View File

@ -43,8 +43,7 @@ DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params)
{ {
MonitorInfo *monitorInfo = (MonitorInfo *)params; MonitorInfo *monitorInfo = (MonitorInfo *)params;
Buffer *buf = monitorInfo->_buffer; Buffer *buf = monitorInfo->_buffer;
ScintillaEditView *mainEditorView = monitorInfo->_mainEditorView; HWND h = monitorInfo->_nppHandle;
ScintillaEditView *subEditorView = monitorInfo->_subEditorView;
const TCHAR *fullFileName = (const TCHAR *)buf->getFullPathName(); const TCHAR *fullFileName = (const TCHAR *)buf->getFullPathName();
@ -91,21 +90,7 @@ DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params)
if (dwAction == FILE_ACTION_MODIFIED && lstrcmp(fullFileName, wstrFilename.GetString()) == 0) if (dwAction == FILE_ACTION_MODIFIED && lstrcmp(fullFileName, wstrFilename.GetString()) == 0)
{ {
MainFileManager->reloadBuffer(buf->getID()); ::PostMessage(h, NPPM_INTERNAL_RELOADSCROLLTOEND, (WPARAM)buf, 0);
buf->updateTimeStamp();
// not only test main view
if (buf == mainEditorView->getCurrentBuffer())
{
int lastLineToShow = mainEditorView->execute(SCI_GETLINECOUNT);
mainEditorView->scroll(0, lastLineToShow);
}
// but also test sub-view, because the buffer could be clonned
if (buf == subEditorView->getCurrentBuffer())
{
int lastLineToShow = subEditorView->execute(SCI_GETLINECOUNT);
subEditorView->scroll(0, lastLineToShow);
}
} }
} }
} }

View File

@ -238,14 +238,14 @@ bool Buffer::checkFileState() //eturns true if the status has been changed (it c
bool isWow64Off = false; bool isWow64Off = false;
NppParameters *pNppParam = NppParameters::getInstance(); NppParameters *pNppParam = NppParameters::getInstance();
if (!PathFileExists(_fullPathName.c_str())) if (not PathFileExists(_fullPathName.c_str()))
{ {
pNppParam->safeWow64EnableWow64FsRedirection(FALSE); pNppParam->safeWow64EnableWow64FsRedirection(FALSE);
isWow64Off = true; isWow64Off = true;
} }
bool isOK = false; bool isOK = false;
if (_currentStatus != DOC_DELETED && !PathFileExists(_fullPathName.c_str())) //document has been deleted if (_currentStatus != DOC_DELETED && not PathFileExists(_fullPathName.c_str())) //document has been deleted
{ {
_currentStatus = DOC_DELETED; _currentStatus = DOC_DELETED;
_isFileReadOnly = false; _isFileReadOnly = false;
@ -256,7 +256,7 @@ bool Buffer::checkFileState() //eturns true if the status has been changed (it c
} }
else if (_currentStatus == DOC_DELETED && PathFileExists(_fullPathName.c_str())) else if (_currentStatus == DOC_DELETED && PathFileExists(_fullPathName.c_str()))
{ //document has returned from its grave { //document has returned from its grave
if (!generic_stat(_fullPathName.c_str(), &buf)) if (not generic_stat(_fullPathName.c_str(), &buf))
{ {
_isFileReadOnly = (bool)(!(buf.st_mode & _S_IWRITE)); _isFileReadOnly = (bool)(!(buf.st_mode & _S_IWRITE));
@ -266,10 +266,10 @@ bool Buffer::checkFileState() //eturns true if the status has been changed (it c
isOK = true; isOK = true;
} }
} }
else if (!generic_stat(_fullPathName.c_str(), &buf)) else if (not generic_stat(_fullPathName.c_str(), &buf))
{ {
int mask = 0; //status always 'changes', even if from modified to modified int mask = 0; //status always 'changes', even if from modified to modified
bool isFileReadOnly = (bool)(!(buf.st_mode & _S_IWRITE)); bool isFileReadOnly = (bool)(not(buf.st_mode & _S_IWRITE));
if (isFileReadOnly != _isFileReadOnly) if (isFileReadOnly != _isFileReadOnly)
{ {
_isFileReadOnly = isFileReadOnly; _isFileReadOnly = isFileReadOnly;
@ -294,11 +294,20 @@ bool Buffer::checkFileState() //eturns true if the status has been changed (it c
if (isWow64Off) if (isWow64Off)
{ {
pNppParam->safeWow64EnableWow64FsRedirection(TRUE); pNppParam->safeWow64EnableWow64FsRedirection(TRUE);
//isWow64Off = false;
} }
return isOK; return isOK;
} }
void Buffer::reload()
{
struct _stat buf;
if (PathFileExists(_fullPathName.c_str()) && not generic_stat(_fullPathName.c_str(), &buf))
{
_timeStamp = buf.st_mtime;
_currentStatus = DOC_NEEDRELOAD;
doNotify(BufferChangeTimestamp | BufferChangeStatus);
}
}
int Buffer::getFileLength() const int Buffer::getFileLength() const
{ {
@ -1341,10 +1350,10 @@ LangType FileManager::detectLanguageFromTextBegining(const unsigned char *data,
return L_TEXT; return L_TEXT;
} }
inline bool FileManager::loadFileData(Document doc, const TCHAR * filename, char* data, Utf8_16_Read * unicodeConvertor, LangType & language, int & encoding, EolType & eolFormat) bool FileManager::loadFileData(Document doc, const TCHAR * filename, char* data, Utf8_16_Read * unicodeConvertor, LangType & language, int & encoding, EolType & eolFormat)
{ {
FILE *fp = generic_fopen(filename, TEXT("rb")); FILE *fp = generic_fopen(filename, TEXT("rb"));
if (!fp) if (not fp)
return false; return false;
//Get file size //Get file size
@ -1354,9 +1363,9 @@ inline bool FileManager::loadFileData(Document doc, const TCHAR * filename, char
// size/6 is the normal room Scintilla keeps for editing, but here we limit it to 1MiB when loading (maybe we want to load big files without editing them too much) // size/6 is the normal room Scintilla keeps for editing, but here we limit it to 1MiB when loading (maybe we want to load big files without editing them too much)
unsigned __int64 bufferSizeRequested = fileSize + min(1<<20,fileSize/6); unsigned __int64 bufferSizeRequested = fileSize + min(1<<20,fileSize/6);
// As a 32bit application, we cannot allocate 2 buffer of more than INT_MAX size (it takes the whole address space) // As a 32bit application, we cannot allocate 2 buffer of more than INT_MAX size (it takes the whole address space)
if(bufferSizeRequested > INT_MAX) if (bufferSizeRequested > INT_MAX)
{ {
::MessageBox(NULL, TEXT("File is too big to be opened by Notepad++"), TEXT("File open problem"), MB_OK|MB_APPLMODAL); ::MessageBox(NULL, TEXT("File is too big to be opened by Notepad++"), TEXT("File size problem"), MB_OK|MB_APPLMODAL);
/* /*
_nativeLangSpeaker.messageBox("NbFileToOpenImportantWarning", _nativeLangSpeaker.messageBox("NbFileToOpenImportantWarning",
_pPublicInterface->getHSelf(), _pPublicInterface->getHSelf(),
@ -1503,6 +1512,7 @@ inline bool FileManager::loadFileData(Document doc, const TCHAR * filename, char
_pscratchTilla->execute(SCI_SETREADONLY, true); _pscratchTilla->execute(SCI_SETREADONLY, true);
_pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault); _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault);
return success; return success;
} }

View File

@ -38,10 +38,11 @@ typedef sptr_t Document;
enum DocFileStatus enum DocFileStatus
{ {
DOC_REGULAR = 0x01, // should not be combined with anything DOC_REGULAR = 0x01, // should not be combined with anything
DOC_UNNAMED = 0x02, // not saved (new ##) DOC_UNNAMED = 0x02, // not saved (new ##)
DOC_DELETED = 0x04, // doesn't exist in environment anymore, but not DOC_UNNAMED DOC_DELETED = 0x04, // doesn't exist in environment anymore, but not DOC_UNNAMED
DOC_MODIFIED = 0x08 // File in environment has changed DOC_MODIFIED = 0x08, // File in environment has changed
DOC_NEEDRELOAD = 0x10 // File is modified & needed to be reload (by log monitoring)
}; };
enum BufferStatusInfo enum BufferStatusInfo
@ -354,6 +355,7 @@ public:
bool isMonitoringOn() const { return _isMonitoringOn; }; bool isMonitoringOn() const { return _isMonitoringOn; };
void updateTimeStamp(); void updateTimeStamp();
void reload();
private: private:
int indexOfReference(const ScintillaEditView * identifier) const; int indexOfReference(const ScintillaEditView * identifier) const;

View File

@ -405,7 +405,7 @@
#define NPPM_INTERNAL_SAVECURRENTSESSION (NOTEPADPLUS_USER_INTERNAL + 39) #define NPPM_INTERNAL_SAVECURRENTSESSION (NOTEPADPLUS_USER_INTERNAL + 39)
#define NPPM_INTERNAL_FINDINFINDERDLG (NOTEPADPLUS_USER_INTERNAL + 40) #define NPPM_INTERNAL_FINDINFINDERDLG (NOTEPADPLUS_USER_INTERNAL + 40)
#define NPPM_INTERNAL_REMOVEFINDER (NOTEPADPLUS_USER_INTERNAL + 41) #define NPPM_INTERNAL_REMOVEFINDER (NOTEPADPLUS_USER_INTERNAL + 41)
#define NPPM_INTERNAL_RELOADSCROLLTOEND (NOTEPADPLUS_USER_INTERNAL + 42) // Used by Monitoring feature
//wParam: 0 //wParam: 0
//lParam: document new index //lParam: document new index