1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "mojo/system/data_pipe_consumer_dispatcher.h"
6
7#include "base/logging.h"
8#include "mojo/system/data_pipe.h"
9#include "mojo/system/memory.h"
10
11namespace mojo {
12namespace system {
13
14DataPipeConsumerDispatcher::DataPipeConsumerDispatcher() {
15}
16
17void DataPipeConsumerDispatcher::Init(scoped_refptr<DataPipe> data_pipe) {
18  DCHECK(data_pipe.get());
19  data_pipe_ = data_pipe;
20}
21
22Dispatcher::Type DataPipeConsumerDispatcher::GetType() const {
23  return kTypeDataPipeConsumer;
24}
25
26DataPipeConsumerDispatcher::~DataPipeConsumerDispatcher() {
27  // |Close()|/|CloseImplNoLock()| should have taken care of the pipe.
28  DCHECK(!data_pipe_.get());
29}
30
31void DataPipeConsumerDispatcher::CancelAllWaitersNoLock() {
32  lock().AssertAcquired();
33  data_pipe_->ConsumerCancelAllWaiters();
34}
35
36void DataPipeConsumerDispatcher::CloseImplNoLock() {
37  lock().AssertAcquired();
38  data_pipe_->ConsumerClose();
39  data_pipe_ = nullptr;
40}
41
42scoped_refptr<Dispatcher>
43DataPipeConsumerDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
44  lock().AssertAcquired();
45
46  scoped_refptr<DataPipeConsumerDispatcher> rv =
47      new DataPipeConsumerDispatcher();
48  rv->Init(data_pipe_);
49  data_pipe_ = nullptr;
50  return scoped_refptr<Dispatcher>(rv.get());
51}
52
53MojoResult DataPipeConsumerDispatcher::ReadDataImplNoLock(
54    UserPointer<void> elements,
55    UserPointer<uint32_t> num_bytes,
56    MojoReadDataFlags flags) {
57  lock().AssertAcquired();
58
59  if ((flags & MOJO_READ_DATA_FLAG_DISCARD)) {
60    // These flags are mutally exclusive.
61    if ((flags & MOJO_READ_DATA_FLAG_QUERY))
62      return MOJO_RESULT_INVALID_ARGUMENT;
63    DVLOG_IF(2, !elements.IsNull())
64        << "Discard mode: ignoring non-null |elements|";
65    return data_pipe_->ConsumerDiscardData(
66        num_bytes, (flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE));
67  }
68
69  if ((flags & MOJO_READ_DATA_FLAG_QUERY)) {
70    DCHECK(!(flags & MOJO_READ_DATA_FLAG_DISCARD));  // Handled above.
71    DVLOG_IF(2, !elements.IsNull())
72        << "Query mode: ignoring non-null |elements|";
73    return data_pipe_->ConsumerQueryData(num_bytes);
74  }
75
76  return data_pipe_->ConsumerReadData(
77      elements, num_bytes, (flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE));
78}
79
80MojoResult DataPipeConsumerDispatcher::BeginReadDataImplNoLock(
81    UserPointer<const void*> buffer,
82    UserPointer<uint32_t> buffer_num_bytes,
83    MojoReadDataFlags flags) {
84  lock().AssertAcquired();
85
86  // These flags may not be used in two-phase mode.
87  if ((flags & MOJO_READ_DATA_FLAG_DISCARD) ||
88      (flags & MOJO_READ_DATA_FLAG_QUERY))
89    return MOJO_RESULT_INVALID_ARGUMENT;
90
91  return data_pipe_->ConsumerBeginReadData(
92      buffer, buffer_num_bytes, (flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE));
93}
94
95MojoResult DataPipeConsumerDispatcher::EndReadDataImplNoLock(
96    uint32_t num_bytes_read) {
97  lock().AssertAcquired();
98
99  return data_pipe_->ConsumerEndReadData(num_bytes_read);
100}
101
102HandleSignalsState DataPipeConsumerDispatcher::GetHandleSignalsStateImplNoLock()
103    const {
104  lock().AssertAcquired();
105  return data_pipe_->ConsumerGetHandleSignalsState();
106}
107
108MojoResult DataPipeConsumerDispatcher::AddWaiterImplNoLock(
109    Waiter* waiter,
110    MojoHandleSignals signals,
111    uint32_t context,
112    HandleSignalsState* signals_state) {
113  lock().AssertAcquired();
114  return data_pipe_->ConsumerAddWaiter(waiter, signals, context, signals_state);
115}
116
117void DataPipeConsumerDispatcher::RemoveWaiterImplNoLock(
118    Waiter* waiter,
119    HandleSignalsState* signals_state) {
120  lock().AssertAcquired();
121  data_pipe_->ConsumerRemoveWaiter(waiter, signals_state);
122}
123
124bool DataPipeConsumerDispatcher::IsBusyNoLock() const {
125  lock().AssertAcquired();
126  return data_pipe_->ConsumerIsBusy();
127}
128
129}  // namespace system
130}  // namespace mojo
131