// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MOJO_EDK_SYSTEM_DATA_PIPE_H_
#define MOJO_EDK_SYSTEM_DATA_PIPE_H_

#include <stdint.h>

#include <memory>

#include "base/compiler_specific.h"
#include "mojo/edk/embedder/platform_handle_vector.h"
#include "mojo/edk/system/channel_endpoint_client.h"
#include "mojo/edk/system/handle_signals_state.h"
#include "mojo/edk/system/memory.h"
#include "mojo/edk/system/mutex.h"
#include "mojo/edk/system/thread_annotations.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/c/system/types.h"
#include "mojo/public/cpp/system/macros.h"

namespace mojo {
namespace system {

class Awakable;
class AwakableList;
class Channel;
class ChannelEndpoint;
class DataPipeImpl;
class MessageInTransitQueue;

// |DataPipe| is a base class for secondary objects implementing data pipes,
// similar to |MessagePipe| (see the explanatory comment in core.cc). It is
// typically owned by the dispatcher(s) corresponding to the local endpoints.
// Its subclasses implement the three cases: local producer and consumer, local
// producer and remote consumer, and remote producer and local consumer. This
// class is thread-safe.
class DataPipe final : public ChannelEndpointClient {
 public:
  // The default options for |MojoCreateDataPipe()|. (Real uses should obtain
  // this via |ValidateCreateOptions()| with a null |in_options|; this is
  // exposed directly for testing convenience.)
  static MojoCreateDataPipeOptions GetDefaultCreateOptions();

  // Validates and/or sets default options for |MojoCreateDataPipeOptions|. If
  // non-null, |in_options| must point to a struct of at least
  // |in_options->struct_size| bytes. |out_options| must point to a (current)
  // |MojoCreateDataPipeOptions| and will be entirely overwritten on success (it
  // may be partly overwritten on failure).
  static MojoResult ValidateCreateOptions(
      UserPointer<const MojoCreateDataPipeOptions> in_options,
      MojoCreateDataPipeOptions* out_options);

  // Creates a local (both producer and consumer) data pipe (using
  // |LocalDataPipeImpl|. |validated_options| should be the output of
  // |ValidateOptions()|. In particular: |struct_size| is ignored (so
  // |validated_options| must be the current version of the struct) and
  // |capacity_num_bytes| must be nonzero.
  static DataPipe* CreateLocal(
      const MojoCreateDataPipeOptions& validated_options);

  // Creates a data pipe with a remote producer and a local consumer, using an
  // existing |ChannelEndpoint| (whose |ReplaceClient()| it'll call) and taking
  // |message_queue|'s contents as already-received incoming messages. If
  // |channel_endpoint| is null, this will create a "half-open" data pipe (with
  // only the consumer open). Note that this may fail, in which case it returns
  // null.
  static DataPipe* CreateRemoteProducerFromExisting(
      const MojoCreateDataPipeOptions& validated_options,
      MessageInTransitQueue* message_queue,
      ChannelEndpoint* channel_endpoint);

  // Creates a data pipe with a local producer and a remote consumer, using an
  // existing |ChannelEndpoint| (whose |ReplaceClient()| it'll call) and taking
  // |message_queue|'s contents as already-received incoming messages
  // (|message_queue| may be null). If |channel_endpoint| is null, this will
  // create a "half-open" data pipe (with only the producer open). Note that
  // this may fail, in which case it returns null.
  static DataPipe* CreateRemoteConsumerFromExisting(
      const MojoCreateDataPipeOptions& validated_options,
      size_t consumer_num_bytes,
      MessageInTransitQueue* message_queue,
      ChannelEndpoint* channel_endpoint);

  // Used by |DataPipeProducerDispatcher::Deserialize()|. Returns true on
  // success (in which case, |*data_pipe| is set appropriately) and false on
  // failure (in which case |*data_pipe| may or may not be set to null).
  static bool ProducerDeserialize(Channel* channel,
                                  const void* source,
                                  size_t size,
                                  scoped_refptr<DataPipe>* data_pipe);

