/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Examples where the code checks what thread it's currently running on. class ThreadSensitivity { Object monitorA, monitorB; void conditionalAssertMainThread_Bad(boolean b) { if (b) { // this branch asserts on Main thread OurThreadUtils.assertMainThread(); synchronized (monitorA) { synchronized (monitorB) { } } } else { // this branch asserts nothing, so may run in parallel with the other branch synchronized (monitorB) { synchronized (monitorA) { } } } } Object monitorC, monitorD; // the branches in the following two methods are both on main/UI thread so cannot deadlock void conditionalIsMainThread_Ok() { if (OurThreadUtils.isMainThread()) { synchronized (monitorC) { synchronized (monitorD) { } } } } void conditionalIsUiThread_Ok() { if (OurThreadUtils.isUiThread()) { synchronized (monitorD) { synchronized (monitorC) { } } } } Object monitorE, monitorF; // identical to the first case above but negated void conditionalNegatedIsMainThread_Bad() { if (!OurThreadUtils.isMainThread()) { synchronized (monitorE) { synchronized (monitorF) { } } } else { synchronized (monitorF) { synchronized (monitorE) { } } } } Object monitorG, monitorH; public void confusedAssertBad(boolean b, boolean c) { if (b) { OurThreadUtils.assertOnBackgroundThread(); } else { OurThreadUtils.assertOnUiThread(); } // not sure if we're on UI or background, should report if (c) { synchronized (monitorG) { synchronized (monitorH) { } } } else { synchronized (monitorH) { synchronized (monitorG) { } } } } Object monitorI, monitorJ; public void FP_confusedAssertOk(boolean b) { if (b) { OurThreadUtils.assertOnBackgroundThread(); } // b determines if running on UI thread, should NOT report if (b) { synchronized (monitorI) { synchronized (monitorJ) { } } } if (b) { synchronized (monitorJ) { synchronized (monitorI) { } } } } }