mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 02:34:11 +01:00 
			
		
		
		
	core_timing: handle concurrent unscheduling of looping events
This commit is contained in:
		
							parent
							
								
									575db04172
								
							
						
					
					
						commit
						05eda56e66
					
				| @ -159,6 +159,8 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, | ||||
|         for (auto h : to_remove) { | ||||
|             event_queue.erase(h); | ||||
|         } | ||||
| 
 | ||||
|         event_type->sequence_number++; | ||||
|     } | ||||
| 
 | ||||
|     // Force any in-progress events to finish
 | ||||
| @ -202,9 +204,10 @@ std::optional<s64> CoreTiming::Advance() { | ||||
|         const Event& evt = event_queue.top(); | ||||
| 
 | ||||
|         if (const auto event_type{evt.type.lock()}) { | ||||
|             if (evt.reschedule_time == 0) { | ||||
|                 const auto evt_time = evt.time; | ||||
|             const auto evt_time = evt.time; | ||||
|             const auto evt_sequence_num = event_type->sequence_number; | ||||
| 
 | ||||
|             if (evt.reschedule_time == 0) { | ||||
|                 event_queue.pop(); | ||||
| 
 | ||||
|                 basic_lock.unlock(); | ||||
| @ -217,10 +220,15 @@ std::optional<s64> CoreTiming::Advance() { | ||||
|                 basic_lock.unlock(); | ||||
| 
 | ||||
|                 const auto new_schedule_time{event_type->callback( | ||||
|                     evt.time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt.time})}; | ||||
|                     evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time})}; | ||||
| 
 | ||||
|                 basic_lock.lock(); | ||||
| 
 | ||||
|                 if (evt_sequence_num != event_type->sequence_number) { | ||||
|                     // Heap handle is invalidated after external modification.
 | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 const auto next_schedule_time{new_schedule_time.has_value() | ||||
|                                                   ? new_schedule_time.value().count() | ||||
|                                                   : evt.reschedule_time}; | ||||
|  | ||||
| @ -27,12 +27,15 @@ using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>( | ||||
| /// Contains the characteristics of a particular event.
 | ||||
| struct EventType { | ||||
|     explicit EventType(TimedCallback&& callback_, std::string&& name_) | ||||
|         : callback{std::move(callback_)}, name{std::move(name_)} {} | ||||
|         : callback{std::move(callback_)}, name{std::move(name_)}, sequence_number{0} {} | ||||
| 
 | ||||
|     /// The event's callback function.
 | ||||
|     TimedCallback callback; | ||||
|     /// A pointer to the name of the event.
 | ||||
|     const std::string name; | ||||
|     /// A monotonic sequence number, incremented when this event is
 | ||||
|     /// changed externally.
 | ||||
|     size_t sequence_number; | ||||
| }; | ||||
| 
 | ||||
| enum class UnscheduleEventType { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user