Ver Fonte

Fixing a nasty task scheduler issue, where re-queuing the task and requesting wait(), would not properly block the calling thread until task finished.

BearishSun há 9 anos atrás
pai
commit
e8175f03bf

+ 4 - 4
Source/BansheeCore/Source/BsAnimationManager.cpp

@@ -20,7 +20,7 @@ namespace BansheeEngine
 	{
 	{
 		mAnimationWorker = Task::create("Animation", std::bind(&AnimationManager::evaluateAnimation, this));
 		mAnimationWorker = Task::create("Animation", std::bind(&AnimationManager::evaluateAnimation, this));
 
 
-		mDataReadyCount.store(0);
+		mDataReadyCount.store(0, std::memory_order_release);
 		mWorkerState.store(WorkerState::Inactive, std::memory_order_release);
 		mWorkerState.store(WorkerState::Inactive, std::memory_order_release);
 
 
 		mBlendShapeVertexDesc = VertexDataDesc::create();
 		mBlendShapeVertexDesc = VertexDataDesc::create();
@@ -468,7 +468,7 @@ namespace BansheeEngine
 
 
 		// Increments counter and ensures all writes are recorded
 		// Increments counter and ensures all writes are recorded
 		mWorkerState.store(WorkerState::DataReady, std::memory_order_release);
 		mWorkerState.store(WorkerState::DataReady, std::memory_order_release);
-		mDataReadyCount.fetch_add(1);
+		mDataReadyCount.fetch_add(1, std::memory_order_acq_rel);
 	}
 	}
 
 
 	void AnimationManager::waitUntilComplete()
 	void AnimationManager::waitUntilComplete()
@@ -476,7 +476,7 @@ namespace BansheeEngine
 		mAnimationWorker->wait();
 		mAnimationWorker->wait();
 
 
 		// Read counter, and ensure all reads are done after writes on anim thread complete
 		// Read counter, and ensure all reads are done after writes on anim thread complete
-		INT32 dataReadyCount = mDataReadyCount.load();
+		INT32 dataReadyCount = mDataReadyCount.load(std::memory_order_acquire);
 
 
 		if (dataReadyCount > CoreThread::NUM_SYNC_BUFFERS)
 		if (dataReadyCount > CoreThread::NUM_SYNC_BUFFERS)
 		{
 		{
@@ -488,7 +488,7 @@ namespace BansheeEngine
 		if (!mDataReady)
 		if (!mDataReady)
 			return;
 			return;
 
 
-		mDataReadyCount.fetch_sub(1);
+		mDataReadyCount.fetch_sub(1, std::memory_order_release);
 		mPoseReadBufferIdx = (mPoseReadBufferIdx + 1) % CoreThread::NUM_SYNC_BUFFERS;
 		mPoseReadBufferIdx = (mPoseReadBufferIdx + 1) % CoreThread::NUM_SYNC_BUFFERS;
 	}
 	}
 
 

+ 3 - 0
Source/BansheeUtility/Source/BsTaskScheduler.cpp

@@ -79,8 +79,11 @@ namespace BansheeEngine
 	{
 	{
 		Lock lock(mReadyMutex);
 		Lock lock(mReadyMutex);
 
 
+		assert(task->mState != 1 && "Task is already executing, it cannot be executed again until it finishes.");
+
 		task->mParent = this;
 		task->mParent = this;
 		task->mTaskId = mNextTaskId++;
 		task->mTaskId = mNextTaskId++;
+		task->mState.store(0); // Reset state in case the task is getting re-queued
 
 
 		mTaskQueue.insert(task);
 		mTaskQueue.insert(task);