launch_daemon: Fixed a race condition in Worker startup.

* When the thread is started during the construction of the base
  class, the virtual method table may still point to the methods
  of the base class when the thread actually starts to run.
* This caused the main worker to have a timeout, which could
  eventually be reached which in turn caused all job processing
  to stop.
* That's what you get when you do Java all day; whoever designed
  C++ should be slapped (I'm talking to you, Bjarne).
This commit is contained in:
Axel Dörfler
2015-07-22 20:44:39 +02:00
parent 5a76694819
commit abb7b71004
3 changed files with 25 additions and 6 deletions
+2
View File
@@ -164,6 +164,8 @@ LaunchDaemon::LaunchDaemon(bool userMode, status_t& error)
fUserMode(userMode)
{
fMainWorker = new MainWorker(fJobQueue);
fMainWorker->Init();
if (fInitTarget != NULL)
_AddTarget(fInitTarget);
+21 -6
View File
@@ -15,12 +15,9 @@ static int32 sWorkerCount;
Worker::Worker(JobQueue& queue)
:
fThread(-1),
fJobQueue(queue)
{
fThread = spawn_thread(&Worker::_Process, "worker", B_NORMAL_PRIORITY,
this);
if (fThread >= 0 && resume_thread(fThread) == B_OK)
atomic_add(&sWorkerCount, 1);
}
@@ -29,6 +26,22 @@ Worker::~Worker()
}
status_t
Worker::Init()
{
fThread = spawn_thread(&Worker::_Process, "worker", B_NORMAL_PRIORITY,
this);
if (fThread < 0)
return fThread;
status_t status = resume_thread(fThread);
if (status == B_OK)
atomic_add(&sWorkerCount, 1);
return status;
}
status_t
Worker::Process()
{
@@ -103,8 +116,10 @@ MainWorker::Run(BJob* job)
if (jobCount > INT_MAX)
jobCount = INT_MAX;
if ((int32)jobCount > count && count < fCPUCount)
new Worker(fJobQueue);
if ((int32)jobCount > count && count < fCPUCount) {
Worker* worker = new Worker(fJobQueue);
worker->Init();
}
return Worker::Run(job);
}
+2
View File
@@ -19,6 +19,8 @@ public:
Worker(JobQueue& queue);
virtual ~Worker();
status_t Init();
protected:
virtual status_t Process();
virtual bigtime_t Timeout() const;