X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FAtomicLinkedList.h;h=4d1d8503452ad6683be6a8fc479a4f343bf16d9f;hp=ee826a7b00d439755a95b4c13f924b3e56588543;hb=70230b7a106820807c8d74fcf3d21ebab3442fbb;hpb=1ac421a539aaf2f349591d4bee36c75ff0ee052c diff --git a/folly/AtomicLinkedList.h b/folly/AtomicLinkedList.h index ee826a7b..4d1d8503 100644 --- a/folly/AtomicLinkedList.h +++ b/folly/AtomicLinkedList.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#pragma once -#include -#include +#pragma once #include #include @@ -46,7 +44,9 @@ class AtomicLinkedList { sweep([](T&&) {}); } - bool empty() const { return list_.empty(); } + bool empty() const { + return list_.empty(); + } /** * Atomically insert t at the head of the list. @@ -54,7 +54,7 @@ class AtomicLinkedList { * after the call. */ bool insertHead(T t) { - auto wrapper = folly::make_unique(std::move(t)); + auto wrapper = std::make_unique(std::move(t)); return list_.insertHead(wrapper.release()); } @@ -73,6 +73,28 @@ class AtomicLinkedList { }); } + /** + * Similar to sweep() but calls func() on elements in LIFO order. + * + * func() is called for all elements in the list at the moment + * reverseSweep() is called. Unlike sweep() it does not loop to ensure the + * list is empty at some point after the last invocation. This way callers + * can reason about the ordering: elements inserted since the last call to + * reverseSweep() will be provided in LIFO order. + * + * Example: if elements are inserted in the order 1-2-3, the callback is + * invoked 3-2-1. If the callback moves elements onto a stack, popping off + * the stack will produce the original insertion order 1-2-3. + */ + template + void reverseSweep(F&& func) { + list_.reverseSweep([&](Wrapper* wrapperPtr) mutable { + std::unique_ptr wrapper(wrapperPtr); + + func(std::move(wrapper->data)); + }); + } + private: struct Wrapper { explicit Wrapper(T&& t) : data(std::move(t)) {}