  // Used by |DataPipeConsumerDispatcher::Deserialize()|. Returns true on
  // success (in which case, |*data_pipe| is set appropriately) and false on
  // failure (in which case |*data_pipe| may or may not be set to null).
  static bool ConsumerDeserialize(Channel* channel,
                                  const void* source,
                                  size_t size,
                                  scoped_refptr<DataPipe>* data_pipe);

  // These are called by the producer dispatcher to implement its methods of
  // corresponding names.
  void ProducerCancelAllAwakables();
  void ProducerClose();
  MojoResult ProducerWriteData(UserPointer<const void> elements,
                               UserPointer<uint32_t> num_bytes,
                               bool all_or_none);
  MojoResult ProducerBeginWriteData(UserPointer<void*> buffer,
                                    UserPointer<uint32_t> buffer_num_bytes);
  MojoResult ProducerEndWriteData(uint32_t num_bytes_written);
  HandleSignalsState ProducerGetHandleSignalsState();
  MojoResult ProducerAddAwakable(Awakable* awakable,
                                 MojoHandleSignals signals,
                                 uint32_t context,
                                 HandleSignalsState* signals_state);
  void ProducerRemoveAwakable(Awakable* awakable,
                              HandleSignalsState* signals_state);
  void ProducerStartSerialize(Channel* channel,
                              size_t* max_size,
                              size_t* max_platform_handles);
  bool ProducerEndSerialize(Channel* channel,
                            void* destination,
                            size_t* actual_size,
                            embedder::PlatformHandleVector* platform_handles);
  bool ProducerIsBusy() const;

  // These are called by the consumer dispatcher to implement its methods of
  // corresponding names.
  void ConsumerCancelAllAwakables();
  void ConsumerClose();
  // This does not validate its arguments, except to check that |*num_bytes| is
  // a multiple of |element_num_bytes_|.
  MojoResult ConsumerReadData(UserPointer<void> elements,
                              UserPointer<uint32_t> num_bytes,
                              bool all_or_none,
                              bool peek);
  MojoResult ConsumerDiscardData(UserPointer<uint32_t> num_bytes,
                                 bool all_or_none);
  MojoResult ConsumerQueryData(UserPointer<uint32_t> num_bytes);
  MojoResult ConsumerBeginReadData(UserPointer<const void*> buffer,
                                   UserPointer<uint32_t> buffer_num_bytes);
  MojoResult ConsumerEndReadData(uint32_t num_bytes_read);
  HandleSignalsState ConsumerGetHandleSignalsState();
  MojoResult ConsumerAddAwakable(Awakable* awakable,
                                 MojoHandleSignals signals,
                                 uint32_t context,
                                 HandleSignalsState* signals_state);
  void ConsumerRemoveAwakable(Awakable* awakable,
                              HandleSignalsState* signals_state);
  void ConsumerStartSerialize(Channel* channel,
                              size_t* max_size,
                              size_t* max_platform_handles);
  bool ConsumerEndSerialize(Channel* channel,
                            void* destination,
                            size_t* actual_size,
                            embedder::PlatformHandleVector* platform_handles);
  bool ConsumerIsBusy() const;

  // The following are only to be used by |DataPipeImpl| (and its subclasses):

  // Replaces |impl_| with |new_impl| (which must not be null). For use when
  // serializing data pipe dispatchers (i.e., in |ProducerEndSerialize()| and
  // |ConsumerEndSerialize()|). Returns the old value of |impl_| (in case the
  // caller needs to manage its lifetime).
  std::unique_ptr<DataPipeImpl> ReplaceImplNoLock(
      std::unique_ptr<DataPipeImpl> new_impl)
      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  void SetProducerClosedNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  void SetConsumerClosedNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);

  void ProducerCloseNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  void ConsumerCloseNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);

  // Thread-safe and fast (they don't take |mutex_|):
  const MojoCreateDataPipeOptions& validated_options() const {
    return validated_options_;
  }
  size_t element_num_bytes() const {
    return validated_options_.element_num_bytes;
  }
  size_t capacity_num_bytes() const {
    return validated_options_.capacity_num_bytes;
  }

