// 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.

#include "mojo/system/dispatcher.h"

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/simple_thread.h"
#include "mojo/embedder/platform_shared_buffer.h"
#include "mojo/system/memory.h"
#include "mojo/system/waiter.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace system {
namespace {

// Trivial subclass that makes the constructor public.
class TrivialDispatcher : public Dispatcher {
 public:
  TrivialDispatcher() {}

  virtual Type GetType() const OVERRIDE { return kTypeUnknown; }

 private:
  friend class base::RefCountedThreadSafe<TrivialDispatcher>;
  virtual ~TrivialDispatcher() {}

  virtual scoped_refptr<Dispatcher>
  CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE {
    lock().AssertAcquired();
    return scoped_refptr<Dispatcher>(new TrivialDispatcher());
  }

  DISALLOW_COPY_AND_ASSIGN(TrivialDispatcher);
};

TEST(DispatcherTest, Basic) {
  scoped_refptr<Dispatcher> d(new TrivialDispatcher());

  EXPECT_EQ(Dispatcher::kTypeUnknown, d->GetType());

  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            d->WriteMessage(
                NullUserPointer(), 0, NULL, MOJO_WRITE_MESSAGE_FLAG_NONE));
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            d->ReadMessage(NullUserPointer(),
                           NullUserPointer(),
                           NULL,
                           NULL,
                           MOJO_WRITE_MESSAGE_FLAG_NONE));
  EXPECT_EQ(
      MOJO_RESULT_INVALID_ARGUMENT,
      d->WriteData(
          NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(
      MOJO_RESULT_INVALID_ARGUMENT,
      d->BeginWriteData(
          NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndWriteData(0));
  EXPECT_EQ(
      MOJO_RESULT_INVALID_ARGUMENT,
      d->ReadData(
          NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
  EXPECT_EQ(
      MOJO_RESULT_INVALID_ARGUMENT,
      d->BeginReadData(
          NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndReadData(0));
  Waiter w;
  w.Init();
  HandleSignalsState hss;
  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
            d->AddWaiter(&w, ~MOJO_HANDLE_SIGNAL_NONE, 0, &hss));
  EXPECT_EQ(0u, hss.satisfied_signals);
  EXPECT_EQ(0u, hss.satisfiable_signals);
  // Okay to remove even if it wasn't added (or was already removed).
  hss = HandleSignalsState();
  d->RemoveWaiter(&w, &hss);
  EXPECT_EQ(0u, hss.satisfied_signals);
  EXPECT_EQ(0u, hss.satisfiable_signals);
  hss = HandleSignalsState();
  d->RemoveWaiter(&w, &hss);
  EXPECT_EQ(0u, hss.satisfied_signals);
  EXPECT_EQ(0u, hss.satisfiable_signals);

  EXPECT_EQ(MOJO_RESULT_OK, d->Close());

  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            d->WriteMessage(
                NullUserPointer(), 0, NULL, MOJO_WRITE_MESSAGE_FLAG_NONE));
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            d->ReadMessage(NullUserPointer(),
                           NullUserPointer(),
                           NULL,
                           NULL,
                           MOJO_WRITE_MESSAGE_FLAG_NONE));
  EXPECT_EQ(
      MOJO_RESULT_INVALID_ARGUMENT,
      d->WriteData(
          NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(
      MOJO_RESULT_INVALID_ARGUMENT,
      d->BeginWriteData(
          NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndWriteData(0));
  EXPECT_EQ(
      MOJO_RESULT_INVALID_ARGUMENT,
      d->ReadData(
          NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
  EXPECT_EQ(
      MOJO_RESULT_INVALID_ARGUMENT,
      d->BeginReadData(
          NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndReadData(0));
  hss = HandleSignalsState();
  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
            d->AddWaiter(&w, ~MOJO_HANDLE_SIGNAL_NONE, 0, &hss));
  EXPECT_EQ(0u, hss.satisfied_signals);
  EXPECT_EQ(0u, hss.satisfiable_signals);
  hss = HandleSignalsState();
  d->RemoveWaiter(&w, &hss);
  EXPECT_EQ(0u, hss.satisfied_signals);
  EXPECT_EQ(0u, hss.satisfiable_signals);
}

class ThreadSafetyStressThread : public base::SimpleThread {
 public:
  enum DispatcherOp {
    CLOSE = 0,
    WRITE_MESSAGE,
    READ_MESSAGE,
    WRITE_DATA,
    BEGIN_WRITE_DATA,
    END_WRITE_DATA,
    READ_DATA,
    BEGIN_READ_DATA,
    END_READ_DATA,
    DUPLICATE_BUFFER_HANDLE,
    MAP_BUFFER,
    ADD_WAITER,
    REMOVE_WAITER,
    DISPATCHER_OP_COUNT
  };

  ThreadSafetyStressThread(base::WaitableEvent* event,
                           scoped_refptr<Dispatcher> dispatcher,
                           DispatcherOp op)
      : base::SimpleThread("thread_safety_stress_thread"),
        event_(event),
        dispatcher_(dispatcher),
        op_(op) {
    CHECK_LE(0, op_);
    CHECK_LT(op_, DISPATCHER_OP_COUNT);
  }

  virtual ~ThreadSafetyStressThread() { Join(); }

 private:
  virtual void Run() OVERRIDE {
    event_->Wait();

    waiter_.Init();
    switch (op_) {
      case CLOSE: {
        MojoResult r = dispatcher_->Close();
        EXPECT_TRUE(r == MOJO_RESULT_OK || r == MOJO_RESULT_INVALID_ARGUMENT)
            << "Result: " << r;
        break;
      }
      case WRITE_MESSAGE:
        EXPECT_EQ(
            MOJO_RESULT_INVALID_ARGUMENT,
            dispatcher_->WriteMessage(
                NullUserPointer(), 0, NULL, MOJO_WRITE_MESSAGE_FLAG_NONE));
        break;
      case READ_MESSAGE:
        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
                  dispatcher_->ReadMessage(NullUserPointer(),
                                           NullUserPointer(),
                                           NULL,
                                           NULL,
                                           MOJO_WRITE_MESSAGE_FLAG_NONE));
        break;
      case WRITE_DATA:
        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
                  dispatcher_->WriteData(NullUserPointer(),
                                         NullUserPointer(),
                                         MOJO_WRITE_DATA_FLAG_NONE));
        break;
      case BEGIN_WRITE_DATA:
        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
                  dispatcher_->BeginWriteData(NullUserPointer(),
                                              NullUserPointer(),
                                              MOJO_WRITE_DATA_FLAG_NONE));
        break;
      case END_WRITE_DATA:
        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndWriteData(0));
        break;
      case READ_DATA:
        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
                  dispatcher_->ReadData(NullUserPointer(),
                                        NullUserPointer(),
                                        MOJO_READ_DATA_FLAG_NONE));
        break;
      case BEGIN_READ_DATA:
        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
                  dispatcher_->BeginReadData(NullUserPointer(),
                                             NullUserPointer(),
                                             MOJO_READ_DATA_FLAG_NONE));
        break;
      case END_READ_DATA:
        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndReadData(0));
        break;
      case DUPLICATE_BUFFER_HANDLE: {
        scoped_refptr<Dispatcher> unused;
        EXPECT_EQ(
            MOJO_RESULT_INVALID_ARGUMENT,
            dispatcher_->DuplicateBufferHandle(NullUserPointer(), &unused));
        break;
      }
      case MAP_BUFFER: {
        scoped_ptr<embedder::PlatformSharedBufferMapping> unused;
        EXPECT_EQ(
            MOJO_RESULT_INVALID_ARGUMENT,
            dispatcher_->MapBuffer(0u, 0u, MOJO_MAP_BUFFER_FLAG_NONE, &unused));
        break;
      }
      case ADD_WAITER: {
        HandleSignalsState hss;
        MojoResult r =
            dispatcher_->AddWaiter(&waiter_, ~MOJO_HANDLE_SIGNAL_NONE, 0, &hss);
        EXPECT_TRUE(r == MOJO_RESULT_FAILED_PRECONDITION ||
                    r == MOJO_RESULT_INVALID_ARGUMENT);
        EXPECT_EQ(0u, hss.satisfied_signals);
        EXPECT_EQ(0u, hss.satisfiable_signals);
        break;
      }
      case REMOVE_WAITER: {
        HandleSignalsState hss;
        dispatcher_->RemoveWaiter(&waiter_, &hss);
        EXPECT_EQ(0u, hss.satisfied_signals);
        EXPECT_EQ(0u, hss.satisfiable_signals);
        break;
      }
      default:
        NOTREACHED();
        break;
    }

    // Always try to remove the waiter, in case we added it.
    HandleSignalsState hss;
    dispatcher_->RemoveWaiter(&waiter_, &hss);
    EXPECT_EQ(0u, hss.satisfied_signals);
    EXPECT_EQ(0u, hss.satisfiable_signals);
  }

  base::WaitableEvent* const event_;
  const scoped_refptr<Dispatcher> dispatcher_;
  const DispatcherOp op_;

  Waiter waiter_;

  DISALLOW_COPY_AND_ASSIGN(ThreadSafetyStressThread);
};

