1. 31 Oct, 2017 2 commits
    • Yedidya Feldblum's avatar
      Remove folly/ContainerTraits.h · b22935cd
      Yedidya Feldblum authored
      Summary:
      [Folly] Remove `folly/ContainerTraits.h`.
      
      It has some handly helpers, but it is not a real abstraction or utility library. Within Folly, only `folly/Padded.h` uses it, so just rewrite the bit that needs it.
      
      Reviewed By: LeeHowes
      
      Differential Revision: D6183066
      
      fbshipit-source-id: 24a223fe517d21ff531e0fa80172f15d4f963e51
      b22935cd
    • Yedidya Feldblum's avatar
      Move folly/experimental/AsymmetricMemoryBarrier.h · 056261eb
      Yedidya Feldblum authored
      Summary: [Folly] Move `folly/experimental/AsymmetricMemoryBarrier.h` to `folly/synchronization/AsymmetricMemoryBarrier.h`.
      
      Reviewed By: Orvid
      
      Differential Revision: D6180676
      
      fbshipit-source-id: f4833318cd365181e202d5f379815e728fba168b
      056261eb
  2. 30 Oct, 2017 8 commits
    • Christopher Dykes's avatar
      Fix the CMake build · 24db1040
      Christopher Dykes authored
      Summary: By excluding the tools directory, excluding poly, and moving all the tests that have moved around to their new homes.
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6191644
      
      fbshipit-source-id: bdb39d01a796c1e52257200c0d411a4cb44116ce
      24db1040
    • Felix Leupold's avatar
      Allow to pass ObjC blocks into folly::Function · d3eb9415
      Felix Leupold authored
      Summary:
      In iOS blocks are initially allocated on the stack and only lazily copied to the heap (e.g when they are assigned to a variable). This means, if you pass a block as an rvalue to a C++ method that keeps moving it around instead of copy assigning it at some point, the block remains on the stack and will get freed once the original method is done (leading to use after free if the block is executed later).
      
      This was mitigated by deleting the conversion from ObjC functions to folly functions. Given that all we need is to make sure that the block is allocated on the heap (that is it is an instance of NSMallocBlock rather than NSStackBlock), it seems drastic to ban the conversion. ObjC developers tend to be more familiar with ObjC blocks and will find it convenient to use this conversion.
      
      This diff insteads implements the constructor and assignment operator by wrapping the ObjC block in a c++ lambda and capturing it by copy. ARC keeps track of the reference count and automatically releases the block when the lambda is deallocated. Moreover, copy only increase the retain count (instead of doing an actual copy) if the block was already stored on the heap (https://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html section NSMallocBlock never actually copies).
      
      Reviewed By: ericniebler
      
      Differential Revision: D6109932
      
      fbshipit-source-id: 48bb446d3a66f46affba774cfe1cfb8a60c661de
      d3eb9415
    • Yedidya Feldblum's avatar
      Simplify type_t · ffe039c4
      Yedidya Feldblum authored
      Summary:
      [Folly] Simplify `type_t` by lifting the type to be aliased into the structure template parameter list.
      
      May also fix curious build failures in some compilers.
      
      Reviewed By: akrieger
      
      Differential Revision: D6188953
      
      fbshipit-source-id: 96e1c3af9c11959c0899c092933158922efa7e60
      ffe039c4
    • Lee Howes's avatar
      Split SemiFuture and Future into separate types. Add BasicFuture shared between them. · 46af81b6
      Lee Howes authored
      Summary:
      To avoid the risk of bugs caused by a Future being cast to a SemiFuture, and losing some of the properties in the process, this splits SemiFuture and Future into unrelated types, sharing a private superclass for code reuse.
       * Add BasicFuture in futures::detail
       * Make superclass privately inherited.
       * Unset executor when constructing SemiFuture from Future.
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6177780
      
      fbshipit-source-id: dea3116aeec0572bb973c2a561e17785199e86f2
      46af81b6
    • Arkady Shapkin's avatar
      Mention Windows (Vcpkg) build in README.md · cceed93a
      Arkady Shapkin authored
      Summary: Closes https://github.com/facebook/folly/pull/697
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6144274
      
      Pulled By: Orvid
      
      fbshipit-source-id: a79a2e36e8fcf271925e97ece2a6adbb3c074216
      cceed93a
    • Eric Niebler's avatar
      Folly.Poly: a library for creating type-erasing polymorphic wrappers · 18882128
      Eric Niebler authored
      Summary:
      `Poly` is a class template that makes it relatively easy to define a type-erasing polymorphic object wrapper.
      
      == Type-erasure
      
      `std::function` is one example of a type-erasing polymorphic object wrapper;
      `folly::exception_wrapper` is another. Type-erasure is often used as an
      alternative to dynamic polymorphism via inheritance-based virtual dispatch.
      The distinguishing characteristic of type-erasing wrappers are:
      
      * **Duck typing:** Types do not need to inherit from an abstract base
          class in order to be assignable to a type-erasing wrapper; they merely
          need to satisfy a particular interface.
      * **Value semantics:** Type-erasing wrappers are objects that can be
          passed around _by value_. This is in contrast to abstract base classes
          which must be passed by reference or by pointer or else suffer from
          _slicing_, which causes them to lose their polymorphic behaviors.
          Reference semantics make it difficult to reason locally about code.
      * **Automatic memory management:** When dealing with inheritance-based
          dynamic polymorphism, it is often necessary to allocate and manage
          objects on the heap. This leads to a proliferation of `shared_ptr`s and
          `unique_ptr`s in APIs, complicating their point-of-use. APIs that take
          type-erasing wrappers, on the other hand, can often store small objects
          in-situ, with no dynamic allocation. The memory management, if any, is
          handled for you, and leads to cleaner APIs: consumers of your API don't
          need to pass `shared_ptr<AbstractBase>`; they can simply pass any object
          that satisfies the interface you require. (`std::function` is a
          particularly compelling example of this benefit. Far worse would be an
          inheritance-based callable solution like
          `shared_ptr<ICallable<void(int)>>`. )
      
      == Example: Defining a type-erasing function wrapper with `folly::Poly`
      
      Defining a polymorphic wrapper with `Poly` is a matter of defining two
      things:
      
      * An *interface*, consisting of public member functions, and
      * A *mapping* from a concrete type to a set of member function bindings.
      
      Below is a (heavily commented) example of a simple implementation of a
      `std::function`-like polymorphic wrapper. Its interface has only a single
      member function: `operator()`
      
        lang=c++
        // An interface for a callable object of a particular signature, Fun
        // (most interfaces don't need to be templates, FWIW).
        template <class Fun>
        struct IFunction;
      
        template <class R, class... As>
        struct IFunction<R(As...)> {
          // An interface is defined as a nested class template called
          // Interface that takes a single template parameter, Base, from
          // which it inherits.
          template <class Base>
          struct Interface : Base {
            // The Interface has public member functions. These become the
            // public interface of the resulting Poly instantiation.
            // (Implementation note: Poly<IFunction<Sig>> will publicly
            // inherit from this struct, which is what gives it the right
            // member functions.)
            R operator()(As... as) const {
              // The definition of each member function in your interface will
              // always consist of a single line dispatching to folly::call<N>.
              // The "N" corresponds to the N-th member function in the
              // list of member function bindings, Members, defined below.
              // The first argument will always be *this, and the rest of the
              // arguments should simply forward (if necessary) the member
              // function's arguments.
              return static_cast<R>(
                  folly::poly_call<0>(*this, std::forward<As>(as)...));
            }
          };
          // The "Members" alias template is a comma-separated list of bound
          // member functions for a given concrete type "T". The
          // "FOLLY_POLY_MEMBERS" macro accepts a comma-separated list, and the
          // (optional) "FOLLY_POLY_MEMBER" macro lets you disambiguate overloads
          // by explicitly specifying the function signature the target member
          // function should have. In this case, we require "T" to have a
          // function call operator with the signature `R(As...) const`.
          //
          // If you are using a C++17-compatible compiler, you can do away with
          // the macros and write this as:
          //
          //   template <class T>
          //   using Members =
          //       folly::PolyMembers<folly::sig<R(As...) const>(&T::operator())>;
          //
          // And since `folly::sig` is only needed for disambiguation in case of
          // overloads, if you are not concerned about objects with overloaded
          // function call operators, it could be further simplified to:
          //
          //   template <class T> using Members = folly::PolyMembers<&T::operator()>;
          //
          template <class T>
          using Members = FOLLY_POLY_MEMBERS(
              FOLLY_POLY_MEMBER(R(As...) const, &T::operator()));
        };
      
        // Now that we have defined the interface, we can pass it to Poly to
        // create our type-erasing wrapper:
        template <class Fun>
        using Function = Poly<IFunction<Fun>>;
      
      Given the above definition of `Function`, users can now initialize instances
      of (say) `Function<int(int, int)>` with function objects like
      `std::plus<int>` and `std::multiplies<int>`, as below:
      
        lang=c++
        Function<int(int, int)> fun = std::plus<int>{};
        assert(5 == fun(2, 3));
        fun = std::multiplies<int>{};
        assert(6 = fun(2, 3));
      
      == Defining an interface with C++17
      
      With C++17, defining an interface to be used with `Poly` is fairly
      straightforward. As in the `Function` example above, there is a struct with
      a nested `Interface` class template and a nested `Members` alias template.
      No macros are needed with C++17.
      
      Imagine we were defining something like a Java-style iterator. If we are
      using a C++17 compiler, our interface would look something like this:
      
        lang=c++
        template <class Value>
        struct IJavaIterator {
          template <class Base>
          struct Interface : Base {
            bool Done() const { return folly::poly_call<0>(*this); }
            Value Current() const { return folly::poly_call<1>(*this); }
            void Next() { folly::poly_call<2>(*this); }
          };
          // NOTE: This works in C++17 only:
          template <class T>
          using Members = folly::PolyMembers<&T::Done, &T::Current, &T::Next>;
        };
      
        template <class Value>
        using JavaIterator = Poly<IJavaIterator>;
      
      Given the above definition, `JavaIterator<int>` can be used to hold instances
      of any type that has `Done`, `Current`, and `Next` member functions with the
      correct (or compatible) signatures.
      
      The presence of overloaded member functions complicates this picture. Often,
      property members are faked in C++ with `const` and non-`const` member
      function overloads, like in the interface specified below:
      
        lang=c++
        struct IIntProperty {
          template <class Base>
          struct Interface : Base {
            int Value() const { return folly::poly_call<0>(*this); }
            void Value(int i) { folly::poly_call<1>(*this, i); }
          };
          // NOTE: This works in C++17 only:
          template <class T>
          using Members = folly::PolyMembers<
            folly::sig<int() const>(&T::Value),
            folly::sig<void(int)>(&T::Value)>;
        };
      
        using IntProperty = Poly<IIntProperty>;
      
      Now, any object that has `Value` members of compatible signatures can be
      assigned to instances of `IntProperty` object. Note how `folly::sig` is used
      to disambiguate the overloads of `&T::Value`.
      
      == Defining an interface with C++14
      
      In C++14, the nice syntax above doesn't work, so we have to resort to macros.
      The two examples above would look like this:
      
        lang=c++
        template <class Value>
        struct IJavaIterator {
          template <class Base>
          struct Interface : Base {
            bool Done() const { return folly::poly_call<0>(*this); }
            Value Current() const { return folly::poly_call<1>(*this); }
            void Next() { folly::poly_call<2>(*this); }
          };
          // NOTE: This works in C++14 and C++17:
          template <class T>
          using Members = FOLLY_POLY_MEMBERS(&T::Done, &T::Current, &T::Next);
        };
      
        template <class Value>
        using JavaIterator = Poly<IJavaIterator>;
      
      and
      
        lang=c++
        struct IIntProperty {
          template <class Base>
          struct Interface : Base {
            int Value() const { return folly::poly_call<0>(*this); }
            void Value(int i) { return folly::poly_call<1>(*this, i); }
          };
          // NOTE: This works in C++14 and C++17:
          template <class T>
          using Members = FOLLY_POLY_MEMBERS(
            FOLLY_POLY_MEMBER(int() const, &T::Value),
            FOLLY_POLY_MEMBER(void(int), &T::Value));
        };
      
        using IntProperty = Poly<IIntProperty>;
      
      == Extending interfaces
      
      One typical advantage of inheritance-based solutions to runtime polymorphism
      is that one polymorphic interface could extend another through inheritance.
      The same can be accomplished with type-erasing polymorphic wrappers. In
      the `Poly` library, you can use `folly::PolyExtends` to say that one interface
      extends another.
      
        lang=c++
        struct IFoo {
          template <class Base>
          struct Interface : Base {
            void Foo() const { return folly::poly_call<0>(*this); }
          };
          template <class T>
          using Members = FOLLY_POLY_MEMBERS(&T::Foo);
        };
      
        // The IFooBar interface extends the IFoo interface
        struct IFooBar : PolyExtends<IFoo> {
          template <class Base>
          struct Interface : Base {
            void Bar() const { return folly::poly_call<0>(*this); }
          };
          template <class T>
          using Members = FOLLY_POLY_MEMBERS(&T::Bar);
        };
      
        using FooBar = Poly<IFooBar>;
      
      Given the above definition, instances of type `FooBar` have both `Foo()` and
      `Bar()` member functions.
      
      The sensible conversions exist between a wrapped derived type and a wrapped
      base type. For instance, assuming `IDerived` extends `IBase` with `Extends`:
      
        lang=c++
        Poly<IDerived> derived = ...;
        Poly<IBase> base = derived; // This conversion is OK.
      
      As you would expect, there is no conversion in the other direction, and at
      present there is no `Poly` equivalent to `dynamic_cast`.
      
      == Type-erasing polymorphic reference wrappers
      
      Sometimes you don't need to own a copy of an object; a reference will do. For
      that you can use `Poly` to capture a //reference// to an object satisfying an
      interface rather than the whole object itself. The syntax is intuitive.
      
        lang=c++
        int i = 42;
      
        // Capture a mutable reference to an object of any IRegular type:
        Poly<IRegular &> intRef = i;
      
        assert(42 == folly::poly_cast<int>(intRef));
        // Assert that we captured the address of "i":
        assert(&i == &folly::poly_cast<int>(intRef));
      
      A reference-like `Poly` has a different interface than a value-like `Poly`.
      Rather than calling member functions with the `obj.fun()` syntax, you would
      use the `obj->fun()` syntax. This is for the sake of `const`-correctness.
      For example, consider the code below:
      
        lang=c++
        struct IFoo {
          template <class Base>
          struct Interface {
            void Foo() { folly::poly_call<0>(*this); }
          };
          template <class T>
          using Members = folly::PolyMembers<&T::Foo>;
        };
      
        struct SomeFoo {
          void Foo() { std::printf("SomeFoo::Foo\n"); }
        };
      
        SomeFoo foo;
        Poly<IFoo &> const anyFoo = foo;
        anyFoo->Foo(); // prints "SomeFoo::Foo"
      
      Notice in the above code that the `Foo` member function is non-`const`.
      Notice also that the `anyFoo` object is `const`. However, since it has
      captured a non-`const` reference to the `foo` object, it should still be
      possible to dispatch to the non-`const` `Foo` member function. When
      instantiated with a reference type, `Poly` has an overloaded `operator->`
      member that returns a pointer to the `IFoo` interface with the correct
      `const`-ness, which makes this work.
      
      The same mechanism also prevents users from calling non-`const` member
      functions on `Poly` objects that have captured `const` references, which
      would violate `const`-correctness.
      
      Sensible conversions exist between non-reference and reference `Poly`s. For
      instance:
      
        lang=c++
        Poly<IRegular> value = 42;
        Poly<IRegular &> mutable_ref = value;
        Poly<IRegular const &> const_ref = mutable_ref;
      
        assert(&poly_cast<int>(value) == &poly_cast<int>(mutable_ref));
        assert(&poly_cast<int>(value) == &poly_cast<int>(const_ref));
      
      == Non-member functions (C++17)
      
      If you wanted to write the interface `ILogicallyNegatable`, which captures
      all types that can be negated with unary `operator!`, you could do it
      as we've shown above, by binding `&T::operator!` in the nested `Members`
      alias template, but that has the problem that it won't work for types that
      have defined unary `operator!` as a free function. To handle this case,
      the `Poly` library lets you use a free function instead of a member function
      when creating a binding.
      
      With C++17 you may use a lambda to create a binding, as shown in the example
      below:
      
        lang=c++
        struct ILogicallyNegatable {
          template <class Base>
          struct Interface : Base {
            bool operator!() const { return folly::poly_call<0>(*this); }
          };
          template <class T>
          using Members = folly::PolyMembers<
            +[](T const& t) -> decltype(!t) { return !t; }>;
        };
      
      This requires some explanation. The unary `operator+` in front of the lambda
      is necessary! It causes the lambda to decay to a C-style function pointer,
      which is one of the types that `folly::PolyMembers` accepts. The `decltype` in
      the lambda return type is also necessary. Through the magic of SFINAE, it
      will cause `Poly<ILogicallyNegatable>` to reject any types that don't support
      unary `operator!`.
      
      If you are using a free function to create a binding, the first parameter is
      implicitly the `this` parameter. It will receive the type-erased object.
      
      == Non-member functions (C++14)
      
      If you are using a C++14 compiler, the definition of `ILogicallyNegatable`
      above will fail because lambdas are not `constexpr`. We can get the same
      effect by writing the lambda as a named free function, as show below:
      
        lang=c++
        struct ILogicallyNegatable {
          template <class Base>
          struct Interface : Base {
            bool operator!() const { return folly::poly_call<0>(*this); }
          };
          template <class T>
          static auto negate(T const& t) -> decltype(!t) { return !t; }
          template <class T>
          using Members = FOLLY_POLY_MEMBERS(&negate<T>);
        };
      
      As with the example that uses the lambda in the preceding section, the first
      parameter is implicitly the `this` parameter. It will receive the type-erased
      object.
      
      == Multi-dispatch
      
      What if you want to create an `IAddable` interface for things that can be
      added? Adding requires //two// objects, both of which are type-erased. This
      interface requires dispatching on both objects, doing the addition only
      if the types are the same. For this we make use of the `Self` template
      alias to define an interface that takes more than one object of the the
      erased type.
      
        lang=c++
        struct IAddable {
          template <class Base>
          struct Interface : Base {
            friend Self<Base>
            operator+(Self<Base> const& a, Self<Base> const& b) const {
              return folly::poly_call<0>(a, b);
            }
          };
          template <class T>
          using Members = folly::PolyMembers<
            +[](T const& a, T const& b) -> decltype(a + b) { return a + b; }>;
        };
      
      Given the above defintion of `IAddable` we would be able to do the following:
      
        lang=c++
        Poly<IAddable> a = 2, b = 3;
        Poly<IAddable> c = a + b;
        assert(poly_cast<int>(c) == 5);
      
      If `a` and `b` stored objects of different types, a `BadPolyCast` exception
      would be thrown.
      
      == Move-only types
      
      If you want to store move-only types, then your interface should extend the
      `IMoveOnly` interface.
      
      == Implementation notes
      
      `Poly` will store "small" objects in an internal buffer, avoiding the cost of
      of dynamic allocations. At present, this size is not configurable; it is
      pegged at the size of two `double`s.
      
      `Poly` objects are always nothrow movable. If you store an object in one that
      has a potentially throwing move contructor, the object will be stored on the
      heap, even if it could fit in the internal storage of the `Poly` object.
      (So be sure to give your objects nothrow move constructors!)
      
      `Poly` implements type-erasure in a manner very similar to how the compiler
      accomplishes virtual dispatch. Every `Poly` object contains a pointer to a
      table of function pointers. Member function calls involve a double-
      indirection: once through the v-pointer, and other indirect function call
      through the function pointer.
      
      Reviewed By: yfeldblum
      
      Differential Revision: D4897112
      
      fbshipit-source-id: ff1c1156316bfbdd8f2205c4f57932c0067cacac
      18882128
    • Alexander Pronchenkov's avatar
      Remove a few memory allocations in ThreadWheelTimekeeper.after() · cda07daf
      Alexander Pronchenkov authored
      Summary:
      This diff reduces number of memory allocation in folly::ThreadWheelTimekeeper.after() method for a bit.
      
       * std::shared_ptr(new T) is replaced with std::make_shared<T>()
       * folly::Promise is stored by value
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6172017
      
      fbshipit-source-id: 41bf123f10570c76d64eaac1800b7e65fe381110
      cda07daf
    • Murali Vilayannur's avatar
      Override TemporaryFile's default move constructor · 017cae98
      Murali Vilayannur authored
      Summary:
      A default move constructor/move assignment operator caused a bunch
      of bugs in my test that was depending on the move constructor to either
      not close the underlying file descriptor or to ensure that the TemporaryFile
      object doesn't have a dangling reference to a file descriptor that has already
      been closed. The current implementation caused both the moved' from and to
      object to share the same underlying file descriptor and when the former object
      is destroyed it ends up closing the file descriptor leaving the latter
      with a dangling file descriptor which could be reused for some other
      socket(s)/file descriptor by the kernel and ends up causing seg-faults
      when the latter object is eventually destroyed due to it releasing
      a file descriptor that now belongs to some other resource.
      
      I changed the move constructor/move assignment operator
      to have the former semantics to not close the underlying file descriptor of
      the move'd from object (by releasing it and assigning it to the move'd to
      object). I am not sure if anyone would ever want the alternative
      semantics because the TemporaryFile object would not be usable
      without a valid underlying file descriptor
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6182075
      
      fbshipit-source-id: bc809d704449c1c1182d76cdfa2f7d17b38a719a
      017cae98
  3. 29 Oct, 2017 5 commits
    • Yedidya Feldblum's avatar
      CodeMod: Replace includes of folly/Hash.h with folly/hash/Hash.h · 1badabb2
      Yedidya Feldblum authored
      Summary: CodeMod: Replace includes of `folly/Hash.h` with `folly/hash/Hash.h`.
      
      Reviewed By: luciang
      
      Differential Revision: D6156195
      
      fbshipit-source-id: 0941b3c9cf1d17d7cc62595111e506c06ee51236
      1badabb2
    • Yedidya Feldblum's avatar
      Make SysBufferDeleter::operator() inlineable · 090b0ac7
      Yedidya Feldblum authored
      Summary: [Folly] Make `SysBufferDeleter::operator()` inlineable, specifically, into `SysBufferUniquePtr`.
      
      Reviewed By: luciang
      
      Differential Revision: D6182999
      
      fbshipit-source-id: e0409c0019f21ed44d7d4c531ebc11a239f25831
      090b0ac7
    • Yedidya Feldblum's avatar
      Move folly/Launder.h · 8034b69f
      Yedidya Feldblum authored
      Summary: [Folly] Move `folly/Launder.h` to `folly/lang/`.
      
      Reviewed By: luciang
      
      Differential Revision: D6182882
      
      fbshipit-source-id: 97e46bd4e4d6f212d8234209ee90a41e7850ecb9
      8034b69f
    • Yedidya Feldblum's avatar
      Move folly/Array.h · f9b6d012
      Yedidya Feldblum authored
      Summary: [Folly] Move `folly/Array.h` to `folly/container/`.
      
      Reviewed By: luciang
      
      Differential Revision: D6182858
      
      fbshipit-source-id: 59340b96058cc6d0c7a0289e316bbde98c15d724
      f9b6d012
    • Yedidya Feldblum's avatar
      Move folly/Assume.h · 2ee091de
      Yedidya Feldblum authored
      Summary: [Folly] Move `folly/Assume.h` to `folly/lang/`.
      
      Reviewed By: luciang, ot
      
      Differential Revision: D6181983
      
      fbshipit-source-id: 25564bb07daa1a6765651cd919b4778efb931446
      2ee091de
  4. 28 Oct, 2017 3 commits
    • Andrew Krieger's avatar
      Break out BitIterator into its own header · cbd3e7fb
      Andrew Krieger authored
      Summary:
      BitIterator is a standalone construct that has a heavy boost
      dependency, but not common usage. Breaking it out into its own header
      will help a lot of transitive dependendencies, because it is included
      in Hash.h which is included in a variety of other common headers.
      
      This reduces the number of transitively included headers by 248 (!)
      
      Reviewed By: yfeldblum, ot, luciang
      
      Differential Revision: D6178564
      
      fbshipit-source-id: 1380154b012615b7b8c73bc15ab0ac62f6b990d3
      cbd3e7fb
    • Yedidya Feldblum's avatar
      Move folly/detail/AtomicUtils.h · e89f46cd
      Yedidya Feldblum authored
      Summary: [Folly] Move `folly/detail/AtomicUtils.h` to `folly/synchronization/detail/`.
      
      Reviewed By: Orvid
      
      Differential Revision: D6180482
      
      fbshipit-source-id: 5671c149a59eea824db2935ffabcf85a2f78b690
      e89f46cd
    • Scott Michelson's avatar
      LOG_EVERY_N instead of every time · f72422cc
      Scott Michelson authored
      Summary: when queues fill, this starts blowing up, affecting server performance and making logs useless. It's useful to know queues are full, but we don't need the log every time we try to append
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6175784
      
      fbshipit-source-id: b4e6966087c4a6f9fba51d7f9193b9f41e13b899
      f72422cc
  5. 27 Oct, 2017 2 commits
    • Yedidya Feldblum's avatar
      Fix FunctionScheduler::resetFunctionTimer concurrency bug · d89c342a
      Yedidya Feldblum authored
      Summary:
      [Folly] Fix `FunctionScheduler::resetFunctionTimer` concurrency bug.
      
      The original code from the blamed diff code has a comment with this correct assessment of the bug:
      > TODO: This moves out of RepeatFunc object while folly:Function can potentially be executed. This might be unsafe.
      
      Namely, when the method is invoked with the id of a scheduled function which is concurrently being executed, the function object (including, say, lambda captures) will be moved while possibly being accessed. If the function object is small enough to be placed in-situ within `folly::Function` (48 bytes on x64), then that access to a moved-from object can happen. It might or might not, depending on the particular instance of the race in question. Or, worse, the access might be to a half-moved-from object!
      
      The new test case for `resetFunctionTimer` passes after the fix, but is guaranteed to fail before the fix because we manage to control the concurrency enough to force the bad version of the race to happen. In the test, we just capture a `std::shared_ptr` (we could have capatured, e.g., a `std::unique_ptr` or a long-enough `std::string`) and check that it is not empty - if it is moved from, it will be empty, and the test expectation will fail.
      
      Reviewed By: simpkins
      
      Differential Revision: D6158722
      
      fbshipit-source-id: 33a7ae699bb3b22089fddbebb6d922737668309d
      d89c342a
    • Yedidya Feldblum's avatar
      type_t, a generalization of void_t · 7ec1449d
      Yedidya Feldblum authored
      Summary: [Folly] `type_t`, a generalization of `void_t`.
      
      Reviewed By: ericniebler
      
      Differential Revision: D6082913
      
      fbshipit-source-id: f9557b5da1f6684b12d570b6c1bd52c102cb0703
      7ec1449d
  6. 26 Oct, 2017 5 commits
    • Christopher Dykes's avatar
      Just use a volatile static in Malloc.h · a15fcb1e
      Christopher Dykes authored
      Summary: As suggested late in the initial diff (D5840883), just mark it volatile, as it works under all supported platforms.
      
      Reviewed By: davidtgoldblatt, yfeldblum
      
      Differential Revision: D6155241
      
      fbshipit-source-id: 00c07a11dc7fc2e33c2d1f9a45fd28006eeff6f9
      a15fcb1e
    • Christopher Dykes's avatar
      Fix build with Windows SDK v10.0.16232 · 760b0714
      Christopher Dykes authored
      Summary:
      It defines `MSG_ERRQUEUE` which breaks things.
      
      There's a github PR to do this in a different way, but it's faster to just do it myself.
      
      Closes https://github.com/facebook/folly/pull/689
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6155606
      
      fbshipit-source-id: f1c6b247efc452b4005ad3b6d82fabfd5a92f49f
      760b0714
    • Dan Melnic's avatar
      Disable zerocopy if we're notified about deferred copies, add a... · 8f4003a8
      Dan Melnic authored
      Disable zerocopy if we're notified about deferred copies, add a isZeroCopyWriteInProgress method, replace pair with a proper struct
      
      Summary: Add zeroWriteDone callback
      
      Reviewed By: djwatson
      
      Differential Revision: D6097129
      
      fbshipit-source-id: b82a942557680c3a7a3be8f81ee6f2886e99e165
      8f4003a8
    • Yedidya Feldblum's avatar
      Expected coroutines support · 0e8c7e1c
      Yedidya Feldblum authored
      Summary:
      [Folly] `Expected` coroutines support.
      
      Copied from `Optional` coroutines support.
      
      Reviewed By: ericniebler, Orvid
      
      Differential Revision: D5923792
      
      fbshipit-source-id: 8661012c65762a0e540a4af2fd2fc237a8cb87a1
      0e8c7e1c
    • Kenny Yu's avatar
      folly: Fix data race in folly::Codel · 9fb1f368
      Kenny Yu authored
      Summary:
      Data race reported by TSAN:
      
      ```
      WARNING: ThreadSanitizer: data race (pid=608219)
        Read of size 1 at 0x7b5800000c29 by thread T314:
          #0 0x60b3441 in folly::Codel::overloaded(std::chrono::duration<long, std::ratio<1l, 1000000000l> >) ./folly/executors/Codel.cpp:76
          #1 0x5c1222 in apache::thrift::concurrency::ThreadManager::ImplT<folly::LifoSemImpl<std::atomic, folly::Baton<std::atomic, true, true> > >::Worker<folly::LifoSemImpl<std::atomic, folly::Baton<std::atomic, true, true> > >::run() ./thrift/lib/cpp/concurrency/ThreadManager.tcc:119
          #2 0x5d803e7 in apache::thrift::concurrency::PthreadThread::threadMain(void*) ./thrift/lib/cpp/concurrency/PosixThreadFactory.cpp:200
          #3 0x619739d in __tsan_thread_start_func crtstuff.c:?
      
        Previous write of size 1 at 0x7b5800000c29 by thread T315:
          #0 0x60b33e4 in folly::Codel::overloaded(std::chrono::duration<long, std::ratio<1l, 1000000000l> >) ??:?
          #1 0x5c1222 in apache::thrift::concurrency::ThreadManager::ImplT<folly::LifoSemImpl<std::atomic, folly::Baton<std::atomic, true, true> > >::Worker<folly::LifoSemImpl<std::atomic, folly::Baton<std::atomic, true, true> > >::run() ./thrift/lib/cpp/concurrency/ThreadManager.tcc:119
          #2 0x5d803e7 in apache::thrift::concurrency::PthreadThread::threadMain(void*) ./thrift/lib/cpp/concurrency/PosixThreadFactory.cpp:200
          #3 0x619739d in __tsan_thread_start_func crtstuff.c:?
      
        Location is heap block of size 768 at 0x7b5800000c00 allocated by main thread:
          #0 0x616ab83 in operator new(unsigned long) ??:?
          #1 0x53cb92 in __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<apache::thrift::concurrency::SimpleThreadManager<folly::LifoSemImpl<std::atomic, folly::Baton<std::atomic, true, true> > >, std::allocator<apache::thrift::concurrency::SimpleThreadManager<folly::LifoSemImpl<std::atomic, folly::Baton<std::atomic, true, true> > > >, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*)
          ...
      ```
      
      It looks like there are multiple threads reading and writing the `overloaded_` bool. To fix it, wrap it in a `std::atomic`.
      
      Reviewed By: yfeldblum, meyering
      
      Differential Revision: D6149766
      
      fbshipit-source-id: 605b29fa2f602d2ed2dfc22e46b739ef169f914e
      9fb1f368
  7. 25 Oct, 2017 4 commits
    • Luca Niccolini's avatar
      rework reads/writes · d4f016d5
      Luca Niccolini authored
      Summary:
      the current implementation had problems with scheduling reads and writes and
      it would sometimes get stuck when transfering large chunks of data
      
      here I am restructuring the code to look more like the one in HTTPSession
      
      session flow control is not implemented yet really, it's coming next
      
      Depends on: D6048238
      
      Reviewed By: afrind
      
      Differential Revision: D6048238
      
      fbshipit-source-id: ae601e771154a7f1a669a58a6e05c9e3720e7017
      d4f016d5
    • Marko Novakovic's avatar
      Supply an explicit default dtor impl · 43200974
      Marko Novakovic authored
      Reviewed By: yfeldblum
      
      Differential Revision: D6142252
      
      fbshipit-source-id: 9ac98585a92299ca5915982c65c7d2cfa68bf60f
      43200974
    • Yedidya Feldblum's avatar
      Flesh out Optional members swap, reset, emplace, has_value · 2ca10eee
      Yedidya Feldblum authored
      Summary:
      [Folly] Flesh out `Optional` members `swap`, `reset`, `emplace`, `has_value`.
      
      * `swap` as a member and deriving `noexcept`-ness to mimic `std::optional::swap`.
      * `reset` v.s. `clear` to mimic `std::optional::reset`.
      * `emplace` returning ref and overload taking initializer list to mimic `std::optional::emplace`.
      * `has_value` v.s. `hasValue` to mimic `std::optional::has_value`.
      
      Reviewed By: WillerZ
      
      Differential Revision: D6132775
      
      fbshipit-source-id: 34c58367b9dc63289e4b9721c5e79b1c41ba31e4
      2ca10eee
    • Yedidya Feldblum's avatar
      Simplify IsUniquePtrToSL in IOBuf.h · 2f5439e4
      Yedidya Feldblum authored
      Summary: [Folly] Simplify `IsUniquePtrToSL` in `IOBuf.h`.
      
      Reviewed By: Orvid
      
      Differential Revision: D6131231
      
      fbshipit-source-id: b054ef7ef9f313943a3ac1022ca6a23874a464df
      2f5439e4
  8. 24 Oct, 2017 4 commits
  9. 23 Oct, 2017 7 commits
    • Christopher Dykes's avatar
      Modernize uses of std::make_shared · d21f7165
      Christopher Dykes authored
      Summary: Via the modernize-make-shared from clang-tidy
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6129464
      
      fbshipit-source-id: 04f560c6beeb2b8631b819fd4e6a2d51b37eeb4b
      d21f7165
    • Lee Howes's avatar
      Add a full drain for folly's ManualExecutor. · e65a4541
      Lee Howes authored
      Summary: ManualExecutor::run() is stable, which means that in cases where we want to fully drain the executor we have to loop over it. This adds ManualExecutor::drain() which does that internally.
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6126840
      
      fbshipit-source-id: e36cba5c373a57fe01de244977ec852636b58dbd
      e65a4541
    • James Sedgwick's avatar
      move Iterator, Enumerate, EvictingCacheMap, Foreach, Merge, and · 6cc78c35
      James Sedgwick authored
      Summary: this is all non-hphp includes that are going in container/
      
      Reviewed By: mzlee, yfeldblum
      
      Differential Revision: D6121745
      
      fbshipit-source-id: b024bde8835fc7f332686793d75eb8e71591c912
      6cc78c35
    • Qi Wang's avatar
      MemoryIdler: use mallctl directly for tcache.flush · 12361241
      Qi Wang authored
      Summary:
      tcache.flush may fail if tcache is disabled.  Avoid using mallctlCall
      which throws on error.
      
      Reviewed By: davidtgoldblatt
      
      Differential Revision: D6115419
      
      fbshipit-source-id: 39411c80af08dc7c855efd43297809b749f935bf
      12361241
    • Christopher Dykes's avatar
      Modernize use of std::make_unique · 5bb0e1da
      Christopher Dykes authored
      Summary: Via the clang-tidy check modernize-make-unique.
      
      Reviewed By: yfeldblum
      
      Differential Revision: D6107790
      
      fbshipit-source-id: 1cf186feae511cbd91f44893059737a85778b6cf
      5bb0e1da
    • Jon Maltiel Swenson's avatar
      Rename unique_lock variables in `TimedMutex` in order to avoid shadowing · a9ade34f
      Jon Maltiel Swenson authored
      Summary: Rename `std::unique_lock` variables named `lock` to `ulock` in `folly::fibers::TimedMutex` member functions in order to avoid shadowing.
      
      Reviewed By: andreazevedo
      
      Differential Revision: D6123449
      
      fbshipit-source-id: 5fa331bb1541ac995d9b69360ee09923c14f6698
      a9ade34f
    • Andrew Krieger's avatar
      Gate std::invoke_result et. al. to appropriate MSVC versions. · 6d012519
      Andrew Krieger authored
      Summary: Only available in >= 2017 15.3, which is 1911+.
      
      Reviewed By: aary, Orvid
      
      Differential Revision: D6117237
      
      fbshipit-source-id: 255804af5bfd0c743fd225b8a4fddf3cfc9cfeaf
      6d012519