• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #include "pw_multisink/multisink.h"
15 
16 #include <cstring>
17 
18 #include "pw_assert/light.h"
19 #include "pw_multisink/drain.h"
20 #include "pw_status/try.h"
21 #include "pw_varint/varint.h"
22 
23 namespace pw {
24 namespace multisink {
25 
GetEntry(Drain & drain,ByteSpan buffer,uint32_t & sequence_id_out)26 Result<ConstByteSpan> MultiSink::GetEntry(Drain& drain,
27                                           ByteSpan buffer,
28                                           uint32_t& sequence_id_out) {
29   size_t bytes_read = 0;
30 
31   // Exit immediately if there's no multisink attached to this drain.
32   if (drain.multisink_ == nullptr) {
33     return Status::FailedPrecondition();
34   }
35 
36   const Status status =
37       drain.reader_.PeekFrontWithPreamble(buffer, sequence_id_out, bytes_read);
38   if (status.IsOutOfRange()) {
39     // If the drain has caught up, report the last handled sequence ID so that
40     // it can still process any dropped entries.
41     sequence_id_out = drain.multisink_->sequence_id_ - 1;
42     return status;
43   }
44   PW_CHECK(drain.reader_.PopFront().ok());
45   return std::as_bytes(buffer.first(bytes_read));
46 }
47 
AttachDrain(Drain & drain)48 Status MultiSink::AttachDrain(Drain& drain) {
49   PW_DCHECK(drain.multisink_ == nullptr);
50   drain.multisink_ = this;
51   drain.last_handled_sequence_id_ = sequence_id_ - 1;
52   return ring_buffer_.AttachReader(drain.reader_);
53 }
54 
DetachDrain(Drain & drain)55 Status MultiSink::DetachDrain(Drain& drain) {
56   PW_DCHECK(drain.multisink_ == this);
57   drain.multisink_ = nullptr;
58   return ring_buffer_.DetachReader(drain.reader_);
59 }
60 
61 }  // namespace multisink
62 }  // namespace pw
63