  // Must be called under |mutex_|.
  bool producer_open_no_lock() const MOJO_SHARED_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    return producer_open_;
  }
  bool consumer_open_no_lock() const MOJO_SHARED_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    return consumer_open_;
  }
  uint32_t producer_two_phase_max_num_bytes_written_no_lock() const
      MOJO_SHARED_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    return producer_two_phase_max_num_bytes_written_;
  }
  uint32_t consumer_two_phase_max_num_bytes_read_no_lock() const
      MOJO_SHARED_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    return consumer_two_phase_max_num_bytes_read_;
  }
  void set_producer_two_phase_max_num_bytes_written_no_lock(uint32_t num_bytes)
      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    producer_two_phase_max_num_bytes_written_ = num_bytes;
  }
  void set_consumer_two_phase_max_num_bytes_read_no_lock(uint32_t num_bytes)
      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    consumer_two_phase_max_num_bytes_read_ = num_bytes;
  }
  bool producer_in_two_phase_write_no_lock() const
      MOJO_SHARED_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    return producer_two_phase_max_num_bytes_written_ > 0;
  }
  bool consumer_in_two_phase_read_no_lock() const
      MOJO_SHARED_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    return consumer_two_phase_max_num_bytes_read_ > 0;
  }

 private:
  // |validated_options| should be the output of |ValidateOptions()|. In
  // particular: |struct_size| is ignored (so |validated_options| must be the
  // current version of the struct) and |capacity_num_bytes| must be nonzero.
  // TODO(vtl): |has_local_producer|/|has_local_consumer| shouldn't really be
  // arguments here. Instead, they should be determined from the |impl| ... but
  // the |impl|'s typically figures these out by examining the owner, i.e., the
  // |DataPipe| object. Probably, this indicates that more stuff should be moved
  // to |DataPipeImpl|, but for now we'll live with this.
  DataPipe(bool has_local_producer,
           bool has_local_consumer,
           const MojoCreateDataPipeOptions& validated_options,
           std::unique_ptr<DataPipeImpl> impl);
  ~DataPipe() override;

  // |ChannelEndpointClient| implementation:
  bool OnReadMessage(unsigned port, MessageInTransit* message) override;
  void OnDetachFromChannel(unsigned port) override;

  void AwakeProducerAwakablesForStateChangeNoLock(
      const HandleSignalsState& new_producer_state)
      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  void AwakeConsumerAwakablesForStateChangeNoLock(
      const HandleSignalsState& new_consumer_state)
      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);

  void SetProducerClosed();
  void SetConsumerClosed();

  bool has_local_producer_no_lock() const MOJO_SHARED_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    return !!producer_awakable_list_;
  }
  bool has_local_consumer_no_lock() const MOJO_SHARED_LOCKS_REQUIRED(mutex_) {
    mutex_.AssertHeld();
    return !!consumer_awakable_list_;
  }

  MSVC_SUPPRESS_WARNING(4324)
  const MojoCreateDataPipeOptions validated_options_;

  mutable Mutex mutex_;
  // *Known* state of producer or consumer.
  bool producer_open_ MOJO_GUARDED_BY(mutex_);
  bool consumer_open_ MOJO_GUARDED_BY(mutex_);
  // Non-null only if the producer or consumer, respectively, is local.
  std::unique_ptr<AwakableList> producer_awakable_list_ MOJO_GUARDED_BY(mutex_);
  std::unique_ptr<AwakableList> consumer_awakable_list_ MOJO_GUARDED_BY(mutex_);
  // These are nonzero if and only if a two-phase write/read is in progress.
  uint32_t producer_two_phase_max_num_bytes_written_ MOJO_GUARDED_BY(mutex_);
  uint32_t consumer_two_phase_max_num_bytes_read_ MOJO_GUARDED_BY(mutex_);
  std::unique_ptr<DataPipeImpl> impl_ MOJO_GUARDED_BY(mutex_);

  MOJO_DISALLOW_COPY_AND_ASSIGN(DataPipe);
};

}  // namespace system
}  // namespace mojo

#endif  // MOJO_EDK_SYSTEM_DATA_PIPE_H_
