1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
//
// FileStreamRWLock.h
//
// Library: Foundation
// Package: Processes
// Module: FileStreamRWLock
//
// Definition of the FileStreamRWLock class.
//
// Copyright (c) 2004-2024, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_FileStreamRWLock_INCLUDED
#define Foundation_FileStreamRWLock_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Exception.h"
#include "Poco/FileStream.h"
#include <atomic>
#if defined(POCO_OS_FAMILY_WINDOWS)
#include "Poco/FileStreamRWLock_WIN32.h"
#else
#include "Poco/FileStreamRWLock_POSIX.h"
#endif
namespace Poco {
class ScopedFStreamRWLock;
class ScopedFStreamReadRWLock;
class ScopedFStreamWriteRWLock;
class Foundation_API FileStreamRWLock: private FileStreamRWLockImpl
/// A reader writer lock on the file region allows multiple concurrent
/// process-readers or one exclusive process-writer.
{
public:
using ScopedLock = ScopedFStreamRWLock;
using ScopedReadLock = ScopedFStreamReadRWLock;
using ScopedWriteLock = ScopedFStreamWriteRWLock;
FileStreamRWLock(const FileStream &fs, Poco::UInt64 offset, Poco::UInt64 size);
/// Creates the Reader/Writer lock on the file region.
/// offset - from start of the file
/// size - size of the locker region
~FileStreamRWLock();
/// Destroys the Reader/Writer lock on the file region.
void readLock();
/// Acquires a read lock. If another process currently holds a write lock,
/// waits until the write lock is released.
bool tryReadLock();
/// Tries to acquire a read lock. Immediately returns true if successful, or
/// false if another process currently holds a write lock.
void writeLock();
/// Acquires a write lock on the file region. If one or more other processes currently hold
/// locks, waits until all locks are released.
bool tryWriteLock();
/// Tries to acquire a write lock on the file region. Immediately returns true if successful,
/// or false if one or more other processes currently hold
/// locks.
void unlock();
/// Releases the read or write lock.
private:
std::atomic_bool _locked = false;
FileStreamRWLock(const FileStreamRWLock&);
FileStreamRWLock& operator = (const FileStreamRWLock&);
};
class Foundation_API ScopedFStreamRWLock
/// A variant of ScopedLock for reader/writer locks.
{
public:
ScopedFStreamRWLock(FileStreamRWLock& rwl, bool write = false);
~ScopedFStreamRWLock();
private:
FileStreamRWLock& _rwl;
ScopedFStreamRWLock();
ScopedFStreamRWLock(const ScopedFStreamRWLock&);
ScopedFStreamRWLock& operator = (const ScopedFStreamRWLock&);
};
class Foundation_API ScopedFStreamReadRWLock : public ScopedFStreamRWLock
/// A variant of ScopedLock for reader locks.
{
public:
ScopedFStreamReadRWLock(FileStreamRWLock& rwl);
~ScopedFStreamReadRWLock();
};
class Foundation_API ScopedFStreamWriteRWLock : public ScopedFStreamRWLock
/// A variant of ScopedLock for writer locks.
{
public:
ScopedFStreamWriteRWLock(FileStreamRWLock& rwl);
~ScopedFStreamWriteRWLock();
};
//
// inlines
//
inline void FileStreamRWLock::readLock()
{
readLockImpl();
_locked = true;
}
inline bool FileStreamRWLock::tryReadLock()
{
bool locked = tryReadLockImpl();
if (locked) _locked = true; // assign only if success lock
return locked;
}
inline void FileStreamRWLock::writeLock()
{
writeLockImpl();
_locked = true;
}
inline bool FileStreamRWLock::tryWriteLock()
{
bool locked = tryWriteLockImpl();
if (locked) _locked = true; // assign only if success lock
return locked;
}
inline void FileStreamRWLock::unlock()
{
unlockImpl();
_locked = false;
}
inline ScopedFStreamRWLock::ScopedFStreamRWLock(FileStreamRWLock& rwl, bool write): _rwl(rwl)
{
if (write)
_rwl.writeLock();
else
_rwl.readLock();
}
inline ScopedFStreamRWLock::~ScopedFStreamRWLock()
{
try
{
_rwl.unlock();
}
catch (...)
{
poco_unexpected();
}
}
inline ScopedFStreamReadRWLock::ScopedFStreamReadRWLock(FileStreamRWLock& rwl): ScopedFStreamRWLock(rwl, false)
{
}
inline ScopedFStreamReadRWLock::~ScopedFStreamReadRWLock()
{
}
inline ScopedFStreamWriteRWLock::ScopedFStreamWriteRWLock(FileStreamRWLock& rwl): ScopedFStreamRWLock(rwl, true)
{
}
inline ScopedFStreamWriteRWLock::~ScopedFStreamWriteRWLock()
{
}
} // namespace Poco
#endif // Foundation_FileStreamRWLock_INCLUDED
|