101 lines
2.8 KiB
C
101 lines
2.8 KiB
C
|
// 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 <atomic>
|
||
|
#include <cstdint>
|
||
|
#include <limits>
|
||
|
#include <stdexcept>
|
||
|
|
||
|
namespace yarpl {
|
||
|
namespace credits {
|
||
|
|
||
|
constexpr int64_t kCanceled{std::numeric_limits<int64_t>::min()};
|
||
|
constexpr int64_t kNoFlowControl{std::numeric_limits<int64_t>::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<int64_t>.
|
||
|
*
|
||
|
* 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>*, 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<int64_t>*);
|
||
|
|
||
|
/**
|
||
|
* Consume (remove) credits from the 'current' atomic<int64_t>.
|
||
|
*
|
||
|
* 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>*, int64_t);
|
||
|
|
||
|
/**
|
||
|
* Try Consume (remove) credits from the 'current' atomic<int64_t>.
|
||
|
*
|
||
|
* Returns true if consuming the credit was successful.
|
||
|
*/
|
||
|
bool tryConsume(std::atomic<int64_t>*, 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<int64_t>*);
|
||
|
|
||
|
/**
|
||
|
* If the requested value is MAX so we can ignore flow control.
|
||
|
*/
|
||
|
bool isInfinite(std::atomic<int64_t>*);
|
||
|
|
||
|
} // namespace credits
|
||
|
} // namespace yarpl
|