// Copyright (c) Facebook, Inc. and its affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #include #include #include namespace yarpl { namespace credits { constexpr int64_t kCanceled{std::numeric_limits::min()}; constexpr int64_t kNoFlowControl{std::numeric_limits::max()}; /** * Utility functions to help with handling request(int64_t n) since it can be * called concurrently and must handle rollover. * * Since Flowable Subscription must have an int64_t per Subscription, we also * leverage it for storing cancellation by setting to INT64_MIN so we don't have * to also deal with a separate boolean field per Subscription. * * These functions are thread-safe and intended to deal with concurrent * modification by all working off of std::atomic and using * compare_exchange_strong. */ /** * Add the new value 'n' to the 'current' atomic. * * Caps the result at INT64_MAX. * * Adding a negative number does nothing. * * If 'current' is set to "cancelled" using the magic number INT64_MIN it will * not be changed. * * Returns new value of credits. */ int64_t add(std::atomic*, int64_t); /** * Version of add that works for non-atomic integers. */ int64_t add(int64_t, int64_t); /** * Set 'current' to INT64_MIN as a magic number to represent "cancelled". * * Return true if this changed to cancelled, or false if it was already * cancelled. */ bool cancel(std::atomic*); /** * Consume (remove) credits from the 'current' atomic. * * This MUST only be used to remove credits after emitting a value via onNext. * * Returns new value of credits. */ int64_t consume(std::atomic*, int64_t); /** * Try Consume (remove) credits from the 'current' atomic. * * Returns true if consuming the credit was successful. */ bool tryConsume(std::atomic*, int64_t); /** * Version of consume that works for non-atomic integers. */ int64_t consume(int64_t&, int64_t); /** * Whether the current value represents a "cancelled" subscription. */ bool isCancelled(std::atomic*); /** * If the requested value is MAX so we can ignore flow control. */ bool isInfinite(std::atomic*); } // namespace credits } // namespace yarpl