File: FileStreamRWLock_WIN32.h

package info (click to toggle)
poco 1.14.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 56,460 kB
  • sloc: cpp: 340,542; ansic: 245,601; makefile: 1,742; yacc: 1,005; sh: 698; sql: 312; lex: 282; xml: 128; perl: 29; python: 24
file content (134 lines) | stat: -rw-r--r-- 2,860 bytes parent folder | download
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
//
// FileStreamRWLock_WIN32.h
//
// Library: Foundation
// Package: Processes
// Module:  FileStreamRWLock
//
// Definition of the FileStreamRWLockImpl class for WIN32 FileStream.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier:	BSL-1.0
//


#ifndef Foundation_FileStreamRWLock_WIN32_INCLUDED
#define Foundation_FileStreamRWLock_WIN32_INCLUDED


#include "Poco/Foundation.h"
#include "Poco/Exception.h"
#include "Poco/FileStream.h"
#include <Windows.h>

namespace Poco {

struct LockMode
{
	static constexpr DWORD READ = 0;
	static constexpr DWORD WRITE = LOCKFILE_EXCLUSIVE_LOCK;
	static constexpr DWORD TRY_READ = LOCKFILE_FAIL_IMMEDIATELY;
	static constexpr DWORD TRY_WRITE = (LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY);
};

class Foundation_API FileStreamRWLockImpl
{
protected:
	FileStreamRWLockImpl(const FileStream::NativeHandle &fd, Poco::UInt64 offset, Poco::UInt64 size);
	~FileStreamRWLockImpl();
	void readLockImpl();
	bool tryReadLockImpl();
	void writeLockImpl();
	bool tryWriteLockImpl();
	void unlockImpl();

private:
	FileStream::NativeHandle _fd;
	OVERLAPPED _overlapped;
	LARGE_INTEGER _size;
};


//
// inlines
//
inline void FileStreamRWLockImpl::readLockImpl()
{
	BOOL fSuccess = LockFileEx(_fd, LockMode::READ, 0, _size.LowPart, _size.HighPart, &_overlapped);
	if (!fSuccess)
	{
		throw SystemException("cannot lock reader lock", GetLastError());
	}
}


inline bool FileStreamRWLockImpl::tryReadLockImpl()
{
	BOOL fSuccess = LockFileEx(_fd, LockMode::TRY_READ, 0, _size.LowPart, _size.HighPart, &_overlapped);
	if (fSuccess)
	{
		return true;
	}
	else
	{
		auto lastError = GetLastError();
		if (lastError == ERROR_IO_PENDING || lastError == ERROR_LOCK_VIOLATION)
		{
			return false;
		}
		else
		{
			throw SystemException("cannot lock try-reader lock", lastError);
		}
	}
}


inline void FileStreamRWLockImpl::writeLockImpl()
{
	BOOL fSuccess = LockFileEx(_fd, LockMode::WRITE, 0, _size.LowPart, _size.HighPart, &_overlapped);
	if (!fSuccess)
	{
		throw SystemException("cannot lock writer lock", GetLastError());
	}
}


inline bool FileStreamRWLockImpl::tryWriteLockImpl()
{
	BOOL fSuccess = LockFileEx(_fd, LockMode::TRY_WRITE, 0, _size.LowPart, _size.HighPart, &_overlapped);
	if (fSuccess)
	{
		return true;
	}
	else 
	{
		auto lastError = GetLastError();
		if (lastError == ERROR_IO_PENDING || lastError == ERROR_LOCK_VIOLATION)
		{
			return false;
		}
		else
		{
			throw SystemException("cannot lock try-writer lock", lastError);
		}
	}
}


inline void FileStreamRWLockImpl::unlockImpl()
{
	BOOL fSuccess = UnlockFileEx(_fd, 0, _size.LowPart, _size.HighPart, &_overlapped);
	if (!fSuccess)
	{
		throw SystemException("cannot unlock ", GetLastError());
	}
}


} // namespace Poco


#endif // Foundation_FileStreamRWLock_WIN32_INCLUDED