core/auth/src/main/java/software/amazon/awssdk/auth/signer/internal/AsyncSigV4SubscriberAdapter.java [55:98]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                downstreamDemand.getAndAdd(n);

                if (upstreamDone.get()) {
                    sendTrailingEmptyFrame();
                } else {
                    s.request(n);
                }
            }

            @Override
            public void cancel() {
                s.cancel();
            }
        });
    }

    @Override
    public void onNext(ByteBuffer byteBuffer) {
        downstreamDemand.decrementAndGet();
        delegate.onNext(byteBuffer);
    }

    @Override
    public void onError(Throwable t) {
        upstreamDone.compareAndSet(false, true);
        delegate.onError(t);
    }

    @Override
    public void onComplete() {
        upstreamDone.compareAndSet(false, true);

        if (downstreamDemand.get() > 0) {
            sendTrailingEmptyFrame();
        }
    }

    private void sendTrailingEmptyFrame() {
        //when upstream complete, send a trailing empty frame
        synchronized (lock) {
            if (!sentTrailingFrame) {
                sentTrailingFrame = true;
                delegate.onNext(ByteBuffer.wrap(new byte[] {}));
                delegate.onComplete();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/eventstream/internal/io/TrailingDataFramePublisher.java [66:109]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                    downstreamDemand.getAndAdd(n);

                    if (upstreamDone.get()) {
                        sendTrailingEmptyFrame();
                    } else {
                        s.request(n);
                    }
                }

                @Override
                public void cancel() {
                    s.cancel();
                }
            });
        }

        @Override
        public void onNext(ByteBuffer byteBuffer) {
            downstreamDemand.decrementAndGet();
            delegate.onNext(byteBuffer);
        }

        @Override
        public void onError(Throwable t) {
            upstreamDone.compareAndSet(false, true);
            delegate.onError(t);
        }

        @Override
        public void onComplete() {
            upstreamDone.compareAndSet(false, true);

            if (downstreamDemand.get() > 0) {
                sendTrailingEmptyFrame();
            }
        }

        private void sendTrailingEmptyFrame() {
            // when upstream complete, send a trailing empty frame
            synchronized (lock) {
                if (!sentTrailingFrame) {
                    sentTrailingFrame = true;
                    delegate.onNext(ByteBuffer.wrap(new byte[] {}));
                    delegate.onComplete();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



