blob: d666dba2d256ede57812699115c18cec8538da60 [file] [log] [blame]
// Copyright 2021 The Fuchsia 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 <wlan/drivers/components/frame_container.h>
#include <wlan/drivers/components/frame_storage.h>
namespace wlan::drivers::components {
void FrameContainer::ReturnToStorage() {
if (container_.empty()) {
return;
}
// Ignore all frames at the start of the container that have no storage, do not return these.
auto frame = container_.begin();
while (frame != container_.end() && frame->storage_ == nullptr) {
++frame;
}
if (frame == container_.end()) {
return;
}
// The next frame is guaranteed to have storage, so we can safely lock it. The frames following
// the first frame may or may not have storage and they may have different storage. Keep track
// of the current storage and make sure we handle locks correctly.
FrameStorage* storage = frame->storage_;
storage->lock();
for (; frame != container_.end(); ++frame) {
if (!frame->storage_) {
// Don't return frames without storage
continue;
}
if (frame->storage_ != storage) {
// This frame has a different storage than the previous frame, unlock the previous storage
// then track the new storage and lock it. At this point we're guaranteed that both storage
// and frame->storage_ are not null (because of the earlier check and we only assign to
// storage when we know it's not going to be null).
storage->unlock();
storage = frame->storage_;
storage->lock();
}
frame->Restore();
storage->Store(std::move(*frame));
}
// Since we make sure to never assign null to storage we can (and should) safely unlock it here.
storage->unlock();
}
} // namespace wlan::drivers::components