-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Do not call workSocket() in TNonblockigServer without ensuring that there is data on the socket #1497
Do not call workSocket() in TNonblockigServer without ensuring that there is data on the socket #1497
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -472,6 +472,18 @@ void TNonblockingServer::TConnection::workSocket() { | |
} | ||
// size known; now get the rest of the frame | ||
transition(); | ||
|
||
// If the socket has more data than the frame header, continue to work on it. This is not strictly necessary for | ||
// regular sockets, because if there is more data, libevent will fire the event handler registered for read | ||
// readiness, which will in turn call workSocket(). However, some socket types (such as TSSLSocket) may have the | ||
// data sitting in their internal buffers and from libevent's perspective, there is no further data available. In | ||
// that case, not having this workSocket() call here would result in a hang as we will never get to work the socket, | ||
// despite having more data. | ||
if (tSocket_->hasPendingDataToRead()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am concerned this can cause an infinite loop if data is always available, since it calls itself. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It can't. Note that the line above is Btw, I assume you notice that the original |
||
{ | ||
workSocket(); | ||
} | ||
|
||
return; | ||
|
||
case SOCKET_RECV: | ||
|
@@ -677,9 +689,6 @@ void TNonblockingServer::TConnection::transition() { | |
appState_ = APP_SEND_RESULT; | ||
setWrite(); | ||
|
||
// Try to work the socket immediately | ||
// workSocket(); | ||
|
||
return; | ||
} | ||
|
||
|
@@ -718,9 +727,6 @@ void TNonblockingServer::TConnection::transition() { | |
// Register read event | ||
setRead(); | ||
|
||
// Try to work the socket right away | ||
// workSocket(); | ||
|
||
return; | ||
|
||
case APP_READ_FRAME_SIZE: | ||
|
@@ -753,9 +759,6 @@ void TNonblockingServer::TConnection::transition() { | |
socketState_ = SOCKET_RECV; | ||
appState_ = APP_READ_REQUEST; | ||
|
||
// Work the socket right away | ||
workSocket(); | ||
|
||
return; | ||
|
||
case APP_CLOSE_CONNECTION: | ||
|
@@ -1063,7 +1066,7 @@ void TNonblockingServer::expireClose(stdcxx::shared_ptr<Runnable> task) { | |
connection->forceClose(); | ||
} | ||
|
||
void TNonblockingServer::stop() { | ||
void TNonblockingServer::stop() { | ||
// Breaks the event loop in all threads so that they end ASAP. | ||
for (uint32_t i = 0; i < ioThreads_.size(); ++i) { | ||
ioThreads_[i]->stop(); | ||
|
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 this be an "if" or a "while"?
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.
It should be an
if
. At this point, we know the frame size. The next step is to read the frame data itself. And for that, there is already logic to work the socket until all the data is read. For SSL specifically, there is no concern that the SSL buffers can keep pending data forever, because when the entire data frame arrives, there won't be any incomplete SSL bytes. In any case, the code should work generically for all socket types.