-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
store: replace Modified+Load with ReloadIfChanged #898
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice Fix
LGTM
The diagnosis at #880 (comment) looks good, but I'm missing how this keeps one goroutine that's using the data without having taken the |
add a new method to reload the store information from the hard disk if has changed. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
simplify the pattern if store.Modified() => store.Load() with a single function call store.ReloadIfChanged(). In addition to the code simplification, it solves a race condition that when only a RLock() is hold and that multiple goroutines could run the sequence store.Modified() and store.Load(). In this case only one goroutine would see store.Modified( and run store.Load(). Other goroutines could access the old data while the goroutine that saw the change modifies the store data. Closes: containers#880 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
that is protected by the other locking mechanisms we have. A goroutine that is accessing the data must already hold a RO or a RW lock. A goroutine checks for The issue I've seen only happens when there are multiple goroutines checking
ReloadIfChanged() should never cause a One possible race condition though is that we attempt the
A temporary error could cause the race as it calls |
does the explanation above make sense? Are there other cases where a race can happen? |
I was thinking of the case where one thread is calling a method like store.Images(), which takes a read lock, but another is in a method like store.ImageSize(), which also takes a read lock, and one of them alters the data the object is holding while the other is iterating through it. It's not exclusive to this pair of methods, but that's a window I don't see us closing here. |
That is the case I've tried to explain with the table. If one thread is calling |
Hmm, okay, that makes sense. LGTM. |
@haircommander, that should fix the issue in CRI-O |
simplify the pattern if store.Modified() => store.Load() with a single function call store.ReloadIfChanged().
In addition to the code simplification, it solves a race condition that when only a RLock() is hold and that multiple goroutines could
run the sequence store.Modified() and store.Load(). In this case only one goroutine would see store.Modified( and run store.Load().
Other goroutines could access the old data while the goroutine that saw the change modifies the store data.
Closes: #880
Signed-off-by: Giuseppe Scrivano gscrivan@redhat.com