WIN allow setting a memory limit for soffice.bin

This adds a Win32 section and two keys to the bootstrap.ini, which
can be used to apply a memory limit to the soffice.bin process on
Windows. Per default the limit won't affect any sub-processes,
because the 2nd key adds JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK to
the Jobs' flag list.

To activte the limit, extend the bootstrap.ini like this:

[Win32]
LimitMaximumMemoryInMB=0
ExcludeChildProcessesFromLimit=true

and adapt the values to your needs. Zero disables the limit.

Change-Id: Ic474c6d6cdfe5ff3cfadbe6614030442171df1ae
Reviewed-on: https://gerrit.libreoffice.org/78819
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
This commit is contained in:
Jan-Marek Glogowski 2019-09-11 14:35:19 +02:00 committed by Jan-Marek Glogowski
parent d37330ce1b
commit 6df7568e46
2 changed files with 55 additions and 0 deletions

View file

@ -10,6 +10,10 @@
$(eval $(call gb_StaticLibrary_StaticLibrary,winloader))
$(eval $(call gb_StaticLibrary_use_externals,winloader,\
boost_headers \
))
$(eval $(call gb_StaticLibrary_add_exception_objects,winloader,\
desktop/win32/source/loader \
))

View file

@ -26,6 +26,9 @@
#include <desktop/exithelper.h>
#include <tools/pathutils.hxx>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
namespace {
void fail()
@ -160,6 +163,47 @@ int officeloader_impl(bool bAllowConsole)
}
std::vector<std::wstring> aEscapedArgs;
// read limit values from bootstrap.ini
unsigned int nMaxMemoryInMB = 0;
bool bExcludeChildProcesses = true;
const WCHAR* szIniFile = L"\\bootstrap.ini";
const size_t nDirLen = wcslen(szIniDirectory);
if (wcslen(szIniFile) + nDirLen < MAX_PATH)
{
WCHAR szBootstrapIni[MAX_PATH];
wcscpy(szBootstrapIni, szIniDirectory);
wcscpy(&szBootstrapIni[nDirLen], szIniFile);
try
{
boost::property_tree::ptree pt;
std::fstream aFile(szBootstrapIni);
boost::property_tree::ini_parser::read_ini(aFile, pt);
nMaxMemoryInMB = pt.get("Win32.LimitMaximumMemoryInMB", nMaxMemoryInMB);
bExcludeChildProcesses = pt.get("Win32.ExcludeChildProcessesFromLimit", bExcludeChildProcesses);
}
catch (...)
{
nMaxMemoryInMB = 0;
}
}
// create a Windows JobObject with a memory limit
HANDLE hJobObject = NULL;
if (nMaxMemoryInMB > 0)
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION aJobLimit;
aJobLimit.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_JOB_MEMORY;
if (bExcludeChildProcesses)
aJobLimit.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
aJobLimit.JobMemoryLimit = nMaxMemoryInMB * 1024 * 1024;
hJobObject = CreateJobObjectW(NULL, NULL);
if (hJobObject != NULL)
SetInformationJobObject(hJobObject, JobObjectExtendedLimitInformation, &aJobLimit,
sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
}
do
{
if (bFirst)
@ -247,6 +291,9 @@ int officeloader_impl(bool bAllowConsole)
{
DWORD dwWaitResult;
if (hJobObject)
AssignProcessToJobObject(hJobObject, aProcessInfo.hProcess);
do
{
// On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWith" so
@ -272,6 +319,10 @@ int officeloader_impl(bool bAllowConsole)
} while (fSuccess
&& (EXITHELPER_CRASH_WITH_RESTART == dwExitCode
|| EXITHELPER_NORMAL_RESTART == dwExitCode));
if (hJobObject)
CloseHandle(hJobObject);
delete[] lpCommandLine;
return fSuccess ? dwExitCode : -1;