poco/Foundation/include/Poco/FileStreamRWLock.h
Aleksandar Fabijanic e5752a5c6d
File lock (#4734)
* add RWLock implementation for file [posix]

* add implementation FileStreamRWLock for windows
replace FileStreamRWLock to the Process package

* add files FileStreamRWLock* into makefile and vcproj

* remove unnecessary file from makefile

* use absolute path to the TesApp with ProcessRunner

* fix vc*.proj

* add new test files into vc.proj.filters

* fix comments

* fix spelling fo PR #4723
add atomic_bool _locked and check if FileStreamRWLock is locked on
destruction for force unlock

* add atomic header

* File lock (#4740)

* throw error on any errno not only on EDEADLK

* fix function naming

* fix windows build

* fix windows build

---------

Co-authored-by: Alexander B <ale.bychuk@gmail.com>
Co-authored-by: bas524 <bas524@ya.ru>
2024-10-16 23:58:00 +02:00

205 lines
4.2 KiB
C++

//
// 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