From: Wei Wang Date: Fri, 11 Aug 2017 22:05:46 +0000 (-0700) Subject: exynos9610: USB: Fix potential racing by wall time change X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=f623ed973246655b2d3848f057e8bef9f267badd;p=GitHub%2FLineageOS%2Fandroid_device_motorola_exynos9610-common.git exynos9610: USB: Fix potential racing by wall time change in USBhal pthread_cond_timedwait used wall time so it might introduce racing, pthread_cond_timedwait_monotonic_np is Android specific but it is being deprecated. And now Android support pthread_condattr_setclock so use it to wait on CLOCK_MONOTONIC instead. Bug: 64623895 Test: USB switch function works, charging/MTP/PTP Change-Id: I136533ff90ef1be2b042ef1e0829643f2f7aa968 --- diff --git a/hidl/usb/Usb.cpp b/hidl/usb/Usb.cpp index 3fc188e..7b08450 100644 --- a/hidl/usb/Usb.cpp +++ b/hidl/usb/Usb.cpp @@ -182,12 +182,12 @@ bool switchMode(const hidl_string &portName, if (ret != EOF) { struct timespec to; - struct timeval tp; + struct timespec now; wait_again: - gettimeofday(&tp, NULL); - to.tv_sec = tp.tv_sec + PORT_TYPE_TIMEOUT; - to.tv_nsec = tp.tv_usec * 1000;; + clock_gettime(CLOCK_MONOTONIC, &now); + to.tv_sec = now.tv_sec + PORT_TYPE_TIMEOUT; + to.tv_nsec = now.tv_nsec; int err = pthread_cond_timedwait(&usb->mPartnerCV, &usb->mPartnerLock, &to); // There are no uevent signals which implies role swap timed out. @@ -212,6 +212,29 @@ wait_again: return roleSwitch; } +Usb::Usb() + : mLock(PTHREAD_MUTEX_INITIALIZER), + mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER), + mPartnerLock(PTHREAD_MUTEX_INITIALIZER), + mPartnerUp(false) { + pthread_condattr_t attr; + if (pthread_condattr_init(&attr)) { + ALOGE("pthread_condattr_init failed: %s", strerror(errno)); + abort(); + } + if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) { + ALOGE("pthread_condattr_setclock failed: %s", strerror(errno)); + abort(); + } + if (pthread_cond_init(&mPartnerCV, &attr)) { + ALOGE("pthread_cond_init failed: %s", strerror(errno)); + abort(); + } + if (pthread_condattr_destroy(&attr)) { + ALOGE("pthread_condattr_destroy failed: %s", strerror(errno)); + abort(); + } +} Return Usb::switchRole(const hidl_string &portName, diff --git a/hidl/usb/Usb.h b/hidl/usb/Usb.h index dfd48ca..78be2f9 100644 --- a/hidl/usb/Usb.h +++ b/hidl/usb/Usb.h @@ -40,6 +40,8 @@ using ::android::hardware::Void; using ::android::sp; struct Usb : public IUsb { + Usb(); + Return switchRole(const hidl_string& portName, const PortRole& role) override; Return setCallback(const sp& callback) override; Return queryPortStatus() override; @@ -47,13 +49,13 @@ struct Usb : public IUsb { sp mCallback_1_0; // Protects mCallback variable - pthread_mutex_t mLock = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t mLock; // Protects roleSwitch operation - pthread_mutex_t mRoleSwitchLock = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t mRoleSwitchLock; // Threads waiting for the partner to come back wait here - pthread_cond_t mPartnerCV = PTHREAD_COND_INITIALIZER; + pthread_cond_t mPartnerCV; // lock protecting mPartnerCV - pthread_mutex_t mPartnerLock = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t mPartnerLock; // Variable to signal partner coming back online after type switch bool mPartnerUp;