Skip to content

Commit

Permalink
qgsfileutils: add method to know if we are close to the limit of simu…
Browse files Browse the repository at this point in the history
…ltaneously opened files (refs #43620)
  • Loading branch information
rouault authored and nyalldawson committed Sep 23, 2021
1 parent 80d7014 commit d69d8e5
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
2 changes: 2 additions & 0 deletions python/core/auto_generated/qgsfileutils.sip.in
Expand Up @@ -181,6 +181,8 @@ desired.
.. versionadded:: 3.22
%End



};

/************************************************************************
Expand Down
39 changes: 39 additions & 0 deletions src/core/qgsfileutils.cpp
Expand Up @@ -26,6 +26,12 @@
#include <QSet>
#include <QDirIterator>

#ifdef Q_OS_UNIX
// For getrlimit()
#include <sys/resource.h>
#include <sys/time.h>
#endif

#ifdef MSVC
#include <Windows.h>
#include <ShlObj.h>
Expand Down Expand Up @@ -462,3 +468,36 @@ bool QgsFileUtils::renameDataset( const QString &oldPath, const QString &newPath

return res;
}

int QgsFileUtils::openedFileLimit()
{
#ifdef Q_OS_UNIX
struct rlimit rescLimit;
if ( getrlimit( RLIMIT_NOFILE, &rescLimit ) == 0 )
{
return rescLimit.rlim_cur;
}
#endif
return -1;
}

int QgsFileUtils::openedFileCount()
{
#ifdef Q_OS_LINUX
int res = static_cast<int>( QDir( "/proc/self/fd" ).entryList().size() );
if ( res == 0 )
res = -1;
return res;
#else
return -1;
#endif
}

bool QgsFileUtils::isCloseToLimitOfOpenedFiles( int filesToBeOpened )
{
const int nFileLimit = QgsFileUtils::openedFileLimit();
const int nFileCount = QgsFileUtils::openedFileCount();
// We need some margin as Qt will crash if it cannot create some file descriptors
constexpr int SOME_MARGIN = 20;
return nFileCount > 0 && nFileLimit > 0 && nFileCount + filesToBeOpened > nFileLimit - SOME_MARGIN;
}
34 changes: 34 additions & 0 deletions src/core/qgsfileutils.h
Expand Up @@ -180,6 +180,40 @@ class CORE_EXPORT QgsFileUtils
*/
static bool renameDataset( const QString &oldPath, const QString &newPath, QString &error SIP_OUT, Qgis::FileOperationFlags flags = Qgis::FileOperationFlag::IncludeMetadataFile | Qgis::FileOperationFlag::IncludeStyleFile );

/**
* Returns the limit of simultaneously opened files by the process.
*
* Currently only implemented on Unix.
*
* \returns Limit, or -1 if unknown.
* \note not available in Python bindings
* \since QGIS 3.22
*/
static int openedFileLimit() SIP_SKIP;

/**
* Returns the number of currently opened files by the process.
*
* Currently only implemented on Linux.
*
* \returns Number of files, or -1 if unknown
* \note not available in Python bindings
* \since QGIS 3.22
*/
static int openedFileCount() SIP_SKIP;

/**
* Returns whether when opening new file(s) will reach, or nearly reach,
* the limit of simultaneously opened files by the process.
*
* Currently only implemented on Linux.
*
* \param filesToBeOpened Number of files that will be opened.
* \returns true if close to the limit, or false if not, or unknown.
* \note not available in Python bindings
* \since QGIS 3.22
*/
static bool isCloseToLimitOfOpenedFiles( int filesToBeOpened = 1 ) SIP_SKIP;
};

#endif // QGSFILEUTILS_H

0 comments on commit d69d8e5

Please sign in to comment.