Skip to content

A reader writer lock on the file region#4723

Closed
bas524 wants to merge 11 commits intopocoproject:mainfrom
bas524:file-lock
Closed

A reader writer lock on the file region#4723
bas524 wants to merge 11 commits intopocoproject:mainfrom
bas524:file-lock

Conversation

@bas524
Copy link
Copy Markdown
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
Copy Markdown
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