Make atransport be a real class.
Using non-POD types in atransport means we'll need to start treating
it as a real class (specifically with regards to new/delete rather
than malloc/free).
I've also cleaned up the home grown linked lists for transport_list
and pending_list to just be std::lists. We might want to refactor that
again to be an std::unordered_map keyed on serial, since that seems to
be a common way to search it.
Change-Id: I7f5e23cdc47944a9278099723ca029585fe52105
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 818ed97..379c702 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -26,6 +26,8 @@
#include <string.h>
#include <unistd.h>
+#include <list>
+
#include <base/stringprintf.h>
#include "adb.h"
@@ -33,15 +35,8 @@
static void transport_unref(atransport *t);
-static atransport transport_list = {
- .next = &transport_list,
- .prev = &transport_list,
-};
-
-static atransport pending_list = {
- .next = &pending_list,
- .prev = &pending_list,
-};
+static std::list<atransport*> transport_list;
+static std::list<atransport*> pending_list;
ADB_MUTEX_DEFINE( transport_lock );
@@ -553,8 +548,7 @@
adb_close(t->fd);
adb_mutex_lock(&transport_lock);
- t->next->prev = t->prev;
- t->prev->next = t->next;
+ transport_list.remove(t);
adb_mutex_unlock(&transport_lock);
run_transport_disconnects(t);
@@ -570,8 +564,7 @@
if (t->devpath)
free(t->devpath);
- memset(t,0xee,sizeof(atransport));
- free(t);
+ delete t;
update_transports();
return;
@@ -582,7 +575,7 @@
/* initial references are the two threads */
t->ref_count = 2;
- if(adb_socketpair(s)) {
+ if (adb_socketpair(s)) {
fatal_errno("cannot open transport socketpair");
}
@@ -608,14 +601,8 @@
}
adb_mutex_lock(&transport_lock);
- /* remove from pending list */
- t->next->prev = t->prev;
- t->prev->next = t->next;
- /* put us on the master device list */
- t->next = &transport_list;
- t->prev = transport_list.prev;
- t->next->prev = t;
- t->prev->next = t;
+ pending_list.remove(t);
+ transport_list.push_front(t);
adb_mutex_unlock(&transport_lock);
t->disconnects.next = t->disconnects.prev = &t->disconnects;
@@ -740,7 +727,6 @@
atransport* acquire_one_transport(ConnectionState state, TransportType type,
const char* serial, std::string* error_out) {
- atransport *t;
atransport *result = NULL;
int ambiguous = 0;
@@ -748,7 +734,7 @@
if (error_out) *error_out = android::base::StringPrintf("device '%s' not found", serial);
adb_mutex_lock(&transport_lock);
- for (t = transport_list.next; t != &transport_list; t = t->next) {
+ for (auto t : transport_list) {
if (t->connection_state == kCsNoPerm) {
if (error_out) *error_out = "insufficient permissions for device";
continue;
@@ -866,7 +852,8 @@
}
}
-static void append_transport(atransport* t, std::string* result, bool long_listing) {
+static void append_transport(const atransport* t, std::string* result,
+ bool long_listing) {
const char* serial = t->serial;
if (!serial || !serial[0]) {
serial = "(no serial number)";
@@ -890,7 +877,7 @@
std::string list_transports(bool long_listing) {
std::string result;
adb_mutex_lock(&transport_lock);
- for (atransport* t = transport_list.next; t != &transport_list; t = t->next) {
+ for (const auto t : transport_list) {
append_transport(t, &result, long_listing);
}
adb_mutex_unlock(&transport_lock);
@@ -898,11 +885,10 @@
}
/* hack for osx */
-void close_usb_devices()
-{
+void close_usb_devices() {
adb_mutex_lock(&transport_lock);
- for (atransport* t = transport_list.next; t != &transport_list; t = t->next) {
- if ( !t->kicked ) {
+ for (auto t : transport_list) {
+ if (!t->kicked) {
t->kicked = 1;
t->kick(t);
}
@@ -911,47 +897,39 @@
}
#endif // ADB_HOST
-int register_socket_transport(int s, const char *serial, int port, int local)
-{
- atransport *t = reinterpret_cast<atransport*>(calloc(1, sizeof(atransport)));
- if (t == nullptr) {
- return -1;
- }
-
- atransport *n;
- char buff[32];
+int register_socket_transport(int s, const char *serial, int port, int local) {
+ atransport* t = new atransport();
if (!serial) {
- snprintf(buff, sizeof buff, "T-%p", t);
- serial = buff;
+ char buf[32];
+ snprintf(buf, sizeof(buf), "T-%p", t);
+ serial = buf;
}
+
D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port);
if (init_socket_transport(t, s, port, local) < 0) {
- free(t);
+ delete t;
return -1;
}
adb_mutex_lock(&transport_lock);
- for (n = pending_list.next; n != &pending_list; n = n->next) {
- if (n->serial && !strcmp(serial, n->serial)) {
+ for (auto transport : pending_list) {
+ if (transport->serial && strcmp(serial, transport->serial) == 0) {
adb_mutex_unlock(&transport_lock);
- free(t);
+ delete t;
return -1;
}
}
- for (n = transport_list.next; n != &transport_list; n = n->next) {
- if (n->serial && !strcmp(serial, n->serial)) {
+ for (auto transport : transport_list) {
+ if (transport->serial && strcmp(serial, transport->serial) == 0) {
adb_mutex_unlock(&transport_lock);
- free(t);
+ delete t;
return -1;
}
}
- t->next = &pending_list;
- t->prev = pending_list.prev;
- t->next->prev = t;
- t->prev->next = t;
+ pending_list.push_front(t);
t->serial = strdup(serial);
adb_mutex_unlock(&transport_lock);
@@ -960,95 +938,83 @@
}
#if ADB_HOST
-atransport *find_transport(const char *serial)
-{
- atransport *t;
+atransport *find_transport(const char *serial) {
+ atransport* result = nullptr;
adb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
- if (t->serial && !strcmp(serial, t->serial)) {
+ for (auto t : transport_list) {
+ if (t->serial && strcmp(serial, t->serial) == 0) {
+ result = t;
break;
}
- }
+ }
adb_mutex_unlock(&transport_lock);
- if (t != &transport_list)
- return t;
- else
- return 0;
+ return result;
}
void unregister_transport(atransport *t)
{
adb_mutex_lock(&transport_lock);
- t->next->prev = t->prev;
- t->prev->next = t->next;
+ transport_list.remove(t);
adb_mutex_unlock(&transport_lock);
kick_transport(t);
transport_unref(t);
}
-// unregisters all non-emulator TCP transports
-void unregister_all_tcp_transports()
-{
- atransport *t, *next;
+// Unregisters all non-emulator TCP transports.
+void unregister_all_tcp_transports() {
adb_mutex_lock(&transport_lock);
- for (t = transport_list.next; t != &transport_list; t = next) {
- next = t->next;
+ for (auto it = transport_list.begin(); it != transport_list.end(); ) {
+ atransport* t = *it;
if (t->type == kTransportLocal && t->adb_port == 0) {
- t->next->prev = t->prev;
- t->prev->next = next;
- // we cannot call kick_transport when holding transport_lock
- if (!t->kicked)
- {
+ // We cannot call kick_transport when holding transport_lock.
+ if (!t->kicked) {
t->kicked = 1;
t->kick(t);
}
transport_unref_locked(t);
+
+ it = transport_list.erase(it);
+ } else {
+ ++it;
}
- }
+ }
adb_mutex_unlock(&transport_lock);
}
#endif
-void register_usb_transport(usb_handle *usb, const char *serial, const char *devpath, unsigned writeable)
-{
- atransport *t = reinterpret_cast<atransport*>(calloc(1, sizeof(atransport)));
- if (t == nullptr) fatal("cannot allocate USB atransport");
+void register_usb_transport(usb_handle* usb, const char* serial,
+ const char* devpath, unsigned writeable) {
+ atransport* t = new atransport();
+
D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
serial ? serial : "");
init_usb_transport(t, usb, (writeable ? kCsOffline : kCsNoPerm));
if(serial) {
t->serial = strdup(serial);
}
- if(devpath) {
+
+ if (devpath) {
t->devpath = strdup(devpath);
}
adb_mutex_lock(&transport_lock);
- t->next = &pending_list;
- t->prev = pending_list.prev;
- t->next->prev = t;
- t->prev->next = t;
+ pending_list.push_front(t);
adb_mutex_unlock(&transport_lock);
register_transport(t);
}
// This should only be used for transports with connection_state == kCsNoPerm.
-void unregister_usb_transport(usb_handle* usb) {
+void unregister_usb_transport(usb_handle *usb) {
adb_mutex_lock(&transport_lock);
- for (atransport* t = transport_list.next; t != &transport_list;
- t = t->next) {
- if (t->usb == usb && t->connection_state == kCsNoPerm) {
- t->next->prev = t->prev;
- t->prev->next = t->next;
- break;
- }
- }
+ transport_list.remove_if([usb](atransport* t) {
+ return t->usb == usb && t->connection_state == kCsNoPerm;
+ });
adb_mutex_unlock(&transport_lock);
}