core.git: include/sfx2 sc/inc sc/qa sc/source sfx2/source
include/sfx2/objsh.hxx |6 sc/inc/scabstdlg.hxx|3 sc/qa/unit/data/csv/tdf48731.csv|4 sc/source/ui/attrdlg/scdlgfact.cxx |5 sc/source/ui/attrdlg/scdlgfact.hxx |3 sc/source/ui/dbgui/scuiasciiopt.cxx | 33 +++ sc/source/ui/inc/scuiasciiopt.hxx |3 sc/source/ui/unoobj/filtuno.cxx | 12 + sfx2/source/doc/objstor.cxx | 327 9 files changed, 383 insertions(+), 13 deletions(-) New commits: commit 2feda8ba21acdcf33a9b4ba94742f574c17839bd Author: Gabriel Masei AuthorDate: Sun Mar 17 10:13:25 2024 +0200 Commit: Mike Kaganski CommitDate: Sat Apr 6 19:39:22 2024 +0200 tdf#152336 Detect charset and separators for csv files Change-Id: Ie8451b3d30e390d363d8f9e5ec8bdf47350ca3a2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164936 Reviewed-by: Mike Kaganski Tested-by: Jenkins diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index 075b3e57f4b9..e26c242d 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -45,6 +45,8 @@ #include #include +#include + namespace weld {class Button; } namespace model {class ColorSet; } struct NamedColor; @@ -443,6 +445,10 @@ public: const css::uno::Sequence< css::beans::PropertyValue >& GetModifyPasswordInfo() const; boolSetModifyPasswordInfo( const css::uno::Sequence< css::beans::PropertyValue >& aInfo ); +static void DetectCharSet(SvStream& stream, rtl_TextEncoding& eCharSet, SvStreamEndian& endian); +static void DetectCsvSeparators(SvStream& stream, rtl_TextEncoding& eCharSet, OUString& separators, sal_Unicode cStringDelimiter, bool bForceCommonSeps = true, bool bAllowMultipleSeps = false); +static void DetectCsvFilterOptions(SvStream& stream, OUString& aFilterOptions, bool bForceDetect = false); +static void DetectFilterOptions(SfxMedium* pMedium, bool bForceDetect = false); static ErrCode HandleFilter( SfxMedium* pMedium, SfxObjectShell const * pDoc ); virtual boolPrepareClose(bool bUI = true); diff --git a/sc/inc/scabstdlg.hxx b/sc/inc/scabstdlg.hxx index 7a94af5f6fe9..afd9abf4fbfc 100644 --- a/sc/inc/scabstdlg.hxx +++ b/sc/inc/scabstdlg.hxx @@ -417,7 +417,8 @@ public: virtual VclPtr CreateScImportAsciiDlg(weld::Window* pParent, const OUString& aDatName, SvStream* pInStream, - ScImportAsciiCall eCall) = 0; + ScImportAsciiCall eCall, + ScAsciiOptions* aOptions = nullptr) = 0; virtual VclPtr CreateScTextImportOptionsDlg(weld::Window* pParent) = 0; diff --git a/sc/qa/unit/data/csv/tdf48731.csv b/sc/qa/unit/data/csv/tdf48731.csv index c0353427ced3..fdbead52112e 100644 --- a/sc/qa/unit/data/csv/tdf48731.csv +++ b/sc/qa/unit/data/csv/tdf48731.csv @@ -1,4 +1,4 @@ -WITHOUT QUOTES +WITHOUT QUOTES, 1 apostrophe,' 2 apostrophes,'' 3 apostrophes,''' @@ -6,7 +6,7 @@ A number,'3 A word,'word A misspelled word,'mword -WITH QUOTES +WITH QUOTES, 1 apostrophe,"'" 2 apostrophes,"''" 3 apostrophes,"'''" diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx index 4fe36f303c57..03926077d9f1 100644 --- a/sc/source/ui/attrdlg/scdlgfact.cxx +++ b/sc/source/ui/attrdlg/scdlgfact.cxx @@ -1058,9 +1058,10 @@ const SfxItemSet* ScAsyncTabController_Impl::GetOutputItemSet() const // =Factories for createdialog === VclPtr ScAbstractDialogFactory_Impl::CreateScImportAsciiDlg(weld::Window* pParent, const OUString& aDatName, -SvStream* pInStream, ScImportAsciiCall eCall) +SvStream* pInStream, ScImportAsciiCall eCall, +ScAsciiOptions* aOptions) { -return VclPtr::Create(std::make_shared(pParent, aDatName,pInStream, eCall)); +return VclPtr::Create(std::make_shared(pParent, aDatName,pInStream, eCall, aOptions)); } VclPtr ScAbstractDialogFactory_Impl::CreateScTextImportOptionsDlg(weld::Window* pParent) diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx index 276bffd63195..4644ff4b35e2 100644 --- a/sc/source/ui/attrdlg/scdlgfact.hxx +++ b/sc/source/ui/attrdlg/scdlgfact.hxx @@ -663,7 +663,8 @@ public: virtual VclPtr CreateScImportAsciiDlg(weld::Window* pParent, const OUString&
core.git: Branch 'distro/collabora/co-23.05' - desktop/source
desktop/source/lib/init.cxx |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) New commits: commit 37973107356d47cfa6ad197cb778ecfeef3a9e99 Author: Gabriel Masei AuthorDate: Fri Jan 19 18:11:42 2024 +0200 Commit: Andras Timar CommitDate: Wed Feb 7 13:11:33 2024 +0100 lok: remove non-filter options from filter options Filter options should be what remains after extracting any other options from the original list of options. Change-Id: Iad787b34aba58c3910118e94df66a102b44034c2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162316 Tested-by: Jenkins Reviewed-by: Henry Castro (cherry picked from commit 8c10c63388502322ac0ac6a7e5b14e657edbe630) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162450 Tested-by: Jenkins CollaboraOffice Reviewed-by: Andras Timar diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 238f2f76d935..9b5f50b2a93a 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2785,8 +2785,6 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, Application::SetDialogCancelMode(DialogCancelMode::LOKSilent); } -const OUString sFilterOptions = aOptions; - rtl::Reference const pInteraction( new LOKInteractionHandler("load", pLib)); auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction))); @@ -2822,7 +2820,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, // as regular files, otherwise we cannot save them; it will try // to bring saveas dialog which cannot work with LOK case uno::Sequence aFilterOptions{ -comphelper::makePropertyValue("FilterOptions", sFilterOptions), +comphelper::makePropertyValue("FilterOptions", aOptions), comphelper::makePropertyValue("InteractionHandler", xInteraction), comphelper::makePropertyValue("MacroExecutionMode", nMacroExecMode), comphelper::makePropertyValue("AsTemplate", false),
core.git: Branch 'distro/collabora/co-24.04' - desktop/source
desktop/source/lib/init.cxx |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) New commits: commit 8bad43079758460c0b65455bf9f7a2187d05e27b Author: Gabriel Masei AuthorDate: Fri Jan 19 18:11:42 2024 +0200 Commit: Andras Timar CommitDate: Wed Feb 7 13:11:40 2024 +0100 lok: remove non-filter options from filter options Filter options should be what remains after extracting any other options from the original list of options. Change-Id: Iad787b34aba58c3910118e94df66a102b44034c2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162316 Tested-by: Jenkins Reviewed-by: Henry Castro (cherry picked from commit 8c10c63388502322ac0ac6a7e5b14e657edbe630) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162451 Tested-by: Jenkins CollaboraOffice Reviewed-by: Andras Timar diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index c76e7a014725..0085b2609800 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2765,8 +2765,6 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, Application::SetDialogCancelMode(DialogCancelMode::LOKSilent); } -const OUString sFilterOptions = aOptions; - rtl::Reference const pInteraction( new LOKInteractionHandler("load"_ostr, pLib)); auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction))); @@ -2802,7 +2800,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, // as regular files, otherwise we cannot save them; it will try // to bring saveas dialog which cannot work with LOK case uno::Sequence aFilterOptions{ -comphelper::makePropertyValue(u"FilterOptions"_ustr, sFilterOptions), +comphelper::makePropertyValue(u"FilterOptions"_ustr, aOptions), comphelper::makePropertyValue(u"InteractionHandler"_ustr, xInteraction), comphelper::makePropertyValue(u"MacroExecutionMode"_ustr, nMacroExecMode), comphelper::makePropertyValue(u"AsTemplate"_ustr, false),
core.git: desktop/source
desktop/source/lib/init.cxx |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) New commits: commit 8c10c63388502322ac0ac6a7e5b14e657edbe630 Author: Gabriel Masei AuthorDate: Fri Jan 19 18:11:42 2024 +0200 Commit: Henry Castro CommitDate: Fri Jan 19 18:34:21 2024 +0100 lok: remove non-filter options from filter options Filter options should be what remains after extracting any other options from the original list of options. Change-Id: Iad787b34aba58c3910118e94df66a102b44034c2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162316 Tested-by: Jenkins Reviewed-by: Henry Castro diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index dc6931e931bb..a2675fd97871 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2762,8 +2762,6 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, Application::SetDialogCancelMode(DialogCancelMode::LOKSilent); } -const OUString sFilterOptions = aOptions; - rtl::Reference const pInteraction( new LOKInteractionHandler("load"_ostr, pLib)); auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction))); @@ -2799,7 +2797,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, // as regular files, otherwise we cannot save them; it will try // to bring saveas dialog which cannot work with LOK case uno::Sequence aFilterOptions{ -comphelper::makePropertyValue(u"FilterOptions"_ustr, sFilterOptions), +comphelper::makePropertyValue(u"FilterOptions"_ustr, aOptions), comphelper::makePropertyValue(u"InteractionHandler"_ustr, xInteraction), comphelper::makePropertyValue(u"MacroExecutionMode"_ustr, nMacroExecMode), comphelper::makePropertyValue(u"AsTemplate"_ustr, false),
[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - desktop/source
desktop/source/lib/init.cxx | 31 +++ 1 file changed, 31 insertions(+) New commits: commit 9de8dbd17fa25e57454c024078b256e5fef38114 Author: Gabriel Masei AuthorDate: Mon Nov 15 21:05:17 2021 +0200 Commit: Jan Holesovsky CommitDate: Wed Dec 8 11:07:38 2021 +0100 lok: add pdf version option for export Change-Id: I02c1edecd291309bf028e6e5a0f04a578ac1b639 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125255 Tested-by: Jenkins Reviewed-by: Jan Holesovsky Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125805 Tested-by: Jenkins CollaboraOffice diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 2e1bc71f626a..19b5578d704e 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2731,6 +2731,34 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha bool bFullSheetPreview = sFullSheetPreview == "true"; +// Select a pdf version if specified a valid one. If invalid then fail. +// If not specified then ignore. +sal_Int32 pdfVer = 0; +if ((aIndex = aFilterOptions.indexOf(",PDFVer=")) >= 0) +{ +int bIndex = aFilterOptions.indexOf("PDFVEREND"); +OUString sPdfVer = aFilterOptions.copy(aIndex+8, bIndex-(aIndex+8)); + +OUString temp = aFilterOptions.copy(0, aIndex); +aFilterOptions = temp + aFilterOptions.copy(bIndex+9); + +if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-1b")) +pdfVer = 1; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-2b")) +pdfVer = 2; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-3b")) +pdfVer = 3; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.5")) +pdfVer = 15; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.6")) +pdfVer = 16; +else +{ +SetLastExceptionMsg("wrong PDF version"); +return false; +} +} + // 'TakeOwnership' == this is a 'real' SaveAs (that is, the document // gets a new name). When this is not provided, the meaning of // saveAs() is more like save-a-copy, which allows saving to any @@ -2767,6 +2795,9 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha if (bFullSheetPreview) aFilterDataMap["SinglePageSheets"] <<= true; +if (pdfVer) +aFilterDataMap["SelectPdfVersion"] <<= pdfVer; + if (!aFilterDataMap.empty()) { aSaveMediaDescriptor["FilterData"] <<= aFilterDataMap.getAsConstPropertyValueList();
[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/source
desktop/source/lib/init.cxx | 30 ++ 1 file changed, 30 insertions(+) New commits: commit 962f906395d4b73291df25558dd259af2cb549fc Author: Gabriel Masei AuthorDate: Mon Nov 15 21:05:17 2021 +0200 Commit: Jan Holesovsky CommitDate: Wed Dec 8 11:07:34 2021 +0100 lok: add pdf version option for export Change-Id: I02c1edecd291309bf028e6e5a0f04a578ac1b639 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125255 Tested-by: Jenkins Reviewed-by: Jan Holesovsky Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125806 Tested-by: Jenkins CollaboraOffice diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index feed3452dcf1..16ffe6f097e7 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2938,6 +2938,33 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha bool bFullSheetPreview = sFullSheetPreview == "true"; +// Select a pdf version if specified a valid one. +// If not specified then ignore. If invalid then fail. +sal_Int32 pdfVer = 0; +if ((aIndex = aFilterOptions.indexOf(",PDFVer=")) >= 0) +{ +int bIndex = aFilterOptions.indexOf("PDFVEREND"); +OUString sPdfVer; +sPdfVer = aFilterOptions.subView(aIndex+8, bIndex-(aIndex+8)); +aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex)) + aFilterOptions.subView(bIndex+9); + +if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-1b")) +pdfVer = 1; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-2b")) +pdfVer = 2; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-3b")) +pdfVer = 3; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.5")) +pdfVer = 15; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.6")) +pdfVer = 16; +else +{ +SetLastExceptionMsg("wrong PDF version"); +return false; +} +} + // 'TakeOwnership' == this is a 'real' SaveAs (that is, the document // gets a new name). When this is not provided, the meaning of // saveAs() is more like save-a-copy, which allows saving to any @@ -2974,6 +3001,9 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha if (bFullSheetPreview) aFilterDataMap["SinglePageSheets"] <<= true; +if (pdfVer) +aFilterDataMap["SelectPdfVersion"] <<= pdfVer; + if (!aFilterDataMap.empty()) { aSaveMediaDescriptor["FilterData"] <<= aFilterDataMap.getAsConstPropertyValueList();
[Libreoffice-commits] core.git: desktop/source
desktop/source/lib/init.cxx | 30 ++ 1 file changed, 30 insertions(+) New commits: commit 3eb9eb9906c93fd7b1d1d8461bd34ea5a1ef2fa3 Author: Gabriel Masei AuthorDate: Mon Nov 15 21:05:17 2021 +0200 Commit: Jan Holesovsky CommitDate: Thu Nov 25 12:12:00 2021 +0100 lok: add pdf version option for export Change-Id: I02c1edecd291309bf028e6e5a0f04a578ac1b639 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125255 Tested-by: Jenkins Reviewed-by: Jan Holesovsky diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 2191a87f5b87..5b6c941e2d08 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2908,6 +2908,33 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha bool bFullSheetPreview = sFullSheetPreview == "true"; +// Select a pdf version if specified a valid one. If not specified then ignore. +// If invalid then fail. +sal_Int32 pdfVer = 0; +if ((aIndex = aFilterOptions.indexOf(",PDFVer=")) >= 0) +{ +int bIndex = aFilterOptions.indexOf("PDFVEREND"); +OUString sPdfVer; +sPdfVer = aFilterOptions.subView(aIndex+8, bIndex-(aIndex+8)); +aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex)) + aFilterOptions.subView(bIndex+9); + +if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-1b")) +pdfVer = 1; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-2b")) +pdfVer = 2; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-3b")) +pdfVer = 3; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.5")) +pdfVer = 15; +else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.6")) +pdfVer = 16; +else +{ +SetLastExceptionMsg("wrong PDF version"); +return false; +} +} + // 'TakeOwnership' == this is a 'real' SaveAs (that is, the document // gets a new name). When this is not provided, the meaning of // saveAs() is more like save-a-copy, which allows saving to any @@ -2944,6 +2971,9 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha if (bFullSheetPreview) aFilterDataMap["SinglePageSheets"] <<= true; +if (pdfVer) +aFilterDataMap["SelectPdfVersion"] <<= pdfVer; + if (!aFilterDataMap.empty()) { aSaveMediaDescriptor["FilterData"] <<= aFilterDataMap.getAsConstPropertyValueList();
[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - vcl/source
vcl/source/window/dialog.cxx | 25 ++--- vcl/source/window/mouse.cxx |3 ++- vcl/source/window/paint.cxx | 17 +++-- vcl/source/window/window2.cxx |5 + vcl/source/window/winproc.cxx | 34 ++ 5 files changed, 58 insertions(+), 26 deletions(-) New commits: commit 16aac413015beac2b5bfc4024810534cbd035452 Author: Gabriel Masei AuthorDate: Wed Jun 16 09:41:12 2021 +0300 Commit: Aron Budea CommitDate: Thu Aug 26 09:23:05 2021 +0200 vcl: check mpWindowImpl for nullptr Change-Id: I492c7d5c1846df7507b1f043b80de4e61ff8ca86 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117282 Tested-by: Jenkins Reviewed-by: Michael Meeks (cherry picked from commit bf6dabe0ebad3cc5bc0edc04ae74fba0190b6203) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121049 Tested-by: Jenkins CollaboraOffice Reviewed-by: Aron Budea diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index a30aa19f71b4..74462fc1c7c5 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -418,7 +418,8 @@ vcl::Window* Dialog::GetDefaultParent(WinBits nStyle) auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; auto it = std::find_if(rExecuteDialogs.rbegin(), rExecuteDialogs.rend(), [](VclPtr& rDialogPtr) { -return pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && +return pParent->ImplGetFirstOverlapWindow() && + pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && rDialogPtr->IsReallyVisible() && rDialogPtr->IsEnabled() && rDialogPtr->IsInputEnabled() && !rDialogPtr->IsInModalMode(); }); if (it != rExecuteDialogs.rend()) @@ -964,12 +965,15 @@ bool Dialog::ImplStartExecute() if ( pParent ) { pParent = pParent->ImplGetFirstOverlapWindow(); -SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", - "Dialog::StartExecuteModal() - Parent not visible" ); -SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", - "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); -SAL_WARN_IF( pParent->IsInModalMode(), "vcl", - "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); +if (pParent) +{ +SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", +"Dialog::StartExecuteModal() - Parent not visible" ); +SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", +"Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); +SAL_WARN_IF( pParent->IsInModalMode(), "vcl", +"Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); +} } #endif @@ -1287,12 +1291,11 @@ void Dialog::ImplSetModalInputMode( bool bModal ) void Dialog::GrabFocusToFirstControl() { -vcl::Window* pFocusControl; +vcl::Window* pFocusControl = nullptr; +vcl::Window* pFirstOverlapWindow = ImplGetFirstOverlapWindow(); // find focus control, even if the dialog has focus -if ( HasFocus() ) -pFocusControl = nullptr; -else +if (!HasFocus() && pFirstOverlapWindow && pFirstOverlapWindow->mpWindowImpl) { // prefer a child window which had focus before pFocusControl = ImplGetFirstOverlapWindow()->mpWindowImpl->mpLastFocusWindow; diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index c1a59bc0dc90..6517ad2d90c1 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -292,7 +292,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) // mark this windows as the last FocusWindow vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow(); -pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; +if (pOverlapWindow->mpWindowImpl) +pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; mpWindowImpl->mpFrameData->mpFocusWin = this; if( !bHasFocus ) diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx index 034eef555d6a..95640db261bb 100644 --- a/vcl/source/window/paint.cxx +++ b/vcl/source/window/paint.cxx @@ -622,6 +622,9 @@ void Window::ImplCallPaint(const vcl::Region* pRegion, ImplPaintFlags nPaintFlag void Window::ImplCallOverlapPaint() { +if (!mpWindowImpl) +return; + // emit overlapping windows first vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap; while ( pTempWindow ) @@ -988,7 +991,7 @@ void Window::ImplValidate() void Window::ImplUpdateAll() { -if (
[Libreoffice-commits] core.git: Changes to 'refs/tags/cp-6.4-40'
Tag 'cp-6.4-40' created by Andras Timar at 2021-06-16 13:12 + cp-6.4-40 Changes since cp-6.4-39-15: --- 0 files changed --- ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - vcl/source
vcl/source/window/dialog.cxx | 25 ++--- vcl/source/window/mouse.cxx |3 ++- vcl/source/window/paint.cxx | 17 +++-- vcl/source/window/window2.cxx |5 + vcl/source/window/winproc.cxx | 34 ++ 5 files changed, 58 insertions(+), 26 deletions(-) New commits: commit cf30850d2e04737ca1c646eef6668f110d7ab883 Author: Gabriel Masei AuthorDate: Wed Jun 16 09:41:12 2021 +0300 Commit: Andras Timar CommitDate: Wed Jun 16 12:51:13 2021 +0200 vcl: check mpWindowImpl for nullptr Change-Id: I492c7d5c1846df7507b1f043b80de4e61ff8ca86 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117282 Tested-by: Jenkins Reviewed-by: Michael Meeks (cherry picked from commit bf6dabe0ebad3cc5bc0edc04ae74fba0190b6203) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117292 Tested-by: Jenkins CollaboraOffice Reviewed-by: Andras Timar diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index 3cbffb41da66..a68a6a8e4249 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -416,7 +416,8 @@ vcl::Window* Dialog::GetDefaultParent(WinBits nStyle) auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; auto it = std::find_if(rExecuteDialogs.rbegin(), rExecuteDialogs.rend(), [](VclPtr& rDialogPtr) { -return pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && +return pParent->ImplGetFirstOverlapWindow() && + pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && rDialogPtr->IsReallyVisible() && rDialogPtr->IsEnabled() && rDialogPtr->IsInputEnabled() && !rDialogPtr->IsInModalMode(); }); if (it != rExecuteDialogs.rend()) @@ -962,12 +963,15 @@ bool Dialog::ImplStartExecute() if ( pParent ) { pParent = pParent->ImplGetFirstOverlapWindow(); -SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", - "Dialog::StartExecuteModal() - Parent not visible" ); -SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", - "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); -SAL_WARN_IF( pParent->IsInModalMode(), "vcl", - "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); +if (pParent) +{ +SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", +"Dialog::StartExecuteModal() - Parent not visible" ); +SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", +"Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); +SAL_WARN_IF( pParent->IsInModalMode(), "vcl", +"Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); +} } #endif @@ -1264,12 +1268,11 @@ void Dialog::ImplSetModalInputMode( bool bModal ) void Dialog::GrabFocusToFirstControl() { -vcl::Window* pFocusControl; +vcl::Window* pFocusControl = nullptr; +vcl::Window* pFirstOverlapWindow = ImplGetFirstOverlapWindow(); // find focus control, even if the dialog has focus -if ( HasFocus() ) -pFocusControl = nullptr; -else +if (!HasFocus() && pFirstOverlapWindow && pFirstOverlapWindow->mpWindowImpl) { // prefer a child window which had focus before pFocusControl = ImplGetFirstOverlapWindow()->mpWindowImpl->mpLastFocusWindow; diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index e2f0458bf0fe..513b186b2dc7 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -292,7 +292,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) // mark this windows as the last FocusWindow vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow(); -pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; +if (pOverlapWindow->mpWindowImpl) +pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; mpWindowImpl->mpFrameData->mpFocusWin = this; if( !bHasFocus ) diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx index 218cdd3216ed..f361e49d392b 100644 --- a/vcl/source/window/paint.cxx +++ b/vcl/source/window/paint.cxx @@ -622,6 +622,9 @@ void Window::ImplCallPaint(const vcl::Region* pRegion, ImplPaintFlags nPaintFlag void Window::ImplCallOverlapPaint() { +if (!mpWindowImpl) +return; + // emit overlapping windows first vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap; while ( pTempWindow ) @@ -988,7 +991,7 @@ void Window::ImplValidate() void Window::ImplUpdateAll() { -if (
[Libreoffice-commits] core.git: vcl/source
vcl/source/window/dialog.cxx | 25 ++--- vcl/source/window/mouse.cxx |3 ++- vcl/source/window/paint.cxx | 17 +++-- vcl/source/window/window2.cxx |5 + vcl/source/window/winproc.cxx | 34 ++ 5 files changed, 58 insertions(+), 26 deletions(-) New commits: commit bf6dabe0ebad3cc5bc0edc04ae74fba0190b6203 Author: Gabriel Masei AuthorDate: Wed Jun 16 09:41:12 2021 +0300 Commit: Michael Meeks CommitDate: Wed Jun 16 10:16:50 2021 +0200 vcl: check mpWindowImpl for nullptr Change-Id: I492c7d5c1846df7507b1f043b80de4e61ff8ca86 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117282 Tested-by: Jenkins Reviewed-by: Michael Meeks diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index 538ad37b0ede..f9c6e3b1b503 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -418,7 +418,8 @@ vcl::Window* Dialog::GetDefaultParent(WinBits nStyle) auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; auto it = std::find_if(rExecuteDialogs.rbegin(), rExecuteDialogs.rend(), [](VclPtr& rDialogPtr) { -return pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && +return pParent->ImplGetFirstOverlapWindow() && + pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && rDialogPtr->IsReallyVisible() && rDialogPtr->IsEnabled() && rDialogPtr->IsInputEnabled() && !rDialogPtr->IsInModalMode(); }); if (it != rExecuteDialogs.rend()) @@ -963,12 +964,15 @@ bool Dialog::ImplStartExecute() if ( pParent ) { pParent = pParent->ImplGetFirstOverlapWindow(); -SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", - "Dialog::StartExecuteModal() - Parent not visible" ); -SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", - "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); -SAL_WARN_IF( pParent->IsInModalMode(), "vcl", - "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); +if (pParent) +{ +SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", +"Dialog::StartExecuteModal() - Parent not visible" ); +SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", +"Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); +SAL_WARN_IF( pParent->IsInModalMode(), "vcl", +"Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); +} } #endif @@ -1284,12 +1288,11 @@ void Dialog::ImplSetModalInputMode( bool bModal ) void Dialog::GrabFocusToFirstControl() { -vcl::Window* pFocusControl; +vcl::Window* pFocusControl = nullptr; +vcl::Window* pFirstOverlapWindow = ImplGetFirstOverlapWindow(); // find focus control, even if the dialog has focus -if ( HasFocus() ) -pFocusControl = nullptr; -else +if (!HasFocus() && pFirstOverlapWindow && pFirstOverlapWindow->mpWindowImpl) { // prefer a child window which had focus before pFocusControl = ImplGetFirstOverlapWindow()->mpWindowImpl->mpLastFocusWindow; diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index b2f978dbe7cf..1c0eaa3ba3cc 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -291,7 +291,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) // mark this windows as the last FocusWindow vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow(); -pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; +if (pOverlapWindow->mpWindowImpl) +pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; mpWindowImpl->mpFrameData->mpFocusWin = this; if( !bHasFocus ) diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx index d595bd78d82d..734e4d8ed63b 100644 --- a/vcl/source/window/paint.cxx +++ b/vcl/source/window/paint.cxx @@ -623,6 +623,9 @@ void Window::ImplCallPaint(const vcl::Region* pRegion, ImplPaintFlags nPaintFlag void Window::ImplCallOverlapPaint() { +if (!mpWindowImpl) +return; + // emit overlapping windows first vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap; while ( pTempWindow ) @@ -985,7 +988,7 @@ void Window::ImplValidate() void Window::ImplUpdateAll() { -if ( !mpWindowImpl->mbReallyVisible ) +if ( !mpWindowImpl || !mpWindowImpl->mbReallyVisible ) return; bool bFlush = false; @@ -1264,6 +1267,9 @@ bool Window::HasPaintEvent() const void
[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - 3 commits - configure.ac sw/inc sw/source vcl/source
configure.ac |2 - sw/inc/strings.hrc |3 -- sw/inc/view.hxx |3 -- sw/source/uibase/uiview/view.cxx | 35 - vcl/source/window/mouse.cxx | 19 +-- vcl/source/window/toolbox.cxx|4 +-- vcl/source/window/winproc.cxx| 47 --- 7 files changed, 44 insertions(+), 69 deletions(-) New commits: commit f1f0c101109bcf9b54a47bf1010376fd8736e56c Author: Gabriel Masei AuthorDate: Fri May 28 14:37:52 2021 +0300 Commit: Andras Timar CommitDate: Mon Jun 14 08:11:34 2021 +0200 vcl: check mpWindowImpl before referencing it Fixed some cases generating crashes because mpWindowImpl was not checked for nullptr. Change-Id: I5540f9f21a870b02655b5bf2afdbf3a8153c1519 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116330 Tested-by: Jenkins Reviewed-by: Jan Holesovsky diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index fbe81aed7499..2a1583a3ba5c 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -252,7 +252,7 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) bool bAsyncFocusWaiting = false; vcl::Window *pFrame = pSVData->maFrameData.mpFirstFrame; -while( pFrame ) +while( pFrame && pFrame->mpWindowImpl && pFrame->mpWindowImpl->mpFrameData ) { if( pFrame != mpWindowImpl->mpFrameWindow.get() && pFrame->mpWindowImpl->mpFrameData->mnFocusId ) { @@ -275,6 +275,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) bMustNotGrabFocus = true; break; } +if (!pParent->mpWindowImpl) +break; pParent = pParent->mpWindowImpl->mpParent; } @@ -332,13 +334,16 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) else { vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow(); -vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); -pNewOverlapWindow->mpWindowImpl->mbActive = true; -pNewOverlapWindow->Activate(); -if ( pNewRealWindow != pNewOverlapWindow ) +if ( pNewOverlapWindow && pNewOverlapWindow->mpWindowImpl ) { -pNewRealWindow->mpWindowImpl->mbActive = true; -pNewRealWindow->Activate(); +vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); +pNewOverlapWindow->mpWindowImpl->mbActive = true; +pNewOverlapWindow->Activate(); +if ( pNewRealWindow != pNewOverlapWindow && pNewRealWindow && pNewRealWindow->mpWindowImpl ) +{ +pNewRealWindow->mpWindowImpl->mbActive = true; +pNewRealWindow->Activate(); +} } } diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx index 289f9e522954..11aab62126f6 100644 --- a/vcl/source/window/toolbox.cxx +++ b/vcl/source/window/toolbox.cxx @@ -3050,7 +3050,7 @@ void ToolBox::MouseMove( const MouseEvent& rMEvt ) vcl::Window *pWin = pFocusWin->GetParent(); while (pWin) { -if(pWin->ImplGetWindowImpl()->mbToolBox) +if(pWin->ImplGetWindowImpl() && pWin->ImplGetWindowImpl()->mbToolBox) { bFocusWindowIsAToolBoxChild = true; break; @@ -3059,7 +3059,7 @@ void ToolBox::MouseMove( const MouseEvent& rMEvt ) } } -if( bFocusWindowIsAToolBoxChild || (pFocusWin && pFocusWin->ImplGetWindowImpl()->mbToolBox && pFocusWin != this) ) +if( bFocusWindowIsAToolBoxChild || (pFocusWin && pFocusWin->ImplGetWindowImpl() && pFocusWin->ImplGetWindowImpl()->mbToolBox && pFocusWin != this) ) bDrawHotSpot = false; if ( mbDragging ) diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index aab2cb21bb21..4e1f4f5117d3 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -810,17 +810,20 @@ static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow ) vcl::Window* pChild = pSVData->mpWinData->mpFirstFloat; while (pChild) { -if (pChild->ImplGetWindowImpl()->mbFloatWin) +if (pChild->ImplGetWindowImpl()) { -if (static_cast(pChild)->GrabsFocus()) -break; -} -else if (pChild->ImplGetWindowImpl()->mbDockWin) -{ -vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent); -if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin && -static_cast(pParent)->GrabsFocus()) -break; +if (pChild->ImplGetWindowImpl()->mbFloatWin) +{ +if (static_cast(pChild)->GrabsFocus()) +break; +} +else if (pChild->ImplGetWindowImpl()->mbDockWin) +{ +vcl::Window* pParent =
[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - vcl/source
vcl/source/window/mouse.cxx | 19 ++-- vcl/source/window/toolbox.cxx |4 +-- vcl/source/window/winproc.cxx | 47 +- 3 files changed, 43 insertions(+), 27 deletions(-) New commits: commit 5a1c5c9495f31820d55ba77b0cf5dfe10ab0e6f7 Author: Gabriel Masei AuthorDate: Fri May 28 14:37:52 2021 +0300 Commit: Dennis Francis CommitDate: Sat Jun 12 07:30:30 2021 +0200 vcl: check mpWindowImpl before referencing it. Fixed some cases generating crashes because mpWindowImpl was not checked for nullptr. Change-Id: I5540f9f21a870b02655b5bf2afdbf3a8153c1519 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116466 Tested-by: Jenkins CollaboraOffice Reviewed-by: Dennis Francis diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index 16993d199987..e2f0458bf0fe 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -252,7 +252,7 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) bool bAsyncFocusWaiting = false; vcl::Window *pFrame = pSVData->maFrameData.mpFirstFrame; -while( pFrame ) +while( pFrame && pFrame->mpWindowImpl && pFrame->mpWindowImpl->mpFrameData ) { if( pFrame != mpWindowImpl->mpFrameWindow.get() && pFrame->mpWindowImpl->mpFrameData->mnFocusId ) { @@ -275,6 +275,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) bMustNotGrabFocus = true; break; } +if (!pParent->mpWindowImpl) +break; pParent = pParent->mpWindowImpl->mpParent; } @@ -332,13 +334,16 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) else { vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow(); -vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); -pNewOverlapWindow->mpWindowImpl->mbActive = true; -pNewOverlapWindow->Activate(); -if ( pNewRealWindow != pNewOverlapWindow ) +if ( pNewOverlapWindow && pNewOverlapWindow->mpWindowImpl ) { -pNewRealWindow->mpWindowImpl->mbActive = true; -pNewRealWindow->Activate(); +vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); +pNewOverlapWindow->mpWindowImpl->mbActive = true; +pNewOverlapWindow->Activate(); +if ( pNewRealWindow != pNewOverlapWindow && pNewRealWindow && pNewRealWindow->mpWindowImpl ) +{ +pNewRealWindow->mpWindowImpl->mbActive = true; +pNewRealWindow->Activate(); +} } } diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx index e7a15643f111..0a255688dd46 100644 --- a/vcl/source/window/toolbox.cxx +++ b/vcl/source/window/toolbox.cxx @@ -3077,7 +3077,7 @@ void ToolBox::MouseMove( const MouseEvent& rMEvt ) vcl::Window *pWin = pFocusWin->GetParent(); while (pWin) { -if(pWin->ImplGetWindowImpl()->mbToolBox) +if(pWin->ImplGetWindowImpl() && pWin->ImplGetWindowImpl()->mbToolBox) { bFocusWindowIsAToolBoxChild = true; break; @@ -3086,7 +3086,7 @@ void ToolBox::MouseMove( const MouseEvent& rMEvt ) } } -if( bFocusWindowIsAToolBoxChild || (pFocusWin && pFocusWin->ImplGetWindowImpl()->mbToolBox && pFocusWin != this) ) +if( bFocusWindowIsAToolBoxChild || (pFocusWin && pFocusWin->ImplGetWindowImpl() && pFocusWin->ImplGetWindowImpl()->mbToolBox && pFocusWin != this) ) bDrawHotSpot = false; if ( mbSelection && bDrawHotSpot ) diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index cd6e91b21f7e..fe3b8bee916d 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -810,17 +810,20 @@ static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow ) vcl::Window* pChild = pSVData->mpWinData->mpFirstFloat; while (pChild) { -if (pChild->ImplGetWindowImpl()->mbFloatWin) +if (pChild->ImplGetWindowImpl()) { -if (static_cast(pChild)->GrabsFocus()) -break; -} -else if (pChild->ImplGetWindowImpl()->mbDockWin) -{ -vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent); -if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin && -static_cast(pParent)->GrabsFocus()) -break; +if (pChild->ImplGetWindowImpl()->mbFloatWin) +{ +if (static_cast(pChild)->GrabsFocus()) +break; +} +else if (pChild->ImplGetWindowImpl()->mbDockWin) +{ +vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent); +if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin && +static_cast(pParent)->GrabsFocus()) +
[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - vcl/source
vcl/source/window/mouse.cxx | 19 ++-- vcl/source/window/toolbox.cxx |2 - vcl/source/window/winproc.cxx | 47 +- 3 files changed, 42 insertions(+), 26 deletions(-) New commits: commit 54916b178bdee9be0f3faef7b62aa735cb3d3ab5 Author: Gabriel Masei AuthorDate: Fri May 28 14:37:52 2021 +0300 Commit: Dennis Francis CommitDate: Wed Jun 9 11:01:04 2021 +0200 vcl: check mpWindowImpl before referencing it Fixed some cases generating crashes because mpWindowImpl was not checked for nullptr. Conflicts: vcl/source/window/toolbox.cxx Change-Id: I5540f9f21a870b02655b5bf2afdbf3a8153c1519 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116330 Tested-by: Jenkins Reviewed-by: Jan Holesovsky Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116774 Tested-by: Jenkins CollaboraOffice Reviewed-by: Gabriel Masei Reviewed-by: Dennis Francis diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index 47116725856f..663da0ff872c 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -253,7 +253,7 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) bool bAsyncFocusWaiting = false; vcl::Window *pFrame = pSVData->maFrameData.mpFirstFrame; -while( pFrame ) +while( pFrame && pFrame->mpWindowImpl && pFrame->mpWindowImpl->mpFrameData ) { if( pFrame != mpWindowImpl->mpFrameWindow.get() && pFrame->mpWindowImpl->mpFrameData->mnFocusId ) { @@ -276,6 +276,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) bMustNotGrabFocus = true; break; } +if (!pParent->mpWindowImpl) +break; pParent = pParent->mpWindowImpl->mpParent; } @@ -333,13 +335,16 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) else { vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow(); -vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); -pNewOverlapWindow->mpWindowImpl->mbActive = true; -pNewOverlapWindow->Activate(); -if ( pNewRealWindow != pNewOverlapWindow ) +if ( pNewOverlapWindow && pNewOverlapWindow->mpWindowImpl ) { -pNewRealWindow->mpWindowImpl->mbActive = true; -pNewRealWindow->Activate(); +vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); +pNewOverlapWindow->mpWindowImpl->mbActive = true; +pNewOverlapWindow->Activate(); +if ( pNewRealWindow != pNewOverlapWindow && pNewRealWindow && pNewRealWindow->mpWindowImpl ) +{ +pNewRealWindow->mpWindowImpl->mbActive = true; +pNewRealWindow->Activate(); +} } } diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx index ef8641986555..0d22f446dea7 100644 --- a/vcl/source/window/toolbox.cxx +++ b/vcl/source/window/toolbox.cxx @@ -3209,7 +3209,7 @@ void ToolBox::MouseMove( const MouseEvent& rMEvt ) // and do not highlight when focus is in a different toolbox bool bDrawHotSpot = true; vcl::Window *pWin = Application::GetFocusWindow(); -if( pWin && pWin->ImplGetWindowImpl()->mbToolBox && pWin != this ) +if( pWin && pWin->ImplGetWindowImpl() && pWin->ImplGetWindowImpl()->mbToolBox && pWin != this ) bDrawHotSpot = false; if ( mbSelection && bDrawHotSpot ) diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index 31620bc6a0ac..4dea82046299 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -814,17 +814,20 @@ static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow ) vcl::Window* pChild = pSVData->mpWinData->mpFirstFloat; while (pChild) { -if (pChild->ImplGetWindowImpl()->mbFloatWin) +if (pChild->ImplGetWindowImpl()) { -if (static_cast(pChild)->GrabsFocus()) -break; -} -else if (pChild->ImplGetWindowImpl()->mbDockWin) -{ -vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent); -if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin && -static_cast(pParent)->GrabsFocus()) -break; +if (pChild->ImplGetWindowImpl()->mbFloatWin) +{ +if (static_cast(pChild)->GrabsFocus()) +break; +} +else if (pChild->ImplGetWindowImpl()->mbDockWin) +{ +vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent); +if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin && +static_cast(pParent)->GrabsFocus()) +break; +} } pChild = pChild->GetParent(); } @@ -832,7 +835,7 @@ static vcl::Window*
[Libreoffice-commits] core.git: vcl/source
vcl/source/window/mouse.cxx | 19 ++-- vcl/source/window/toolbox.cxx |4 +-- vcl/source/window/winproc.cxx | 47 +- 3 files changed, 43 insertions(+), 27 deletions(-) New commits: commit 71888075c160d97855f35b306bd6eb01a2922d1f Author: Gabriel Masei AuthorDate: Fri May 28 14:37:52 2021 +0300 Commit: Gabriel Masei CommitDate: Thu Jun 3 11:06:37 2021 +0200 vcl: check mpWindowImpl before referencing it Fixed some cases generating crashes because mpWindowImpl was not checked for nullptr. Change-Id: I5540f9f21a870b02655b5bf2afdbf3a8153c1519 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116330 Tested-by: Jenkins Reviewed-by: Jan Holesovsky diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index d1b3590ed97b..b2f978dbe7cf 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -251,7 +251,7 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) bool bAsyncFocusWaiting = false; vcl::Window *pFrame = pSVData->maFrameData.mpFirstFrame; -while( pFrame ) +while( pFrame && pFrame->mpWindowImpl && pFrame->mpWindowImpl->mpFrameData ) { if( pFrame != mpWindowImpl->mpFrameWindow.get() && pFrame->mpWindowImpl->mpFrameData->mnFocusId ) { @@ -274,6 +274,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) bMustNotGrabFocus = true; break; } +if (!pParent->mpWindowImpl) +break; pParent = pParent->mpWindowImpl->mpParent; } @@ -331,13 +333,16 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) else { vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow(); -vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); -pNewOverlapWindow->mpWindowImpl->mbActive = true; -pNewOverlapWindow->Activate(); -if ( pNewRealWindow != pNewOverlapWindow ) +if ( pNewOverlapWindow && pNewOverlapWindow->mpWindowImpl ) { -pNewRealWindow->mpWindowImpl->mbActive = true; -pNewRealWindow->Activate(); +vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); +pNewOverlapWindow->mpWindowImpl->mbActive = true; +pNewOverlapWindow->Activate(); +if ( pNewRealWindow != pNewOverlapWindow && pNewRealWindow && pNewRealWindow->mpWindowImpl ) +{ +pNewRealWindow->mpWindowImpl->mbActive = true; +pNewRealWindow->Activate(); +} } } diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx index a993b697b100..38704c2dae69 100644 --- a/vcl/source/window/toolbox.cxx +++ b/vcl/source/window/toolbox.cxx @@ -3057,7 +3057,7 @@ void ToolBox::MouseMove( const MouseEvent& rMEvt ) vcl::Window *pWin = pFocusWin->GetParent(); while (pWin) { -if(pWin->ImplGetWindowImpl()->mbToolBox) +if(pWin->ImplGetWindowImpl() && pWin->ImplGetWindowImpl()->mbToolBox) { bFocusWindowIsAToolBoxChild = true; break; @@ -3066,7 +3066,7 @@ void ToolBox::MouseMove( const MouseEvent& rMEvt ) } } -if( bFocusWindowIsAToolBoxChild || (pFocusWin && pFocusWin->ImplGetWindowImpl()->mbToolBox && pFocusWin != this) ) +if( bFocusWindowIsAToolBoxChild || (pFocusWin && pFocusWin->ImplGetWindowImpl() && pFocusWin->ImplGetWindowImpl()->mbToolBox && pFocusWin != this) ) bDrawHotSpot = false; if ( mbDragging ) diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index dfb7a89e6aa0..80e306b17625 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -805,17 +805,20 @@ static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow ) vcl::Window* pChild = pSVData->mpWinData->mpFirstFloat; while (pChild) { -if (pChild->ImplGetWindowImpl()->mbFloatWin) +if (pChild->ImplGetWindowImpl()) { -if (static_cast(pChild)->GrabsFocus()) -break; -} -else if (pChild->ImplGetWindowImpl()->mbDockWin) -{ -vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent); -if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin && -static_cast(pParent)->GrabsFocus()) -break; +if (pChild->ImplGetWindowImpl()->mbFloatWin) +{ +if (static_cast(pChild)->GrabsFocus()) +break; +} +else if (pChild->ImplGetWindowImpl()->mbDockWin) +{ +vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent); +if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin && +static_cast(pParent)->GrabsFocus()) +break; +}
[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - sfx2/source
sfx2/source/control/unoctitm.cxx |6 +- 1 file changed, 5 insertions(+), 1 deletion(-) New commits: commit 8bac13f3295f5403a6ea26bba6437d707d1bdbbc Author: Gabriel Masei AuthorDate: Wed Apr 7 12:46:27 2021 +0300 Commit: Szymon Kłos CommitDate: Mon Apr 12 09:42:23 2021 +0200 lok: intercept indentation and decimals state change events This solves some toolbar buttons enabling issues in online when dynamically changing UI mode to classic. Change-Id: I3301b92c35effce905f1283ae645d8ad2b168ece Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113723 Tested-by: Jenkins Reviewed-by: Szymon Kłos (cherry picked from commit 8859e62d7dfaa71c35f80b5eff99b0788b49c9fa) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113766 Reviewed-by: Gabriel Masei Tested-by: Jenkins CollaboraOffice diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx index dc1e80cbf1b4..694959d327e6 100644 --- a/sfx2/source/control/unoctitm.cxx +++ b/sfx2/source/control/unoctitm.cxx @@ -1169,7 +1169,11 @@ static void InterceptLOKStateChangeEvent(sal_uInt16 nSID, SfxViewFrame* pViewFra aEvent.FeatureURL.Path == "Substract" || aEvent.FeatureURL.Path == "DistributeSelection" || aEvent.FeatureURL.Path == "Intersect" || - aEvent.FeatureURL.Path == "ResetAttributes") + aEvent.FeatureURL.Path == "ResetAttributes" || + aEvent.FeatureURL.Path == "IncrementIndent" || + aEvent.FeatureURL.Path == "DecrementIndent" || + aEvent.FeatureURL.Path == "NumberFormatDecDecimals" || + aEvent.FeatureURL.Path == "NumberFormatIncDecimals") { aBuffer.append(aEvent.IsEnabled ? OUStringLiteral("enabled") : OUStringLiteral("disabled")); } ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: sfx2/source
sfx2/source/control/unoctitm.cxx |6 +- 1 file changed, 5 insertions(+), 1 deletion(-) New commits: commit 8859e62d7dfaa71c35f80b5eff99b0788b49c9fa Author: Gabriel Masei AuthorDate: Wed Apr 7 12:46:27 2021 +0300 Commit: Szymon Kłos CommitDate: Fri Apr 9 10:53:05 2021 +0200 lok: intercept indentation and decimals state change events This solves some toolbar buttons enabling issues in online when dynamically changing UI mode to classic. Change-Id: I3301b92c35effce905f1283ae645d8ad2b168ece Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113723 Tested-by: Jenkins Reviewed-by: Szymon Kłos diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx index 64f097503256..ecee69062180 100644 --- a/sfx2/source/control/unoctitm.cxx +++ b/sfx2/source/control/unoctitm.cxx @@ -1170,7 +1170,11 @@ static void InterceptLOKStateChangeEvent(sal_uInt16 nSID, SfxViewFrame* pViewFra aEvent.FeatureURL.Path == "Substract" || aEvent.FeatureURL.Path == "DistributeSelection" || aEvent.FeatureURL.Path == "Intersect" || - aEvent.FeatureURL.Path == "ResetAttributes") + aEvent.FeatureURL.Path == "ResetAttributes" || + aEvent.FeatureURL.Path == "IncrementIndent" || + aEvent.FeatureURL.Path == "DecrementIndent" || + aEvent.FeatureURL.Path == "NumberFormatDecDecimals" || + aEvent.FeatureURL.Path == "NumberFormatIncDecimals") { aBuffer.append(aEvent.IsEnabled ? std::u16string_view(u"enabled") : std::u16string_view(u"disabled")); } ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - desktop/source sc/source
desktop/source/lib/init.cxx| 15 ++- sc/source/ui/view/tabvwsha.cxx | 19 --- 2 files changed, 22 insertions(+), 12 deletions(-) New commits: commit 2d4e43ef8c6f563087330c180b18ef83a1fad207 Author: Gabriel Masei AuthorDate: Wed Sep 2 19:22:23 2020 +0300 Commit: Jan Holesovsky CommitDate: Mon Sep 21 16:57:35 2020 +0200 lok: remove .uno:ModifiedStatus message from deduplication mechanism This fixes the following issue in Online: When a save is performed while a cell is still edited the save icon does not reflect the correct state of the document: it shows that the document is dirty although it is not. This is generated by two facts: 1. The status cache is avoided when sending the -dirty- status right after the cell editing is finished. Because the cache has an old value of -false- for ModifiedStatus, the notification that is sent after saving, with -false- value, is ignored. We should not avoid the status cache. 2. Because there is a mechanism that keeps only the last notification value for a status change in the queue that keeps messages that were not sent yet (deduplication), the .uno:ModifiedStatus message with a value of -true- that is enqueued right after the cell edit is finished is replaced by the same message with a value of -false- that is enqueued after the save is finished. This happens if the flush mechanism doesn't occur between them. Change-Id: I3348bf230ba53a154c29e7d8ab064df7694adeae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103053 Reviewed-by: Gabriel Masei Reviewed-by: Jan Holesovsky Tested-by: Jenkins CollaboraOffice diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index eaba422a3e4a..2dffed0204b5 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1584,11 +1584,16 @@ void CallbackFlushHandler::queue(const int type, const char* data) if (pos != std::string::npos) { const std::string name = payload.substr(0, pos + 1); -removeAll( -[type, ] (const queue_type::value_type& elem) { -return (elem.Type == type) && (elem.PayloadString.compare(0, name.size(), name) == 0); -} -); +// This is needed because otherwise it creates some problems when +// a save occurs while a cell is still edited in Calc. +if (name != ".uno:ModifiedStatus=") +{ +removeAll( +[type, ] (const queue_type::value_type& elem) { +return (elem.Type == type) && (elem.PayloadString.compare(0, name.size(), name) == 0); +} +); +} } } break; diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx index f527e539b62b..19ac69aec2d0 100644 --- a/sc/source/ui/view/tabvwsha.cxx +++ b/sc/source/ui/view/tabvwsha.cxx @@ -745,20 +745,25 @@ void ScTabViewShell::ExecuteSave( SfxRequest& rReq ) // Finish entering unless 'DontTerminateEdit' is specified, even if a formula is being processed if (bCommitChanges) { +SC_MOD()->InputEnterHandler(); + if (comphelper::LibreOfficeKit::isActive()) { // Normally this isn't needed, but in Calc when editing a cell formula // and manually saving (without changing cells or hitting enter), while // InputEnterHandler will mark the doc as modified (when it is), because // we will save the doc immediately afterwards, the modified state event -// is clobbered. To avoid that, we notify all views immediately of the -// modified state, apply the modification, then save the document. -ScInputHandler* pHdl = GetInputHandler(); -if (pHdl != nullptr && pHdl->GetModified()) -SfxLokHelper::notifyAllViews(LOK_CALLBACK_STATE_CHANGED, ".uno:ModifiedStatus=true"); +// is clobbered. To avoid that, we need to update SID_DOC_MODIFIED so that +// a possible state of "true" after "InputEnterHandler" will be sent +// as a notification. It is important that the notification goes through +// normal process (cache) rather than directly notifying the views. +// Otherwise, because there is a previous state of "false" in cache, the +// "false" state after saving will be ignored. +// This will work only if .uno:ModifiedStatus message will be removed from +// the mechanism that keeps in the message queue only last message of +// a particular status even if the values are different. +
[Libreoffice-commits] online.git: common/MessageQueue.cpp
common/MessageQueue.cpp |5 + 1 file changed, 5 insertions(+) New commits: commit 95c9c58f5b3f8116aef348f48ce4583df59718a2 Author: Gabriel Masei AuthorDate: Mon Sep 21 09:46:38 2020 +0300 Commit: Jan Holesovsky CommitDate: Mon Sep 21 14:51:10 2020 +0200 remove .uno:ModifiedStatus message from deduplication mechanism This fixes the following issue in Online: When a save is performed while a cell is still edited the save icon does not reflect the correct state of the document: it shows that the document is dirty although it is not. This works only in conjunction with the following commit from core: -lok: remove .uno:ModifiedStatus message from deduplication mechanism- Change-Id: Ie671097ef2b206c8801a5bdfc2b908ee260951fb Reviewed-on: https://gerrit.libreoffice.org/c/online/+/103084 Tested-by: Jenkins CollaboraOffice Reviewed-by: Jan Holesovsky diff --git a/common/MessageQueue.cpp b/common/MessageQueue.cpp index f239a2e9c..632c696b3 100644 --- a/common/MessageQueue.cpp +++ b/common/MessageQueue.cpp @@ -324,6 +324,11 @@ std::string TileQueue::removeCallbackDuplicate(const std::string& callbackMsg) if (unoCommand.empty()) return std::string(); +// This is needed because otherwise it creates some problems when +// a save occurs while a cell is still edited in Calc. +if (unoCommand == ".uno:ModifiedStatus") +return std::string(); + // remove obsolete states of the same .uno: command for (std::size_t i = 0; i < getQueue().size(); ++i) { ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: desktop/source sc/source
desktop/source/lib/init.cxx| 15 ++- sc/source/ui/view/tabvwsha.cxx | 19 --- 2 files changed, 22 insertions(+), 12 deletions(-) New commits: commit 137440e161f0f8631e7e67ba0609680d6686fa94 Author: Gabriel Masei AuthorDate: Wed Sep 2 19:22:23 2020 +0300 Commit: Jan Holesovsky CommitDate: Mon Sep 21 14:39:17 2020 +0200 lok: remove .uno:ModifiedStatus message from deduplication mechanism This fixes the following issue in Online: When a save is performed while a cell is still edited the save icon does not reflect the correct state of the document: it shows that the document is dirty although it is not. This is generated by two facts: 1. The status cache is avoided when sending the -dirty- status right after the cell editing is finished. Because the cache has an old value of -false- for ModifiedStatus, the notification that is sent after saving, with -false- value, is ignored. We should not avoid the status cache. 2. Because there is a mechanism that keeps only the last notification value for a status change in the queue that keeps messages that were not sent yet (deduplication), the .uno:ModifiedStatus message with a value of -true- that is enqueued right after the cell edit is finished is replaced by the same message with a value of -false- that is enqueued after the save is finished. This happens if the flush mechanism doesn't occur between them. Change-Id: I3348bf230ba53a154c29e7d8ab064df7694adeae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101948 Tested-by: Jenkins Reviewed-by: Jan Holesovsky diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index a5c2b7c4ea8b..ecef209842a8 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1571,11 +1571,16 @@ void CallbackFlushHandler::queue(const int type, const char* data) if (pos != std::string::npos) { const std::string name = payload.substr(0, pos + 1); -removeAll( -[type, ] (const queue_type::value_type& elem) { -return (elem.Type == type) && (elem.PayloadString.compare(0, name.size(), name) == 0); -} -); +// This is needed because otherwise it creates some problems when +// a save occurs while a cell is still edited in Calc. +if (name != ".uno:ModifiedStatus=") +{ +removeAll( +[type, ] (const queue_type::value_type& elem) { +return (elem.Type == type) && (elem.PayloadString.compare(0, name.size(), name) == 0); +} +); +} } } break; diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx index 210500e651d9..211a047c9bb1 100644 --- a/sc/source/ui/view/tabvwsha.cxx +++ b/sc/source/ui/view/tabvwsha.cxx @@ -742,20 +742,25 @@ void ScTabViewShell::ExecuteSave( SfxRequest& rReq ) // Finish entering unless 'DontTerminateEdit' is specified, even if a formula is being processed if (bCommitChanges) { +SC_MOD()->InputEnterHandler(); + if (comphelper::LibreOfficeKit::isActive()) { // Normally this isn't needed, but in Calc when editing a cell formula // and manually saving (without changing cells or hitting enter), while // InputEnterHandler will mark the doc as modified (when it is), because // we will save the doc immediately afterwards, the modified state event -// is clobbered. To avoid that, we notify all views immediately of the -// modified state, apply the modification, then save the document. -ScInputHandler* pHdl = GetInputHandler(); -if (pHdl != nullptr && pHdl->GetModified()) -SfxLokHelper::notifyAllViews(LOK_CALLBACK_STATE_CHANGED, ".uno:ModifiedStatus=true"); +// is clobbered. To avoid that, we need to update SID_DOC_MODIFIED so that +// a possible state of "true" after "InputEnterHandler" will be sent +// as a notification. It is important that the notification goes through +// normal process (cache) rather than directly notifying the views. +// Otherwise, because there is a previous state of "false" in cache, the +// "false" state after saving will be ignored. +// This will work only if .uno:ModifiedStatus message will be removed from +// the mechanism that keeps in the message queue only last message of +// a particular status even if the values are different. +
[Libreoffice-commits] online.git: Branch 'distro/collabora/co-4-2' - kit/ChildSession.cpp kit/Kit.cpp net/Socket.hpp net/WebSocketHandler.hpp
kit/ChildSession.cpp |9 + kit/Kit.cpp | 10 ++ net/Socket.hpp | 41 ++--- net/WebSocketHandler.hpp | 16 4 files changed, 73 insertions(+), 3 deletions(-) New commits: commit 39a5f4ac30268ddbf012f7f4816edda3a8ddb6b4 Author: Gabriel Masei AuthorDate: Fri Jul 10 15:22:35 2020 +0300 Commit: Andras Timar CommitDate: Sun Jul 26 23:18:24 2020 +0200 kit: disable parallel handling of messages while processing load and save The map._activate, among other actions, is sending indirectly some messages to the server like clientzoom and clientvisiblearea. If these messages are send before the document finishes processing the load message then there is a chance that a nodocloaded error will be thrown because there is a chance that the messages will be processed in parallel with load. This happens constantly for xlsx files. This is generated by the Unipoll mechanism which, in case of xlsx files, triggers a parallel processing. To avoid the above scenario a mechanism of disabling parallel processing of messages in kit was implemented and is used for load and save messages, for now. Change-Id: I4c83e72e600f92d0bb4f1f18cebe694e326256d0 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/98519 Tested-by: Jenkins Tested-by: Michael Meeks Reviewed-by: Michael Meeks Reviewed-on: https://gerrit.libreoffice.org/c/online/+/99275 Tested-by: Jenkins CollaboraOffice Reviewed-by: Andras Timar diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index b0aa69701..71440c290 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -212,6 +212,8 @@ bool ChildSession::_handleInput(const char *buffer, int length) return false; } +// Disable processing of other messages while loading document +InputProcessingManager processInput(getProtocol(), false); _isDocLoaded = loadDocument(buffer, length, tokens); LOG_TRC("isDocLoaded state after loadDocument: " << _isDocLoaded << '.'); @@ -379,6 +381,13 @@ bool ChildSession::_handleInput(const char *buffer, int length) newTokens.push_back(firstLine.substr(4)); // Copy the remaining part. return unoCommand(buffer, length, newTokens); } +else if (tokens[1].find(".uno:Save") != std::string::npos) +{ +// Disable processing of other messages while saving document +InputProcessingManager processInput(getProtocol(), false); +return unoCommand(buffer, length, tokens); +} + return unoCommand(buffer, length, tokens); } else if (tokens.equals(0, "selecttext")) diff --git a/kit/Kit.cpp b/kit/Kit.cpp index 3e4944740..4d20d27b4 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -2356,6 +2356,16 @@ protected: } } +virtual void enableProcessInput(bool enable = true) override +{ +WebSocketHandler::enableProcessInput(enable); +// Wake up poll to process data from socket input buffer +if (enable) +{ +_ksPoll.wakeup(); +} +} + void onDisconnect() override { #if !MOBILEAPP diff --git a/net/Socket.hpp b/net/Socket.hpp index 55cfe05bb..399d6b408 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -370,6 +370,10 @@ public: /// Will be called exactly once. virtual void onConnect(const std::shared_ptr& socket) = 0; +/// Enable/disable processing of incoming data at socket level. +virtual void enableProcessInput(bool /*enable*/){}; +virtual bool processInputEnabled(){ return true; }; + /// Called after successful socket reads. virtual void handleIncomingMessage(SocketDisposition ) = 0; @@ -469,6 +473,32 @@ public: virtual void dumpState(std::ostream& os) = 0; }; +class InputProcessingManager +{ +public: +InputProcessingManager(const std::shared_ptr , bool inputProcess) +: _protocol(protocol) +{ +if (_protocol) +{ +// Save previous state to be restored in destructor +_prevInputProcess = _protocol->processInputEnabled(); +protocol->enableProcessInput(inputProcess); +} +} + +~InputProcessingManager() +{ +// Restore previous state +if (_protocol) +_protocol->enableProcessInput(_prevInputProcess); +} + +private: +std::shared_ptr _protocol; +bool _prevInputProcess; +}; + /// Handles non-blocking socket event polling. /// Only polls on N-Sockets and invokes callback and /// doesn't manage buffers or client data. @@ -782,7 +812,8 @@ public: _sentHTTPContinue(false), _shutdownSignalled(false), _incomingFD(-1), -_readType(readType) +_readType(readType), +_inputProcessingEnabled(true) {
[Libreoffice-commits] online.git: kit/Kit.cpp net/WebSocketHandler.hpp
kit/Kit.cpp | 12 ++-- net/WebSocketHandler.hpp |2 +- 2 files changed, 11 insertions(+), 3 deletions(-) New commits: commit d458f35c1f17f74dfa17558b74b74ab5d9c3edeb Author: Gabriel Masei AuthorDate: Fri Jul 24 19:50:43 2020 +0300 Commit: Gabriel Masei CommitDate: Sat Jul 25 21:22:50 2020 +0200 kit: disable parallel processing at higher levels Sometimes multiple messages are processed in a single iteration at socket level. This happens in WebSocketHandler and when draining Document queue.Just covered these cases. Change-Id: Ifa46f5d484b67015cca64008b2c89426cc839e64 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/99387 Tested-by: Jenkins Tested-by: Gabriel Masei Reviewed-by: Michael Meeks Reviewed-by: Gabriel Masei diff --git a/kit/Kit.cpp b/kit/Kit.cpp index 3ca92b01b..2ad1c545a 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -455,7 +455,8 @@ public: _isLoading(0), _editorId(-1), _editorChangeWarning(false), -_mobileAppDocId(mobileAppDocId) +_mobileAppDocId(mobileAppDocId), +_inputProcessingEnabled(true) { LOG_INF("Document ctor for [" << _docKey << "] url [" << anonymizeUrl(_url) << "] on child [" << _jailId << @@ -1388,6 +1389,9 @@ private: } public: +void enableProcessInput(bool enable = true){ _inputProcessingEnabled = enable; } +bool processInputEnabled() { return _inputProcessingEnabled; } + bool hasQueueItems() const { return _tileQueue && !_tileQueue->isEmpty(); @@ -1397,7 +1401,7 @@ public: { try { -while (hasQueueItems()) +while (processInputEnabled() && hasQueueItems()) { if (_stop || SigUtil::getTerminationFlag()) { @@ -1640,6 +1644,7 @@ private: #endif const unsigned _mobileAppDocId; +bool _inputProcessingEnabled; }; #ifdef __ANDROID__ @@ -1942,6 +1947,9 @@ protected: virtual void enableProcessInput(bool enable = true) override { WebSocketHandler::enableProcessInput(enable); +if (_document) +_document->enableProcessInput(enable); + // Wake up poll to process data from socket input buffer if (enable && _ksPoll) { diff --git a/net/WebSocketHandler.hpp b/net/WebSocketHandler.hpp index 615400798..9cab57118 100644 --- a/net/WebSocketHandler.hpp +++ b/net/WebSocketHandler.hpp @@ -422,7 +422,7 @@ public: #endif else { -while (handleTCPStream(socket)) +while (socket->processInputEnabled() && handleTCPStream(socket)) ; // might have multiple messages in the accumulated buffer. } } ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] online.git: Branch 'libreoffice-7-0' - kit/ChildSession.cpp kit/Kit.cpp net/Socket.hpp net/WebSocketHandler.hpp
kit/ChildSession.cpp |9 + kit/Kit.cpp | 10 ++ net/Socket.hpp | 41 ++--- net/WebSocketHandler.hpp | 16 4 files changed, 73 insertions(+), 3 deletions(-) New commits: commit d5d972b587f3d92166f5019e5848612f34589e28 Author: Gabriel Masei AuthorDate: Fri Jul 10 15:22:35 2020 +0300 Commit: Andras Timar CommitDate: Thu Jul 23 16:50:17 2020 +0200 kit: disable parallel handling of messages while processing load and save The map._activate, among other actions, is sending indirectly some messages to the server like clientzoom and clientvisiblearea. If these messages are send before the document finishes processing the load message then there is a chance that a nodocloaded error will be thrown because there is a chance that the messages will be processed in parallel with load. This happens constantly for xlsx files. This is generated by the Unipoll mechanism which, in case of xlsx files, triggers a parallel processing. To avoid the above scenario a mechanism of disabling parallel processing of messages in kit was implemented and is used for load and save messages, for now. Change-Id: I4c83e72e600f92d0bb4f1f18cebe694e326256d0 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/98519 Tested-by: Jenkins Tested-by: Michael Meeks Reviewed-by: Michael Meeks diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index 3c153a225..6ab9b6797 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -208,6 +208,8 @@ bool ChildSession::_handleInput(const char *buffer, int length) return false; } +// Disable processing of other messages while loading document +InputProcessingManager processInput(getProtocol(), false); _isDocLoaded = loadDocument(buffer, length, tokens); if (!_isDocLoaded) { @@ -379,6 +381,13 @@ bool ChildSession::_handleInput(const char *buffer, int length) newTokens.push_back(firstLine.substr(4)); // Copy the remaining part. return unoCommand(buffer, length, newTokens); } +else if (tokens[1].find(".uno:Save") != std::string::npos) +{ +// Disable processing of other messages while saving document +InputProcessingManager processInput(getProtocol(), false); +return unoCommand(buffer, length, tokens); +} + return unoCommand(buffer, length, tokens); } else if (tokens.equals(0, "selecttext")) diff --git a/kit/Kit.cpp b/kit/Kit.cpp index db95047f9..6e1b1a8e1 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -2354,6 +2354,16 @@ protected: } } +virtual void enableProcessInput(bool enable = true) override +{ +WebSocketHandler::enableProcessInput(enable); +// Wake up poll to process data from socket input buffer +if (enable && _ksPoll) +{ +_ksPoll->wakeup(); +} +} + void onDisconnect() override { #if !MOBILEAPP diff --git a/net/Socket.hpp b/net/Socket.hpp index 967e7b8c6..c8efd94e6 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -370,6 +370,10 @@ public: /// Will be called exactly once. virtual void onConnect(const std::shared_ptr& socket) = 0; +/// Enable/disable processing of incoming data at socket level. +virtual void enableProcessInput(bool /*enable*/){}; +virtual bool processInputEnabled(){ return true; }; + /// Called after successful socket reads. virtual void handleIncomingMessage(SocketDisposition ) = 0; @@ -469,6 +473,32 @@ public: virtual void dumpState(std::ostream& os) = 0; }; +class InputProcessingManager +{ +public: +InputProcessingManager(const std::shared_ptr , bool inputProcess) +: _protocol(protocol) +{ +if (_protocol) +{ +// Save previous state to be restored in destructor +_prevInputProcess = _protocol->processInputEnabled(); +protocol->enableProcessInput(inputProcess); +} +} + +~InputProcessingManager() +{ +// Restore previous state +if (_protocol) +_protocol->enableProcessInput(_prevInputProcess); +} + +private: +std::shared_ptr _protocol; +bool _prevInputProcess; +}; + /// Handles non-blocking socket event polling. /// Only polls on N-Sockets and invokes callback and /// doesn't manage buffers or client data. @@ -782,7 +812,8 @@ public: _sentHTTPContinue(false), _shutdownSignalled(false), _incomingFD(-1), -_readType(readType) +_readType(readType), +_inputProcessingEnabled(true) { LOG_DBG("StreamSocket ctor #" << fd); @@ -1032,6 +1063,9 @@ public: return _incomingFD; } +bool processInputEnabled(){ return
[Libreoffice-commits] online.git: kit/ChildSession.cpp kit/Kit.cpp net/Socket.hpp net/WebSocketHandler.hpp
kit/ChildSession.cpp |9 + kit/Kit.cpp | 10 ++ net/Socket.hpp | 41 ++--- net/WebSocketHandler.hpp | 16 4 files changed, 73 insertions(+), 3 deletions(-) New commits: commit 9c6739eee01952708409717c5cdf28c8f9fb94a5 Author: Gabriel Masei AuthorDate: Fri Jul 10 15:22:35 2020 +0300 Commit: Gabriel Masei CommitDate: Wed Jul 22 17:38:05 2020 +0200 kit: disable parallel handling of messages while processing load and save The map._activate, among other actions, is sending indirectly some messages to the server like clientzoom and clientvisiblearea. If these messages are send before the document finishes processing the load message then there is a chance that a nodocloaded error will be thrown because there is a chance that the messages will be processed in parallel with load. This happens constantly for xlsx files. This is generated by the Unipoll mechanism which, in case of xlsx files, triggers a parallel processing. To avoid the above scenario a mechanism of disabling parallel processing of messages in kit was implemented and is used for load and save messages, for now. Change-Id: I4c83e72e600f92d0bb4f1f18cebe694e326256d0 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/98519 Tested-by: Jenkins Tested-by: Michael Meeks Reviewed-by: Michael Meeks diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index e34de28c2..38a5b699f 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -209,6 +209,8 @@ bool ChildSession::_handleInput(const char *buffer, int length) return false; } +// Disable processing of other messages while loading document +InputProcessingManager processInput(getProtocol(), false); _isDocLoaded = loadDocument(buffer, length, tokens); LOG_TRC("isDocLoaded state after loadDocument: " << _isDocLoaded << '.'); @@ -376,6 +378,13 @@ bool ChildSession::_handleInput(const char *buffer, int length) newTokens.push_back(firstLine.substr(4)); // Copy the remaining part. return unoCommand(buffer, length, newTokens); } +else if (tokens[1].find(".uno:Save") != std::string::npos) +{ +// Disable processing of other messages while saving document +InputProcessingManager processInput(getProtocol(), false); +return unoCommand(buffer, length, tokens); +} + return unoCommand(buffer, length, tokens); } else if (tokens.equals(0, "selecttext")) diff --git a/kit/Kit.cpp b/kit/Kit.cpp index 1853bed45..3ca92b01b 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -1939,6 +1939,16 @@ protected: } } +virtual void enableProcessInput(bool enable = true) override +{ +WebSocketHandler::enableProcessInput(enable); +// Wake up poll to process data from socket input buffer +if (enable && _ksPoll) +{ +_ksPoll->wakeup(); +} +} + void onDisconnect() override { #if !MOBILEAPP diff --git a/net/Socket.hpp b/net/Socket.hpp index 84b4bfafd..ce80d2253 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -369,6 +369,10 @@ public: /// Will be called exactly once. virtual void onConnect(const std::shared_ptr& socket) = 0; +/// Enable/disable processing of incoming data at socket level. +virtual void enableProcessInput(bool /*enable*/){}; +virtual bool processInputEnabled(){ return true; }; + /// Called after successful socket reads. virtual void handleIncomingMessage(SocketDisposition ) = 0; @@ -468,6 +472,32 @@ public: virtual void dumpState(std::ostream& os) = 0; }; +class InputProcessingManager +{ +public: +InputProcessingManager(const std::shared_ptr , bool inputProcess) +: _protocol(protocol) +{ +if (_protocol) +{ +// Save previous state to be restored in destructor +_prevInputProcess = _protocol->processInputEnabled(); +protocol->enableProcessInput(inputProcess); +} +} + +~InputProcessingManager() +{ +// Restore previous state +if (_protocol) +_protocol->enableProcessInput(_prevInputProcess); +} + +private: +std::shared_ptr _protocol; +bool _prevInputProcess; +}; + /// Handles non-blocking socket event polling. /// Only polls on N-Sockets and invokes callback and /// doesn't manage buffers or client data. @@ -781,7 +811,8 @@ public: _sentHTTPContinue(false), _shutdownSignalled(false), _incomingFD(-1), -_readType(readType) +_readType(readType), +_inputProcessingEnabled(true) { LOG_DBG("StreamSocket ctor #" << fd); @@ -1032,6 +1063,9 @@ public: return _incomingFD; } +bool
[Libreoffice-commits] online.git: Branch 'distro/collabora/co-4-2' - 2 commits - common/SigUtil.cpp common/SigUtil.hpp loleaflet/images loolwsd.xml.in wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp ws
common/SigUtil.cpp |6 +-- common/SigUtil.hpp |3 + loleaflet/images/lc_wordcountdialog.svg |1 loolwsd.xml.in |7 +++ wsd/Admin.cpp | 26 +++-- wsd/Admin.hpp |4 ++ wsd/AdminModel.cpp | 63 +++- wsd/AdminModel.hpp | 60 +- wsd/LOOLWSD.cpp | 15 +++ 9 files changed, 168 insertions(+), 17 deletions(-) New commits: commit 6af9ea4b9dc0c85d004dc8e2e7c4b33dbbdcad47 Author: Gabriel Masei AuthorDate: Mon Jun 8 13:41:03 2020 +0300 Commit: Andras Timar CommitDate: Wed Jun 10 16:40:04 2020 +0200 admin: cleanup resource consuming kits Change-Id: Ifafbadc61b788adc90c03fb92e0231f9e599c360 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/95794 Tested-by: Jenkins Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks Reviewed-on: https://gerrit.libreoffice.org/c/online/+/96006 Reviewed-by: Andras Timar diff --git a/common/SigUtil.cpp b/common/SigUtil.cpp index 5a587f30d..4891010db 100644 --- a/common/SigUtil.cpp +++ b/common/SigUtil.cpp @@ -355,13 +355,13 @@ namespace SigUtil sigaction(SIGUSR1, , nullptr); } -/// Kill the given pid with SIGTERM. Returns true when the pid does not exist any more. -bool killChild(const int pid) +/// Kill the given pid with SIGKILL as default. Returns true when the pid does not exist any more. +bool killChild(const int pid, const int signal) { LOG_DBG("Killing PID: " << pid); // Don't kill anything in the fuzzer case: pid == 0 would kill the fuzzer itself, and // killing random other processes is not a great idea, either. -if (Util::isFuzzing() || kill(pid, SIGKILL) == 0 || errno == ESRCH) +if (Util::isFuzzing() || kill(pid, signal) == 0 || errno == ESRCH) { // Killed or doesn't exist. return true; diff --git a/common/SigUtil.hpp b/common/SigUtil.hpp index 9bccf0256..d3eaf9726 100644 --- a/common/SigUtil.hpp +++ b/common/SigUtil.hpp @@ -11,6 +11,7 @@ #include #include +#include #if MOBILEAPP static constexpr bool ShutdownRequestFlag(false); @@ -73,7 +74,7 @@ namespace SigUtil /// Kills a child process and returns true when /// child pid is removed from the process table /// after a certain (short) timeout. -bool killChild(const int pid); +bool killChild(const int pid, const int signal = SIGKILL); /// Dump a signal-safe back-trace void dumpBacktrace(); diff --git a/loolwsd.xml.in b/loolwsd.xml.in index e66f3526d..27e1d6e87 100644 --- a/loolwsd.xml.in +++ b/loolwsd.xml.in @@ -30,6 +30,13 @@ 0 100 100 + +1 +60 +300 +3072 +85 + diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp index 78956b222..c1aec45da 100644 --- a/wsd/Admin.cpp +++ b/wsd/Admin.cpp @@ -389,7 +389,8 @@ Admin::Admin() : _lastRecvCount(0), _cpuStatsTaskIntervalMs(DefStatsIntervalMs), _memStatsTaskIntervalMs(DefStatsIntervalMs * 2), -_netStatsTaskIntervalMs(DefStatsIntervalMs * 2) +_netStatsTaskIntervalMs(DefStatsIntervalMs * 2), +_cleanupIntervalMs(DefStatsIntervalMs * 10) { LOG_INF("Admin ctor."); @@ -415,13 +416,14 @@ Admin::~Admin() void Admin::pollingThread() { -std::chrono::steady_clock::time_point lastCPU, lastMem, lastNet; +std::chrono::steady_clock::time_point lastCPU, lastMem, lastNet, lastCleanup; _model.setThreadOwner(std::this_thread::get_id()); lastCPU = std::chrono::steady_clock::now(); lastMem = lastCPU; lastNet = lastCPU; +lastCleanup = lastCPU; while (!isStop() && !SigUtil::getTerminationFlag() && !SigUtil::getShutdownRequestFlag()) { @@ -483,6 +485,19 @@ void Admin::pollingThread() lastNet = now; } +int cleanupWait = _cleanupIntervalMs - +std::chrono::duration_cast(now - lastCleanup).count(); +if (cleanupWait <= MinStatsIntervalMs / 2) // Close enough +{ +if (_defDocProcSettings.getCleanupSettings().getEnable()) +{ +cleanupResourceConsumingDocs(); + +cleanupWait += _cleanupIntervalMs; +lastCleanup = now; +} +} + // (re)-connect (with sync. DNS - urk) to one monitor at a time if (_pendingConnects.size()) { @@ -495,7 +510,7 @@ void Admin::pollingThread() } // Handle websockets & other work. -const int timeout = capAndRoundInterval(std::min(std::min(cpuWait, memWait), netWait)); +const int timeout = capAndRoundInterval(std::min(std::min(std::min(cpuWait, memWait), netWait),
[Libreoffice-commits] online.git: common/SigUtil.cpp common/SigUtil.hpp loolwsd.xml.in wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp wsd/LOOLWSD.cpp
common/SigUtil.cpp |6 ++--- common/SigUtil.hpp |3 +- loolwsd.xml.in |7 + wsd/Admin.cpp | 26 +++-- wsd/Admin.hpp |4 +++ wsd/AdminModel.cpp | 63 - wsd/AdminModel.hpp | 60 ++ wsd/LOOLWSD.cpp| 15 8 files changed, 167 insertions(+), 17 deletions(-) New commits: commit ac17984226dac695fbd68699e168e2332f1ab9c7 Author: Gabriel Masei AuthorDate: Mon Jun 8 13:41:03 2020 +0300 Commit: Michael Meeks CommitDate: Tue Jun 9 11:25:44 2020 +0200 admin: cleanup resource consuming kits Change-Id: Ifafbadc61b788adc90c03fb92e0231f9e599c360 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/95794 Tested-by: Jenkins Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks diff --git a/common/SigUtil.cpp b/common/SigUtil.cpp index 5a587f30d..4891010db 100644 --- a/common/SigUtil.cpp +++ b/common/SigUtil.cpp @@ -355,13 +355,13 @@ namespace SigUtil sigaction(SIGUSR1, , nullptr); } -/// Kill the given pid with SIGTERM. Returns true when the pid does not exist any more. -bool killChild(const int pid) +/// Kill the given pid with SIGKILL as default. Returns true when the pid does not exist any more. +bool killChild(const int pid, const int signal) { LOG_DBG("Killing PID: " << pid); // Don't kill anything in the fuzzer case: pid == 0 would kill the fuzzer itself, and // killing random other processes is not a great idea, either. -if (Util::isFuzzing() || kill(pid, SIGKILL) == 0 || errno == ESRCH) +if (Util::isFuzzing() || kill(pid, signal) == 0 || errno == ESRCH) { // Killed or doesn't exist. return true; diff --git a/common/SigUtil.hpp b/common/SigUtil.hpp index 9bccf0256..d3eaf9726 100644 --- a/common/SigUtil.hpp +++ b/common/SigUtil.hpp @@ -11,6 +11,7 @@ #include #include +#include #if MOBILEAPP static constexpr bool ShutdownRequestFlag(false); @@ -73,7 +74,7 @@ namespace SigUtil /// Kills a child process and returns true when /// child pid is removed from the process table /// after a certain (short) timeout. -bool killChild(const int pid); +bool killChild(const int pid, const int signal = SIGKILL); /// Dump a signal-safe back-trace void dumpBacktrace(); diff --git a/loolwsd.xml.in b/loolwsd.xml.in index e66f3526d..27e1d6e87 100644 --- a/loolwsd.xml.in +++ b/loolwsd.xml.in @@ -30,6 +30,13 @@ 0 100 100 + +1 +60 +300 +3072 +85 + diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp index 78956b222..c1aec45da 100644 --- a/wsd/Admin.cpp +++ b/wsd/Admin.cpp @@ -389,7 +389,8 @@ Admin::Admin() : _lastRecvCount(0), _cpuStatsTaskIntervalMs(DefStatsIntervalMs), _memStatsTaskIntervalMs(DefStatsIntervalMs * 2), -_netStatsTaskIntervalMs(DefStatsIntervalMs * 2) +_netStatsTaskIntervalMs(DefStatsIntervalMs * 2), +_cleanupIntervalMs(DefStatsIntervalMs * 10) { LOG_INF("Admin ctor."); @@ -415,13 +416,14 @@ Admin::~Admin() void Admin::pollingThread() { -std::chrono::steady_clock::time_point lastCPU, lastMem, lastNet; +std::chrono::steady_clock::time_point lastCPU, lastMem, lastNet, lastCleanup; _model.setThreadOwner(std::this_thread::get_id()); lastCPU = std::chrono::steady_clock::now(); lastMem = lastCPU; lastNet = lastCPU; +lastCleanup = lastCPU; while (!isStop() && !SigUtil::getTerminationFlag() && !SigUtil::getShutdownRequestFlag()) { @@ -483,6 +485,19 @@ void Admin::pollingThread() lastNet = now; } +int cleanupWait = _cleanupIntervalMs - +std::chrono::duration_cast(now - lastCleanup).count(); +if (cleanupWait <= MinStatsIntervalMs / 2) // Close enough +{ +if (_defDocProcSettings.getCleanupSettings().getEnable()) +{ +cleanupResourceConsumingDocs(); + +cleanupWait += _cleanupIntervalMs; +lastCleanup = now; +} +} + // (re)-connect (with sync. DNS - urk) to one monitor at a time if (_pendingConnects.size()) { @@ -495,7 +510,7 @@ void Admin::pollingThread() } // Handle websockets & other work. -const int timeout = capAndRoundInterval(std::min(std::min(cpuWait, memWait), netWait)); +const int timeout = capAndRoundInterval(std::min(std::min(std::min(cpuWait, memWait), netWait), cleanupWait)); LOG_TRC("Admin poll for " << timeout << "ms."); poll(timeout * 1000); // continue with ms for admin, settings etc. } @@ -773,6 +788,11 @@ void Admin::notifyDocsMemDirtyChanged()
[Libreoffice-commits] online.git: wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp
wsd/Admin.cpp |9 + wsd/Admin.hpp |1 + wsd/AdminModel.cpp | 27 +-- wsd/AdminModel.hpp | 15 +++ 4 files changed, 46 insertions(+), 6 deletions(-) New commits: commit 16f6d8c25a99fcd47b40b27c01d0f24e80341348 Author: Gabriel Masei AuthorDate: Fri May 29 14:32:04 2020 +0300 Commit: Michael Meeks CommitDate: Thu Jun 4 12:59:34 2020 +0200 admin: notify subscribers that doc memory has changed Change-Id: I139c7d49a2cd1b86c3a281613f5628f6af8b3365 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/95133 Tested-by: Jenkins Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp index 8d85dfbc7..78956b222 100644 --- a/wsd/Admin.cpp +++ b/wsd/Admin.cpp @@ -443,6 +443,8 @@ void Admin::pollingThread() std::chrono::duration_cast(now - lastMem).count(); if (memWait <= MinStatsIntervalMs / 2) // Close enough { +_model.UpdateMemoryDirty(); + const size_t totalMem = getTotalMemoryUsage(); _model.addMemStats(totalMem); @@ -454,6 +456,8 @@ void Admin::pollingThread() _lastTotalMemory = totalMem; } +notifyDocsMemDirtyChanged(); + memWait += _memStatsTaskIntervalMs; lastMem = now; } @@ -764,6 +768,11 @@ void Admin::triggerMemoryCleanup(const size_t totalMem) } } +void Admin::notifyDocsMemDirtyChanged() +{ +_model.notifyDocsMemDirtyChanged(); +} + void Admin::dumpState(std::ostream& os) { // FIXME: be more helpful ... diff --git a/wsd/Admin.hpp b/wsd/Admin.hpp index 42e7a247a..5a3feee61 100644 --- a/wsd/Admin.hpp +++ b/wsd/Admin.hpp @@ -148,6 +148,7 @@ private: /// Memory consumption has increased, start killing kits etc. till memory consumption gets back /// under @hardModeLimit void triggerMemoryCleanup(size_t hardModeLimit); +void notifyDocsMemDirtyChanged(); /// Round the interval up to multiples of MinStatsIntervalMs. /// This is to avoid arbitrarily small intervals that hammer the server. diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp index ab2d81df7..387796452 100644 --- a/wsd/AdminModel.cpp +++ b/wsd/AdminModel.cpp @@ -134,16 +134,18 @@ std::string Document::to_string() const return oss.str(); } -int Document::getMemoryDirty() const +void Document::updateMemoryDirty() { // Avoid accessing smaps too often const time_t now = std::time(nullptr); if (now - _lastTimeSMapsRead >= 5) { +int lastMemDirty = _memoryDirty; _memoryDirty = _procSMaps ? Util::getPssAndDirtyFromSMaps(_procSMaps).second : 0; _lastTimeSMapsRead = now; +if (lastMemDirty != _memoryDirty) +_hasMemDirtyChanged = true; } -return _memoryDirty; } bool Subscriber::notify(const std::string& message) @@ -1041,4 +1043,25 @@ std::set AdminModel::getDocumentPids() const return pids; } +void AdminModel::UpdateMemoryDirty() +{ +for (const auto& it: _documents) +{ +it.second->updateMemoryDirty(); +} +} + +void AdminModel::notifyDocsMemDirtyChanged() +{ +for (const auto& it: _documents) +{ +int memoryDirty = it.second->getMemoryDirty(); +if (it.second->hasMemDirtyChanged()) +{ +notify("propchange " + std::to_string(it.second->getPid()) + " mem " + std::to_string(memoryDirty)); +it.second->setMemDirtyChanged(false); +} +} +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/AdminModel.hpp b/wsd/AdminModel.hpp index ae88ef8cd..98bd01495 100644 --- a/wsd/AdminModel.hpp +++ b/wsd/AdminModel.hpp @@ -121,7 +121,8 @@ public: _wopiUploadDuration(0), _procSMaps(nullptr), _lastTimeSMapsRead(0), - _isModified(false) + _isModified(false), + _hasMemDirtyChanged(true) { } @@ -155,7 +156,8 @@ public: const std::map& getViews() const { return _views; } void updateLastActivityTime() { _lastActivity = std::time(nullptr); } -int getMemoryDirty() const; +void updateMemoryDirty(); +int getMemoryDirty() const { return _memoryDirty; } std::pair getSnapshot() const; const std::string getHistory() const; @@ -182,6 +184,8 @@ public: void setWopiUploadDuration(const std::chrono::milliseconds wopiUploadDuration) { _wopiUploadDuration = wopiUploadDuration; } std::chrono::milliseconds getWopiUploadDuration() const { return _wopiUploadDuration; } void setProcSMapsFD(const int smapsFD) { _procSMaps = fdopen(smapsFD, "r"); } +bool hasMemDirtyChanged() const { return _hasMemDirtyChanged; } +void setMemDirtyChanged(bool changeStatus) { _hasMemDirtyChanged = changeStatus; } std::string to_string() const; @@ -195,7 +199,7 @@ private: /// Hosted filename std::string _filename; ///
[Libreoffice-commits] online.git: 2 commits - net/WebSocketHandler.hpp wsd/AdminModel.cpp wsd/LOOLWSD.cpp
net/WebSocketHandler.hpp | 28 wsd/AdminModel.cpp |2 +- wsd/LOOLWSD.cpp |2 +- 3 files changed, 2 insertions(+), 30 deletions(-) New commits: commit b1e970371e289652b11648cc659b512bd45d27ed Author: Gabriel Masei AuthorDate: Wed Apr 29 14:59:03 2020 +0300 Commit: Michael Meeks CommitDate: Wed Apr 29 16:46:32 2020 +0200 admin: fix kit CPU metrics computation Change-Id: Ib0f8411fa3919b4cffe640c13d87e1a644ed8e69 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/93149 Reviewed-by: Michael Meeks Tested-by: Michael Meeks diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp index ff99578ae..e88b7aeab 100644 --- a/wsd/AdminModel.cpp +++ b/wsd/AdminModel.cpp @@ -941,7 +941,7 @@ struct KitProcStats void UpdateAggregateStats(int pid) { _threadCount.Update(Util::getStatFromPid(pid, 19)); -_cpuTime.Update(Util::getCpuUsage(pid)); +_cpuTime.Update(Util::getCpuUsage(pid) / sysconf (_SC_CLK_TCK)); } int unassignedCount; commit 1ded31fc35c436dc89e062baa6d32f14a4063930 Author: Gabriel Masei AuthorDate: Tue Apr 28 20:19:36 2020 +0300 Commit: Michael Meeks CommitDate: Wed Apr 29 16:46:21 2020 +0200 remove unused method from WebSocketHandler Change-Id: I97ff8a4606b571424b687776d51d1640b3be5209 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/93096 Tested-by: Michael Meeks Reviewed-by: Michael Meeks diff --git a/net/WebSocketHandler.hpp b/net/WebSocketHandler.hpp index 9fb8682ac..5815a720e 100644 --- a/net/WebSocketHandler.hpp +++ b/net/WebSocketHandler.hpp @@ -546,34 +546,6 @@ public: return sendFrame(socket, data, len, WSFrameMask::Fin | static_cast(code), flush); } -#if !MOBILEAPP -/// Sends a message while giving at the same time the rights -/// for file descriptor to the receiving process. -/// DO NOT USE IT unless you have no other option. -int sendTextMessageWithFD(const char* msg, size_t len, int fd) -{ -std::shared_ptr socket = _socket.lock(); - -if (!socket || msg == nullptr || len == 0) -return -1; - -if (socket->isClosed()) -return 0; - -socket->assertCorrectThread(); - -std::vector out; - -buildFrame(msg, len, WSFrameMask::Fin | static_cast(WSOpCode::Text), out); - -const size_t size = out.size(); - -socket->sendFD(out.data(), out.size(), fd); - -return size; -} -#endif - protected: #if !MOBILEAPP diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index dbabc5b9b..6ef3f2c84 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -2072,7 +2072,7 @@ private: if (docBroker) docBroker->handleInput(data); else -LOG_WRN("Child " << child->getPid() << +LOG_WRN("Child " << child->getPid() << " has no DocumentBroker to handle message: [" << abbr << "]."); } ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] online.git: net/Socket.hpp
net/Socket.hpp | 19 ++- 1 file changed, 6 insertions(+), 13 deletions(-) New commits: commit 753b0a8e91c65abc4ffbc8e0d3fd484e68b5b6de Author: Gabriel Masei AuthorDate: Tue Apr 28 23:45:26 2020 +0300 Commit: Michael Meeks CommitDate: Wed Apr 29 14:45:19 2020 +0200 let the higher levels to process the recvmsg return value Change-Id: I41c089229095739f38f40dbd0fb7c1d4c82efd41 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/93110 Reviewed-by: Michael Meeks Tested-by: Michael Meeks diff --git a/net/Socket.hpp b/net/Socket.hpp index 34da98aab..37e289a63 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -1178,25 +1178,18 @@ protected: msg.msg_flags = 0; int ret = recvmsg(getFD(), , 0); -if (ret >= 0) +if (ret > 0 && msg.msg_controllen) { -if (msg.msg_controllen) +cmsghdr *cmsg = CMSG_FIRSTHDR(); +if (cmsg && cmsg->cmsg_type == SCM_RIGHTS && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { -cmsghdr *cmsg = CMSG_FIRSTHDR(); -if (cmsg && cmsg->cmsg_type == SCM_RIGHTS && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) +fd = *(int*)CMSG_DATA(cmsg); +if (_readType == UseRecvmsgExpectFD) { -fd = *(int*)CMSG_DATA(cmsg); -if (_readType == UseRecvmsgExpectFD) -{ -_readType = NormalRead; -} +_readType = NormalRead; } } } -else -{ -LOG_ERR("recvmsg call ended with error: " << errno); -} return ret; } ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] online.git: kit/Kit.cpp net/Socket.cpp net/Socket.hpp wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp wsd/DocumentBroker.cpp wsd/LOOLWSD.cpp
kit/Kit.cpp| 22 ++ net/Socket.cpp | 15 +++ net/Socket.hpp |6 -- wsd/Admin.cpp | 10 +++--- wsd/Admin.hpp |5 +++-- wsd/AdminModel.cpp | 11 +++ wsd/AdminModel.hpp |5 +++-- wsd/DocumentBroker.cpp | 15 ++- wsd/LOOLWSD.cpp|3 ++- 9 files changed, 33 insertions(+), 59 deletions(-) New commits: commit d006204478cb4a10e35574f4c12a37318f7b39eb Author: Gabriel Masei AuthorDate: Tue Apr 28 16:55:47 2020 +0300 Commit: Michael Meeks CommitDate: Tue Apr 28 17:20:07 2020 +0200 wsd: admin: send smaps fd along websocket upgrade request Change-Id: I2c5c23284b7578f4c177ec337cc1262bf1259e96 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/93074 Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks diff --git a/kit/Kit.cpp b/kit/Kit.cpp index ae775fee3..b5409ca68 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -649,9 +649,6 @@ public: } }; -#if !MOBILEAPP -static int ProcSMapsFile = -1; -#endif class ThreadPool { std::mutex _mutex; @@ -795,22 +792,6 @@ public: "] and id [" << _docId << "]."); assert(_loKit); -#if !MOBILEAPP -if (ProcSMapsFile >= 0) -{ -static const std::string str = "smapsfd:"; -if (websocketHandler->sendTextMessageWithFD(str.c_str(), str.size(), ProcSMapsFile) > 0) -{ -LOG_DBG("Successfully sent smaps fd to wsd"); -close(ProcSMapsFile); -ProcSMapsFile = -1; -} -else -{ -LOG_ERR("Failed to send smaps fd to wsd"); -} -} -#endif } virtual ~Document() @@ -2505,6 +2486,7 @@ void lokit_main( std::string userdir_url; std::string instdir_path; +int ProcSMapsFile = -1; // lokit's destroy typically throws from // framework/source/services/modulemanager.cxx:198 @@ -2749,7 +2731,7 @@ void lokit_main( std::make_shared("child_ws", loKit, jailId, mainKit); #if !MOBILEAPP -mainKit.insertNewUnixSocket(MasterLocation, pathAndQuery, websocketHandler); +mainKit.insertNewUnixSocket(MasterLocation, pathAndQuery, websocketHandler, ProcSMapsFile); #else mainKit.insertNewFakeSocket(docBrokerSocket, websocketHandler); #endif diff --git a/net/Socket.cpp b/net/Socket.cpp index 0b7a2f2ff..5e96ab2ac 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -407,7 +407,7 @@ void SocketPoll::insertNewWebSocketSync( // should this be a static method in the WebsocketHandler(?) void SocketPoll::clientRequestWebsocketUpgrade(const std::shared_ptr& socket, const std::shared_ptr& websocketHandler, - const std::string ) + const std::string , const int shareFD) { // cf. WebSocketHandler::upgradeToWebSocket (?) // send Sec-WebSocket-Key: ... Sec-WebSocket-Protocol: chat, Sec-WebSocket-Version: 13 @@ -426,14 +426,21 @@ void SocketPoll::clientRequestWebsocketUpgrade(const std::shared_ptrsend(oss.str()); +if (shareFD == -1) +socket->send(oss.str()); +else +{ +std::string request = oss.str(); +socket->sendFD(request.c_str(), request.size(), shareFD); +} websocketHandler->onConnect(socket); } void SocketPoll::insertNewUnixSocket( const std::string , const std::string , -const std::shared_ptr& websocketHandler) +const std::shared_ptr& websocketHandler, +const int shareFD) { int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); @@ -456,7 +463,7 @@ void SocketPoll::insertNewUnixSocket( if (socket) { LOG_DBG("Connected to local UDS " << location << " #" << socket->getFD()); -clientRequestWebsocketUpgrade(socket, websocketHandler, pathAndQuery); +clientRequestWebsocketUpgrade(socket, websocketHandler, pathAndQuery, shareFD); insertNewSocket(socket); } } diff --git a/net/Socket.hpp b/net/Socket.hpp index ed59edb23..34da98aab 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -640,7 +640,8 @@ public: void insertNewUnixSocket( const std::string , const std::string , -const std::shared_ptr& websocketHandler); +const std::shared_ptr& websocketHandler, +const int shareFD = -1); #else void insertNewFakeSocket( int peerSocket, @@ -698,9 +699,10 @@ protected: private: /// Generate the request to connect & upgrade this socket to a given path +/// and sends a file descriptor along request if is != -1. void clientRequestWebsocketUpgrade(const std::shared_ptr& socket, const std::shared_ptr& websocketHandler, -
[Libreoffice-commits] online.git: wsd/AdminModel.cpp
wsd/AdminModel.cpp |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) New commits: commit 93bd4875a23c6731ef370b93f63eaa83926d925f Author: Gabriel Masei AuthorDate: Mon Apr 27 17:03:52 2020 +0300 Commit: Michael Meeks CommitDate: Mon Apr 27 16:21:01 2020 +0200 admin: fix kit_memory_usage metrics computation Change-Id: I2f1d4f2320336e690fcf84fb9c26b5142f53508e Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92979 Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp index e2ba77898..18ccb62f1 100644 --- a/wsd/AdminModel.cpp +++ b/wsd/AdminModel.cpp @@ -915,7 +915,7 @@ struct DocumentAggregateStats { void Update(const Document , bool active) { -_kitUsedMemory.Update(d.getMemoryDirty(), active); +_kitUsedMemory.Update(d.getMemoryDirty() * 1024, active); _viewsCount.Update(d.getViews().size(), active); _activeViewsCount.Update(d.getActiveViews(), active); _expiredViewsCount.Update(d.getViews().size() - d.getActiveViews(), active); @@ -1012,7 +1012,7 @@ void AdminModel::getMetrics(std::ostringstream ) oss << "kit_assigned_count " << kitStats.assignedCount << std::endl; oss << "kit_segfault_count " << _segFaultCount << std::endl; PrintKitAggregateMetrics(oss, "thread_count", "", kitStats._threadCount); -PrintKitAggregateMetrics(oss, "memory_used", "bytes", docStats._kitUsedMemory._all); +PrintKitAggregateMetrics(oss, "memory_used", "bytes", docStats._kitUsedMemory._active); PrintKitAggregateMetrics(oss, "cpu_time", "seconds", kitStats._cpuTime); oss << std::endl; ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] online.git: common/Util.hpp kit/Kit.cpp net/Socket.hpp net/SslSocket.hpp net/WebSocketHandler.hpp wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp wsd/DocumentBr
common/Util.hpp |4 + kit/Kit.cpp | 28 ++- net/Socket.hpp | 113 +-- net/SslSocket.hpp|5 +- net/WebSocketHandler.hpp | 66 +-- wsd/Admin.cpp|9 ++- wsd/Admin.hpp|2 wsd/AdminModel.cpp | 42 - wsd/AdminModel.hpp | 19 ++- wsd/DocumentBroker.cpp | 11 ++-- wsd/DocumentBroker.hpp |8 ++- wsd/LOOLWSD.cpp |3 - 12 files changed, 239 insertions(+), 71 deletions(-) New commits: commit 6b486f229a68cf9ee1641e14c82b0de4c64b1fe2 Author: Gabriel Masei AuthorDate: Thu Apr 23 13:35:42 2020 +0300 Commit: Michael Meeks CommitDate: Sat Apr 25 09:11:35 2020 +0200 wsd: admin: move kit memory reporting from kit to admin module Sometimes kit process goes into a heavy processing state (or even hangs) and is not able to report its memory usage. Thus we can't implement cleanup of problematic kit processes based on memory information reported by kit. By moving memory reporting to admin module we avoid this problem. Change-Id: Icf274e3a3a97b33623a93f9d2dc1e640ad9b7d99 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92752 Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks diff --git a/common/Util.hpp b/common/Util.hpp index 820f4e6ce..d154942f8 100644 --- a/common/Util.hpp +++ b/common/Util.hpp @@ -144,6 +144,10 @@ namespace Util /// Example: "procmemstats: pid=123 rss=12400 pss=566" std::string getMemoryStats(FILE* file); +/// Reads from SMaps file Pss and Private_Dirty values and +/// returns them as a pair in the same order +std::pair getPssAndDirtyFromSMaps(FILE* file); + size_t getCpuUsage(const Poco::Process::PID pid); size_t getStatFromPid(const Poco::Process::PID pid, int ind); diff --git a/kit/Kit.cpp b/kit/Kit.cpp index ad37d3a2e..8cd62f43b 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -796,8 +796,20 @@ public: assert(_loKit); #if !MOBILEAPP -_lastMemStatsTime = std::chrono::steady_clock::now(); -sendTextFrame(Util::getMemoryStats(ProcSMapsFile)); +if (ProcSMapsFile) +{ +static const std::string str = "smapsfd:"; +if (websocketHandler->sendTextMessageWithFD(str.c_str(), str.size(), ProcSMapsFile->_fileno) > 0) +{ +LOG_DBG("Successfully sent smaps fd to wsd"); +fclose(ProcSMapsFile); +ProcSMapsFile = nullptr; +} +else +{ +LOG_ERR("Failed to send smaps fd to wsd"); +} +} #endif } @@ -1935,7 +1947,7 @@ private: } public: -void drainQueue(const std::chrono::steady_clock::time_point ) +void drainQueue(const std::chrono::steady_clock::time_point &/*now*/) { try { @@ -2045,16 +2057,6 @@ public: } } -#if !MOBILEAPP -std::chrono::milliseconds::rep durationMs = -std::chrono::duration_cast(now - _lastMemStatsTime).count(); -// Update memory stats and editor every 5 seconds. -if (durationMs > 5000) -{ -sendTextFrame(Util::getMemoryStats(ProcSMapsFile)); -_lastMemStatsTime = std::chrono::steady_clock::now(); -} -#endif } catch (const std::exception& exc) { diff --git a/net/Socket.hpp b/net/Socket.hpp index 5966b1047..218de2866 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -758,9 +758,16 @@ class StreamSocket : public Socket, public std::enable_shared_from_this { public: +enum ReadType +{ +NormalRead, +UseRecvmsgExpectFD +}; + /// Create a StreamSocket from native FD. StreamSocket(const int fd, bool /* isClient */, - std::shared_ptr socketHandler) : + std::shared_ptr socketHandler, + ReadType readType = NormalRead) : Socket(fd), _socketHandler(std::move(socketHandler)), _bytesSent(0), @@ -768,7 +775,9 @@ public: _wsState(WSState::HTTP), _closed(false), _sentHTTPContinue(false), -_shutdownSignalled(false) +_shutdownSignalled(false), +_incomingFD(-1), +_readType(readType) { LOG_DBG("StreamSocket ctor #" << fd); @@ -845,6 +854,45 @@ public: /// Adds Date and User-Agent. void send(Poco::Net::HTTPResponse& response); +/// Sends data with file descriptor as control data. +/// Can be used only with Unix sockets. +void sendFD(const char* data, const uint64_t len, int fd) +{ +assertCorrectThread(); + +// Flush existing non-ancillary data +// so that our non-ancillary data will +// match ancillary data. +if
[Libreoffice-commits] online.git: wsd/metrics.txt
wsd/metrics.txt |1 + 1 file changed, 1 insertion(+) New commits: commit b2f3b96c3de0dae8867280ec782b21a9a5c0cfea Author: Gabriel Masei AuthorDate: Thu Apr 9 16:54:48 2020 +0300 Commit: Michael Meeks CommitDate: Tue Apr 14 17:22:54 2020 +0200 Add description for kit_segfault_count metric Change-Id: Id9111dc2ac1581dca2a640cd2c3215953c9e2436 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/91981 Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks diff --git a/wsd/metrics.txt b/wsd/metrics.txt index f12c3fe64..bb1df4ac5 100644 --- a/wsd/metrics.txt +++ b/wsd/metrics.txt @@ -28,6 +28,7 @@ KITS kit_count – total number of running kit processes. kit_unassigned_count – number of running kit processes that are not assigned to documents. kit_assigned_count – number of running kit processes that are assigned to documents. +kit_segfault_count - number of kit processes terminated with SIGSEGV or SIGBUS signals since the start of application. kit_thread_count_total - total number of threads in all running kit processes. kit_thread_count_average – average number of threads per running kit process. kit_thread_count_min - minimum from the number of threads in each running kit process. ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] online.git: common/SigUtil.cpp kit/ForKit.cpp wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp wsd/LOOLWSD.cpp
common/SigUtil.cpp |2 +- kit/ForKit.cpp | 36 ++-- wsd/Admin.cpp |5 + wsd/Admin.hpp |1 + wsd/AdminModel.cpp |6 ++ wsd/AdminModel.hpp |4 wsd/LOOLWSD.cpp| 22 +++--- 7 files changed, 70 insertions(+), 6 deletions(-) New commits: commit 0ac330f599b8daaeae5ba057fddb6994fd078e73 Author: Gabriel Masei AuthorDate: Wed Apr 8 00:21:17 2020 +0300 Commit: Michael Meeks CommitDate: Wed Apr 8 15:06:39 2020 +0200 Add segmentation fault metric for Kit processes Change-Id: Ifb0de004274213ef512f601e4419f98f456c7288 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/91857 Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks diff --git a/common/SigUtil.cpp b/common/SigUtil.cpp index 944a8d376..cd4c779dc 100644 --- a/common/SigUtil.cpp +++ b/common/SigUtil.cpp @@ -260,7 +260,7 @@ namespace SigUtil dumpBacktrace(); // let default handler process the signal -kill(getpid(), signal); +::raise(signal); } void dumpBacktrace() diff --git a/kit/ForKit.cpp b/kit/ForKit.cpp index 8b18ef34e..bea72f4d5 100644 --- a/kit/ForKit.cpp +++ b/kit/ForKit.cpp @@ -36,6 +36,9 @@ #include #include #include +#if !MOBILEAPP +#include +#endif #include #include @@ -226,7 +229,7 @@ static void cleanupChildren() { std::vector jails; Process::PID exitedChildPid; -int status; +int status, segFaultCount = 0; // Reap quickly without doing slow cleanup so WSD can spawn more rapidly. while ((exitedChildPid = waitpid(-1, , WUNTRACED | WNOHANG)) > 0) @@ -242,13 +245,42 @@ static void cleanupChildren() // We ran out of kits and we aren't terminating. LOG_WRN("No live Kits exist, and we are not terminating yet."); } + +if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGSEGV || WTERMSIG(status) == SIGBUS)) +{ +segFaultCount ++; +} } else { LOG_ERR("Unknown child " << exitedChildPid << " has exited"); } } - + +if (segFaultCount) +{ +#ifdef KIT_IN_PROCESS +#if !MOBILEAPP +Admin::instance().addSegFaultCount(segFaultCount); +#endif +#else +if (WSHandler) +{ +std::stringstream stream; +stream << "segfaultcount " << segFaultCount << "\n"; +int ret = WSHandler->sendMessage(stream.str()); +if (ret == -1) +{ +LOG_WRN("Could not send 'segfaultcount' message through websocket"); +} +else +{ +LOG_WRN("Successfully sent 'segfaultcount' message " << stream.str()); +} +} +#endif +} + // Now delete the jails. for (const auto& path : jails) { diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp index 88b9268df..3fc0b6955 100644 --- a/wsd/Admin.cpp +++ b/wsd/Admin.cpp @@ -593,6 +593,11 @@ void Admin::setDocWopiUploadDuration(const std::string& docKey, const std::chron addCallback([=]{ _model.setDocWopiUploadDuration(docKey, uploadDuration); }); } +void Admin::addSegFaultCount(unsigned segFaultCount) +{ +addCallback([=]{ _model.addSegFaultCount(segFaultCount); }); +} + void Admin::notifyForkit() { std::ostringstream oss; diff --git a/wsd/Admin.hpp b/wsd/Admin.hpp index e39d89fe7..6287d38bc 100644 --- a/wsd/Admin.hpp +++ b/wsd/Admin.hpp @@ -129,6 +129,7 @@ public: void setViewLoadDuration(const std::string& docKey, const std::string& sessionId, std::chrono::milliseconds viewLoadDuration); void setDocWopiDownloadDuration(const std::string& docKey, std::chrono::milliseconds wopiDownloadDuration); void setDocWopiUploadDuration(const std::string& docKey, const std::chrono::milliseconds uploadDuration); +void addSegFaultCount(unsigned segFaultCount); void getMetrics(std::ostringstream ); diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp index 22e402a83..f19d6e367 100644 --- a/wsd/AdminModel.cpp +++ b/wsd/AdminModel.cpp @@ -771,6 +771,11 @@ void AdminModel::setDocWopiUploadDuration(const std::string& docKey, const std:: it->second.setWopiUploadDuration(wopiUploadDuration); } +void AdminModel::addSegFaultCount(unsigned segFaultCount) +{ +_segFaultCount += segFaultCount; +} + int filterNumberName(const struct dirent *dir) { return !fnmatch("[0-9]*", dir->d_name, 0); @@ -993,6 +998,7 @@ void AdminModel::getMetrics(std::ostringstream ) oss << "kit_count " << kitStats.unassignedCount + kitStats.assignedCount << std::endl; oss << "kit_unassigned_count " << kitStats.unassignedCount << std::endl; oss << "kit_assigned_count " << kitStats.assignedCount << std::endl; +oss << "kit_segfault_count " << _segFaultCount << std::endl; PrintKitAggregateMetrics(oss, "thread_count", "", kitStats._threadCount);
[Libreoffice-commits] online.git: common/Common.hpp kit/ForKit.cpp net/Socket.hpp wsd/Admin.cpp wsd/Admin.hpp wsd/DocumentBroker.hpp wsd/LOOLWSD.cpp wsd/LOOLWSD.hpp
common/Common.hpp |1 kit/ForKit.cpp | 124 --- net/Socket.hpp |5 + wsd/Admin.cpp |7 - wsd/Admin.hpp |3 wsd/DocumentBroker.hpp | 124 +-- wsd/LOOLWSD.cpp| 102 ++--- wsd/LOOLWSD.hpp| 172 - 8 files changed, 333 insertions(+), 205 deletions(-) New commits: commit 70af76e28cbca4a45869fcecfe221d21eb7a3790 Author: Gabriel Masei AuthorDate: Thu Apr 2 18:11:36 2020 +0300 Commit: Michael Meeks CommitDate: Tue Apr 7 15:04:47 2020 +0200 Replaced pipe with websocket based on Unix socket in communication with ForKit Change-Id: I80f1a4e84ca6820503966a8ee5d9958a150eac14 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/91585 Tested-by: Jenkins CollaboraOffice Reviewed-by: Michael Meeks diff --git a/common/Common.hpp b/common/Common.hpp index 7a02dfaae..82f848579 100644 --- a/common/Common.hpp +++ b/common/Common.hpp @@ -36,6 +36,7 @@ constexpr const char JAILED_DOCUMENT_ROOT[] = "/user/docs/"; constexpr const char CHILD_URI[] = "/loolws/child?"; constexpr const char NEW_CHILD_URI[] = "/loolws/newchild"; constexpr const char LO_JAIL_SUBPATH[] = "lo"; +constexpr const char FORKIT_URI[] = "/loolws/forkit"; constexpr const char CAPABILITIES_END_POINT[] = "/hosting/capabilities"; diff --git a/kit/ForKit.cpp b/kit/ForKit.cpp index 4ebd57907..8b18ef34e 100644 --- a/kit/ForKit.cpp +++ b/kit/ForKit.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -64,75 +65,88 @@ int ClientPortNumber = DEFAULT_CLIENT_PORT_NUMBER; std::string MasterLocation; #endif -/// Dispatcher class to demultiplex requests from -/// WSD and handles them. -class CommandDispatcher : public IoUtil::PipeReader +class ServerWSHandler; + +// We have a single thread and a single connection so we won't bother with +// access synchronization +std::shared_ptr WSHandler; + +class ServerWSHandler final : public WebSocketHandler { +std::string _socketName; + public: -CommandDispatcher(const int pipe) : -PipeReader("wsd_pipe_rd", pipe) +ServerWSHandler(const std::string& socketName) : +WebSocketHandler(/* isClient = */ true, /* isMasking */ false), +_socketName(socketName) { } -/// Polls WSD commands and handles them. -bool pollAndDispatch() +protected: +void handleMessage(const std::vector& data) override { -std::string message; -const int ready = readLine(message, [](){ return SigUtil::getTerminationFlag(); }); -if (ready <= 0) +std::string message(data.data(), data.size()); + +#if !MOBILEAPP +if (UnitKit::get().filterKitMessage(this, message)) +return; +#endif +StringVector tokens = LOOLProtocol::tokenize(message); +Log::StreamLogger logger = Log::debug(); +if (logger.enabled()) { -// Termination is done via SIGTERM, which breaks the wait. -if (ready < 0) +logger << _socketName << ": recv ["; +for (const auto& token : tokens) { -if (SigUtil::getTerminationFlag()) -{ -LOG_INF("Poll interrupted in " << getName() << " and TerminationFlag is set."); -} - -// Break. -return false; +logger << tokens.getParam(token) << ' '; } -// Timeout. -return true; +LOG_END(logger, true); } -LOG_INF("ForKit command: [" << message << "]."); -try +// Note: Syntax or parsing errors here are unexpected and fatal. +if (SigUtil::getTerminationFlag()) { -StringVector tokens = LOOLProtocol::tokenize(message); -if (tokens.size() == 2 && tokens.equals(0, "spawn")) +LOG_DBG("Termination flag set: skip message processing"); +} +else if (tokens.size() == 2 && tokens.equals(0, "spawn")) +{ +const int count = std::stoi(tokens[1]); +if (count > 0) { -const int count = std::stoi(tokens[1]); -if (count > 0) -{ -LOG_INF("Setting to spawn " << tokens[1] << " child" << (count == 1 ? "" : "ren") << " per request."); -ForkCounter = count; -} -else -{ -LOG_WRN("Cannot spawn " << tokens[1] << " children as requested."); -} +LOG_INF("Setting to spawn " << tokens[1] << " child" << (count == 1 ? "" : "ren") << " per request."); +ForkCounter = count; } -else if (tokens.size() == 3 && tokens.equals(0, "setconfig")) +else { -
[Libreoffice-commits] online.git: wsd/DocumentBroker.hpp
wsd/DocumentBroker.hpp | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) New commits: commit 3046c5748bb54b16738aa5a7ee5e90b9420d68ac Author: Gabriel Masei AuthorDate: Tue Feb 11 17:51:20 2020 +0200 Commit: Andras Timar CommitDate: Wed Feb 12 16:28:10 2020 +0100 Fix removal of kit procs when they are blocked Change-Id: Ifa2a2a56a305e33bb07ad622fce14f0e8b3e83eb Reviewed-on: https://gerrit.libreoffice.org/c/online/+/88464 Reviewed-by: Michael Meeks Tested-by: Andras Timar diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index 890e89e38..8b2b42551 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -119,14 +119,23 @@ public: // Shutdown the socket. if (_ws) +{ _ws->shutdown(); +// If socket was shutdown and buffers cleared then there's no +// reason to keep the object. This is crucial for DocumentBroker +// to be considered as not alive and associated kit process +// terminated in cleanupDocBrokers. Otherwise if kit process +// hangs then the asociated DocumentBroker object won't be +// removed and kit process won't be forcefully terminated. This +// is in conjunction with not clearing _pid data member which +// is needed later in call to terminate(). +_ws.reset(); +} } catch (const std::exception& ex) { LOG_ERR("Error while closing child process: " << ex.what()); } - -_pid = -1; } /// Kill or abandon the child. ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] online.git: common/Util.cpp common/Util.hpp kit/ForKit.cpp loolwsd.spec.in Makefile.am wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp wsd/ClientSession.cpp wsd
Makefile.am|3 common/Util.cpp| 25 +++- common/Util.hpp|3 kit/ForKit.cpp |1 loolwsd.spec.in|1 wsd/Admin.cpp | 47 +++- wsd/Admin.hpp | 11 + wsd/AdminModel.cpp | 280 - wsd/AdminModel.hpp | 38 ++ wsd/ClientSession.cpp |6 + wsd/ClientSession.hpp |3 wsd/DocumentBroker.cpp | 11 + wsd/DocumentBroker.hpp |3 wsd/LOOLWSD.cpp| 47 +++- wsd/Storage.cpp|3 wsd/Storage.hpp|3 wsd/metrics.txt| 155 +++ 17 files changed, 621 insertions(+), 19 deletions(-) New commits: commit 2164f5207c1717173edcd462433bfa0ee3257045 Author: Gabriel Masei AuthorDate: Tue Nov 12 11:50:33 2019 +0200 Commit: Michael Meeks CommitDate: Mon Nov 25 13:06:01 2019 +0100 Add REST endpoint for admin metrics. Change-Id: I701485631931334d27594c4907cb770f9888e5bf Reviewed-on: https://gerrit.libreoffice.org/82492 Reviewed-by: Michael Meeks Tested-by: Michael Meeks diff --git a/Makefile.am b/Makefile.am index c2912f279..ac6a45307 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,7 +33,8 @@ man_MANS = man/loolwsd.1 \ dist_doc_DATA = wsd/README \ wsd/README.vars \ wsd/protocol.txt \ -wsd/reference.md +wsd/reference.md \ +wsd/metrics.txt loolwsddatadir = @LOOLWSD_DATADIR@ diff --git a/common/Util.cpp b/common/Util.cpp index a589785d4..931de51d2 100644 --- a/common/Util.cpp +++ b/common/Util.cpp @@ -195,7 +195,7 @@ namespace Util } // close what we have - far faster than going up to a 1m open_max eg. -static bool closeFdsFromProc() +static bool closeFdsFromProc(std::map *mapFdsToKeep = nullptr) { DIR *fdDir = opendir("/proc/self/fd"); if (!fdDir) @@ -219,6 +219,9 @@ namespace Util if (fd < 3) continue; + if (mapFdsToKeep && mapFdsToKeep->find(fd) != mapFdsToKeep->end()) + continue; + if (close(fd) < 0) std::cerr << "Unexpected failure to close fd " << fd << std::endl; } @@ -227,22 +230,23 @@ namespace Util return true; } -static void closeFds() +static void closeFds(std::map *mapFdsToKeep = nullptr) { -if (!closeFdsFromProc()) +if (!closeFdsFromProc(mapFdsToKeep)) { std::cerr << "Couldn't close fds efficiently from /proc" << std::endl; for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd) -close(fd); +if (mapFdsToKeep->find(fd) != mapFdsToKeep->end()) +close(fd); } } -int spawnProcess(const std::string , const std::vector , int *stdInput) +int spawnProcess(const std::string , const std::vector , const std::vector* fdsToKeep, int *stdInput) { int pipeFds[2] = { -1, -1 }; if (stdInput) { -if (pipe(pipeFds) < 0) +if (pipe2(pipeFds, O_NONBLOCK) < 0) { LOG_ERR("Out of file descriptors spawning " << cmd); throw Poco::SystemException("Out of file descriptors"); @@ -255,6 +259,12 @@ namespace Util params.push_back(const_cast(i.c_str())); params.push_back(nullptr); +std::map mapFdsToKeep; + +if (fdsToKeep) +for (const auto& i : *fdsToKeep) +mapFdsToKeep[i] = i; + int pid = fork(); if (pid < 0) { @@ -266,7 +276,7 @@ namespace Util if (stdInput) dup2(pipeFds[0], STDIN_FILENO); -closeFds(); +closeFds(); int ret = execvp(params[0], [0]); if (ret < 0) @@ -282,6 +292,7 @@ namespace Util } return pid; } + #endif bool dataFromHexString(const std::string& hexString, std::vector& data) diff --git a/common/Util.hpp b/common/Util.hpp index 82389c1ab..66ce0b5b1 100644 --- a/common/Util.hpp +++ b/common/Util.hpp @@ -69,7 +69,8 @@ namespace Util /// Spawn a process if stdInput is non-NULL it contains a writable descriptor /// to send data to the child. int spawnProcess(const std::string , const std::vector , - int *stdInput = nullptr); + const std::vector* fdsToKeep = nullptr, int *stdInput = nullptr); + #endif /// Hex to unsigned char diff --git a/kit/ForKit.cpp b/kit/ForKit.cpp index 62491374c..164489589 100644 --- a/kit/ForKit.cpp +++ b/kit/ForKit.cpp @@ -209,6 +209,7 @@ static void cleanupChildren() std::vector jails; Process::PID exitedChildPid; int status; + // Reap quickly without doing slow cleanup so WSD can spawn more rapidly. while ((exitedChildPid = waitpid(-1, , WUNTRACED |
[Libreoffice-commits] online.git: kubernetes/helm
kubernetes/helm/README.md| 11 + kubernetes/helm/libreoffice-online/Chart.yaml|4 kubernetes/helm/libreoffice-online/templates/_helpers.tpl| 11 + kubernetes/helm/libreoffice-online/templates/deployment.yaml | 89 +++ kubernetes/helm/libreoffice-online/templates/hpa.yaml| 32 +++ kubernetes/helm/libreoffice-online/templates/service.yaml| 19 ++ kubernetes/helm/libreoffice-online/values.yaml | 77 + 7 files changed, 243 insertions(+) New commits: commit 0ca4d204bb1361b198666a82d5072a281ed62a82 Author: Gabriel Masei AuthorDate: Thu Oct 10 15:48:21 2019 +0300 Commit: Gabriel Masei CommitDate: Thu Oct 10 15:48:21 2019 +0300 Add basic support for kubernetes deploy Change-Id: I695f412570339a6225b198bcd3fd3b4f29fb4bd3 diff --git a/kubernetes/helm/README.md b/kubernetes/helm/README.md new file mode 100644 index 0..d038dbe38 --- /dev/null +++ b/kubernetes/helm/README.md @@ -0,0 +1,11 @@ +# OnlineOffice Helm-Charts + +# Available Charts + +## LibreOffice-Online +Chart for deploying C++ application [LibreOffice Online] in Kubernetes cluster. +To install the chart a command similar to the one above needs to be issued. +``` +.. cd helm-charts +helm install --namespace=${your desired namespace} --generate-name libreoffice-online +``` diff --git a/kubernetes/helm/libreoffice-online/Chart.yaml b/kubernetes/helm/libreoffice-online/Chart.yaml new file mode 100644 index 0..63e2067bc --- /dev/null +++ b/kubernetes/helm/libreoffice-online/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: LibreOffice Online helm chart +name: libreoffice-online +version: 1.1.0 diff --git a/kubernetes/helm/libreoffice-online/templates/_helpers.tpl b/kubernetes/helm/libreoffice-online/templates/_helpers.tpl new file mode 100644 index 0..ec188b25f --- /dev/null +++ b/kubernetes/helm/libreoffice-online/templates/_helpers.tpl @@ -0,0 +1,11 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "name" -}} +{{- default .Values.global.app.name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "chartname" -}} +{{- printf "%s-%s" .Chart.Name (.Chart.Version | replace "+" "_") -}} +{{- end -}} diff --git a/kubernetes/helm/libreoffice-online/templates/deployment.yaml b/kubernetes/helm/libreoffice-online/templates/deployment.yaml new file mode 100644 index 0..f0e600c68 --- /dev/null +++ b/kubernetes/helm/libreoffice-online/templates/deployment.yaml @@ -0,0 +1,89 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ default .Values.global.app.name .Values.deployment.name }} + labels: +app: {{ template "name" . }} +chart: {{ template "chartname" . }} +release: {{ .Release.Name }} +version: "{{ .Values.global.app.version }}" +spec: + minReadySeconds: {{ .Values.deployment.minReadySeconds }} + replicas: {{ .Values.replicaCount }} + selector: +matchLabels: + app: {{ template "name" . }} + release: {{ .Release.Name }} + strategy: +type: {{ .Values.deployment.type }} +{{- if eq .Values.deployment.type "RollingUpdate"}} +rollingUpdate: + maxSurge: {{ .Values.deployment.maxSurge }} + maxUnavailable: {{ .Values.deployment.maxUnavailable }} +{{- end}} + template: +metadata: + labels: +app: {{ template "name" . }} +release: {{ .Release.Name }} +version: "{{ .Values.global.app.version }}" +exposed: "true" + annotations: + {{- if .Values.global.app.monitoring.activate }} +prometheus.io/scrape: "true" +prometheus.io/port: "{{ .Values.global.app.monitoring.port }}" +prometheus.io/path: "{{ .Values.global.app.monitoring.path }}" + {{- end }} +spec: + containers: +- name: {{ .Values.global.app.name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: +- containerPort: {{ .Values.global.app.service.internalPort }} + securityContext: +readOnlyRootFilesystem: false +runAsNonRoot: true +#Lool user id +runAsUser: 101 +{{- if .Values.probes.liveness.activate }} + livenessProbe: +httpGet: + path: {{ .Values.probes.liveness.path }} + port: {{ .Values.probes.port }} + scheme: {{ .Values.probes.urlScheme }} +initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }} +periodSeconds: {{ .Values.probes.liveness.periodSeconds }} +timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }} +successThreshold: {{ .Values.probes.liveness.successThreshold }} +failureThreshold: {{ .Values.probes.liveness.failureThreshold }} + {{- end }}
[Libreoffice-commits] online.git: loolwsd.xml.in wsd/LOOLWSD.cpp wsd/LOOLWSD.hpp wsd/Storage.cpp wsd/Storage.hpp
loolwsd.xml.in |7 +++ wsd/LOOLWSD.cpp |1 + wsd/LOOLWSD.hpp | 34 -- wsd/Storage.cpp | 48 +++- wsd/Storage.hpp |4 5 files changed, 75 insertions(+), 19 deletions(-) New commits: commit d597f22dac9042c3917d3b105adc810b6900d52c Author: Gabriel Masei AuthorDate: Mon Oct 7 14:51:30 2019 +0300 Commit: Michael Meeks CommitDate: Tue Oct 8 18:57:36 2019 +0200 Add minimal TLS support for communication with storage Change-Id: Iafd9946a4240063c07f5c519b8af30b52e23d3e8 Reviewed-on: https://gerrit.libreoffice.org/80373 Reviewed-by: Michael Meeks Tested-by: Michael Meeks diff --git a/loolwsd.xml.in b/loolwsd.xml.in index baa42874d..91c748e93 100644 --- a/loolwsd.xml.in +++ b/loolwsd.xml.in @@ -125,6 +125,13 @@ localhost + + + + + + + true diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index d0dd39878..c39f62d99 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -850,6 +850,7 @@ void LOOLWSD::initialize(Application& self) { "ssl.key_file_path", LOOLWSD_CONFIGDIR "/key.pem" }, { "ssl.termination", "true" }, { "storage.filesystem[@allow]", "false" }, +{ "storage.ssl.enable", "false" }, { "storage.webdav[@allow]", "false" }, { "storage.wopi.host[0]", "localhost" }, { "storage.wopi.host[0][@allow]", "true" }, diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp index 0253d08b2..333a6afc1 100644 --- a/wsd/LOOLWSD.hpp +++ b/wsd/LOOLWSD.hpp @@ -130,6 +130,27 @@ public: return getConfigValue(Application::instance().config(), name, def); } +/// Reads and processes path entries with the given property +/// from the configuration. +/// Converts relative paths to absolute. +static +std::string getPathFromConfig(const std::string& name) +{ +return getPathFromConfig(Application::instance().config(), name); +} + +/// Reads and processes path entries with the given property +/// from the configuration. If value is empty then it reads from fallback +/// Converts relative paths to absolute. +static +std::string getPathFromConfigWithFallback(const std::string& name, const std::string& fallbackName) +{ +std::string value = LOOLWSD::getPathFromConfig(name); +if (value.empty()) +return LOOLWSD::getPathFromConfig(fallbackName); +return value; +} + /// Trace a new session and take a snapshot of the file. static void dumpNewSessionTrace(const std::string& id, const std::string& sessionId, const std::string& uri, const std::string& path); @@ -253,19 +274,20 @@ private: /// Reads and processes path entries with the given property /// from the configuration. /// Converts relative paths to absolute. -std::string getPathFromConfig(const std::string& property) const +static +std::string getPathFromConfig(Poco::Util::LayeredConfiguration& config, const std::string& property) { -std::string path = config().getString(property); -if (path.empty() && config().hasProperty(property + "[@default]")) +std::string path = config.getString(property); +if (path.empty() && config.hasProperty(property + "[@default]")) { // Use the default value if empty and a default provided. -path = config().getString(property + "[@default]"); +path = config.getString(property + "[@default]"); } // Reconstruct absolute path if relative. if (!Poco::Path(path).isAbsolute() && -config().hasProperty(property + "[@relative]") && -config().getBool(property + "[@relative]")) +config.hasProperty(property + "[@relative]") && +config.getBool(property + "[@relative]")) { path = Poco::Path(Application::instance().commandPath()).parent().append(path).toString(); } diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp index c96bd208f..49e804b89 100644 --- a/wsd/Storage.cpp +++ b/wsd/Storage.cpp @@ -54,6 +54,7 @@ using std::size_t; bool StorageBase::FilesystemEnabled; bool StorageBase::WopiEnabled; +bool StorageBase::SSLEnabled; Util::RegexListMatcher StorageBase::WopiHosts; #if !MOBILEAPP @@ -124,8 +125,29 @@ void StorageBase::initialize() // Init client Poco::Net::Context::Params sslClientParams; -// TODO: Be more strict and setup SSL key/certs for remote server and us -sslClientParams.verificationMode = Poco::Net::Context::VERIFY_NONE; +SSLEnabled = LOOLWSD::getConfigValue("storage.ssl.enable", false); +#if ENABLE_DEBUG +char *StorageSSLEnabled = getenv("STORAGE_SSL_ENABLE"); +if (StorageSSLEnabled != NULL) +{ +if (!strcasecmp(StorageSSLEnabled, "true")) +
[Libreoffice-commits] online.git: Branch 'libreoffice-6-2' - net/WebSocketHandler.hpp
net/WebSocketHandler.hpp | 268 +++ 1 file changed, 182 insertions(+), 86 deletions(-) New commits: commit 1a9e34581c281b4d43c60aff2628bcc996fdc025 Author: Gabriel Masei AuthorDate: Fri Mar 8 10:21:17 2019 +0200 Commit: Samuel Mehrbrodt CommitDate: Thu Jul 25 17:08:06 2019 +0200 Added support for defragmentation of incoming websocket fragmented messages and handled some protocol error cases Change-Id: I4d11a6527b6b131c65101fd53b71015529645f74 Reviewed-on: https://gerrit.libreoffice.org/68901 Reviewed-by: Michael Meeks Tested-by: Michael Meeks Reviewed-on: https://gerrit.libreoffice.org/76327 Reviewed-by: Samuel Mehrbrodt Tested-by: Samuel Mehrbrodt diff --git a/net/WebSocketHandler.hpp b/net/WebSocketHandler.hpp index a037cb6b5..e20ff5d5a 100644 --- a/net/WebSocketHandler.hpp +++ b/net/WebSocketHandler.hpp @@ -37,6 +37,8 @@ private: std::atomic _shuttingDown; bool _isClient; bool _isMasking; +bool _inFragmentBlock; +bool _isManualDefrag; protected: struct WSFrameMask @@ -50,16 +52,29 @@ protected: public: /// Perform upgrade ourselves, or select a client web socket. -WebSocketHandler(bool isClient = false, bool isMasking = true) : +/// Parameters: +/// isClient: the instance should behave like a client (true) or like a server (false) +/// (from websocket perspective) +/// isMasking: a client should mask (true) or not (false) outgoing frames +/// isManualDefrag: the message handler should be called for every fragment of a message and +/// defragmentation should be handled inside message handler (true) or the message handler +/// should be called after all fragments of a message were received and the message +/// was defragmented (false). +WebSocketHandler(bool isClient = false, bool isMasking = true, bool isManualDefrag = false) : _lastPingSentTime(std::chrono::steady_clock::now()), _pingTimeUs(0), _shuttingDown(false), _isClient(isClient), -_isMasking(isClient && isMasking) +_isMasking(isClient && isMasking), +_inFragmentBlock(false), +_isManualDefrag(isManualDefrag) { } /// Upgrades itself to a websocket directly. +/// Parameters: +/// socket: the TCP socket which received the upgrade request +/// request: the HTTP upgrade request to WebSocket WebSocketHandler(const std::weak_ptr& socket, const Poco::Net::HTTPRequest& request) : _socket(socket), @@ -69,7 +84,9 @@ public: _pingTimeUs(0), _shuttingDown(false), _isClient(false), -_isMasking(false) +_isMasking(false), +_inFragmentBlock(false), +_isManualDefrag(false) { upgradeToWebSocket(request); } @@ -99,8 +116,8 @@ public: RESERVED_TLS_FAILURE= 1015 }; -/// Sends WS shutdown message to the peer. -void shutdown(const StatusCodes statusCode = StatusCodes::NORMAL_CLOSE, const std::string& statusMessage = "") +/// Sends WS Close frame to the peer. +void sendCloseFrame(const StatusCodes statusCode = StatusCodes::NORMAL_CLOSE, const std::string& statusMessage = "") { std::shared_ptr socket = _socket.lock(); if (socket == nullptr) @@ -126,7 +143,22 @@ public: #endif } -bool handleOneIncomingMessage(const std::shared_ptr& socket) +void shutdown(const StatusCodes statusCode = StatusCodes::NORMAL_CLOSE, const std::string& statusMessage = "") +{ +if (!_shuttingDown) +sendCloseFrame(statusCode, statusMessage); +std::shared_ptr socket = _socket.lock(); +if (socket) +{ +socket->closeConnection(); +socket->getInBuffer().clear(); +} +_wsPayload.clear(); +_inFragmentBlock = false; +_shuttingDown = false; +} + +bool handleTCPStream(const std::shared_ptr& socket) { assert(socket && "Expected a valid socket instance."); @@ -177,7 +209,7 @@ public: headerLen += 8; } -unsigned char *data, *mask; +unsigned char *data, *mask = nullptr; if (hasMask) { @@ -187,117 +219,165 @@ public: if (payloadLen + headerLen > len) { // partial read wait for more data. -LOG_TRC("#" << socket->getFD() << ": Still incomplete WebSocket message, have " << len << " bytes, message is " << payloadLen + headerLen << " bytes"); +LOG_TRC("#" << socket->getFD() << ": Still incomplete WebSocket frame, have " << len << " bytes, frame is " << payloadLen + headerLen << " bytes"); return false; } +if (hasMask && _isClient) +{ +LOG_ERR("#" << socket->getFD() << ": Servers should not send masked frames. Only
[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-4-0' - net/WebSocketHandler.hpp
net/WebSocketHandler.hpp | 267 +++ 1 file changed, 181 insertions(+), 86 deletions(-) New commits: commit ea803124a0a79742e3532c8421af9deb1e184902 Author: Gabriel Masei AuthorDate: Fri Mar 8 10:21:17 2019 +0200 Commit: Andras Timar CommitDate: Thu Jun 13 10:03:44 2019 +0200 Added support for defragmentation of incoming websocket fragmented messages and handled some protocol error cases Change-Id: I4d11a6527b6b131c65101fd53b71015529645f74 Reviewed-on: https://gerrit.libreoffice.org/68901 Reviewed-by: Michael Meeks Tested-by: Michael Meeks Reviewed-on: https://gerrit.libreoffice.org/72479 Reviewed-by: Andras Timar Tested-by: Andras Timar diff --git a/net/WebSocketHandler.hpp b/net/WebSocketHandler.hpp index a037cb6b5..472360ab6 100644 --- a/net/WebSocketHandler.hpp +++ b/net/WebSocketHandler.hpp @@ -37,6 +37,8 @@ private: std::atomic _shuttingDown; bool _isClient; bool _isMasking; +bool _inFragmentBlock; +bool _isManualDefrag; protected: struct WSFrameMask @@ -50,16 +52,29 @@ protected: public: /// Perform upgrade ourselves, or select a client web socket. -WebSocketHandler(bool isClient = false, bool isMasking = true) : +/// Parameters: +/// isClient: the instance should behave like a client (true) or like a server (false) +/// (from websocket perspective) +/// isMasking: a client should mask (true) or not (false) outgoing frames +/// isManualDefrag: the message handler should be called for every fragment of a message and +/// defragmentation should be handled inside message handler (true) or the message handler +/// should be called after all fragments of a message were received and the message +/// was defragmented (false). +WebSocketHandler(bool isClient = false, bool isMasking = true, bool isManualDefrag = false) : _lastPingSentTime(std::chrono::steady_clock::now()), _pingTimeUs(0), _shuttingDown(false), _isClient(isClient), -_isMasking(isClient && isMasking) +_isMasking(isClient && isMasking), +_inFragmentBlock(false), +_isManualDefrag(isManualDefrag) { } /// Upgrades itself to a websocket directly. +/// Parameters: +/// socket: the TCP socket which received the upgrade request +/// request: the HTTP upgrade request to WebSocket WebSocketHandler(const std::weak_ptr& socket, const Poco::Net::HTTPRequest& request) : _socket(socket), @@ -69,7 +84,9 @@ public: _pingTimeUs(0), _shuttingDown(false), _isClient(false), -_isMasking(false) +_isMasking(false), +_inFragmentBlock(false), +_isManualDefrag(false) { upgradeToWebSocket(request); } @@ -99,8 +116,8 @@ public: RESERVED_TLS_FAILURE= 1015 }; -/// Sends WS shutdown message to the peer. -void shutdown(const StatusCodes statusCode = StatusCodes::NORMAL_CLOSE, const std::string& statusMessage = "") +/// Sends WS Close frame to the peer. +void sendCloseFrame(const StatusCodes statusCode = StatusCodes::NORMAL_CLOSE, const std::string& statusMessage = "") { std::shared_ptr socket = _socket.lock(); if (socket == nullptr) @@ -126,7 +143,22 @@ public: #endif } -bool handleOneIncomingMessage(const std::shared_ptr& socket) +void shutdown(const StatusCodes statusCode = StatusCodes::NORMAL_CLOSE, const std::string& statusMessage = "") +{ +if (!_shuttingDown) +sendCloseFrame(statusCode, statusMessage); +std::shared_ptr socket = _socket.lock(); +if (socket) +{ +socket->closeConnection(); +socket->getInBuffer().clear(); +} +_wsPayload.clear(); +_inFragmentBlock = false; +_shuttingDown = false; +} + +bool handleTCPStream(const std::shared_ptr& socket) { assert(socket && "Expected a valid socket instance."); @@ -177,7 +209,7 @@ public: headerLen += 8; } -unsigned char *data, *mask; +unsigned char *data, *mask = nullptr; if (hasMask) { @@ -187,117 +219,164 @@ public: if (payloadLen + headerLen > len) { // partial read wait for more data. -LOG_TRC("#" << socket->getFD() << ": Still incomplete WebSocket message, have " << len << " bytes, message is " << payloadLen + headerLen << " bytes"); +LOG_TRC("#" << socket->getFD() << ": Still incomplete WebSocket frame, have " << len << " bytes, frame is " << payloadLen + headerLen << " bytes"); return false; } +if (hasMask && _isClient) +{ +LOG_ERR("#" << socket->getFD() << ": Servers should not send masked frames. Only clients.");