Merge "Delay initial accept() until server initialized"
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 9b663be..430123a 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -979,8 +979,12 @@
if (kill_forward) {
r = remove_listener(pieces[0].c_str(), transport);
} else {
- r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind,
- &resolved_tcp_port, &error);
+ int flags = 0;
+ if (no_rebind) {
+ flags |= INSTALL_LISTENER_NO_REBIND;
+ }
+ r = install_listener(pieces[0], pieces[1].c_str(), transport, flags, &resolved_tcp_port,
+ &error);
}
if (r == INSTALL_STATUS_OK) {
#if ADB_HOST
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index 29909a5..43a9252 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -164,6 +164,15 @@
}
}
+void enable_daemon_sockets() EXCLUDES(listener_list_mutex) {
+ std::lock_guard<std::mutex> lock(listener_list_mutex);
+ for (auto& l : listener_list) {
+ if (l->connect_to == "*smartsocket*") {
+ fdevent_set(l->fde, FDE_READ);
+ }
+ }
+}
+
void close_smartsockets() EXCLUDES(listener_list_mutex) {
std::lock_guard<std::mutex> lock(listener_list_mutex);
auto pred = [](const std::unique_ptr<alistener>& listener) {
@@ -173,7 +182,7 @@
}
InstallStatus install_listener(const std::string& local_name, const char* connect_to,
- atransport* transport, int no_rebind, int* resolved_tcp_port,
+ atransport* transport, int flags, int* resolved_tcp_port,
std::string* error) EXCLUDES(listener_list_mutex) {
std::lock_guard<std::mutex> lock(listener_list_mutex);
for (auto& l : listener_list) {
@@ -184,8 +193,8 @@
return INSTALL_STATUS_INTERNAL_ERROR;
}
- // Can't repurpose a listener if 'no_rebind' is true.
- if (no_rebind) {
+ // Can't repurpose a listener if INSTALL_LISTENER_NO_REBIND is set
+ if (flags & INSTALL_LISTENER_NO_REBIND) {
*error = "cannot rebind";
return INSTALL_STATUS_CANNOT_REBIND;
}
@@ -222,7 +231,9 @@
} else {
listener->fde = fdevent_create(listener->fd, listener_event_func, listener.get());
}
- fdevent_set(listener->fde, FDE_READ);
+ if ((flags & INSTALL_LISTENER_DISABLED) == 0) {
+ fdevent_set(listener->fde, FDE_READ);
+ }
listener->transport = transport;
diff --git a/adb/adb_listeners.h b/adb/adb_listeners.h
index 70a2ee1..354dcc5 100644
--- a/adb/adb_listeners.h
+++ b/adb/adb_listeners.h
@@ -32,8 +32,11 @@
INSTALL_STATUS_LISTENER_NOT_FOUND = -4,
};
+inline constexpr int INSTALL_LISTENER_NO_REBIND = 1 << 0;
+inline constexpr int INSTALL_LISTENER_DISABLED = 1 << 1;
+
InstallStatus install_listener(const std::string& local_name, const char* connect_to,
- atransport* transport, int no_rebind, int* resolved_tcp_port,
+ atransport* transport, int flags, int* resolved_tcp_port,
std::string* error);
std::string format_listeners();
@@ -41,6 +44,7 @@
InstallStatus remove_listener(const char* local_name, atransport* transport);
void remove_all_listeners(void);
+void enable_daemon_sockets();
void close_smartsockets();
#endif /* __ADB_LISTENERS_H */
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 0c5c28f..5669a01 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -137,9 +137,10 @@
auto start = std::chrono::steady_clock::now();
// If we told a previous adb server to quit because of version mismatch, we can get to this
- // point before it's finished exiting. Retry for a while to give it some time.
- while (install_listener(socket_spec, "*smartsocket*", nullptr, 0, nullptr, &error) !=
- INSTALL_STATUS_OK) {
+ // point before it's finished exiting. Retry for a while to give it some time. Don't actually
+ // accept any connections until adb_wait_for_device_initialization finishes below.
+ while (install_listener(socket_spec, "*smartsocket*", nullptr, INSTALL_LISTENER_DISABLED,
+ nullptr, &error) != INSTALL_STATUS_OK) {
if (std::chrono::steady_clock::now() - start > 0.5s) {
LOG(FATAL) << "could not install *smartsocket* listener: " << error;
}
@@ -160,12 +161,14 @@
PLOG(FATAL) << "setsid() failed";
}
#endif
+ }
- // Wait for the USB scan to complete before notifying the parent that we're up.
- // We need to perform this in a thread, because we would otherwise block the event loop.
- std::thread notify_thread([ack_reply_fd]() {
- adb_wait_for_device_initialization();
+ // Wait for the USB scan to complete before notifying the parent that we're up.
+ // We need to perform this in a thread, because we would otherwise block the event loop.
+ std::thread notify_thread([ack_reply_fd]() {
+ adb_wait_for_device_initialization();
+ if (ack_reply_fd >= 0) {
// Any error output written to stderr now goes to adb.log. We could
// keep around a copy of the stderr fd and use that to write any errors
// encountered by the following code, but that is probably overkill.
@@ -191,9 +194,13 @@
}
unix_close(ack_reply_fd);
#endif
- });
- notify_thread.detach();
- }
+ }
+ // We don't accept() client connections until this point: this way, clients
+ // can't see wonky state early in startup even if they're connecting directly
+ // to the server instead of going through the adb program.
+ fdevent_run_on_main_thread([] { enable_daemon_sockets(); });
+ });
+ notify_thread.detach();
#if defined(__linux__)
// Write our location to .android/adb.$PORT, so that older clients can exec us.