1 #include "filelocks.h"
2 
3 #include <utility>
4 
5 #include "lockable.h"
6 #include "meta.h"
7 
8 using namespace std;
9 
10 namespace acng
11 {
12 base_with_condition g_mmapLocksMx;
13 
14 decltype(TFileShrinkGuard::g_mmapLocks) TFileShrinkGuard::g_mmapLocks;
15 
16 // little helper to exclude competing mmap and file shrinking operations
~TFileShrinkGuard()17 TFileShrinkGuard::~TFileShrinkGuard()
18 {
19 	lockguard g(g_mmapLocksMx);
20 	g_mmapLocks.erase(m_it);
21 	g_mmapLocksMx.notifyAll();
22 }
23 
Acquire(const struct stat & info)24 unique_ptr<TFileShrinkGuard> TFileShrinkGuard::Acquire(const struct stat& info)
25 {
26 	lockuniq g(g_mmapLocksMx);
27 	while(true) {
28 #ifdef COMPATGCC47
29 		auto res = g_mmapLocks.insert(make_pair(info.st_dev, info.st_ino));
30 #else
31 		auto res = g_mmapLocks.emplace(info.st_dev, info.st_ino);
32 #endif
33 		if(res.second) // true if freshly inserted, false if there was an entry already
34 		{
35 			auto ret = new TFileShrinkGuard();
36 			ret->m_it = res.first;
37 			return unique_ptr<TFileShrinkGuard>(ret);
38 		}
39 		g_mmapLocksMx.wait(g);
40 	}
41 }
42 
43 }
44