Merge changes I0ed00441,I12d46493,Ib484f701 am: 0a01830612
am: 1425641300
Change-Id: I6fbd5287542ee758c6a15fff544b12bac8205eb4
This commit is contained in:
commit
da20ef4684
5 changed files with 66 additions and 62 deletions
|
|
@ -412,8 +412,13 @@ static void device_disconnected(libusb_device* device) {
|
||||||
if (it != usb_handles.end()) {
|
if (it != usb_handles.end()) {
|
||||||
if (!it->second->device_handle) {
|
if (!it->second->device_handle) {
|
||||||
// If the handle is null, we were never able to open the device.
|
// If the handle is null, we were never able to open the device.
|
||||||
unregister_usb_transport(it->second.get());
|
|
||||||
|
// Temporarily release the usb handles mutex to avoid deadlock.
|
||||||
|
std::unique_ptr<usb_handle> handle = std::move(it->second);
|
||||||
usb_handles.erase(it);
|
usb_handles.erase(it);
|
||||||
|
lock.unlock();
|
||||||
|
unregister_usb_transport(handle.get());
|
||||||
|
lock.lock();
|
||||||
} else {
|
} else {
|
||||||
// Closure of the transport will erase the usb_handle.
|
// Closure of the transport will erase the usb_handle.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
105
adb/socket.h
105
adb/socket.h
|
|
@ -19,84 +19,83 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "fdevent.h"
|
#include "fdevent.h"
|
||||||
|
|
||||||
struct apacket;
|
struct apacket;
|
||||||
class atransport;
|
class atransport;
|
||||||
|
|
||||||
/* An asocket represents one half of a connection between a local and
|
/* An asocket represents one half of a connection between a local and
|
||||||
** remote entity. A local asocket is bound to a file descriptor. A
|
* remote entity. A local asocket is bound to a file descriptor. A
|
||||||
** remote asocket is bound to the protocol engine.
|
* remote asocket is bound to the protocol engine.
|
||||||
*/
|
*/
|
||||||
struct asocket {
|
struct asocket {
|
||||||
/* chain pointers for the local/remote list of
|
/* chain pointers for the local/remote list of
|
||||||
** asockets that this asocket lives in
|
* asockets that this asocket lives in
|
||||||
*/
|
*/
|
||||||
asocket *next;
|
asocket* next;
|
||||||
asocket *prev;
|
asocket* prev;
|
||||||
|
|
||||||
/* the unique identifier for this asocket
|
/* the unique identifier for this asocket
|
||||||
*/
|
*/
|
||||||
unsigned id;
|
unsigned id;
|
||||||
|
|
||||||
/* flag: set when the socket's peer has closed
|
/* flag: set when the socket's peer has closed
|
||||||
** but packets are still queued for delivery
|
* but packets are still queued for delivery
|
||||||
*/
|
*/
|
||||||
int closing;
|
int closing;
|
||||||
|
|
||||||
// flag: set when the socket failed to write, so the socket will not wait to
|
// flag: set when the socket failed to write, so the socket will not wait to
|
||||||
// write packets and close directly.
|
// write packets and close directly.
|
||||||
bool has_write_error;
|
bool has_write_error;
|
||||||
|
|
||||||
/* flag: quit adbd when both ends close the
|
/* flag: quit adbd when both ends close the
|
||||||
** local service socket
|
* local service socket
|
||||||
*/
|
*/
|
||||||
int exit_on_close;
|
int exit_on_close;
|
||||||
|
|
||||||
/* the asocket we are connected to
|
// the asocket we are connected to
|
||||||
*/
|
asocket* peer;
|
||||||
|
|
||||||
asocket *peer;
|
/* For local asockets, the fde is used to bind
|
||||||
|
* us to our fd event system. For remote asockets
|
||||||
/* For local asockets, the fde is used to bind
|
* these fields are not used.
|
||||||
** us to our fd event system. For remote asockets
|
*/
|
||||||
** these fields are not used.
|
|
||||||
*/
|
|
||||||
fdevent fde;
|
fdevent fde;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* queue of apackets waiting to be written
|
// queue of apackets waiting to be written
|
||||||
*/
|
apacket* pkt_first;
|
||||||
apacket *pkt_first;
|
apacket* pkt_last;
|
||||||
apacket *pkt_last;
|
|
||||||
|
|
||||||
/* enqueue is called by our peer when it has data
|
/* enqueue is called by our peer when it has data
|
||||||
** for us. It should return 0 if we can accept more
|
* for us. It should return 0 if we can accept more
|
||||||
** data or 1 if not. If we return 1, we must call
|
* data or 1 if not. If we return 1, we must call
|
||||||
** peer->ready() when we once again are ready to
|
* peer->ready() when we once again are ready to
|
||||||
** receive data.
|
* receive data.
|
||||||
*/
|
*/
|
||||||
int (*enqueue)(asocket *s, apacket *pkt);
|
int (*enqueue)(asocket* s, apacket* pkt);
|
||||||
|
|
||||||
/* ready is called by the peer when it is ready for
|
/* ready is called by the peer when it is ready for
|
||||||
** us to send data via enqueue again
|
* us to send data via enqueue again
|
||||||
*/
|
*/
|
||||||
void (*ready)(asocket *s);
|
void (*ready)(asocket* s);
|
||||||
|
|
||||||
/* shutdown is called by the peer before it goes away.
|
/* shutdown is called by the peer before it goes away.
|
||||||
** the socket should not do any further calls on its peer.
|
* the socket should not do any further calls on its peer.
|
||||||
** Always followed by a call to close. Optional, i.e. can be NULL.
|
* Always followed by a call to close. Optional, i.e. can be NULL.
|
||||||
*/
|
*/
|
||||||
void (*shutdown)(asocket *s);
|
void (*shutdown)(asocket* s);
|
||||||
|
|
||||||
/* close is called by the peer when it has gone away.
|
/* close is called by the peer when it has gone away.
|
||||||
** we are not allowed to make any further calls on the
|
* we are not allowed to make any further calls on the
|
||||||
** peer once our close method is called.
|
* peer once our close method is called.
|
||||||
*/
|
*/
|
||||||
void (*close)(asocket *s);
|
void (*close)(asocket* s);
|
||||||
|
|
||||||
/* A socket is bound to atransport */
|
/* A socket is bound to atransport */
|
||||||
atransport *transport;
|
atransport* transport;
|
||||||
|
|
||||||
size_t get_max_payload() const;
|
size_t get_max_payload() const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ void install_local_socket(asocket* s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_socket(asocket* s) {
|
void remove_socket(asocket* s) {
|
||||||
// socket_list_lock should already be held
|
std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock);
|
||||||
if (s->prev && s->next) {
|
if (s->prev && s->next) {
|
||||||
s->prev->next = s->next;
|
s->prev->next = s->next;
|
||||||
s->next->prev = s->prev;
|
s->next->prev = s->prev;
|
||||||
|
|
|
||||||
|
|
@ -615,15 +615,15 @@ static void remove_transport(atransport* transport) {
|
||||||
static void transport_unref(atransport* t) {
|
static void transport_unref(atransport* t) {
|
||||||
CHECK(t != nullptr);
|
CHECK(t != nullptr);
|
||||||
|
|
||||||
size_t old_refcount = t->ref_count--;
|
std::lock_guard<std::recursive_mutex> lock(transport_lock);
|
||||||
CHECK_GT(old_refcount, 0u);
|
CHECK_GT(t->ref_count, 0u);
|
||||||
|
t->ref_count--;
|
||||||
if (old_refcount == 1u) {
|
if (t->ref_count == 0) {
|
||||||
D("transport: %s unref (kicking and closing)", t->serial);
|
D("transport: %s unref (kicking and closing)", t->serial);
|
||||||
t->close(t);
|
t->close(t);
|
||||||
remove_transport(t);
|
remove_transport(t);
|
||||||
} else {
|
} else {
|
||||||
D("transport: %s unref (count=%zu)", t->serial, old_refcount - 1);
|
D("transport: %s unref (count=%zu)", t->serial, t->ref_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ class atransport {
|
||||||
// it's better to do this piece by piece.
|
// it's better to do this piece by piece.
|
||||||
|
|
||||||
atransport(ConnectionState state = kCsOffline)
|
atransport(ConnectionState state = kCsOffline)
|
||||||
: id(NextTransportId()), ref_count(0), connection_state_(state) {
|
: id(NextTransportId()), connection_state_(state) {
|
||||||
transport_fde = {};
|
transport_fde = {};
|
||||||
protocol_version = A_VERSION;
|
protocol_version = A_VERSION;
|
||||||
max_payload = MAX_PAYLOAD;
|
max_payload = MAX_PAYLOAD;
|
||||||
|
|
@ -88,7 +88,7 @@ class atransport {
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int transport_socket = -1;
|
int transport_socket = -1;
|
||||||
fdevent transport_fde;
|
fdevent transport_fde;
|
||||||
std::atomic<size_t> ref_count;
|
size_t ref_count = 0;
|
||||||
uint32_t sync_token = 0;
|
uint32_t sync_token = 0;
|
||||||
bool online = false;
|
bool online = false;
|
||||||
TransportType type = kTransportAny;
|
TransportType type = kTransportAny;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue