Now using a separate QSemaphore to limit the number of tasks in the queue of the QThreadPool. Instead of starting exactly as many task as there are threads in the pool and adding a new task only after a running one finished, we will now keep a fixed number of tasks in the queue (currently hardcoded to 32). Since there always will be more tasks left in the queue than there are threads in the pool, we ensure that no thread will ever become idle. Might be slightly faster than the "old" approach.
This commit is contained in:
parent
61dc8e34c4
commit
a291771153
@ -72,10 +72,10 @@ if not "%LAMEXP_ERROR%"=="0" (
|
|||||||
GOTO:EOF
|
GOTO:EOF
|
||||||
)
|
)
|
||||||
REM ------------------------------------------
|
REM ------------------------------------------
|
||||||
set "OUT_FILE=%OUT_PATH%\..\LameXP.%ISO_DATE%.%LAMEXP_CONFIG:_=-%.Build-%VER_LAMEXP_BUILD%"
|
set "OUT_FILE=%OUT_PATH%\..\%VER_LAMEXP_BASENAME%.%ISO_DATE%.%LAMEXP_CONFIG:_=-%.Build-%VER_LAMEXP_BUILD%"
|
||||||
for /L %%n in (1, 1, 99) do (
|
for /L %%n in (1, 1, 99) do (
|
||||||
if exist "!OUT_FILE!.exe" set "OUT_FILE=%OUT_PATH%\..\LameXP.%ISO_DATE%.%LAMEXP_CONFIG:_=-%.Build-%VER_LAMEXP_BUILD%.Update-%%n"
|
if exist "!OUT_FILE!.exe" set "OUT_FILE=%OUT_PATH%\..\%VER_LAMEXP_BASENAME%.%ISO_DATE%.%LAMEXP_CONFIG:_=-%.Build-%VER_LAMEXP_BUILD%.Update-%%n"
|
||||||
if exist "!OUT_FILE!.zip" set "OUT_FILE=%OUT_PATH%\..\LameXP.%ISO_DATE%.%LAMEXP_CONFIG:_=-%.Build-%VER_LAMEXP_BUILD%.Update-%%n"
|
if exist "!OUT_FILE!.zip" set "OUT_FILE=%OUT_PATH%\..\%VER_LAMEXP_BASENAME%.%ISO_DATE%.%LAMEXP_CONFIG:_=-%.Build-%VER_LAMEXP_BUILD%.Update-%%n"
|
||||||
)
|
)
|
||||||
REM ------------------------------------------
|
REM ------------------------------------------
|
||||||
REM :: DELETE OLD OUTPUT FILE ::
|
REM :: DELETE OLD OUTPUT FILE ::
|
||||||
|
@ -7,6 +7,7 @@ set "VER_LAMEXP_MINOR_LO="
|
|||||||
set "VER_LAMEXP_BUILD="
|
set "VER_LAMEXP_BUILD="
|
||||||
set "VER_LAMEXP_TYPE="
|
set "VER_LAMEXP_TYPE="
|
||||||
set "VER_LAMEXP_PATCH="
|
set "VER_LAMEXP_PATCH="
|
||||||
|
set "VER_LAMEXP_BASENAME="
|
||||||
REM ------------------------------------------
|
REM ------------------------------------------
|
||||||
for /f "tokens=2,*" %%s in (%~dp0\..\..\src\Config.h) do (
|
for /f "tokens=2,*" %%s in (%~dp0\..\..\src\Config.h) do (
|
||||||
if "%%s"=="VER_LAMEXP_MAJOR" set "VER_LAMEXP_MAJOR=%%~t"
|
if "%%s"=="VER_LAMEXP_MAJOR" set "VER_LAMEXP_MAJOR=%%~t"
|
||||||
@ -25,6 +26,9 @@ if "%VER_LAMEXP_BUILD%"=="" GOTO:EOF
|
|||||||
if "%VER_LAMEXP_TYPE%"=="" GOTO:EOF
|
if "%VER_LAMEXP_TYPE%"=="" GOTO:EOF
|
||||||
if "%VER_LAMEXP_PATCH%"=="" GOTO:EOF
|
if "%VER_LAMEXP_PATCH%"=="" GOTO:EOF
|
||||||
REM ------------------------------------------
|
REM ------------------------------------------
|
||||||
|
set "VER_LAMEXP_BASENAME=LameXP"
|
||||||
|
if not "%VER_LAMEXP_TYPE%" == "Final" set "VER_LAMEXP_BASENAME=LameXP-PRERELEASE"
|
||||||
|
REM ------------------------------------------
|
||||||
echo LameXP Version:
|
echo LameXP Version:
|
||||||
echo %VER_LAMEXP_MAJOR%.%VER_LAMEXP_MINOR_HI%%VER_LAMEXP_MINOR_LO%, Build #%VER_LAMEXP_BUILD% (%VER_LAMEXP_TYPE%-%VER_LAMEXP_PATCH%)
|
echo %VER_LAMEXP_MAJOR%.%VER_LAMEXP_MINOR_HI%%VER_LAMEXP_MINOR_LO%, Build #%VER_LAMEXP_BUILD% (%VER_LAMEXP_TYPE%-%VER_LAMEXP_PATCH%)
|
||||||
echo.
|
echo.
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -29,8 +29,8 @@
|
|||||||
#define VER_LAMEXP_MINOR_HI 0
|
#define VER_LAMEXP_MINOR_HI 0
|
||||||
#define VER_LAMEXP_MINOR_LO 5
|
#define VER_LAMEXP_MINOR_LO 5
|
||||||
#define VER_LAMEXP_TYPE Alpha
|
#define VER_LAMEXP_TYPE Alpha
|
||||||
#define VER_LAMEXP_PATCH 2
|
#define VER_LAMEXP_PATCH 3
|
||||||
#define VER_LAMEXP_BUILD 1027
|
#define VER_LAMEXP_BUILD 1031
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Tool versions (minimum expected versions!)
|
// Tool versions (minimum expected versions!)
|
||||||
|
@ -516,27 +516,27 @@ void MainWindow::addFiles(const QStringList &files)
|
|||||||
|
|
||||||
tabWidget->setCurrentIndex(0);
|
tabWidget->setCurrentIndex(0);
|
||||||
|
|
||||||
int timeMT = 0, timeST = 0;
|
//int timeMT = 0, timeST = 0;
|
||||||
|
//
|
||||||
//--Prepass--
|
//--Prepass--
|
||||||
|
//
|
||||||
FileAnalyzer_ST *analyzerPre = new FileAnalyzer_ST(files);
|
//FileAnalyzer_ST *analyzerPre = new FileAnalyzer_ST(files);
|
||||||
connect(analyzerPre, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
|
//connect(analyzerPre, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
|
||||||
connect(analyzerPre, SIGNAL(progressValChanged(unsigned int)), m_banner, SLOT(setProgressVal(unsigned int)), Qt::QueuedConnection);
|
//connect(analyzerPre, SIGNAL(progressValChanged(unsigned int)), m_banner, SLOT(setProgressVal(unsigned int)), Qt::QueuedConnection);
|
||||||
connect(analyzerPre, SIGNAL(progressMaxChanged(unsigned int)), m_banner, SLOT(setProgressMax(unsigned int)), Qt::QueuedConnection);
|
//connect(analyzerPre, SIGNAL(progressMaxChanged(unsigned int)), m_banner, SLOT(setProgressMax(unsigned int)), Qt::QueuedConnection);
|
||||||
connect(analyzerPre, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
|
//connect(analyzerPre, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
|
||||||
connect(m_banner, SIGNAL(userAbort()), analyzerPre, SLOT(abortProcess()), Qt::DirectConnection);
|
//connect(m_banner, SIGNAL(userAbort()), analyzerPre, SLOT(abortProcess()), Qt::DirectConnection);
|
||||||
|
//
|
||||||
try
|
//try
|
||||||
{
|
//{
|
||||||
m_fileListModel->setBlockUpdates(true);
|
// m_fileListModel->setBlockUpdates(true);
|
||||||
m_banner->show(tr("Adding file(s), please wait..."), analyzerPre);
|
// m_banner->show(tr("Adding file(s), please wait..."), analyzerPre);
|
||||||
}
|
//}
|
||||||
catch(...)
|
//catch(...)
|
||||||
{
|
//{
|
||||||
/* ignore any exceptions that may occur */
|
// /* ignore any exceptions that may occur */
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
//--MT--
|
//--MT--
|
||||||
|
|
||||||
FileAnalyzer *analyzer = new FileAnalyzer(files);
|
FileAnalyzer *analyzer = new FileAnalyzer(files);
|
||||||
@ -551,7 +551,7 @@ void MainWindow::addFiles(const QStringList &files)
|
|||||||
m_fileListModel->setBlockUpdates(true);
|
m_fileListModel->setBlockUpdates(true);
|
||||||
QTime startTime = QTime::currentTime();
|
QTime startTime = QTime::currentTime();
|
||||||
m_banner->show(tr("Adding file(s), please wait..."), analyzer);
|
m_banner->show(tr("Adding file(s), please wait..."), analyzer);
|
||||||
timeMT = startTime.secsTo(QTime::currentTime());
|
//timeMT = startTime.secsTo(QTime::currentTime());
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -559,39 +559,39 @@ void MainWindow::addFiles(const QStringList &files)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--ST--
|
//--ST--
|
||||||
|
//
|
||||||
FileAnalyzer_ST *analyzerST = new FileAnalyzer_ST(files);
|
//FileAnalyzer_ST *analyzerST = new FileAnalyzer_ST(files);
|
||||||
connect(analyzerST, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
|
//connect(analyzerST, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
|
||||||
connect(analyzerST, SIGNAL(progressValChanged(unsigned int)), m_banner, SLOT(setProgressVal(unsigned int)), Qt::QueuedConnection);
|
//connect(analyzerST, SIGNAL(progressValChanged(unsigned int)), m_banner, SLOT(setProgressVal(unsigned int)), Qt::QueuedConnection);
|
||||||
connect(analyzerST, SIGNAL(progressMaxChanged(unsigned int)), m_banner, SLOT(setProgressMax(unsigned int)), Qt::QueuedConnection);
|
//connect(analyzerST, SIGNAL(progressMaxChanged(unsigned int)), m_banner, SLOT(setProgressMax(unsigned int)), Qt::QueuedConnection);
|
||||||
connect(analyzerST, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
|
//connect(analyzerST, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
|
||||||
connect(m_banner, SIGNAL(userAbort()), analyzerST, SLOT(abortProcess()), Qt::DirectConnection);
|
//connect(m_banner, SIGNAL(userAbort()), analyzerST, SLOT(abortProcess()), Qt::DirectConnection);
|
||||||
|
//
|
||||||
try
|
//try
|
||||||
{
|
//{
|
||||||
m_fileListModel->setBlockUpdates(true);
|
// m_fileListModel->setBlockUpdates(true);
|
||||||
QTime startTime = QTime::currentTime();
|
// QTime startTime = QTime::currentTime();
|
||||||
m_banner->show(tr("Adding file(s), please wait..."), analyzerST);
|
// m_banner->show(tr("Adding file(s), please wait..."), analyzerST);
|
||||||
timeST = startTime.secsTo(QTime::currentTime());
|
// timeST = startTime.secsTo(QTime::currentTime());
|
||||||
}
|
//}
|
||||||
catch(...)
|
//catch(...)
|
||||||
{
|
//{
|
||||||
/* ignore any exceptions that may occur */
|
// /* ignore any exceptions that may occur */
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
//------
|
//------
|
||||||
|
//
|
||||||
if(timeST > 0 && timeMT > 0)
|
//if(timeST > 0 && timeMT > 0)
|
||||||
{
|
//{
|
||||||
double speedUp = static_cast<double>(timeST) / static_cast<double>(timeMT);
|
// double speedUp = static_cast<double>(timeST) / static_cast<double>(timeMT);
|
||||||
qWarning("ST: %d, MT: %d", timeST, timeMT);
|
// qWarning("ST: %d, MT: %d", timeST, timeMT);
|
||||||
QMessageBox::information(this, "Speed Up", QString().sprintf("Announcement: The new multi-threaded file analyzer is %.1fx faster !!!", speedUp), QMessageBox::Ok);
|
// QMessageBox::information(this, "Speed Up", QString().sprintf("Announcement: The new multi-threaded file analyzer is %.1fx faster !!!", speedUp), QMessageBox::Ok);
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
QMessageBox::information(this, "Speed Up", "Couldn't compare the the new multi-threaded file analyzer this time!", QMessageBox::Ok);
|
// QMessageBox::information(this, "Speed Up", "Couldn't compare the the new multi-threaded file analyzer this time!", QMessageBox::Ok);
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
//------
|
//------
|
||||||
|
|
||||||
m_fileListModel->setBlockUpdates(false);
|
m_fileListModel->setBlockUpdates(false);
|
||||||
@ -619,8 +619,8 @@ void MainWindow::addFiles(const QStringList &files)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LAMEXP_DELETE(analyzer);
|
LAMEXP_DELETE(analyzer);
|
||||||
LAMEXP_DELETE(analyzerST);
|
//LAMEXP_DELETE(analyzerST);
|
||||||
LAMEXP_DELETE(analyzerPre);
|
//LAMEXP_DELETE(analyzerPre);
|
||||||
|
|
||||||
m_banner->close();
|
m_banner->close();
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,8 @@ const char *FileAnalyzer::g_tags_aud[] =
|
|||||||
|
|
||||||
void FileAnalyzer::run()
|
void FileAnalyzer::run()
|
||||||
{
|
{
|
||||||
|
qWarning("--- FileAnalyzer::run() ---");
|
||||||
|
|
||||||
m_abortFlag = false;
|
m_abortFlag = false;
|
||||||
|
|
||||||
m_bAborted = false;
|
m_bAborted = false;
|
||||||
@ -139,40 +141,34 @@ void FileAnalyzer::run()
|
|||||||
{
|
{
|
||||||
while(!(m_inputFiles.isEmpty() || m_bAborted))
|
while(!(m_inputFiles.isEmpty() || m_bAborted))
|
||||||
{
|
{
|
||||||
const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst());
|
if(!AnalyzeTask::waitForFreeSlot(&m_abortFlag))
|
||||||
|
|
||||||
AnalyzeTask *task = new AnalyzeTask(currentFile, m_templateFile->filePath(), &m_abortFlag);
|
|
||||||
connect(task, SIGNAL(fileSelected(QString)), this, SIGNAL(fileSelected(QString)), Qt::DirectConnection);
|
|
||||||
connect(task, SIGNAL(progressValChanged(unsigned int)), this, SIGNAL(progressValChanged(unsigned int)), Qt::DirectConnection);
|
|
||||||
connect(task, SIGNAL(progressMaxChanged(unsigned int)), this, SIGNAL(progressMaxChanged(unsigned int)), Qt::DirectConnection);
|
|
||||||
connect(task, SIGNAL(fileAnalyzed(AudioFileModel)), this, SIGNAL(fileAnalyzed(AudioFileModel)), Qt::DirectConnection);
|
|
||||||
|
|
||||||
while(!pool->tryStart(task))
|
|
||||||
{
|
{
|
||||||
AnalyzeTask::waitForOneThread();
|
qWarning("Timeout in AnalyzeTask::waitForFreeSlot() !!!");
|
||||||
|
|
||||||
if(m_abortFlag)
|
|
||||||
{
|
|
||||||
LAMEXP_DELETE(task);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QThread::yieldCurrentThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_abortFlag)
|
if(m_abortFlag)
|
||||||
{
|
{
|
||||||
MessageBeep(MB_ICONERROR);
|
MessageBeep(MB_ICONERROR);
|
||||||
m_bAborted = true;
|
m_bAborted = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_bAborted)
|
if(!m_bAborted)
|
||||||
{
|
{
|
||||||
|
const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst());
|
||||||
|
|
||||||
|
AnalyzeTask *task = new AnalyzeTask(currentFile, m_templateFile->filePath(), &m_abortFlag);
|
||||||
|
connect(task, SIGNAL(fileSelected(QString)), this, SIGNAL(fileSelected(QString)), Qt::DirectConnection);
|
||||||
|
connect(task, SIGNAL(progressValChanged(unsigned int)), this, SIGNAL(progressValChanged(unsigned int)), Qt::DirectConnection);
|
||||||
|
connect(task, SIGNAL(progressMaxChanged(unsigned int)), this, SIGNAL(progressMaxChanged(unsigned int)), Qt::DirectConnection);
|
||||||
|
connect(task, SIGNAL(fileAnalyzed(AudioFileModel)), this, SIGNAL(fileAnalyzed(AudioFileModel)), Qt::DirectConnection);
|
||||||
|
|
||||||
|
pool->start(task);
|
||||||
|
|
||||||
if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles))
|
if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles))
|
||||||
{
|
{
|
||||||
emit progressMaxChanged(nFiles += count);
|
emit progressMaxChanged(nFiles += count);
|
||||||
}
|
}
|
||||||
QThread::msleep(8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ QMutex AnalyzeTask::s_waitMutex;
|
|||||||
QWaitCondition AnalyzeTask::s_waitCond;
|
QWaitCondition AnalyzeTask::s_waitCond;
|
||||||
QSet<unsigned int> AnalyzeTask::s_threadIdx_running;
|
QSet<unsigned int> AnalyzeTask::s_threadIdx_running;
|
||||||
unsigned int AnalyzeTask::s_threadIdx_next = 0;
|
unsigned int AnalyzeTask::s_threadIdx_next = 0;
|
||||||
|
QSemaphore AnalyzeTask::s_semaphore(0);
|
||||||
|
|
||||||
/* more static vars */
|
/* more static vars */
|
||||||
QReadWriteLock AnalyzeTask::s_lock;
|
QReadWriteLock AnalyzeTask::s_lock;
|
||||||
@ -64,6 +65,7 @@ QSet<QString> AnalyzeTask::s_recentlyAdded;
|
|||||||
/*constants*/
|
/*constants*/
|
||||||
const int WAITCOND_TIMEOUT = 2500;
|
const int WAITCOND_TIMEOUT = 2500;
|
||||||
const int MAX_RETRIES = 60000 / WAITCOND_TIMEOUT;
|
const int MAX_RETRIES = 60000 / WAITCOND_TIMEOUT;
|
||||||
|
const int MAX_QUEUE_SLOTS = 32;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -86,6 +88,8 @@ AnalyzeTask::AnalyzeTask(const QString &inputFile, const QString &templateFile,
|
|||||||
|
|
||||||
AnalyzeTask::~AnalyzeTask(void)
|
AnalyzeTask::~AnalyzeTask(void)
|
||||||
{
|
{
|
||||||
|
s_semaphore.release();
|
||||||
|
|
||||||
s_waitMutex.lock();
|
s_waitMutex.lock();
|
||||||
s_threadIdx_running.remove(m_threadIdx);
|
s_threadIdx_running.remove(m_threadIdx);
|
||||||
s_waitMutex.unlock();
|
s_waitMutex.unlock();
|
||||||
@ -817,13 +821,15 @@ int AnalyzeTask::getAdditionalFiles(QStringList &fileList)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnalyzeTask::waitForOneThread(void)
|
bool AnalyzeTask::waitForFreeSlot(volatile bool *abortFlag)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
s_waitMutex.lock();
|
for(int i = 0; i < MAX_RETRIES; i++)
|
||||||
ret = s_waitCond.wait(&s_waitMutex, WAITCOND_TIMEOUT);
|
{
|
||||||
s_waitMutex.unlock();
|
ret = s_semaphore.tryAcquire(1, WAITCOND_TIMEOUT);
|
||||||
|
if(ret || (*abortFlag)) break;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -844,6 +850,12 @@ void AnalyzeTask::reset(void)
|
|||||||
s_threadIdx_next = 0;
|
s_threadIdx_next = 0;
|
||||||
s_threadIdx_running.clear();
|
s_threadIdx_running.clear();
|
||||||
s_waitMutex.unlock();
|
s_waitMutex.unlock();
|
||||||
|
|
||||||
|
int freeSlots = s_semaphore.available();
|
||||||
|
if(freeSlots < MAX_QUEUE_SLOTS)
|
||||||
|
{
|
||||||
|
s_semaphore.release(MAX_QUEUE_SLOTS - freeSlots);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QSemaphore>
|
||||||
|
|
||||||
class AudioFileModel;
|
class AudioFileModel;
|
||||||
class QFile;
|
class QFile;
|
||||||
@ -53,8 +54,8 @@ public:
|
|||||||
static unsigned int filesDummyCDDA(void);
|
static unsigned int filesDummyCDDA(void);
|
||||||
static unsigned int filesCueSheet(void);
|
static unsigned int filesCueSheet(void);
|
||||||
|
|
||||||
//Wait till the next running thread terminates
|
//Wait until there is a free slot in the queue
|
||||||
static bool waitForOneThread(void);
|
static bool waitForFreeSlot(volatile bool *abortFlag);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void fileSelected(const QString &fileName);
|
void fileSelected(const QString &fileName);
|
||||||
@ -105,6 +106,8 @@ private:
|
|||||||
static QSet<unsigned int> s_threadIdx_running;
|
static QSet<unsigned int> s_threadIdx_running;
|
||||||
static unsigned int s_threadIdx_next;
|
static unsigned int s_threadIdx_next;
|
||||||
|
|
||||||
|
static QSemaphore s_semaphore;
|
||||||
|
|
||||||
static QReadWriteLock s_lock;
|
static QReadWriteLock s_lock;
|
||||||
static unsigned int s_filesAccepted;
|
static unsigned int s_filesAccepted;
|
||||||
static unsigned int s_filesRejected;
|
static unsigned int s_filesRejected;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user