Home | History | Annotate | Download | only in system
      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/dispatcher.h"
      6 
      7 #include "base/logging.h"
      8 #include "mojo/system/constants.h"
      9 
     10 namespace mojo {
     11 namespace system {
     12 
     13 MojoResult Dispatcher::Close() {
     14   base::AutoLock locker(lock_);
     15   if (is_closed_)
     16     return MOJO_RESULT_INVALID_ARGUMENT;
     17 
     18   is_closed_ = true;
     19   CancelAllWaitersNoLock();
     20   return CloseImplNoLock();
     21 }
     22 
     23 MojoResult Dispatcher::WriteMessage(const void* bytes,
     24                                     uint32_t num_bytes,
     25                                     const std::vector<Dispatcher*>* dispatchers,
     26                                     MojoWriteMessageFlags flags) {
     27   DCHECK(!dispatchers || (dispatchers->size() > 0 &&
     28                           dispatchers->size() < kMaxMessageNumHandles));
     29 
     30   base::AutoLock locker(lock_);
     31   if (is_closed_)
     32     return MOJO_RESULT_INVALID_ARGUMENT;
     33 
     34   return WriteMessageImplNoLock(bytes, num_bytes, dispatchers, flags);
     35 }
     36 
     37 MojoResult Dispatcher::ReadMessage(
     38     void* bytes,
     39     uint32_t* num_bytes,
     40     std::vector<scoped_refptr<Dispatcher> >* dispatchers,
     41     uint32_t* num_dispatchers,
     42     MojoReadMessageFlags flags) {
     43   DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
     44          (dispatchers && dispatchers->empty()));
     45 
     46   base::AutoLock locker(lock_);
     47   if (is_closed_)
     48     return MOJO_RESULT_INVALID_ARGUMENT;
     49 
     50   return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers,
     51                                flags);
     52 }
     53 
     54 MojoResult Dispatcher::WriteData(const void* elements,
     55                                  uint32_t* num_elements,
     56                                  MojoWriteDataFlags flags) {
     57   base::AutoLock locker(lock_);
     58   if (is_closed_)
     59     return MOJO_RESULT_INVALID_ARGUMENT;
     60 
     61   return WriteDataImplNoLock(elements, num_elements, flags);
     62 }
     63 
     64 MojoResult Dispatcher::BeginWriteData(void** buffer,
     65                                       uint32_t* buffer_num_elements,
     66                                       MojoWriteDataFlags flags) {
     67   base::AutoLock locker(lock_);
     68   if (is_closed_)
     69     return MOJO_RESULT_INVALID_ARGUMENT;
     70 
     71   return BeginWriteDataImplNoLock(buffer, buffer_num_elements, flags);
     72 }
     73 
     74 MojoResult Dispatcher::EndWriteData(uint32_t num_elements_written) {
     75   base::AutoLock locker(lock_);
     76   if (is_closed_)
     77     return MOJO_RESULT_INVALID_ARGUMENT;
     78 
     79   return EndWriteDataImplNoLock(num_elements_written);
     80 }
     81 
     82 MojoResult Dispatcher::ReadData(void* elements,
     83                                 uint32_t* num_elements,
     84                                 MojoReadDataFlags flags) {
     85   base::AutoLock locker(lock_);
     86   if (is_closed_)
     87     return MOJO_RESULT_INVALID_ARGUMENT;
     88 
     89   return ReadDataImplNoLock(elements, num_elements, flags);
     90 }
     91 
     92 MojoResult Dispatcher::BeginReadData(const void** buffer,
     93                                      uint32_t* buffer_num_elements,
     94                                      MojoReadDataFlags flags) {
     95   base::AutoLock locker(lock_);
     96   if (is_closed_)
     97     return MOJO_RESULT_INVALID_ARGUMENT;
     98 
     99   return BeginReadDataImplNoLock(buffer, buffer_num_elements, flags);
    100 }
    101 
    102 MojoResult Dispatcher::EndReadData(uint32_t num_elements_read) {
    103   base::AutoLock locker(lock_);
    104   if (is_closed_)
    105     return MOJO_RESULT_INVALID_ARGUMENT;
    106 
    107   return EndReadDataImplNoLock(num_elements_read);
    108 }
    109 
    110 MojoResult Dispatcher::AddWaiter(Waiter* waiter,
    111                                  MojoWaitFlags flags,
    112                                  MojoResult wake_result) {
    113   DCHECK_GE(wake_result, 0);
    114 
    115   base::AutoLock locker(lock_);
    116   if (is_closed_)
    117     return MOJO_RESULT_INVALID_ARGUMENT;
    118 
    119   return AddWaiterImplNoLock(waiter, flags, wake_result);
    120 }
    121 
    122 void Dispatcher::RemoveWaiter(Waiter* waiter) {
    123   base::AutoLock locker(lock_);
    124   if (is_closed_)
    125     return;
    126   RemoveWaiterImplNoLock(waiter);
    127 }
    128 
    129 scoped_refptr<Dispatcher>
    130 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
    131   lock_.AssertAcquired();
    132   DCHECK(!is_closed_);
    133 
    134   is_closed_ = true;
    135   CancelAllWaitersNoLock();
    136   return CreateEquivalentDispatcherAndCloseImplNoLock();
    137 }
    138 
    139 Dispatcher::Dispatcher()
    140     : is_closed_(false) {
    141 }
    142 
    143 Dispatcher::~Dispatcher() {
    144   // Make sure that |Close()| was called.
    145   DCHECK(is_closed_);
    146 }
    147 
    148 void Dispatcher::CancelAllWaitersNoLock() {
    149   lock_.AssertAcquired();
    150   DCHECK(is_closed_);
    151   // By default, waiting isn't supported. Only dispatchers that can be waited on
    152   // will do something nontrivial.
    153 }
    154 
    155 MojoResult Dispatcher::CloseImplNoLock() {
    156   lock_.AssertAcquired();
    157   DCHECK(is_closed_);
    158   // This may not need to do anything. Dispatchers should override this to do
    159   // any actual close-time cleanup necessary.
    160   return MOJO_RESULT_OK;
    161 }
    162 
    163 MojoResult Dispatcher::WriteMessageImplNoLock(
    164     const void* bytes,
    165     uint32_t num_bytes,
    166     const std::vector<Dispatcher*>* dispatchers,
    167     MojoWriteMessageFlags flags) {
    168   lock_.AssertAcquired();
    169   DCHECK(!is_closed_);
    170   // By default, not supported. Only needed for message pipe dispatchers.
    171   return MOJO_RESULT_INVALID_ARGUMENT;
    172 }
    173 
    174 MojoResult Dispatcher::ReadMessageImplNoLock(
    175     void* /*bytes*/,
    176     uint32_t* /*num_bytes*/,
    177     std::vector<scoped_refptr<Dispatcher> >* /*dispatchers*/,
    178     uint32_t* /*num_dispatchers*/,
    179     MojoReadMessageFlags /*flags*/) {
    180   lock_.AssertAcquired();
    181   DCHECK(!is_closed_);
    182   // By default, not supported. Only needed for message pipe dispatchers.
    183   return MOJO_RESULT_INVALID_ARGUMENT;
    184 }
    185 
    186 MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/,
    187                                            uint32_t* /*num_elements*/,
    188                                            MojoWriteDataFlags /*flags*/) {
    189   lock_.AssertAcquired();
    190   DCHECK(!is_closed_);
    191   // By default, not supported. Only needed for data pipe dispatchers.
    192   return MOJO_RESULT_INVALID_ARGUMENT;
    193 }
    194 
    195 MojoResult Dispatcher::BeginWriteDataImplNoLock(
    196     void** /*buffer*/,
    197     uint32_t* /*buffer_num_elements*/,
    198     MojoWriteDataFlags /*flags*/) {
    199   lock_.AssertAcquired();
    200   DCHECK(!is_closed_);
    201   // By default, not supported. Only needed for data pipe dispatchers.
    202   return MOJO_RESULT_INVALID_ARGUMENT;
    203 }
    204 
    205 MojoResult Dispatcher::EndWriteDataImplNoLock(
    206     uint32_t /*num_elements_written*/) {
    207   lock_.AssertAcquired();
    208   DCHECK(!is_closed_);
    209   // By default, not supported. Only needed for data pipe dispatchers.
    210   return MOJO_RESULT_INVALID_ARGUMENT;
    211 }
    212 
    213 MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/,
    214                                           uint32_t* /*num_elements*/,
    215                                           MojoReadDataFlags /*flags*/) {
    216   lock_.AssertAcquired();
    217   DCHECK(!is_closed_);
    218   // By default, not supported. Only needed for data pipe dispatchers.
    219   return MOJO_RESULT_INVALID_ARGUMENT;
    220 }
    221 
    222 MojoResult Dispatcher::BeginReadDataImplNoLock(
    223     const void** /*buffer*/,
    224     uint32_t* /*buffer_num_elements*/,
    225     MojoReadDataFlags /*flags*/) {
    226   lock_.AssertAcquired();
    227   DCHECK(!is_closed_);
    228   // By default, not supported. Only needed for data pipe dispatchers.
    229   return MOJO_RESULT_INVALID_ARGUMENT;
    230 }
    231 
    232 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_elements_read*/) {
    233   lock_.AssertAcquired();
    234   DCHECK(!is_closed_);
    235   // By default, not supported. Only needed for data pipe dispatchers.
    236   return MOJO_RESULT_INVALID_ARGUMENT;
    237 }
    238 
    239 MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/,
    240                                            MojoWaitFlags /*flags*/,
    241                                            MojoResult /*wake_result*/) {
    242   lock_.AssertAcquired();
    243   DCHECK(!is_closed_);
    244   // By default, waiting isn't supported. Only dispatchers that can be waited on
    245   // will do something nontrivial.
    246   return MOJO_RESULT_FAILED_PRECONDITION;
    247 }
    248 
    249 void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/) {
    250   lock_.AssertAcquired();
    251   DCHECK(!is_closed_);
    252   // By default, waiting isn't supported. Only dispatchers that can be waited on
    253   // will do something nontrivial.
    254 }
    255 
    256 }  // namespace system
    257 }  // namespace mojo
    258