Revert 0cd3ae1c281f until usb_libusb.cpp adopts 812f030477bc. diff --git adb/adb_utils.cpp adb/adb_utils.cpp index db39ef4..5a3b401 100644 --- adb/adb_utils.cpp +++ adb/adb_utils.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -48,6 +47,8 @@ #include #endif +ADB_MUTEX_DEFINE(basename_lock); +ADB_MUTEX_DEFINE(dirname_lock); #if defined(_WIN32) constexpr char kNullFileName[] = "NUL"; @@ -101,15 +102,13 @@ } std::string adb_basename(const std::string& path) { - static std::mutex& basename_lock = *new std::mutex(); - // Copy path because basename may modify the string passed in. std::string result(path); // Use lock because basename() may write to a process global and return a // pointer to that. Note that this locking strategy only works if all other - // callers to basename in the process also grab this same lock. - std::lock_guard lock(basename_lock); + // callers to dirname in the process also grab this same lock. + adb_mutex_lock(&basename_lock); // Note that if std::string uses copy-on-write strings, &str[0] will cause // the copy to be made, so there is no chance of us accidentally writing to @@ -120,19 +119,19 @@ // before leaving the lock. result.assign(name); + adb_mutex_unlock(&basename_lock); + return result; } std::string adb_dirname(const std::string& path) { - static std::mutex& dirname_lock = *new std::mutex(); - // Copy path because dirname may modify the string passed in. std::string result(path); // Use lock because dirname() may write to a process global and return a // pointer to that. Note that this locking strategy only works if all other // callers to dirname in the process also grab this same lock. - std::lock_guard lock(dirname_lock); + adb_mutex_lock(&dirname_lock); // Note that if std::string uses copy-on-write strings, &str[0] will cause // the copy to be made, so there is no chance of us accidentally writing to @@ -143,6 +142,8 @@ // before leaving the lock. result.assign(parent); + adb_mutex_unlock(&dirname_lock); + return result; } diff --git adb/client/main.cpp adb/client/main.cpp index 571c227..279bb70 100644 --- adb/client/main.cpp +++ adb/client/main.cpp @@ -170,6 +170,7 @@ } int main(int argc, char** argv) { + adb_sysdeps_init(); adb_trace_init(argv); return adb_commandline(argc - 1, const_cast(argv + 1)); } diff --git adb/mutex_list.h adb/mutex_list.h deleted file mode 100644 index 4a188ee..0000000 --- /dev/null +++ adb/mutex_list.h @@ -0,0 +1,17 @@ +/* the list of mutexes used by adb */ +/* #ifndef __MUTEX_LIST_H + * Do not use an include-guard. This file is included once to declare the locks + * and once in win32 to actually do the runtime initialization. + */ +#ifndef ADB_MUTEX +#error ADB_MUTEX not defined when including this file +#endif +ADB_MUTEX(basename_lock) +ADB_MUTEX(dirname_lock) +ADB_MUTEX(transport_lock) +#if ADB_HOST +ADB_MUTEX(local_transports_lock) +#endif +ADB_MUTEX(usb_lock) + +#undef ADB_MUTEX diff --git adb/sysdeps.h adb/sysdeps.h index 8d99722..3ed589c 100644 --- adb/sysdeps.h +++ adb/sysdeps.h @@ -97,6 +97,27 @@ return c == '\\' || c == '/'; } +typedef CRITICAL_SECTION adb_mutex_t; + +#define ADB_MUTEX_DEFINE(x) adb_mutex_t x + +/* declare all mutexes */ +/* For win32, adb_sysdeps_init() will do the mutex runtime initialization. */ +#define ADB_MUTEX(x) extern adb_mutex_t x; +#include "mutex_list.h" + +extern void adb_sysdeps_init(void); + +static __inline__ void adb_mutex_lock( adb_mutex_t* lock ) +{ + EnterCriticalSection( lock ); +} + +static __inline__ void adb_mutex_unlock( adb_mutex_t* lock ) +{ + LeaveCriticalSection( lock ); +} + typedef void (*adb_thread_func_t)(void* arg); typedef HANDLE adb_thread_t; @@ -455,6 +476,27 @@ return c == '/'; } +typedef pthread_mutex_t adb_mutex_t; + +#define ADB_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define adb_mutex_init pthread_mutex_init +#define adb_mutex_lock pthread_mutex_lock +#define adb_mutex_unlock pthread_mutex_unlock +#define adb_mutex_destroy pthread_mutex_destroy + +#define ADB_MUTEX_DEFINE(m) adb_mutex_t m = PTHREAD_MUTEX_INITIALIZER + +#define adb_cond_t pthread_cond_t +#define adb_cond_init pthread_cond_init +#define adb_cond_wait pthread_cond_wait +#define adb_cond_broadcast pthread_cond_broadcast +#define adb_cond_signal pthread_cond_signal +#define adb_cond_destroy pthread_cond_destroy + +/* declare all mutexes */ +#define ADB_MUTEX(x) extern adb_mutex_t x; +#include "mutex_list.h" + static __inline__ void close_on_exec(int fd) { fcntl( fd, F_SETFD, FD_CLOEXEC ); @@ -776,6 +818,10 @@ #undef mkdir #define mkdir ___xxx_mkdir +static __inline__ void adb_sysdeps_init(void) +{ +} + static __inline__ int adb_is_absolute_host_path(const char* path) { return path[0] == '/'; } diff --git adb/sysdeps_test.cpp adb/sysdeps_test.cpp index f871675..9f77942 100644 --- adb/sysdeps_test.cpp +++ adb/sysdeps_test.cpp @@ -269,6 +269,17 @@ m.unlock(); } +// Our implementation on Windows aborts on double lock. +#if defined(_WIN32) +TEST(sysdeps_mutex, mutex_reentrant_lock) { + std::mutex &m = *new std::mutex(); + + m.lock(); + ASSERT_FALSE(m.try_lock()); + EXPECT_DEATH(m.lock(), "non-recursive mutex locked reentrantly"); +} +#endif + TEST(sysdeps_mutex, recursive_mutex_smoke) { static std::recursive_mutex &m = *new std::recursive_mutex(); diff --git adb/sysdeps_win32.cpp adb/sysdeps_win32.cpp index 5fda27b..4dd549d 100644 --- adb/sysdeps_win32.cpp +++ adb/sysdeps_win32.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -138,7 +137,7 @@ #define WIN32_FH_BASE 2048 #define WIN32_MAX_FHS 2048 -static std::mutex& _win32_lock = *new std::mutex(); +static adb_mutex_t _win32_lock; static FHRec _win32_fhs[ WIN32_MAX_FHS ]; static int _win32_fh_next; // where to start search for free FHRec @@ -183,24 +182,27 @@ { FH f = NULL; - std::lock_guard lock(_win32_lock); + adb_mutex_lock( &_win32_lock ); for (int i = _win32_fh_next; i < WIN32_MAX_FHS; ++i) { if (_win32_fhs[i].clazz == NULL) { f = &_win32_fhs[i]; _win32_fh_next = i + 1; - f->clazz = clazz; - f->used = 1; - f->eof = 0; - f->name[0] = '\0'; - clazz->_fh_init(f); - return f; + goto Exit; } } - - D("_fh_alloc: no more free file descriptors"); - errno = EMFILE; // Too many open files - return nullptr; + D( "_fh_alloc: no more free file descriptors" ); + errno = EMFILE; // Too many open files +Exit: + if (f) { + f->clazz = clazz; + f->used = 1; + f->eof = 0; + f->name[0] = '\0'; + clazz->_fh_init(f); + } + adb_mutex_unlock( &_win32_lock ); + return f; } @@ -209,7 +211,7 @@ { // Use lock so that closing only happens once and so that _fh_alloc can't // allocate a FH that we're in the middle of closing. - std::lock_guard lock(_win32_lock); + adb_mutex_lock(&_win32_lock); int offset = f - _win32_fhs; if (_win32_fh_next > offset) { @@ -223,6 +225,7 @@ f->used = 0; f->clazz = NULL; } + adb_mutex_unlock(&_win32_lock); return 0; } @@ -1231,6 +1234,17 @@ return true; } +static adb_mutex_t g_console_output_buffer_lock; + +void +adb_sysdeps_init( void ) +{ +#define ADB_MUTEX(x) InitializeCriticalSection( & x ); +#include "mutex_list.h" + InitializeCriticalSection( &_win32_lock ); + InitializeCriticalSection( &g_console_output_buffer_lock ); +} + /**************************************************************************/ /**************************************************************************/ /***** *****/ @@ -2423,13 +2437,12 @@ // Bytes that have not yet been output to the console because they are incomplete UTF-8 sequences. // Note that we use only one buffer even though stderr and stdout are logically separate streams. // This matches the behavior of Linux. +// Protected by g_console_output_buffer_lock. +static auto& g_console_output_buffer = *new std::vector(); // Internal helper function to write UTF-8 bytes to a console. Returns -1 on error. static int _console_write_utf8(const char* const buf, const size_t buf_size, FILE* stream, HANDLE console) { - static std::mutex& console_output_buffer_lock = *new std::mutex(); - static auto& console_output_buffer = *new std::vector(); - const int saved_errno = errno; std::vector combined_buffer; @@ -2437,25 +2450,24 @@ const char* utf8; size_t utf8_size; - { - std::lock_guard lock(console_output_buffer_lock); - if (console_output_buffer.empty()) { - // If console_output_buffer doesn't have a buffered up incomplete UTF-8 sequence (the - // common case with plain ASCII), parse buf directly. - utf8 = buf; - utf8_size = internal::ParseCompleteUTF8(buf, buf + buf_size, &console_output_buffer); - } else { - // If console_output_buffer has a buffered up incomplete UTF-8 sequence, move it to - // combined_buffer (and effectively clear console_output_buffer) and append buf to - // combined_buffer, then parse it all together. - combined_buffer.swap(console_output_buffer); - combined_buffer.insert(combined_buffer.end(), buf, buf + buf_size); - - utf8 = combined_buffer.data(); - utf8_size = internal::ParseCompleteUTF8(utf8, utf8 + combined_buffer.size(), - &console_output_buffer); - } + adb_mutex_lock(&g_console_output_buffer_lock); + if (g_console_output_buffer.empty()) { + // If g_console_output_buffer doesn't have a buffered up incomplete UTF-8 sequence (the + // common case with plain ASCII), parse buf directly. + utf8 = buf; + utf8_size = internal::ParseCompleteUTF8(buf, buf + buf_size, &g_console_output_buffer); + } else { + // If g_console_output_buffer has a buffered up incomplete UTF-8 sequence, move it to + // combined_buffer (and effectively clear g_console_output_buffer) and append buf to + // combined_buffer, then parse it all together. + combined_buffer.swap(g_console_output_buffer); + combined_buffer.insert(combined_buffer.end(), buf, buf + buf_size); + + utf8 = combined_buffer.data(); + utf8_size = internal::ParseCompleteUTF8(utf8, utf8 + combined_buffer.size(), + &g_console_output_buffer); } + adb_mutex_unlock(&g_console_output_buffer_lock); std::wstring utf16; diff --git adb/transport.cpp adb/transport.cpp index 3eaeb06..87712fc 100644 --- adb/transport.cpp +++ adb/transport.cpp @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -45,7 +44,7 @@ static auto& transport_list = *new std::list(); static auto& pending_list = *new std::list(); -static std::mutex& transport_lock = *new std::mutex(); +ADB_MUTEX_DEFINE( transport_lock ); const char* const kFeatureShell2 = "shell_v2"; const char* const kFeatureCmd = "cmd"; @@ -298,12 +297,13 @@ } void kick_transport(atransport* t) { - std::lock_guard lock(transport_lock); + adb_mutex_lock(&transport_lock); // As kick_transport() can be called from threads without guarantee that t is valid, // check if the transport is in transport_list first. if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) { t->Kick(); } + adb_mutex_unlock(&transport_lock); } static int transport_registration_send = -1; @@ -333,7 +333,7 @@ device_tracker** pnode = &device_tracker_list; device_tracker* node = *pnode; - std::lock_guard lock(transport_lock); + adb_mutex_lock( &transport_lock ); while (node) { if (node == tracker) { *pnode = node->next; @@ -342,6 +342,7 @@ pnode = &node->next; node = *pnode; } + adb_mutex_unlock( &transport_lock ); } static void @@ -503,10 +504,9 @@ fdevent_remove(&(t->transport_fde)); adb_close(t->fd); - { - std::lock_guard lock(transport_lock); - transport_list.remove(t); - } + adb_mutex_lock(&transport_lock); + transport_list.remove(t); + adb_mutex_unlock(&transport_lock); if (t->product) free(t->product); @@ -555,11 +555,10 @@ } } - { - std::lock_guard lock(transport_lock); - pending_list.remove(t); - transport_list.push_front(t); - } + adb_mutex_lock(&transport_lock); + pending_list.remove(t); + transport_list.push_front(t); + adb_mutex_unlock(&transport_lock); update_transports(); } @@ -610,8 +609,7 @@ static void transport_unref(atransport* t) { CHECK(t != nullptr); - - std::lock_guard lock(transport_lock); + adb_mutex_lock(&transport_lock); CHECK_GT(t->ref_count, 0u); t->ref_count--; if (t->ref_count == 0) { @@ -621,6 +619,7 @@ } else { D("transport: %s unref (count=%zu)", t->serial, t->ref_count); } + adb_mutex_unlock(&transport_lock); } static int qual_match(const char *to_test, @@ -666,7 +665,7 @@ *error_out = "no devices found"; } - std::unique_lock lock(transport_lock); + adb_mutex_lock(&transport_lock); for (const auto& t : transport_list) { if (t->connection_state == kCsNoPerm) { #if ADB_HOST @@ -714,7 +713,7 @@ } } } - lock.unlock(); + adb_mutex_unlock(&transport_lock); // Don't return unauthorized devices; the caller can't do anything with them. if (result && result->connection_state == kCsUnauthorized) { @@ -915,20 +914,21 @@ std::string list_transports(bool long_listing) { std::string result; - - std::lock_guard lock(transport_lock); + adb_mutex_lock(&transport_lock); for (const auto& t : transport_list) { append_transport(t, &result, long_listing); } + adb_mutex_unlock(&transport_lock); return result; } /* hack for osx */ void close_usb_devices() { - std::lock_guard lock(transport_lock); + adb_mutex_lock(&transport_lock); for (const auto& t : transport_list) { t->Kick(); } + adb_mutex_unlock(&transport_lock); } #endif // ADB_HOST @@ -947,9 +947,10 @@ return -1; } - std::unique_lock lock(transport_lock); + adb_mutex_lock(&transport_lock); for (const auto& transport : pending_list) { if (transport->serial && strcmp(serial, transport->serial) == 0) { + adb_mutex_unlock(&transport_lock); VLOG(TRANSPORT) << "socket transport " << transport->serial << " is already in pending_list and fails to register"; delete t; @@ -959,6 +960,7 @@ for (const auto& transport : transport_list) { if (transport->serial && strcmp(serial, transport->serial) == 0) { + adb_mutex_unlock(&transport_lock); VLOG(TRANSPORT) << "socket transport " << transport->serial << " is already in transport_list and fails to register"; delete t; @@ -968,8 +970,7 @@ pending_list.push_front(t); t->serial = strdup(serial); - - lock.unlock(); + adb_mutex_unlock(&transport_lock); register_transport(t); return 0; @@ -979,19 +980,20 @@ atransport *find_transport(const char *serial) { atransport* result = nullptr; - std::lock_guard lock(transport_lock); + adb_mutex_lock(&transport_lock); for (auto& t : transport_list) { if (t->serial && strcmp(serial, t->serial) == 0) { result = t; break; } } + adb_mutex_unlock(&transport_lock); return result; } void kick_all_tcp_devices() { - std::lock_guard lock(transport_lock); + adb_mutex_lock(&transport_lock); for (auto& t : transport_list) { if (t->IsTcpDevice()) { // Kicking breaks the read_transport thread of this transport out of any read, then @@ -1001,6 +1003,7 @@ t->Kick(); } } + adb_mutex_unlock(&transport_lock); } #endif @@ -1020,20 +1023,20 @@ t->devpath = strdup(devpath); } - { - std::lock_guard lock(transport_lock); - pending_list.push_front(t); - } + adb_mutex_lock(&transport_lock); + 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) { - std::lock_guard lock(transport_lock); + adb_mutex_lock(&transport_lock); transport_list.remove_if([usb](atransport* t) { return t->usb == usb && t->connection_state == kCsNoPerm; }); + adb_mutex_unlock(&transport_lock); } int check_header(apacket *p, atransport *t) diff --git adb/transport_local.cpp adb/transport_local.cpp index 89e950d..f895943 100644 --- adb/transport_local.cpp +++ adb/transport_local.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -48,7 +47,7 @@ // connected. #define ADB_LOCAL_TRANSPORT_MAX 16 -static std::mutex& local_transports_lock = *new std::mutex(); +ADB_MUTEX_DEFINE(local_transports_lock); /* we keep a list of opened transports. The atransport struct knows to which * local transport it is connected. The list is used to detect when we're @@ -385,13 +384,14 @@ #if ADB_HOST int nn; - std::lock_guard lock(local_transports_lock); + adb_mutex_lock( &local_transports_lock ); for (nn = 0; nn < ADB_LOCAL_TRANSPORT_MAX; nn++) { if (local_transports[nn] == t) { local_transports[nn] = NULL; break; } } + adb_mutex_unlock( &local_transports_lock ); #endif } @@ -435,8 +435,9 @@ atransport* find_emulator_transport_by_adb_port(int adb_port) { - std::lock_guard lock(local_transports_lock); + adb_mutex_lock( &local_transports_lock ); atransport* result = find_emulator_transport_by_adb_port_locked(adb_port); + adb_mutex_unlock( &local_transports_lock ); return result; } @@ -454,8 +455,9 @@ int get_available_local_transport_index() { - std::lock_guard lock(local_transports_lock); + adb_mutex_lock( &local_transports_lock ); int result = get_available_local_transport_index_locked(); + adb_mutex_unlock( &local_transports_lock ); return result; } #endif @@ -475,20 +477,26 @@ #if ADB_HOST if (local) { - std::lock_guard lock(local_transports_lock); - t->SetLocalPortForEmulator(adb_port); - atransport* existing_transport = find_emulator_transport_by_adb_port_locked(adb_port); - int index = get_available_local_transport_index_locked(); - if (existing_transport != NULL) { - D("local transport for port %d already registered (%p)?", adb_port, existing_transport); - fail = -1; - } else if (index < 0) { - // Too many emulators. - D("cannot register more emulators. Maximum is %d", ADB_LOCAL_TRANSPORT_MAX); - fail = -1; - } else { - local_transports[index] = t; - } + adb_mutex_lock( &local_transports_lock ); + { + t->SetLocalPortForEmulator(adb_port); + atransport* existing_transport = + find_emulator_transport_by_adb_port_locked(adb_port); + int index = get_available_local_transport_index_locked(); + if (existing_transport != NULL) { + D("local transport for port %d already registered (%p)?", + adb_port, existing_transport); + fail = -1; + } else if (index < 0) { + // Too many emulators. + D("cannot register more emulators. Maximum is %d", + ADB_LOCAL_TRANSPORT_MAX); + fail = -1; + } else { + local_transports[index] = t; + } + } + adb_mutex_unlock( &local_transports_lock ); } #endif return fail; diff --git adb/transport_test.cpp adb/transport_test.cpp index a6db07a..8b38e03 100644 --- adb/transport_test.cpp +++ adb/transport_test.cpp @@ -20,6 +20,27 @@ #include "adb.h" +class TransportSetup { +public: + TransportSetup() { +#ifdef _WIN32 + // Use extern instead of including sysdeps.h which brings in various macros + // that conflict with APIs used in this file. + extern void adb_sysdeps_init(void); + adb_sysdeps_init(); +#else + // adb_sysdeps_init() is an inline function that we cannot link against. +#endif + } +}; + +// Static initializer will call adb_sysdeps_init() before main() to initialize +// the transport mutex before it is used in the tests. Alternatives would be to +// use __attribute__((constructor)) here or to use that or a static initializer +// for adb_sysdeps_init() itself in sysdeps_win32.cpp (caveats of unclear +// init order), or to use a test fixture whose SetUp() could do the init once. +static TransportSetup g_TransportSetup; + TEST(transport, kick_transport) { atransport t; static size_t kick_count; diff --git adb/usb_linux_client.cpp adb/usb_linux_client.cpp index 0ba6b4b..1b05439 100644 --- adb/usb_linux_client.cpp +++ adb/usb_linux_client.cpp @@ -32,8 +32,6 @@ #include #include -#include -#include #include @@ -56,14 +54,12 @@ static int dummy_fd = -1; -struct usb_handle { - usb_handle() : kicked(false) { - } - - std::condition_variable notify; - std::mutex lock; +struct usb_handle +{ + adb_cond_t notify; + adb_mutex_t lock; + bool open_new_connection; std::atomic kicked; - bool open_new_connection = true; int (*write)(usb_handle *h, const void *data, int len); int (*read)(usb_handle *h, void *data, int len); @@ -71,12 +67,12 @@ void (*close)(usb_handle *h); // Legacy f_adb - int fd = -1; + int fd; // FunctionFS - int control = -1; - int bulk_out = -1; /* "out" from the host's perspective => source for adbd */ - int bulk_in = -1; /* "in" from the host's perspective => sink for adbd */ + int control; + int bulk_out; /* "out" from the host's perspective => source for adbd */ + int bulk_in; /* "in" from the host's perspective => sink for adbd */ }; struct func_desc { @@ -252,12 +248,12 @@ while (true) { // wait until the USB device needs opening - std::unique_lock lock(usb->lock); + adb_mutex_lock(&usb->lock); while (!usb->open_new_connection) { - usb->notify.wait(lock); + adb_cond_wait(&usb->notify, &usb->lock); } usb->open_new_connection = false; - lock.unlock(); + adb_mutex_unlock(&usb->lock); D("[ usb_thread - opening device ]"); do { @@ -343,20 +339,27 @@ h->kicked = false; adb_close(h->fd); // Notify usb_adb_open_thread to open a new connection. - h->lock.lock(); + adb_mutex_lock(&h->lock); h->open_new_connection = true; - h->lock.unlock(); - h->notify.notify_one(); + adb_cond_signal(&h->notify); + adb_mutex_unlock(&h->lock); } static void usb_adb_init() { - usb_handle* h = new usb_handle(); + usb_handle* h = reinterpret_cast(calloc(1, sizeof(usb_handle))); + if (h == nullptr) fatal("couldn't allocate usb_handle"); h->write = usb_adb_write; h->read = usb_adb_read; h->kick = usb_adb_kick; h->close = usb_adb_close; + h->kicked = false; + h->fd = -1; + + h->open_new_connection = true; + adb_cond_init(&h->notify, 0); + adb_mutex_init(&h->lock, 0); // Open the file /dev/android_adb_enable to trigger // the enabling of the adb USB function in the kernel. @@ -465,12 +468,12 @@ while (true) { // wait until the USB device needs opening - std::unique_lock lock(usb->lock); + adb_mutex_lock(&usb->lock); while (!usb->open_new_connection) { - usb->notify.wait(lock); + adb_cond_wait(&usb->notify, &usb->lock); } usb->open_new_connection = false; - lock.unlock(); + adb_mutex_unlock(&usb->lock); while (true) { if (init_functionfs(usb)) { @@ -554,22 +557,31 @@ adb_close(h->bulk_out); adb_close(h->bulk_in); // Notify usb_adb_open_thread to open a new connection. - h->lock.lock(); + adb_mutex_lock(&h->lock); h->open_new_connection = true; - h->lock.unlock(); - h->notify.notify_one(); + adb_cond_signal(&h->notify); + adb_mutex_unlock(&h->lock); } static void usb_ffs_init() { D("[ usb_init - using FunctionFS ]"); - usb_handle* h = new usb_handle(); + usb_handle* h = reinterpret_cast(calloc(1, sizeof(usb_handle))); + if (h == nullptr) fatal("couldn't allocate usb_handle"); h->write = usb_ffs_write; h->read = usb_ffs_read; h->kick = usb_ffs_kick; h->close = usb_ffs_close; + h->kicked = false; + h->control = -1; + h->bulk_out = -1; + h->bulk_out = -1; + + h->open_new_connection = true; + adb_cond_init(&h->notify, 0); + adb_mutex_init(&h->lock, 0); D("[ usb_init - starting thread ]"); if (!adb_thread_create(usb_ffs_open_thread, h)) { @@ -596,7 +608,6 @@ { return h->read(h, data, len); } - int usb_close(usb_handle *h) { h->close(h); diff --git adb/usb_windows.cpp adb/usb_windows.cpp index 8ecca37..4649454 100644 --- adb/usb_windows.cpp +++ adb/usb_windows.cpp @@ -19,17 +19,13 @@ #include "sysdeps.h" #include // winsock.h *must* be included before windows.h. -#include -#include -#include - +#include #include #include #include - -#include - -#include +#include +#include +#include #include @@ -77,7 +73,7 @@ }; /// Locker for the list of opened usb handles -static std::mutex& usb_lock = *new std::mutex(); +ADB_MUTEX_DEFINE( usb_lock ); /// Checks if there is opened usb handle in handle_list for this device. int known_device(const wchar_t* dev_name); @@ -145,8 +141,9 @@ int ret = 0; if (NULL != dev_name) { - std::lock_guard lock(usb_lock); + adb_mutex_lock(&usb_lock); ret = known_device_locked(dev_name); + adb_mutex_unlock(&usb_lock); } return ret; @@ -156,10 +153,11 @@ if (NULL == handle) return 0; - std::lock_guard lock(usb_lock); + adb_mutex_lock(&usb_lock); // Check if device is already in the list if (known_device_locked(handle->interface_name)) { + adb_mutex_unlock(&usb_lock); return 0; } @@ -169,6 +167,8 @@ handle->prev->next = handle; handle->next->prev = handle; + adb_mutex_unlock(&usb_lock); + return 1; } @@ -493,8 +493,11 @@ void usb_kick(usb_handle* handle) { D("usb_kick"); if (NULL != handle) { - std::lock_guard lock(usb_lock); + adb_mutex_lock(&usb_lock); + usb_kick_locked(handle); + + adb_mutex_unlock(&usb_lock); } else { errno = EINVAL; } @@ -505,17 +508,17 @@ if (NULL != handle) { // Remove handle from the list - { - std::lock_guard lock(usb_lock); - - if ((handle->next != handle) && (handle->prev != handle)) { - handle->next->prev = handle->prev; - handle->prev->next = handle->next; - handle->prev = handle; - handle->next = handle; - } + adb_mutex_lock(&usb_lock); + + if ((handle->next != handle) && (handle->prev != handle)) { + handle->next->prev = handle->prev; + handle->prev->next = handle->next; + handle->prev = handle; + handle->next = handle; } + adb_mutex_unlock(&usb_lock); + // Cleanup handle usb_cleanup_handle(handle); free(handle); @@ -648,8 +651,9 @@ static void kick_devices() { // Need to acquire lock to safely walk the list which might be modified // by another thread. - std::lock_guard lock(usb_lock); + adb_mutex_lock(&usb_lock); for (usb_handle* usb = handle_list.next; usb != &handle_list; usb = usb->next) { usb_kick_locked(usb); } + adb_mutex_unlock(&usb_lock); }