Skip to content

Commit 3183545

Browse files
committed
binder: Rationalize @ThreadSafe-ty of BinderTransport. (grpc#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 de9414d commit 3183545

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
@@ -31,6 +31,7 @@
3131
import android.os.Process;
3232
import android.os.RemoteException;
3333
import android.os.TransactionTooLargeException;
34+
import androidx.annotation.BinderThread;
3435
import com.google.common.annotations.VisibleForTesting;
3536
import com.google.common.base.Ticker;
3637
import com.google.common.base.Verify;
@@ -107,8 +108,7 @@
107108
* https://github.com/grpc/proposal/blob/master/L73-java-binderchannel/wireformat.md
108109
*/
109110
@ThreadSafe
110-
public abstract class BinderTransport
111-
implements LeakSafeOneWayBinder.TransactionHandler, IBinder.DeathRecipient {
111+
public abstract class BinderTransport implements IBinder.DeathRecipient {
112112

113113
private static final Logger logger = Logger.getLogger(BinderTransport.class.getName());
114114

@@ -212,9 +212,11 @@ protected enum TransportState {
212212
private final FlowController flowController;
213213

214214
/** The number of incoming bytes we've received. */
215-
private final AtomicLong numIncomingBytes;
215+
// Only read/written on @BinderThread.
216+
private long numIncomingBytes;
216217

217218
/** The number of incoming bytes we've told our peer we've received. */
219+
// Only read/written on @BinderThread.
218220
private long acknowledgedIncomingBytes;
219221

220222
private BinderTransport(
@@ -227,10 +229,9 @@ private BinderTransport(
227229
this.attributes = attributes;
228230
this.logId = logId;
229231
scheduledExecutorService = executorServicePool.getObject();
230-
incomingBinder = new LeakSafeOneWayBinder(this);
232+
incomingBinder = new LeakSafeOneWayBinder(this::handleTransaction);
231233
ongoingCalls = new ConcurrentHashMap<>();
232234
flowController = new FlowController(TRANSACTION_BYTES_WINDOW);
233-
numIncomingBytes = new AtomicLong();
234235
}
235236

236237
// Override in child class.
@@ -425,8 +426,9 @@ final void sendOutOfBandClose(int callId, Status status) {
425426
}
426427
}
427428

428-
@Override
429-
public final boolean handleTransaction(int code, Parcel parcel) {
429+
@BinderThread
430+
@VisibleForTesting
431+
final boolean handleTransaction(int code, Parcel parcel) {
430432
try {
431433
return handleTransactionInternal(code, parcel);
432434
} catch (RuntimeException e) {
@@ -442,6 +444,7 @@ public final boolean handleTransaction(int code, Parcel parcel) {
442444
}
443445
}
444446

447+
@BinderThread
445448
private boolean handleTransactionInternal(int code, Parcel parcel) {
446449
if (code < FIRST_CALL_ID) {
447450
synchronized (this) {
@@ -485,11 +488,12 @@ private boolean handleTransactionInternal(int code, Parcel parcel) {
485488
if (inbound != null) {
486489
inbound.handleTransaction(parcel);
487490
}
488-
long nib = numIncomingBytes.addAndGet(size);
489-
if ((nib - acknowledgedIncomingBytes) > TRANSACTION_BYTES_WINDOW_FORCE_ACK) {
491+
numIncomingBytes += size;
492+
if ((numIncomingBytes - acknowledgedIncomingBytes) > TRANSACTION_BYTES_WINDOW_FORCE_ACK) {
490493
synchronized (this) {
491-
sendAcknowledgeBytes(checkNotNull(outgoingBinder));
494+
sendAcknowledgeBytes(checkNotNull(outgoingBinder), numIncomingBytes);
492495
}
496+
acknowledgedIncomingBytes = numIncomingBytes;
493497
}
494498
return true;
495499
}
@@ -521,10 +525,8 @@ private final void handlePing(Parcel requestParcel) {
521525
protected void handlePingResponse(Parcel parcel) {}
522526

523527
@GuardedBy("this")
524-
private void sendAcknowledgeBytes(OneWayBinderProxy iBinder) {
528+
private void sendAcknowledgeBytes(OneWayBinderProxy iBinder, long n) {
525529
// Send a transaction to acknowledge reception of incoming data.
526-
long n = numIncomingBytes.get();
527-
acknowledgedIncomingBytes = n;
528530
try (ParcelHolder parcel = ParcelHolder.obtain()) {
529531
parcel.get().writeLong(n);
530532
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)