-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Optimize select expression registration phase #1445
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
There is no need for multi-word atomic performAtomicIfNotSelected operation when enqueuing select node for operation. We can simply enqueue (addLast) xxxSelect node (SendSelect, ReceiveSelect, LockSelect). If the coroutine that rendezvous with this node finds out that the select expression was already selected, then it'll try again. * Removed SelectInstance.performAtomicIfNotSelected function * Removed Mutex.TryEnqueueLockDesc class, simplified onLock * Removed AbstractSendChannel.TryEnqueueSendDesc class, simpler onSend * Removed AbstractChannel.TryEnqueueReceiveDesc class, simpler onReceive * Simplified SelectInstance.disposeOnSelect. It does not have to do atomic addLastIf operation. Can do a simple addLast.
It was hanging not being able to properly see that the channel was already closed at that send attempt should fail.
Also fixed a bug with unlimited channel select onSend on closed channel. It was hanging not being able to properly see that the channel was already closed at that send attempt should fail. |
if (prev is ReceiveOrClosed<*>) return@enqueueSend prev | ||
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.
Line 220: return ENQUEUE_FAILED
Nobody checks for ENQUEUE_FAILED
. It doesn't look like a bug because of the current state machine (null
-> success, Closed
-> closed, everything else -> retry), but kind of error-prone.
For example, null
can become ENQUEUE_SUCCESS
and ENQUEUE_FAILED
will become null
instead. Code flow will be more straightforward and explicit
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've rewritten the corresponding when
statements in a more explicit way, checking all possible outcomes and added error
on unexpected result.
Now registerSelectSend and sendSuspend are more alike
Also removed describeRemove and the corresponding tests (not needed in prod code).
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.
Well done!
There is no need for multi-word atomic performAtomicIfNotSelected
operation when enqueuing select node for operation. We can simply
enqueue (addLast) xxxSelect node (SendSelect, ReceiveSelect, LockSelect).
If the coroutine that rendezvous with this node finds out that the
select expression was already selected, then it'll try again.