Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit bc4dbfa

Browse files
committed
adb: fix NonblockingFdConnection's behavior with large writes.
Large opportunistic writes would perform a write without updating writable_ or waking up the polling thread, which resulted in the worker thread never polling with POLLOUT. Test: adb_benchmark Change-Id: Ifed3b97a4b647b539dcd2df858572fa7da9a22d0
1 parent 10d079a commit bc4dbfa

File tree

1 file changed

+15
-17
lines changed

1 file changed

+15
-17
lines changed

adb/transport_fd.cpp

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,9 @@ struct NonblockingFdConnection : public Connection {
8585
if (pfds[0].revents) {
8686
if ((pfds[0].revents & POLLOUT)) {
8787
std::lock_guard<std::mutex> lock(this->write_mutex_);
88-
WriteResult result = DispatchWrites();
89-
switch (result) {
90-
case WriteResult::Error:
91-
*error = "write failed";
92-
return;
93-
94-
case WriteResult::Completed:
95-
writable_ = true;
96-
break;
97-
98-
case WriteResult::TryAgain:
99-
break;
88+
if (DispatchWrites() == WriteResult::Error) {
89+
*error = "write failed";
90+
return;
10091
}
10192
}
10293

@@ -179,13 +170,14 @@ struct NonblockingFdConnection : public Connection {
179170

180171
WriteResult DispatchWrites() REQUIRES(write_mutex_) {
181172
CHECK(!write_buffer_.empty());
182-
if (!writable_) {
183-
return WriteResult::TryAgain;
184-
}
185-
186173
auto iovs = write_buffer_.iovecs();
187174
ssize_t rc = adb_writev(fd_.get(), iovs.data(), iovs.size());
188175
if (rc == -1) {
176+
if (errno == EAGAIN || errno == EWOULDBLOCK) {
177+
writable_ = false;
178+
return WriteResult::TryAgain;
179+
}
180+
189181
return WriteResult::Error;
190182
} else if (rc == 0) {
191183
errno = 0;
@@ -194,6 +186,7 @@ struct NonblockingFdConnection : public Connection {
194186

195187
// TODO: Implement a more efficient drop_front?
196188
write_buffer_.take_front(rc);
189+
writable_ = write_buffer_.empty();
197190
if (write_buffer_.empty()) {
198191
return WriteResult::Completed;
199192
}
@@ -211,7 +204,12 @@ struct NonblockingFdConnection : public Connection {
211204
if (!packet->payload.empty()) {
212205
write_buffer_.append(std::make_unique<IOVector::block_type>(std::move(packet->payload)));
213206
}
214-
return DispatchWrites() != WriteResult::Error;
207+
208+
WriteResult result = DispatchWrites();
209+
if (result == WriteResult::TryAgain) {
210+
WakeThread();
211+
}
212+
return result != WriteResult::Error;
215213
}
216214

217215
std::thread thread_;

0 commit comments

Comments
 (0)