From owner-svn-ports-head@freebsd.org Thu Sep 29 03:44:07 2016 Return-Path: Delivered-To: svn-ports-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 04BC7BE2D23; Thu, 29 Sep 2016 03:44:07 +0000 (UTC) (envelope-from jbeich@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9CF1A8BC; Thu, 29 Sep 2016 03:44:06 +0000 (UTC) (envelope-from jbeich@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u8T3i5D5091468; Thu, 29 Sep 2016 03:44:05 GMT (envelope-from jbeich@FreeBSD.org) Received: (from jbeich@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u8T3i5LH091460; Thu, 29 Sep 2016 03:44:05 GMT (envelope-from jbeich@FreeBSD.org) Message-Id: <201609290344.u8T3i5LH091460@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jbeich set sender to jbeich@FreeBSD.org using -f From: Jan Beich Date: Thu, 29 Sep 2016 03:44:05 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r422901 - in head/devel: android-tools-adb android-tools-adb-devel android-tools-adb-devel/files android-tools-adb/files android-tools-fastboot android-tools-fastboot-devel android-tool... X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the ports tree for head List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Sep 2016 03:44:07 -0000 Author: jbeich Date: Thu Sep 29 03:44:05 2016 New Revision: 422901 URL: https://svnweb.freebsd.org/changeset/ports/422901 Log: devel/android-tools-{adb,fastboot}-devel: update to n.p.5.3582 Changes: https://android.googlesource.com/platform/system/core/+log/2f21b7cecda2..dfd30c4a169e/adb Changes: https://android.googlesource.com/platform/system/core/+log/2f21b7cecda2..dfd30c4a169e/fastboot Added: head/devel/android-tools-adb-devel/files/patch-adb_bugreport__test.cpp (contents, props changed) head/devel/android-tools-adb-devel/files/patch-adb_commandline.h (contents, props changed) head/devel/android-tools-adb-devel/files/patch-adb_mutex (contents, props changed) head/devel/android-tools-adb-devel/files/patch-base_file.cpp (contents, props changed) head/devel/android-tools-adb/files/extra-patch-adb_sysdeps_mutex.h (contents, props changed) - copied, changed from r422899, head/devel/android-tools-adb/files/patch-adb_sysdeps_mutex.h head/devel/android-tools-adb/files/extra-patch-base_file.cpp (contents, props changed) - copied, changed from r422899, head/devel/android-tools-adb/files/patch-base_file.cpp head/devel/android-tools-fastboot-devel/files/patch-base_file.cpp (contents, props changed) head/devel/android-tools-fastboot/files/extra-patch-base_file.cpp (contents, props changed) - copied, changed from r422899, head/devel/android-tools-fastboot/files/patch-base_file.cpp Deleted: head/devel/android-tools-adb-devel/files/get_my_path_freebsd.cpp head/devel/android-tools-adb/files/patch-adb_sysdeps_mutex.h head/devel/android-tools-adb/files/patch-base_file.cpp head/devel/android-tools-fastboot/files/patch-base_file.cpp Modified: head/devel/android-tools-adb-devel/Makefile (contents, props changed) head/devel/android-tools-adb-devel/distinfo (contents, props changed) head/devel/android-tools-adb-devel/files/Makefile (contents, props changed) head/devel/android-tools-adb-devel/files/patch-adb_adb__auth__host.cpp (contents, props changed) head/devel/android-tools-adb/Makefile (contents, props changed) head/devel/android-tools-fastboot-devel/Makefile (contents, props changed) head/devel/android-tools-fastboot-devel/distinfo (contents, props changed) head/devel/android-tools-fastboot/Makefile (contents, props changed) Modified: head/devel/android-tools-adb-devel/Makefile ============================================================================== --- head/devel/android-tools-adb-devel/Makefile Thu Sep 29 03:42:45 2016 (r422900) +++ head/devel/android-tools-adb-devel/Makefile Thu Sep 29 03:44:05 2016 (r422901) @@ -1,9 +1,9 @@ # $FreeBSD$ # Hint: git describe --abbrev=12 --match android-n-preview-5 -DISTVERSION= n-preview-5-126 -DISTVERSIONSUFFIX= -g2f21b7cecda2 -PORTREVISION= 1 +DISTVERSION= n-preview-5-3582 +DISTVERSIONSUFFIX= -gdfd30c4a169e +PORTREVISION= 0 PKGNAMESUFFIX= -devel CONFLICTS_INSTALL= ${PORTNAME}-[0-9]* @@ -15,8 +15,11 @@ EXTRA_PATCHES= ${.CURDIR}/files/patch-* GH_MYTAG= ${DISTVERSIONPREFIX}${DISTVERSION:C/-[0-9]*$//} +CPPFLAGS+= -D_GLIBCXX_USE_C99 # XXX ports/193528 + OPTIONS_DEFINE= TEST_PYTHON +TEST_BUILD_DEPENDS= googlemock>=1.6.0:devel/googlemock TEST_BROKEN= logging.* tests always fail after 4e5fd111d84d TEST_PYTHON_DESC= ${TEST_DESC:S/tests/python &/} Modified: head/devel/android-tools-adb-devel/distinfo ============================================================================== --- head/devel/android-tools-adb-devel/distinfo Thu Sep 29 03:42:45 2016 (r422900) +++ head/devel/android-tools-adb-devel/distinfo Thu Sep 29 03:44:05 2016 (r422901) @@ -1,7 +1,7 @@ -TIMESTAMP = 1470755379 -SHA256 (android-platform_system_core-android-n-preview-5-126-g2f21b7cecda2_GH0.tar.gz) = 61256486af01cfefeee6779f9926ba32334b9fb1a5aacfa2cd4a682d66f01a2a -SIZE (android-platform_system_core-android-n-preview-5-126-g2f21b7cecda2_GH0.tar.gz) = 1561372 -SHA256 (mbrubeck-android-completion-3b0fabe_GH0.tar.gz) = dc774f101acd9514baf3e7a0ac610068116f2c093b94987ba59203a39a6439dc -SIZE (mbrubeck-android-completion-3b0fabe_GH0.tar.gz) = 5948 +TIMESTAMP = 1474960220 +SHA256 (android-platform_system_core-android-n-preview-5-3582-gdfd30c4a169e_GH0.tar.gz) = 2a4530432d51797fcc426b737d66b411d7ba4635afabe32b0c89cb581b19bc34 +SIZE (android-platform_system_core-android-n-preview-5-3582-gdfd30c4a169e_GH0.tar.gz) = 1464524 +SHA256 (mbrubeck-android-completion-c1b0656_GH0.tar.gz) = ca3311ba47a5edd56c929ac9aae57c02c2c3f1636519c5f67abb00b6e3ecd75c +SIZE (mbrubeck-android-completion-c1b0656_GH0.tar.gz) = 5967 SHA256 (android-platform_development-android-n-preview-5-14-g735aab1_GH0.tar.gz) = e3559503f88e0dc3f0fa3e04cd11b0666538c64a24275fc39af951b74e50f32c SIZE (android-platform_development-android-n-preview-5-14-g735aab1_GH0.tar.gz) = 149193336 Modified: head/devel/android-tools-adb-devel/files/Makefile ============================================================================== --- head/devel/android-tools-adb-devel/files/Makefile Thu Sep 29 03:42:45 2016 (r422900) +++ head/devel/android-tools-adb-devel/files/Makefile Thu Sep 29 03:44:05 2016 (r422901) @@ -15,6 +15,7 @@ SRCS+= adb_io.cpp SRCS+= adb_listeners.cpp SRCS+= adb_trace.cpp SRCS+= adb_utils.cpp +SRCS+= bugreport.cpp SRCS+= commandline.cpp SRCS+= console.cpp SRCS+= diagnose_usb.cpp @@ -23,6 +24,7 @@ SRCS+= file_sync_client.cpp SRCS+= line_printer.cpp SRCS+= services.cpp SRCS+= shell_service_protocol.cpp +SRCS+= socket_spec.cpp SRCS+= ../adb/sockets.cpp SRCS+= sysdeps_unix.cpp SRCS+= transport.cpp @@ -32,8 +34,10 @@ SRCS+= transport_usb.cpp TEST_SRCS+= adb_io_test.cpp TEST_SRCS+= adb_listeners_test.cpp TEST_SRCS+= adb_utils_test.cpp +TEST_SRCS+= bugreport_test.cpp TEST_SRCS+= fdevent_test.cpp TEST_SRCS+= shell_service_protocol_test.cpp +TEST_SRCS+= socket_spec_test.cpp TEST_SRCS+= socket_test.cpp TEST_SRCS+= sysdeps_test.cpp TEST_SRCS+= transport_test.cpp @@ -45,7 +49,6 @@ SRCS+= main.cpp TEST_SRCS+= stat_test.cpp .PATH: ${EXTRADIR} -SRCS+= get_my_path_freebsd.cpp SRCS+= usb_libusb.cpp .PATH: ${.CURDIR}/../base @@ -115,6 +118,7 @@ CXXFLAGS+= ${CPPFLAGS} .endif TEST_CPPFLAGS+= $$(${GTEST_CONFIG} --cppflags) +TEST_CPPFLAGS+= $$(${GMOCK_CONFIG} --cppflags) .for f in ${TEST_SRCS} CPPFLAGS.${f}+= ${TEST_CPPFLAGS} .endfor @@ -124,12 +128,14 @@ LDADD+= $$(${PKG_CONFIG} libusb-1.0 --li LDADD+= -lz \-lpthread DPADD+= ${LIBCRYPTO} ${LIBPTHREAD} ${LIBUSB} ${LIBZ} TEST_LDADD+= $$(${GTEST_CONFIG} --libs --ldflags) +TEST_LDADD+= $$(${GMOCK_CONFIG} --libs --ldflags) TEST_OBJS+= ${TEST_SRCS:R:S/$/.o/} CLEANFILES+= ${PROG}_test ${TEST_OBJS} GIT?= git GTEST_CONFIG?= gtest-config +GMOCK_CONFIG?= gmock-config PKG_CONFIG?= pkg-config beforeinstall: Modified: head/devel/android-tools-adb-devel/files/patch-adb_adb__auth__host.cpp ============================================================================== --- head/devel/android-tools-adb-devel/files/patch-adb_adb__auth__host.cpp Thu Sep 29 03:42:45 2016 (r422900) +++ head/devel/android-tools-adb-devel/files/patch-adb_adb__auth__host.cpp Thu Sep 29 03:44:05 2016 (r422901) @@ -1,9 +1,9 @@ --- adb/adb_auth_host.cpp.orig 2016-06-29 23:43:15 UTC +++ adb/adb_auth_host.cpp -@@ -33,7 +33,9 @@ +@@ -34,7 +34,9 @@ + #include + #include #include - #include - +#if defined(OPENSSL_IS_BORINGSSL) #include +#endif Added: head/devel/android-tools-adb-devel/files/patch-adb_bugreport__test.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/devel/android-tools-adb-devel/files/patch-adb_bugreport__test.cpp Thu Sep 29 03:44:05 2016 (r422901) @@ -0,0 +1,18 @@ +--- adb/bugreport_test.cpp.orig 2016-09-28 18:07:09 UTC ++++ adb/bugreport_test.cpp +@@ -40,6 +40,7 @@ using ::testing::internal::CaptureStdout + using ::testing::internal::GetCapturedStderr; + using ::testing::internal::GetCapturedStdout; + ++#ifdef __linux__ + // Empty function so tests don't need to be linked against file_sync_service.cpp, which requires + // SELinux and its transitive dependencies... + bool do_sync_pull(const std::vector& srcs, const char* dst, bool copy_attrs, +@@ -47,6 +48,7 @@ bool do_sync_pull(const std::vector ++ + #include "adb.h" + + // Callback used to handle the standard streams (stdout and stderr) sent by the Added: head/devel/android-tools-adb-devel/files/patch-adb_mutex ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/devel/android-tools-adb-devel/files/patch-adb_mutex Thu Sep 29 03:44:05 2016 (r422901) @@ -0,0 +1,995 @@ +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); + } + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***