TEST(DispatcherTest, ThreadSafetyStress) {
  static const size_t kRepeatCount = 20;
  static const size_t kNumThreads = 100;

  for (size_t i = 0; i < kRepeatCount; i++) {
    // Manual reset, not initially signalled.
    base::WaitableEvent event(true, false);
    scoped_refptr<Dispatcher> d(new TrivialDispatcher());

    {
      ScopedVector<ThreadSafetyStressThread> threads;
      for (size_t j = 0; j < kNumThreads; j++) {
        ThreadSafetyStressThread::DispatcherOp op =
            static_cast<ThreadSafetyStressThread::DispatcherOp>(
                (i + j) % ThreadSafetyStressThread::DISPATCHER_OP_COUNT);
        threads.push_back(new ThreadSafetyStressThread(&event, d, op));
        threads.back()->Start();
      }
      // Kicks off real work on the threads:
      event.Signal();
    }  // Joins all the threads.

    // One of the threads should already have closed the dispatcher.
    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->Close());
  }
}

TEST(DispatcherTest, ThreadSafetyStressNoClose) {
  static const size_t kRepeatCount = 20;
  static const size_t kNumThreads = 100;

  for (size_t i = 0; i < kRepeatCount; i++) {
    // Manual reset, not initially signalled.
    base::WaitableEvent event(true, false);
    scoped_refptr<Dispatcher> d(new TrivialDispatcher());

    {
      ScopedVector<ThreadSafetyStressThread> threads;
      for (size_t j = 0; j < kNumThreads; j++) {
        ThreadSafetyStressThread::DispatcherOp op =
            static_cast<ThreadSafetyStressThread::DispatcherOp>(
                (i + j) % (ThreadSafetyStressThread::DISPATCHER_OP_COUNT - 1) +
                1);
        threads.push_back(new ThreadSafetyStressThread(&event, d, op));
        threads.back()->Start();
      }
      // Kicks off real work on the threads:
      event.Signal();
    }  // Joins all the threads.

    EXPECT_EQ(MOJO_RESULT_OK, d->Close());
  }
}

}  // namespace
}  // namespace system
}  // namespace mojo
