<li>Updated Vorbis decoder to OggDec v1.10.1 (2014-06-25), using libVorbis v1.3.4
<li>Updated GnuPG to v1.4.18 (2014-06-30), compiled with GCC 4.9.1
<li>Fixed potential crash in Cue Sheet importer (occurred when *all* input files were missing)
+<li>Fixed a severe performance bottleneck, especially with a large number of parallel instances
+<li>The limit for the maximum number of parallel instances has been increased to 32
<li>Experimental support for Windows 10 Technical Preview
</ul><br>
#define VER_LAMEXP_MINOR_HI 1
#define VER_LAMEXP_MINOR_LO 1
#define VER_LAMEXP_TYPE Beta
-#define VER_LAMEXP_PATCH 4
-#define VER_LAMEXP_BUILD 1615
+#define VER_LAMEXP_PATCH 5
+#define VER_LAMEXP_BUILD 1616
#define VER_LAMEXP_CONFG 1558
///////////////////////////////////////////////////////////////////////////////
#include <QDir>
/*
- * Static vars
+ * Job Object
*/
-quint64 AbstractTool::s_lastLaunchTime = 0ui64;
-QMutex AbstractTool::s_mutex_startProcess;
-JobObject *AbstractTool::s_jobObject = NULL;
-unsigned int AbstractTool::s_jobObjRefCount = 0U;
+QScopedPointer<JobObject> AbstractTool::s_jobObject;
+QMutex AbstractTool::s_jobObjMtx;
+
+/*
+ * Process Timer
+ */
+quint64 AbstractTool::s_startProcessTimer = 0ui64;
+QMutex AbstractTool::s_startProcessMutex;
/*
* Const
*/
-static const unsigned int START_DELAY = 333; //in milliseconds
-static const quint64 START_DELAY_NANO = START_DELAY * 1000 * 10; //in 100-nanosecond intervals
+static const unsigned int START_DELAY = 50U; //in milliseconds
+static const quint64 START_DELAY_NANO = quint64(START_DELAY) * 10000ui64; //in 100-nanosecond intervals
/*
* Constructor
*/
AbstractTool::AbstractTool(void)
{
- QMutexLocker lock(&s_mutex_startProcess);
+ QMutexLocker lock(&s_jobObjMtx);
- if(s_jobObjRefCount < 1U)
+ if(s_jobObject.isNull())
{
- s_jobObject = new JobObject();
- s_jobObjRefCount = 1U;
- }
- else
- {
- s_jobObjRefCount++;
+ s_jobObject.reset(new JobObject());
}
m_firstLaunch = true;
*/
AbstractTool::~AbstractTool(void)
{
- QMutexLocker lock(&s_mutex_startProcess);
-
- if(s_jobObjRefCount >= 1U)
- {
- s_jobObjRefCount--;
- if(s_jobObjRefCount < 1U)
- {
- MUTILS_DELETE(s_jobObject);
- }
- }
}
/*
*/
bool AbstractTool::startProcess(QProcess &process, const QString &program, const QStringList &args)
{
- QMutexLocker lock(&s_mutex_startProcess);
+ QMutexLocker lock(&s_startProcessMutex);
- if(MUtils::OS::current_file_time() <= s_lastLaunchTime)
+ while(MUtils::OS::current_file_time() <= s_startProcessTimer)
{
+ lock.unlock();
MUtils::OS::sleep_ms(START_DELAY);
+ lock.relock();
}
emit messageLogged(commandline2string(program, args) + "\n");
}
MUtils::OS::change_process_priority(&process, -1);
- lock.unlock();
if(m_firstLaunch)
{
m_firstLaunch = false;
}
- s_lastLaunchTime = MUtils::OS::current_file_time() + START_DELAY_NANO;
+ s_startProcessTimer = MUtils::OS::current_file_time() + START_DELAY_NANO;
return true;
}
process.kill();
process.waitForFinished(-1);
- s_lastLaunchTime = MUtils::OS::current_file_time() + START_DELAY_NANO;
+ s_startProcessTimer = MUtils::OS::current_file_time() + START_DELAY_NANO;
return false;
}
static const int m_processTimeoutInterval = 600000;
private:
- static quint64 s_lastLaunchTime;
- static QMutex s_mutex_startProcess;
- static unsigned int s_jobObjRefCount;
- static JobObject *s_jobObject;
+ static quint64 s_startProcessTimer;
+ static QMutex s_startProcessMutex;
+
+ static QScopedPointer<JobObject> s_jobObject;
+ static QMutex s_jobObjMtx;
bool m_firstLaunch;
};