From 3d435cc9688b36ef887d9210bb0dd2f0eaab7750 Mon Sep 17 00:00:00 2001 From: Avi Kivity <avi.kivity@gmail.com> Date: Wed, 2 Jan 2013 20:42:10 +0200 Subject: [PATCH] mutex: add with_lock() function This function allows executing a block of code under a lock, with a guarantee that any exit from the block will release the lock. Examples: with_lock(my_mutex, [&] { a += b; }); return with_lock(my_spinlock, [&] { return my_list.size(); }); --- libc/fd.cc | 21 +++++++++++---------- mutex.hh | 9 +++++++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libc/fd.cc b/libc/fd.cc index 75c19c73b..6b3741ada 100644 --- a/libc/fd.cc +++ b/libc/fd.cc @@ -40,14 +40,15 @@ int open(const char* fname, int mode, ...) } auto desc = std::shared_ptr<file_desc>( new file_desc(f, mode & O_RDONLY, mode & O_WRONLY)); - std::lock_guard<mutex> guard(file_table_mutex); - auto p = std::find(file_table.begin(), file_table.end(), - std::shared_ptr<file_desc>()); - if (p == file_table.end()) { - file_table.push_back(desc); - p = file_table.end() - 1; - } else { - *p = desc; - } - return p - file_table.begin(); + return with_lock(file_table_mutex, [&] { + auto p = std::find(file_table.begin(), file_table.end(), + std::shared_ptr<file_desc>()); + if (p == file_table.end()) { + file_table.push_back(desc); + p = file_table.end() - 1; + } else { + *p = desc; + } + return p - file_table.begin(); + }); } diff --git a/mutex.hh b/mutex.hh index f28027602..4b3a1ab9d 100644 --- a/mutex.hh +++ b/mutex.hh @@ -1,6 +1,8 @@ #ifndef MUTEX_HH #define MUTEX_HH +#include <mutex> + class mutex { public: void lock(); @@ -8,4 +10,11 @@ public: void unlock(); }; +template <class Lock, class Func> +auto with_lock(Lock& lock, Func func) -> decltype(func()) +{ + std::lock_guard<Lock> guard(lock); + return func(); +} + #endif -- GitLab