All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.rsocket.core.StateUtils Maven / Gradle / Ivy

The newest version!
package io.rsocket.core;

import java.util.concurrent.atomic.AtomicLongFieldUpdater;

final class StateUtils {

  /** Volatile Long Field bit mask that allows extract flags stored in the field */
  static final long FLAGS_MASK =
      0b111111111111111111111111111111111_0000000000000000000000000000000L;
  /** Volatile Long Field bit mask that allows extract int RequestN stored in the field */
  static final long REQUEST_MASK =
      0b000000000000000000000000000000000_1111111111111111111111111111111L;
  /** Bit Flag that indicates Requester Producer has been subscribed once */
  static final long SUBSCRIBED_FLAG =
      0b000000000000000000000000000000001_0000000000000000000000000000000L;
  /** Bit Flag that indicates that the first payload in RequestChannel scenario is received */
  static final long FIRST_PAYLOAD_RECEIVED_FLAG =
      0b000000000000000000000000000000010_0000000000000000000000000000000L;
  /**
   * Bit Flag that indicates that the logical stream is ready to send the first initial frame
   * (applicable for requester only)
   */
  static final long READY_TO_SEND_FIRST_FRAME_FLAG =
      0b000000000000000000000000000000100_0000000000000000000000000000000L;
  /**
   * Bit Flag that indicates that sent first initial frame was sent (in case of requester) or
   * consumed (if responder)
   */
  static final long FIRST_FRAME_SENT_FLAG =
      0b000000000000000000000000000001000_0000000000000000000000000000000L;
  /** Bit Flag that indicates that there is a frame being reassembled */
  static final long REASSEMBLING_FLAG =
      0b000000000000000000000000000010000_0000000000000000000000000000000L;
  /**
   * Bit Flag that indicates requestChannel stream is half terminated. In this case flag indicates
   * that the inbound is terminated
   */
  static final long INBOUND_TERMINATED_FLAG =
      0b000000000000000000000000000100000_0000000000000000000000000000000L;
  /**
   * Bit Flag that indicates requestChannel stream is half terminated. In this case flag indicates
   * that the outbound is terminated
   */
  static final long OUTBOUND_TERMINATED_FLAG =
      0b000000000000000000000000001000000_0000000000000000000000000000000L;
  /** Initial state for any request operator */
  static final long UNSUBSCRIBED_STATE =
      0b000000000000000000000000000000000_0000000000000000000000000000000L;
  /** State that indicates request operator was terminated */
  static final long TERMINATED_STATE =
      0b100000000000000000000000000000000_0000000000000000000000000000000L;

