summaryrefslogtreecommitdiffstats
path: root/mojo/system/data_pipe.h
blob: 2196671a26ac2756d753f954ae6f59ab139f7fd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// 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_SYSTEM_DATA_PIPE_H_
#define MOJO_SYSTEM_DATA_PIPE_H_

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "mojo/public/system/core.h"
#include "mojo/system/system_impl_export.h"

namespace mojo {
namespace system {

class Waiter;
class WaiterList;

// |DataPipe| is a base class for secondary objects implementing data pipes,
// similar to |MessagePipe| (see the explanatory comment in core_impl.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 MOJO_SYSTEM_IMPL_EXPORT DataPipe :
    public base::RefCountedThreadSafe<DataPipe> {
 public:
  // These are called by the producer dispatcher to implement its methods of
  // corresponding names.
  void ProducerCancelAllWaiters();
  void ProducerClose();
  // This does not validate its arguments.
  MojoResult ProducerWriteData(const void* elements,
                               uint32_t* num_elements,
                               MojoWriteDataFlags flags);
  // This does not validate its arguments.
  MojoResult ProducerBeginWriteData(void** buffer,
                                    uint32_t* buffer_num_elements,
                                    MojoWriteDataFlags flags);
  MojoResult ProducerEndWriteData(uint32_t num_elements_written);
  MojoResult ProducerAddWaiter(Waiter* waiter,
                               MojoWaitFlags flags,
                               MojoResult wake_result);
  void ProducerRemoveWaiter(Waiter* waiter);

  // These are called by the consumer dispatcher to implement its methods of
  // corresponding names.
  void ConsumerCancelAllWaiters();
  void ConsumerClose();
  // This does not validate its arguments.
  MojoResult ConsumerReadData(void* elements,
                              uint32_t* num_elements,
                              MojoReadDataFlags flags);
  // This does not validate its arguments.
  MojoResult ConsumerBeginReadData(const void** buffer,
                                   uint32_t* buffer_num_elements,
                                   MojoReadDataFlags flags);
  MojoResult ConsumerEndReadData(uint32_t num_elements_read);
  MojoResult ConsumerAddWaiter(Waiter* waiter,
                               MojoWaitFlags flags,
                               MojoResult wake_result);
  void ConsumerRemoveWaiter(Waiter* waiter);

  // Thread-safe and fast (doesn't take the lock).
  size_t element_size() const { return element_size_; }

 protected:
  DataPipe(bool has_local_producer, bool has_local_consumer);

  void Init(size_t element_size);

  virtual void ProducerCloseImplNoLock() = 0;
  virtual MojoResult ProducerBeginWriteDataImplNoLock(
      void** buffer,
      uint32_t* buffer_num_elements,
      MojoWriteDataFlags flags) = 0;
  virtual MojoResult ProducerEndWriteDataImplNoLock(
      uint32_t num_elements_written) = 0;
  virtual MojoWaitFlags ProducerSatisfiedFlagsNoLock() = 0;
  virtual MojoWaitFlags ProducerSatisfiableFlagsNoLock() = 0;

  virtual void ConsumerCloseImplNoLock() = 0;
  virtual MojoResult ConsumerDiscardDataNoLock(uint32_t* num_elements,
                                               bool all_or_none) = 0;
  virtual MojoResult ConsumerQueryDataNoLock(uint32_t* num_elements) = 0;
  virtual MojoResult ConsumerBeginReadDataImplNoLock(
      const void** buffer,
      uint32_t* buffer_num_elements,
      MojoReadDataFlags flags) = 0;
  virtual MojoResult ConsumerEndReadDataImplNoLock(
      uint32_t num_elements_read) = 0;
  virtual MojoWaitFlags ConsumerSatisfiedFlagsNoLock() = 0;
  virtual MojoWaitFlags ConsumerSatisfiableFlagsNoLock() = 0;

 private:
  friend class base::RefCountedThreadSafe<DataPipe>;
  virtual ~DataPipe();

  bool has_local_producer_no_lock() const {
    return !!producer_waiter_list_.get();
  }
  bool has_local_consumer_no_lock() const {
    return !!consumer_waiter_list_.get();
  }

  // Set by |Init()| and never changed afterwards.
  size_t element_size_;

  base::Lock lock_;  // Protects the following members.
  scoped_ptr<WaiterList> producer_waiter_list_;
  scoped_ptr<WaiterList> consumer_waiter_list_;

  DISALLOW_COPY_AND_ASSIGN(DataPipe);
};

}  // namespace system
}  // namespace mojo

#endif  // MOJO_SYSTEM_DATA_PIPE_H_