Fix a subtle bug in the poll code
This commit is contained in:
@@ -261,6 +261,7 @@ class Driver {
|
||||
// Copy data from the send BIO into the socket.
|
||||
//
|
||||
// If it detects an error, sets the recent_errno flag.
|
||||
// It is an error to call this when there is nothing in the send BIO.
|
||||
//
|
||||
void transfer_send_bio_to_socket(ChanInfo &chan) {
|
||||
if ((chan.state == CHAN_INACTIVE) || (!chan.recent_error.empty())) {
|
||||
@@ -270,7 +271,10 @@ class Driver {
|
||||
char *data;
|
||||
int ndata = BIO_get_mem_data(chan.send_bio, &data);
|
||||
if (ndata > DRV_SHORTSTRING_SIZE) ndata = DRV_SHORTSTRING_SIZE;
|
||||
|
||||
// It is an error to call this function when there is nothing in the send BIO.
|
||||
assert(ndata > 0);
|
||||
|
||||
std::string err;
|
||||
int nwrote = socket_send(chan.socket, data, ndata, err);
|
||||
// std::cerr << "chan " << chan.chid << " send " << nwrote << " err=" << err << std::endl;
|
||||
@@ -453,12 +457,6 @@ class Driver {
|
||||
|
||||
// Construct the struct pollfd vector.
|
||||
int pollsize = 0;
|
||||
for (const auto &p : listen_sockets_) {
|
||||
struct pollfd &pfd = pollvec_[pollsize++];
|
||||
pfd.fd = p.second;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
}
|
||||
for (const ChanInfo &chan : chans_) {
|
||||
struct pollfd &pfd = pollvec_[pollsize++];
|
||||
assert(chan.socket != INVALID_SOCKET);
|
||||
@@ -477,20 +475,19 @@ class Driver {
|
||||
mstimeout = 0;
|
||||
}
|
||||
}
|
||||
for (const auto &p : listen_sockets_) {
|
||||
struct pollfd &pfd = pollvec_[pollsize++];
|
||||
pfd.fd = p.second;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
}
|
||||
|
||||
// Do the poll.
|
||||
socket_poll(pollvec_.get(), pollsize, mstimeout, err);
|
||||
if_error_print_and_exit(err);
|
||||
|
||||
// Check listening sockets.
|
||||
// Advance channels where possible and then check listen sockets.
|
||||
int index = 0;
|
||||
for (auto &p : listen_sockets_) {
|
||||
struct pollfd &pfd = pollvec_[index++];
|
||||
if (pfd.revents & (POLLIN | POLLERR)) {
|
||||
accept_connection(p.first, p.second);
|
||||
}
|
||||
}
|
||||
// Advance channels where possible.
|
||||
for (ChanInfo &chan : chans_) {
|
||||
struct pollfd &pfd = pollvec_[index++];
|
||||
if ((pfd.revents & POLLIN) != 0) {
|
||||
@@ -513,6 +510,12 @@ class Driver {
|
||||
chan.nbytes = 0;
|
||||
chan.bytes = 0;
|
||||
}
|
||||
for (auto &p : listen_sockets_) {
|
||||
struct pollfd &pfd = pollvec_[index++];
|
||||
if (pfd.revents & (POLLIN | POLLERR)) {
|
||||
accept_connection(p.first, p.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete any newly-inactive channels
|
||||
drvutil::remove_marked_items(chans_);
|
||||
|
||||
Reference in New Issue
Block a user