Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A reader writer lock on the file region #4723

Closed
wants to merge 11 commits into from

Conversation

bas524
Copy link
Contributor

@bas524 bas524 commented Oct 3, 2024

This PR contains implementation of RWLock on the file descriptor
It allows multiple concurrent process-readers or one exclusive process-writer on the file region

example

// open file for reading and writing
FileStream fs(filepath, std::ios::in | std::ios::out | std::ios::binary);
// write some information
Poco::Int32 i32 = 0;
fs.seekp(0, std::ios::beg);
fs.write((const char *)&i32, sizeof(i32));
fs.flushToDisk();
//...
// other process-reader
FileStreamRWLock fLock(fs, 0, sizeof(Poco::Int32));
ScopedFStreamReadRWLock readLock(fLock);
fs.seekg(0, std::ios::beg);
fs.read((char *)&counter, sizeof(counter));

//...
// other process-writer
FileStreamRWLock fLock(fs, 0, sizeof(Poco::Int32));
ScopedFStreamWriteRWLock writeLock(fLock);
fs.seekp(0, std::ios::beg);
fs.write((char *)&counter, sizeof(counter));
fs.flushToDisk();

!Warning
On windows you should open file by WINAPI and then use handle with poco, because Poco::FileStream doesn't open or create file with FILE_SHARE_READ | FILE_SHARE_WRITE and GENERIC_READ | GENERIC_WRITE

You can do it with this code

HANDLE openFileWithRWAccess(const std::string& path)
{
	DWORD access = GENERIC_READ | GENERIC_WRITE;
	DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;

	HANDLE handle = CreateFileA(path.c_str(), access, shareMode, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	if (handle == INVALID_HANDLE_VALUE)
		Poco::File::handleLastError(path);

	return handle;
}

and then

FileStream fs;
fs.openHandle(openFileForSahredRWAccess(fl), std::ios::in | std::ios::out | std::ios::binary);

#if defined(POCO_OS_FAMILY_WINDOWS)
#include "FileStreamRWLock_WIN32.cpp"
#else
#include "FileStreamRWLock_POSIX.cpp"

Check notice

Code scanning / CodeQL

Include header files only

The #include pre-processor directive should only be used to include header files.
add atomic_bool _locked and check if FileStreamRWLock is locked on
destruction for force unlock
@aleks-f aleks-f requested review from matejk and removed request for matejk October 14, 2024 11:14
@aleks-f
Copy link
Member

aleks-f commented Oct 14, 2024

@bas524 wasn't triggering al CI, moved to #4734

@aleks-f aleks-f closed this Oct 14, 2024
aleks-f added a commit that referenced this pull request Oct 16, 2024
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants