Ticket #9058: with_lock_guard.hpp

File with_lock_guard.hpp, 2.8 KB (added by ruslan_baratov@…, 9 years ago)

implementation

Line 
1// (C) Copyright 2013 Ruslan Baratov
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6// See www.boost.org/libs/thread for documentation.
7
8#ifndef BOOST_THREAD_WITH_LOCK_GUARD_HPP
9#define BOOST_THREAD_WITH_LOCK_GUARD_HPP
10
11#include <boost/thread/lock_guard.hpp>
12#include <boost/utility/result_of.hpp>
13
14namespace boost {
15
16#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
17
18/**
19 * Utility to run functions in scope protected by mutex.
20 *
21 * Examples:
22 *
23 * int func(int, int&);
24 * boost::mutex m;
25 * int a;
26 * int result = boost::with_scoped_lock(m, func, 1, boost::ref(a));
27 *
28 * // using boost::bind
29 * int result = boost::with_scoped_lock(
30 * m, boost::bind(func, 2, boost::ref(a))
31 * );
32 *
33 * // using lambda
34 * int a;
35 * int result = boost::with_scoped_lock(
36 * m,
37 * [&a](int x) {
38 * a = 3;
39 * return x + 4;
40 * },
41 * 5
42 * );
43 */
44template <class Lockable, class Function, class... Args>
45auto with_lock_guard(
46 Lockable& m,
47 BOOST_FWD_REF(Function) f,
48 BOOST_FWD_REF(Args)... args
49) -> decltype(f(boost::forward<Args>(args)...)) {
50 boost::lock_guard<Lockable> lock(m);
51 return f(boost::forward<Args>(args)...);
52}
53
54#else
55
56// Workaround versions for compilers without c++11 support.
57// (function arguments limit: 4, no lambda support)
58
59template <class Lockable, class Func>
60typename boost::result_of<Func()>::type with_lock_guard(
61 Lockable& m,
62 Func func
63) {
64 boost::lock_guard<Lockable> lock(m);
65 return func();
66}
67
68template <class Lockable, class Func, class Arg>
69typename boost::result_of<Func(Arg)>::type with_lock_guard(
70 Lockable& m,
71 Func func,
72 Arg arg
73) {
74 boost::lock_guard<Lockable> lock(m);
75 return func(arg);
76}
77
78template <class Lockable, class Func, class Arg1, class Arg2>
79typename boost::result_of<Func(Arg1, Arg2)>::type with_lock_guard(
80 Lockable& m,
81 Func func,
82 Arg1 arg1,
83 Arg2 arg2
84) {
85 boost::lock_guard<Lockable> lock(m);
86 return func(arg1, arg2);
87}
88
89template <class Lockable, class Func, class Arg1, class Arg2, class Arg3>
90typename boost::result_of<Func(Arg1, Arg2, Arg3)>::type with_lock_guard(
91 Lockable& m,
92 Func func,
93 Arg1 arg1,
94 Arg2 arg2,
95 Arg3 arg3
96) {
97 boost::lock_guard<Lockable> lock(m);
98 return func(arg1, arg2, arg3);
99}
100
101template <
102 class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
103>
104typename boost::result_of<Func(Arg1, Arg2, Arg3, Arg4)>::type with_lock_guard(
105 Lockable& m,
106 Func func,
107 Arg1 arg1,
108 Arg2 arg2,
109 Arg3 arg3,
110 Arg4 arg4
111) {
112 boost::lock_guard<Lockable> lock(m);
113 return func(arg1, arg2, arg3, arg4);
114}
115
116#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
117
118} // namespace boost
119
120#endif // BOOST_THREAD_WITH_LOCK_GUARD_HPP