-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Fluid channels should match the semantics of Go Channels #9265
Conversation
// We cannot do the data transfer because | ||
// this QueueMessage was added by Select | ||
// and some other case was executed. | ||
// So call the Send function again. | ||
// We do not care about notifying other | ||
// because they would have been notified | ||
// by the executed select case. | ||
return send_return(Send(item)); | ||
Send(item); |
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.
Do you need to "lock.unlock();" 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 you are right, it makes sense to release the lock there. With the new semantics if the nested method call leads to an exception then the outer lock will be held forever.
// TODO(abhinavarora) Should panic on closed channel | ||
return send_return(!m->chan_closed); | ||
if (m->chan_closed) { | ||
send_return(); |
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.
Should unlock before throwing exception
send_return(); | ||
PADDLE_THROW("Cannot send on closed channel"); | ||
} | ||
send_return(); |
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.
Do you need to unlock 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.
Good catch, the lock needs to be unlocked here. Thank you for pointing this out.
@@ -118,15 +117,15 @@ bool ChannelImpl<T>::CanReceive() { | |||
} | |||
|
|||
template <typename T> | |||
bool ChannelImpl<T>::Send(T *item) { | |||
void ChannelImpl<T>::Send(T *item) { | |||
send_ctr++; | |||
std::unique_lock<std::recursive_mutex> lock{mu_}; |
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.
Do you need to explicitly lock after constructor? lock->lock() ?
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.
No we don't need to do that. The unique lock constructor automatically does that.
paddle/fluid/framework/channel.h
Outdated
bool Send(T* data) { | ||
if (!IsInitialized()) return false; | ||
void Send(T* data) { | ||
PADDLE_ENFORCE_EQ(IsInitialized(), true); |
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.
Maybe It is better that adding exception information for PADDLE_ENFORCE_EQ
,
e.g.
PADDLE_ENFORCE_EQ(IsInitialized(), true, "The channel hasn't been initialized.");
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.
Done
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.
LGTM!
Fixes #8813