110b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier//===----------------------------------------------------------------------===//
210b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier//
310b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier//                     The LLVM Compiler Infrastructure
410b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier//
510b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
610b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier// Source Licenses. See LICENSE.TXT for details.
710b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier//
810b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier//===----------------------------------------------------------------------===//
910b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier//
1010b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier// UNSUPPORTED: libcpp-has-no-threads
1110b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier// UNSUPPORTED: c++98, c++03
1210b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
1310b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier// <mutex>
1410b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
1510b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier// template <class ...Mutex> class lock_guard;
1610b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
1710b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier// lock_guard(Mutex&..., adopt_lock_t);
1810b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
19bca6de0e4edf5de16fad3566645db68966fede58Eric Fiselier// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
2010b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
2110b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier#include <mutex>
2210b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier#include <cassert>
2310b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
2410b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselierstruct TestMutex {
2510b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    bool locked = false;
2610b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    TestMutex() = default;
2710b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
2810b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    void lock() { assert(!locked); locked = true; }
29c6fcb58914a95b8f552d8c12ad9081aef9c50b05Eric Fiselier    bool try_lock() { if (locked) return false; locked = true; return true; }
3010b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    void unlock() { assert(locked); locked = false; }
3110b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
3210b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    TestMutex(TestMutex const&) = delete;
3310b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    TestMutex& operator=(TestMutex const&) = delete;
3410b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier};
3510b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
3610b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselierint main()
3710b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier{
3810b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    {
3910b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        using LG = std::lock_guard<>;
4010b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        LG lg(std::adopt_lock);
4110b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    }
4210b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    {
4310b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        TestMutex m1, m2;
4410b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        using LG = std::lock_guard<TestMutex, TestMutex>;
4510b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        m1.lock(); m2.lock();
4610b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        {
4710b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier            LG lg(m1, m2, std::adopt_lock);
4810b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier            assert(m1.locked && m2.locked);
4910b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        }
5010b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        assert(!m1.locked && !m2.locked);
5110b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    }
5210b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    {
5310b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        TestMutex m1, m2, m3;
5410b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>;
5510b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        m1.lock(); m2.lock(); m3.lock();
5610b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        {
5710b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier            LG lg(m1, m2, m3, std::adopt_lock);
5810b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier            assert(m1.locked && m2.locked && m3.locked);
5910b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        }
6010b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier        assert(!m1.locked && !m2.locked && !m3.locked);
6110b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier    }
6210b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier
6310b52a0e56cf48387129ac5cf862db80c876ec58Eric Fiselier}
64