This repository was archived by the owner on Dec 18, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 523
Resuse writes, initalize queues #363
Closed
Closed
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Discovered and fixed race here; don't know if was with these changes or is in current build.
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 catch.
If you just want to avoid the NullRefEx, you should do the following:
With the current change, you could still get a NullRefEx if
_head
is set to null between the if comparison and the actual assignment toSelf._head.Start
. This makes the race a lot tighter than it was before, but it's still there.To be safe, all modifications to
_head
should be made with the_returnLock
. This fixes the race because_head
is only set to null when the_returnLock
is taken.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.
Wait a minute! I think this race must have been caused by a change in this PR
I was wondering how I didn't see this was a race when I originally wrote this code, and now I'm pretty sure it's because
_head
is only ever supposed to modified in the SocketOutput ctor and on the libuv thread. If that's the case, this race should be impossible.@benaadams Do you have any idea how
_head
would be modified off of the libuv thread with this change? I'm not seeing it yet.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.
All I can think is the
Write
callback actually completes before the next lines are run? Was going to move the set above theWrite
but didn't feel comfortable enough with the 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.
@benaadams You don't want to move the set above the write in case write throws. If that's the case, we still want to ensure that the blocks get returned to the pool eventually.
Even if the write callback gets executed inline,
Self._head
should never be null immediately after this line:Self._head = _lockedEnd.Block
.We already know
_lockedEnd.Block
can't be null becauseLockWrite
would exit early leavingByteCount
at 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.
Wow, ok it is because the
Write
callback is completing before the rest ofDoWriteIfNeeded
soOnWriteCompleted
is called before_head
is set to_lockedEnd.Block
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.
Ahhhhh.... its the behaviour of
MockLibuv
that's causing this.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.
Fixed it; however gone back to the scheduled write; which means the next write needs to wait for a loop of libuv to complete; so is throttled, due to the way the queues work (switching per loop)
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.
Added throttle fix to #427