Skip to content

Conversation

augusto2112
Copy link

ReflectionContext can potentially be accessed by multiple threads at the same time, make accessing ReflectionContext thread safe by hiding it behind a lock.

rdar://112207497

@augusto2112
Copy link
Author

@swift-ci test

@adrian-prantl
Copy link

@kastiglione @JDevlieghere I would appreciate a second and third pair of eyes on this. The underlying assumption here is that calls into the Swift Reflection API are not thread safe since they build up in-memory reflection data structures and various caches. This is addressed by the ThreadSafeReflectionContext RAII construct.

The second problem is that the ForEach loop in SetupReflection will request a ReflectionContext which recurses into SetupReflection. This is addressed by making the mutex recursive and setting the initialized flag before entering the ForEach loop.

@augusto2112 augusto2112 force-pushed the thread-safe-refl-context branch from 81c6304 to c79cc76 Compare July 31, 2023 22:45
@augusto2112
Copy link
Author

@swift-ci test

@augusto2112
Copy link
Author

@swift-ci test windows

@augusto2112 augusto2112 force-pushed the thread-safe-refl-context branch from c79cc76 to aa2fc0f Compare August 1, 2023 22:37
@augusto2112
Copy link
Author

@swift-ci test

@augusto2112 augusto2112 force-pushed the thread-safe-refl-context branch from aa2fc0f to 35d2e12 Compare August 2, 2023 20:33
@augusto2112
Copy link
Author

@swift-ci test

@augusto2112
Copy link
Author

@swift-ci test windows

ReflectionContext can potentially be accessed by multiple threads at the
same time, make accessing ReflectionContext thread safe by hiding it
behind a lock.

rdar://112207497
@augusto2112 augusto2112 force-pushed the thread-safe-refl-context branch from 35d2e12 to c8aa68b Compare August 2, 2023 21:22
@augusto2112
Copy link
Author

@swift-ci test

@augusto2112
Copy link
Author

@swift-ci test windows

@@ -310,6 +310,14 @@ ModuleList::ModuleList(const ModuleList &rhs) : m_modules(), m_modules_mutex() {
m_modules = rhs.m_modules;
}

ModuleList::ModuleList(ModuleList &&rhs) : m_modules(), m_modules_mutex() {
std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be needed, since nobody can have access to this object while we're still in the constructor.

@adrian-prantl
Copy link

@swift-ci test windows

@augusto2112 augusto2112 force-pushed the thread-safe-refl-context branch from c8aa68b to ead9772 Compare August 3, 2023 00:27
@augusto2112
Copy link
Author

@swift-ci test

@augusto2112
Copy link
Author

@swift-ci test windows

Copy link

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link

@kastiglione kastiglione left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@JDevlieghere JDevlieghere merged commit db8c62e into swiftlang:swift/release/5.9 Aug 3, 2023


std::lock_guard<std::recursive_mutex> lock(m_reflection_ctx_mutex);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this redundant now?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I left it to maintain the invariant that this function has to lock that mutex, in case we ever call it from somewhere else.



std::lock_guard<std::recursive_mutex> lock(m_reflection_ctx_mutex);
if (m_initialized_reflection_ctx)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we hoist this into GetReflectionContext(), since we also check the variable there for ProcessAllModules?


void ModuleList::Swap(ModuleList &other) {
// scoped_lock locks both mutexes at once.
std::scoped_lock lock(m_modules_mutex, other.m_modules_mutex);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants