Skip to content

Commit c206428

Browse files
authored
binder: Rationalize @ThreadSafe-ty of BinderTransport. (#12130)
- Use @BinderThread to document restrictions on methods and certain fields. - Make TransactionHandler non-public since only Android should call it. - Replace an unnecessary AtomicLong with a plain old long.
1 parent 4cd7881 commit c206428

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

binder/src/main/java/io/grpc/binder/internal/BinderTransport.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.os.Process;
3030
import android.os.RemoteException;
3131
import android.os.TransactionTooLargeException;
32+
import androidx.annotation.BinderThread;
3233
import com.google.common.annotations.VisibleForTesting;
3334
import com.google.common.base.Ticker;
3435
import com.google.common.base.Verify;
@@ -105,8 +106,7 @@
105106
* https://github.com/grpc/proposal/blob/master/L73-java-binderchannel/wireformat.md
106107
*/
107108
@ThreadSafe
108-
public abstract class BinderTransport
109-
implements LeakSafeOneWayBinder.TransactionHandler, IBinder.DeathRecipient {
109+
public abstract class BinderTransport implements IBinder.DeathRecipient {
110110

111111
private static final Logger logger = Logger.getLogger(BinderTransport.class.getName());
112112

@@ -210,9 +210,11 @@ protected enum TransportState {
210210
private final FlowController flowController;
211211

212212
/** The number of incoming bytes we've received. */
213-
private final AtomicLong numIncomingBytes;
213+
// Only read/written on @BinderThread.
214+
private long numIncomingBytes;
214215

215216
/** The number of incoming bytes we've told our peer we've received. */
217+
// Only read/written on @BinderThread.
216218
private long acknowledgedIncomingBytes;
217219

218220
private BinderTransport(
@@ -225,10 +227,9 @@ private BinderTransport(
225227
this.attributes = attributes;
226228
this.logId = logId;
227229
scheduledExecutorService = executorServicePool.getObject();
228-
incomingBinder = new LeakSafeOneWayBinder(this);
230+
incomingBinder = new LeakSafeOneWayBinder(this::handleTransaction);
229231
ongoingCalls = new ConcurrentHashMap<>();
230232
flowController = new FlowController(TRANSACTION_BYTES_WINDOW);
231-
numIncomingBytes = new AtomicLong();
232233
}
233234

234235
// Override in child class.
@@ -423,8 +424,9 @@ final void sendOutOfBandClose(int callId, Status status) {
423424
}
424425
}
425426

426-
@Override
427-
public final boolean handleTransaction(int code, Parcel parcel) {
427+
@BinderThread
428+
@VisibleForTesting
429+
final boolean handleTransaction(int code, Parcel parcel) {
428430
try {
429431
return handleTransactionInternal(code, parcel);
430432
} catch (RuntimeException e) {
@@ -440,6 +442,7 @@ public final boolean handleTransaction(int code, Parcel parcel) {
440442
}
441443
}
442444

445+
@BinderThread
443446
private boolean handleTransactionInternal(int code, Parcel parcel) {
444447
if (code < FIRST_CALL_ID) {
445448
synchronized (this) {
@@ -483,11 +486,12 @@ private boolean handleTransactionInternal(int code, Parcel parcel) {
483486
if (inbound != null) {
484487
inbound.handleTransaction(parcel);
485488
}
486-
long nib = numIncomingBytes.addAndGet(size);
487-
if ((nib - acknowledgedIncomingBytes) > TRANSACTION_BYTES_WINDOW_FORCE_ACK) {
489+
numIncomingBytes += size;
490+
if ((numIncomingBytes - acknowledgedIncomingBytes) > TRANSACTION_BYTES_WINDOW_FORCE_ACK) {
488491
synchronized (this) {
489-
sendAcknowledgeBytes(checkNotNull(outgoingBinder));
492+
sendAcknowledgeBytes(checkNotNull(outgoingBinder), numIncomingBytes);
490493
}
494+
acknowledgedIncomingBytes = numIncomingBytes;
491495
}
492496
return true;
493497
}
@@ -519,10 +523,8 @@ private final void handlePing(Parcel requestParcel) {
519523
protected void handlePingResponse(Parcel parcel) {}
520524

521525
@GuardedBy("this")
522-
private void sendAcknowledgeBytes(OneWayBinderProxy iBinder) {
526+
private void sendAcknowledgeBytes(OneWayBinderProxy iBinder, long n) {
523527
// Send a transaction to acknowledge reception of incoming data.
524-
long n = numIncomingBytes.get();
525-
acknowledgedIncomingBytes = n;
526528
try (ParcelHolder parcel = ParcelHolder.obtain()) {
527529
parcel.get().writeLong(n);
528530
iBinder.transact(ACKNOWLEDGE_BYTES, parcel);

binder/src/main/java/io/grpc/binder/internal/LeakSafeOneWayBinder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import android.os.Binder;
2020
import android.os.IBinder;
2121
import android.os.Parcel;
22+
import androidx.annotation.BinderThread;
2223
import io.grpc.Internal;
2324
import java.util.logging.Level;
2425
import java.util.logging.Logger;
@@ -58,6 +59,7 @@ public interface TransactionHandler {
5859
* @return the value to return from {@link Binder#onTransact}. NB: "oneway" semantics mean this
5960
* result will not delivered to the caller of {@link IBinder#transact}
6061
*/
62+
@BinderThread
6163
boolean handleTransaction(int code, Parcel data);
6264
}
6365

0 commit comments

Comments
 (0)