|  | @@ -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() |  |  | DeletedAtShutdown::DeletedAtShutdown() | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); |  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); | 
														
													
														
															
																|  |  | getObjects().add (this); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | getDeletedAtShutdownObjects().add (this); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | DeletedAtShutdown::~DeletedAtShutdown() |  |  | DeletedAtShutdown::~DeletedAtShutdown() | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); |  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); | 
														
													
														
															
																|  |  | getObjects().removeFirstMatchingValue (this); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | getDeletedAtShutdownObjects().removeFirstMatchingValue (this); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | void DeletedAtShutdown::deleteAll() |  |  | void DeletedAtShutdown::deleteAll() | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | // make a local copy of the array, so it can't get into a loop if something |  |  | // make a local copy of the array, so it can't get into a loop if something | 
														
													
														
															
																|  |  | // creates another DeletedAtShutdown object during its destructor. |  |  | // creates another DeletedAtShutdown object during its destructor. | 
														
													
														
															
																|  |  | Array <DeletedAtShutdown*> localCopy; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | Array<DeletedAtShutdown*> localCopy; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); |  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); | 
														
													
														
															
																|  |  | localCopy = getObjects(); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | localCopy = getDeletedAtShutdownObjects(); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | for (int i = localCopy.size(); --i >= 0;) |  |  | 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 |  |  | 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. |  |  | // double-check that it's not already been deleted during another object's destructor. | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); |  |  | const SpinLock::ScopedLockType sl (deletedAtShutdownLock); | 
														
													
														
															
																|  |  | if (! getObjects().contains (deletee)) |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (! getDeletedAtShutdownObjects().contains (deletee)) | 
														
													
														
															
																|  |  | deletee = nullptr; |  |  | deletee = nullptr; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | delete deletee; |  |  | delete deletee; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | JUCE_CATCH_EXCEPTION |  |  | 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 |  |  | // if no objects got re-created during shutdown, this should have been emptied by their | 
														
													
														
															
																|  |  | // destructors |  |  | // 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 | 
														
													
														
															
																|  |  | } |  |  | } |