2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/File.h>
21 #include <glog/logging.h>
22 #include <gtest/gtest.h>
23 #include <boost/thread/locks.hpp>
25 #include <folly/String.h>
26 #include <folly/Subprocess.h>
27 #include <folly/experimental/TestUtil.h>
28 #include <folly/experimental/io/FsUtil.h>
29 #include <folly/portability/GFlags.h>
31 using namespace folly;
32 using namespace folly::test;
34 DEFINE_bool(s, false, "get shared lock");
35 DEFINE_bool(x, false, "get exclusive lock");
38 typedef std::unique_lock<File> Lock;
39 typedef boost::shared_lock<File> SharedLock;
41 // Find out where we are.
42 static constexpr size_t pathLength = 2048;
43 char buf[pathLength + 1];
44 int r = readlink("/proc/self/exe", buf, pathLength);
49 auto helper_basename = "file_test_lock_helper";
51 if (fs::exists(me.parent_path() / helper_basename)) {
52 helper = me.parent_path() / helper_basename;
54 throw std::runtime_error(
55 folly::to<std::string>("cannot find helper ", helper_basename));
58 TemporaryFile tempFile;
59 File f(tempFile.fd());
61 enum LockMode { EXCLUSIVE, SHARED };
62 auto testLock = [&](LockMode mode, bool expectedSuccess) {
63 auto ret = Subprocess({helper.native(),
64 mode == SHARED ? "-s" : "-x",
65 tempFile.path().native()}).wait();
66 EXPECT_TRUE(ret.exited());
68 EXPECT_EQ(expectedSuccess ? 0 : 42, ret.exitStatus());
72 // Make sure nothing breaks and things compile.
75 { SharedLock lock(f); }
78 Lock lock(f, std::defer_lock);
79 EXPECT_TRUE(lock.try_lock());
83 SharedLock lock(f, boost::defer_lock);
84 EXPECT_TRUE(lock.try_lock());
90 testLock(EXCLUSIVE, false);
96 testLock(SHARED, false);
102 testLock(EXCLUSIVE, false);
105 // S does not block S
108 testLock(SHARED, true);