  /**
   * Adds (if possible) to the given state the {@link #SUBSCRIBED_FLAG} flag which indicates that
   * the given stream has already been subscribed once
   *
   * 

Note, the flag will not be added if the stream has already been terminated or if the stream * has already been subscribed once * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance * @return return previous state before setting the new one */ static long markSubscribed(AtomicLongFieldUpdater updater, T instance) { return markSubscribed(updater, instance, false); } /** * Adds (if possible) to the given state the {@link #SUBSCRIBED_FLAG} flag which indicates that * the given stream has already been subscribed once * *

Note, the flag will not be added if the stream has already been terminated or if the stream * has already been subscribed once * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param markPrepared indicates whether the given instance should be marked as prepared * @param generic type of the instance * @return return previous state before setting the new one */ static long markSubscribed( AtomicLongFieldUpdater updater, T instance, boolean markPrepared) { for (; ; ) { long state = updater.get(instance); if (state == TERMINATED_STATE) { return TERMINATED_STATE; } if ((state & SUBSCRIBED_FLAG) == SUBSCRIBED_FLAG) { return state; } if (updater.compareAndSet( instance, state, state | SUBSCRIBED_FLAG | (markPrepared ? READY_TO_SEND_FIRST_FRAME_FLAG : 0))) { return state; } } } /** * Indicates that the given stream has already been subscribed once * * @param state to check whether stream is subscribed * @return true if the {@link #SUBSCRIBED_FLAG} flag is set */ static boolean isSubscribed(long state) { return (state & SUBSCRIBED_FLAG) == SUBSCRIBED_FLAG; } /** * Adds (if possible) to the given state the {@link #FIRST_FRAME_SENT_FLAG} flag which indicates * that the first frame has already set and logical stream has already been established. * *

Note, the flag will not be added if the stream has already been terminated or if the stream * has already been established once * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance * @return return previous state before setting the new one */ static long markFirstFrameSent(AtomicLongFieldUpdater updater, T instance) { for (; ; ) { long state = updater.get(instance); if (state == TERMINATED_STATE) { return TERMINATED_STATE; } if ((state & FIRST_FRAME_SENT_FLAG) == FIRST_FRAME_SENT_FLAG) { return state; } if (updater.compareAndSet(instance, state, state | FIRST_FRAME_SENT_FLAG)) { return state; } } } /** * Indicates that the first frame which established logical stream has already been sent * * @param state to check whether stream is established * @return true if the {@link #FIRST_FRAME_SENT_FLAG} flag is set */ static boolean isFirstFrameSent(long state) { return (state & FIRST_FRAME_SENT_FLAG) == FIRST_FRAME_SENT_FLAG; } /** * Adds (if possible) to the given state the {@link #READY_TO_SEND_FIRST_FRAME_FLAG} flag which * indicates that the logical stream is ready for initial frame sending. * *

Note, the flag will not be added if the stream has already been terminated or if the stream * has already been marked as prepared * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance * @return return previous state before setting the new one */ static long markReadyToSendFirstFrame(AtomicLongFieldUpdater updater, T instance) { for (; ; ) { long state = updater.get(instance); if (state == TERMINATED_STATE) { return TERMINATED_STATE; } if ((state & READY_TO_SEND_FIRST_FRAME_FLAG) == READY_TO_SEND_FIRST_FRAME_FLAG) { return state; } if (updater.compareAndSet(instance, state, state | READY_TO_SEND_FIRST_FRAME_FLAG)) { return state; } } } /** * Indicates that the logical stream is ready for initial frame sending * * @param state to check whether stream is prepared for initial frame sending * @return true if the {@link #READY_TO_SEND_FIRST_FRAME_FLAG} flag is set */ static boolean isReadyToSendFirstFrame(long state) { return (state & READY_TO_SEND_FIRST_FRAME_FLAG) == READY_TO_SEND_FIRST_FRAME_FLAG; } /** * Adds (if possible) to the given state the {@link #FIRST_PAYLOAD_RECEIVED_FLAG} flag which * indicates that the logical stream is ready for initial frame sending. * *

Note, the flag will not be added if the stream has already been terminated or if the stream * has already been marked as prepared * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance * @return return previous state before setting the new one */ static long markFirstPayloadReceived(AtomicLongFieldUpdater updater, T instance) { for (; ; ) { long state = updater.get(instance); if (state == TERMINATED_STATE) { return TERMINATED_STATE; } if ((state & FIRST_PAYLOAD_RECEIVED_FLAG) == FIRST_PAYLOAD_RECEIVED_FLAG) { return state; } if (updater.compareAndSet(instance, state, state | FIRST_PAYLOAD_RECEIVED_FLAG)) { return state; } } } /** * Indicates that the logical stream is ready for initial frame sending * * @param state to check whether stream is established * @return true if the {@link #FIRST_PAYLOAD_RECEIVED_FLAG} flag is set */ static boolean isFirstPayloadReceived(long state) { return (state & FIRST_PAYLOAD_RECEIVED_FLAG) == FIRST_PAYLOAD_RECEIVED_FLAG; } /** * Adds (if possible) to the given state the {@link #REASSEMBLING_FLAG} flag which indicates that * there is a payload reassembling in progress. * *

Note, the flag will not be added if the stream has already been terminated * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance * @return return previous state before setting the new one */ static long markReassembling(AtomicLongFieldUpdater updater, T instance) { for (; ; ) { long state = updater.get(instance); if (state == TERMINATED_STATE) { return TERMINATED_STATE; } if (updater.compareAndSet(instance, state, state | REASSEMBLING_FLAG)) { return state; } } } /** * Removes (if possible) from the given state the {@link #REASSEMBLING_FLAG} flag which indicates * that a payload reassembly process is completed. * *

Note, the flag will not be removed if the stream has already been terminated * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance * @return return previous state before setting the new one */ static long markReassembled(AtomicLongFieldUpdater updater, T instance) { for (; ; ) { long state = updater.get(instance); if (state == TERMINATED_STATE) { return TERMINATED_STATE; } if (updater.compareAndSet(instance, state, state & ~REASSEMBLING_FLAG)) { return state; } } } /** * Indicates that a payload reassembly process is completed. * * @param state to check whether there is reassembly in progress * @return true if the {@link #REASSEMBLING_FLAG} flag is set */ static boolean isReassembling(long state) { return (state & REASSEMBLING_FLAG) == REASSEMBLING_FLAG; } /** * Adds (if possible) to the given state the {@link #INBOUND_TERMINATED_FLAG} flag which indicates * that an inbound channel of a bidirectional stream is terminated. * *

Note, this action will have no effect if the stream has already been terminated or if * the {@link #INBOUND_TERMINATED_FLAG} flag has already been set.
* Note, if the outbound stream has already been terminated, then the result state will be * {@link #TERMINATED_STATE} * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance * @return return previous state before setting the new one */ static long markInboundTerminated(AtomicLongFieldUpdater updater, T instance) { for (; ; ) { long state = updater.get(instance); if (state == TERMINATED_STATE) { return TERMINATED_STATE; } if ((state & INBOUND_TERMINATED_FLAG) == INBOUND_TERMINATED_FLAG) { return state; } if ((state & OUTBOUND_TERMINATED_FLAG) == OUTBOUND_TERMINATED_FLAG) { if (updater.compareAndSet(instance, state, TERMINATED_STATE)) { return state; } } else { if (updater.compareAndSet(instance, state, state | INBOUND_TERMINATED_FLAG)) { return state; } } } } /** * Indicates that a the inbound channel of a bidirectional stream is terminated. * * @param state to check whether it has {@link #INBOUND_TERMINATED_FLAG} set * @return true if the {@link #INBOUND_TERMINATED_FLAG} flag is set */ static boolean isInboundTerminated(long state) { return (state & INBOUND_TERMINATED_FLAG) == INBOUND_TERMINATED_FLAG; } /** * Adds (if possible) to the given state the {@link #OUTBOUND_TERMINATED_FLAG} flag which * indicates that an outbound channel of a bidirectional stream is terminated. * *

Note, this action will have no effect if the stream has already been terminated or if * the {@link #OUTBOUND_TERMINATED_FLAG} flag has already been set.
* Note, if the {@code checkEstablishment} parameter is {@code true} and the logical stream * is not established, then the result state will be {@link #TERMINATED_STATE}
* Note, if the inbound stream has already been terminated, then the result state will be * {@link #TERMINATED_STATE} * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param checkEstablishment indicates whether {@link #FIRST_FRAME_SENT_FLAG} should be checked to * make final decision * @param generic type of the instance * @return return previous state before setting the new one */ static long markOutboundTerminated( AtomicLongFieldUpdater updater, T instance, boolean checkEstablishment) { for (; ; ) { long state = updater.get(instance); if (state == TERMINATED_STATE) { return TERMINATED_STATE; } if ((state & OUTBOUND_TERMINATED_FLAG) == OUTBOUND_TERMINATED_FLAG) { return state; } if ((checkEstablishment && !isFirstFrameSent(state)) || (state & INBOUND_TERMINATED_FLAG) == INBOUND_TERMINATED_FLAG) { if (updater.compareAndSet(instance, state, TERMINATED_STATE)) { return state; } } else { if (updater.compareAndSet(instance, state, state | OUTBOUND_TERMINATED_FLAG)) { return state; } } } } /** * Indicates that a the outbound channel of a bidirectional stream is terminated. * * @param state to check whether it has {@link #OUTBOUND_TERMINATED_FLAG} set * @return true if the {@link #OUTBOUND_TERMINATED_FLAG} flag is set */ static boolean isOutboundTerminated(long state) { return (state & OUTBOUND_TERMINATED_FLAG) == OUTBOUND_TERMINATED_FLAG; } /** * Makes current state a {@link #TERMINATED_STATE} * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance * @return return previous state before setting the new one */ static long markTerminated(AtomicLongFieldUpdater updater, T instance) { return updater.getAndSet(instance, TERMINATED_STATE); } /** * Makes current state a {@link #TERMINATED_STATE} using {@link * AtomicLongFieldUpdater#lazySet(Object, long)} * * @param updater of the volatile state field * @param instance instance holder of the volatile state * @param generic type of the instance */ static void lazyTerminate(AtomicLongFieldUpdater updater, T instance) { updater.lazySet(instance, TERMINATED_STATE); } /** * Indicates that a the outbound channel of a bidirectional stream is terminated. * * @param state to check whether it has {@link #OUTBOUND_TERMINATED_FLAG} set * @return true if the {@link #OUTBOUND_TERMINATED_FLAG} flag is set */ static boolean isTerminated(long state) { return state == TERMINATED_STATE; } /** * Shortcut for {@link #isSubscribed} {@code ||} {@link #isTerminated} methods * * @param state to check flags on * @return true if state is terminated or has flag subscribed */ static boolean isSubscribedOrTerminated(long state) { return state == TERMINATED_STATE || (state & SUBSCRIBED_FLAG) == SUBSCRIBED_FLAG; } static long addRequestN(AtomicLongFieldUpdater updater, T instance, long toAdd) { return addRequestN(updater, instance, toAdd, false); } static long addRequestN( AtomicLongFieldUpdater updater, T instance, long toAdd, boolean markPrepared) { long currentState, flags, requestN, nextRequestN; for (; ; ) { currentState = updater.get(instance); if (currentState == TERMINATED_STATE) { return TERMINATED_STATE; } requestN = currentState & REQUEST_MASK; if (requestN == REQUEST_MASK) { return currentState; } flags = (currentState & FLAGS_MASK) | (markPrepared ? READY_TO_SEND_FIRST_FRAME_FLAG : 0); nextRequestN = addRequestN(requestN, toAdd); if (updater.compareAndSet(instance, currentState, nextRequestN | flags)) { return currentState; } } } static long addRequestN(long a, long b) { long res = a + b; if (res < 0 || res > REQUEST_MASK) { return REQUEST_MASK; } return res; } static boolean hasRequested(long state) { return (state & REQUEST_MASK) > 0; } static long extractRequestN(long state) { long requestN = state & REQUEST_MASK; if (requestN == REQUEST_MASK) { return REQUEST_MASK; } return requestN; } static boolean isMaxAllowedRequestN(long n) { return n >= REQUEST_MASK; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy