|  |  | @@ -28,58 +28,70 @@ | 
		
	
		
			
			|  |  |  | ============================================================================== | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | static SpinLock deletedAtShutdownLock; | 
		
	
		
			
			|  |  |  | static SpinLock deletedAtShutdownLock; // use a spin lock because it can be statically initialised | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | static Array<DeletedAtShutdown*>& getDeletedAtShutdownObjects() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | static Array<DeletedAtShutdown*> objects; | 
		
	
		
			
			|  |  |  | return objects; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | DeletedAtShutdown::DeletedAtShutdown() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); | 
		
	
		
			
			|  |  |  | getObjects().add (this); | 
		
	
		
			
			|  |  |  | getDeletedAtShutdownObjects().add (this); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | DeletedAtShutdown::~DeletedAtShutdown() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); | 
		
	
		
			
			|  |  |  | getObjects().removeFirstMatchingValue (this); | 
		
	
		
			
			|  |  |  | getDeletedAtShutdownObjects().removeFirstMatchingValue (this); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | void DeletedAtShutdown::deleteAll() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | // make a local copy of the array, so it can't get into a loop if something | 
		
	
		
			
			|  |  |  | // creates another DeletedAtShutdown object during its destructor. | 
		
	
		
			
			|  |  |  | Array <DeletedAtShutdown*> localCopy; | 
		
	
		
			
			|  |  |  | Array<DeletedAtShutdown*> localCopy; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); | 
		
	
		
			
			|  |  |  | localCopy = getObjects(); | 
		
	
		
			
			|  |  |  | localCopy = getDeletedAtShutdownObjects(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | for (int i = localCopy.size(); --i >= 0;) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | #if JUCE_MSVC | 
		
	
		
			
			|  |  |  | // Disable unreachable code warning, in case the compiler manages to figure out | 
		
	
		
			
			|  |  |  | // that you have no classes of DeletedAtShutdown that could throw an exception here. | 
		
	
		
			
			|  |  |  | #pragma warning (push) | 
		
	
		
			
			|  |  |  | #pragma warning (disable: 4702) | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | JUCE_TRY | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | DeletedAtShutdown* deletee = localCopy.getUnchecked(i); | 
		
	
		
			
			|  |  |  | auto* deletee = localCopy.getUnchecked(i); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // double-check that it's not already been deleted during another object's destructor. | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); | 
		
	
		
			
			|  |  |  | if (! getObjects().contains (deletee)) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (! getDeletedAtShutdownObjects().contains (deletee)) | 
		
	
		
			
			|  |  |  | deletee = nullptr; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | delete deletee; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | JUCE_CATCH_EXCEPTION | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | #if JUCE_MSVC | 
		
	
		
			
			|  |  |  | #pragma warning (pop) | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // if no objects got re-created during shutdown, this should have been emptied by their | 
		
	
		
			
			|  |  |  | // destructors | 
		
	
		
			
			|  |  |  | jassert (getObjects().size() == 0); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | getObjects().clear(); // just to make sure the array doesn't have any memory still allocated | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | jassert (getDeletedAtShutdownObjects().isEmpty()); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | Array <DeletedAtShutdown*>& DeletedAtShutdown::getObjects() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | static Array <DeletedAtShutdown*> objects; | 
		
	
		
			
			|  |  |  | return objects; | 
		
	
		
			
			|  |  |  | getDeletedAtShutdownObjects().clear(); // just to make sure the array doesn't have any memory still allocated | 
		
	
		
			
			|  |  |  | } |