Skip to content

File lock#4734

Merged
aleks-f merged 13 commits intomainfrom
file-lock
Oct 16, 2024
Merged

File lock#4734
aleks-f merged 13 commits intomainfrom
file-lock

Conversation

@aleks-f
Copy link
Copy Markdown
Member

@aleks-f aleks-f commented Oct 14, 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);

@aleks-f
Copy link
Copy Markdown
Member Author

aleks-f commented Oct 14, 2024

@bas524 there is a problem with windows cmake build in CI:

D:\a\poco\poco\Foundation\testsuite\src\TestApp.cpp(267,19): error C3861: 'openFileForSahredRWAccess': identifier not found [D:\a\poco\poco\cmake-build\Foundation\testsuite\TestApp.vcxproj]
D:\a\poco\poco\Foundation\testsuite\src\TestApp.cpp(339,19): error C3861: 'openFileForSahredRWAccess': identifier not found [D:\a\poco\poco\cmake-build\Foundation\testsuite\TestApp.vcxproj]

Copy link
Copy Markdown
Contributor

@matejk matejk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few observations from my side.

@aleks-f
Copy link
Copy Markdown
Member Author

aleks-f commented Oct 15, 2024

@bas524 if you want this in 1.14, please resolve the outstanding issues this week

@bas524
Copy link
Copy Markdown
Contributor

bas524 commented Oct 16, 2024

@bas524 if you want this in 1.14, please resolve the outstanding issues this week

Please re-run PR, I did my work in the #4740

* throw error on any errno not only on EDEADLK

* fix function naming

* fix windows build

* fix windows build
@aleks-f aleks-f added this to the Release 1.14.0 milestone Oct 16, 2024
@aleks-f aleks-f merged commit e5752a5 into main Oct 16, 2024
@aleks-f aleks-f deleted the file-lock branch October 16, 2024 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants