-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fix memory leaks in ThreadBarriers.swift #12212
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
Conversation
// FIXME: leaking memory, leaking a mutex. | ||
guard pthread_cond_init(barrier.pointee.cond!, nil) == 0 else { | ||
barrier.pointee.cond!.deinitialize() | ||
barrier.pointee.cond!.deallocate(capacity: 1) |
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.
The mutex would also have to be cleaned up here. Maybe the whole thing belongs in a defer
that just checks that barrier.pointee.count
is non-zero?
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.
Or this can be merged into one guard statement:
guard pthread_mutex_init(barrier.pointee.mutex!, nil) == 0 && pthread_cond_init(barrier.pointee.cond!, nil) == 0 else {
barrier.pointee.mutex!.deinitialize()
barrier.pointee.mutex!.deallocate(capacity: 1)
barrier.pointee.cond!.deinitialize()
barrier.pointee.cond!.deallocate(capacity: 1)
return -1
}
If one of them fails, both mutex
and cond
will be deallocated. What do you think?
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.
This still doesn't call pthread_mutex_destroy
when pthread_mutex_init
succeeds but pthread_cond_init
fails.
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.
Understood. Updating code to destroy mutex when pthread_cond_init
fails.
@airspeedswift Is this change still good to take (with some rebasing?) |
if pthread_mutex_destroy(barrier.pointee.mutex!) != 0 { | ||
// FIXME: leaking memory. | ||
guard pthread_cond_destroy(barrier.pointee.cond!) == 0 && | ||
pthread_mutex_destroy(barrier.pointee.mutex!) == 0 else { |
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.
Failures when releasing resources kind of weird me out. This would leak or leave the barrier in an invalid state if pthread_cond_destroy
fails.
According to the man page, this can only fail due to API abuse (either passing an invalid parameter, or trying to destroy it while it's in use by another thread). The callers of this function either fatalError
or signal a test failure. I'm wondering if we should just not even try to pretend that this failure can be handled gracefully, and just abort here instead.
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.
Good point. The caller of this function in SwiftPrivatePthreadExtras.swift does fatalError when this returns -1. Should this function simply just return Void and fatalError in here?
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.
I think so. If somebody wants to try to handle these errors gracefully one day, they can figure out how. No need to do that work now, only to immediately fatalError anyway.
22a91d4
to
315f510
Compare
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.
👍
@swift-ci please test |
Build failed |
Build failed |
/home/buildnode/jenkins/workspace/swift-PR-Linux@2/branch-master/swift/stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift:84:90: error: use of undeclared type '_stdlib_pthread_barrier_t' My bad, that has been renamed to |
@swift-ci please test |
Build failed |
Seems like you need to fix the call to pthread_mutex_init & pthread_cond_init:
|
Build failed |
@swift-ci please test |
Build failed |
Build failed |
barrier.pointee.mutex!.deinitialize(count: 1) | ||
barrier.pointee.mutex!.deallocate() | ||
barrier.pointee.cond!.deinitialize(count: 1) | ||
barrier.pointee.cond!.deallocate() |
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.
This has to exit the enclosing scope.
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.
Thanks! Rebasing isn't as straightforward as I thought, I'll try building locally this time
Ran
|
@swift-ci test |
Thanks for sticking with us. ⛵️ |
Just a note, it broke Windows: https://ci-external.swift.org/job/oss-swift-windows-x86_64/2645/ (/cc @compnerd) |
Thanks for catching this one! I thought GitHub did a check for all platforms. I created this PR to fix it #29536 |
Fix memory leaks in PthreadBarriers.swift as indicated by
FIXME
s.