1/*
2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Paweł Dziepak, pdziepak@quarnos.org
7 */
8
9
10#include "Cookie.h"
11
12#include "Inode.h"
13#include "Request.h"
14
15
16LockOwner::LockOwner(uint32 owner)
17	:
18	fSequence(0),
19	fOwner(owner),
20	fUseCount(0),
21	fNext(NULL),
22	fPrev(NULL)
23{
24	memset(fStateId, 0, sizeof(fStateId));
25	mutex_init(&fLock, NULL);
26}
27
28
29LockOwner::~LockOwner()
30{
31	mutex_destroy(&fLock);
32}
33
34
35LockInfo::LockInfo(LockOwner* owner)
36	:
37	fOwner(owner)
38{
39	ASSERT(owner != NULL);
40	fOwner->fUseCount++;
41}
42
43
44LockInfo::~LockInfo()
45{
46	fOwner->fUseCount--;
47}
48
49
50bool
51LockInfo::operator==(const struct flock& lock) const
52{
53	bool eof = lock.l_len + lock.l_start == OFF_MAX;
54	uint64 start = static_cast<uint64>(lock.l_start);
55	uint64 length = static_cast<uint64>(lock.l_len);
56
57	return fStart == start && (fLength == length
58		|| (eof && fLength == UINT64_MAX));
59}
60
61
62bool
63LockInfo::operator==(const LockInfo& lock) const
64{
65	return fOwner == lock.fOwner && fStart == lock.fStart
66		&& fLength == lock.fLength && fType == lock.fType;
67}
68
69
70Cookie::Cookie(FileSystem* fileSystem)
71	:
72	fFileSystem(fileSystem),
73	fRequests(NULL),
74	fSnoozeCancel(create_sem(1, NULL))
75{
76	acquire_sem(fSnoozeCancel);
77	mutex_init(&fRequestLock, NULL);
78}
79
80
81Cookie::~Cookie()
82{
83	delete_sem(fSnoozeCancel);
84	mutex_destroy(&fRequestLock);
85}
86
87
88status_t
89Cookie::RegisterRequest(RPC::Request* request)
90{
91	ASSERT(request != NULL);
92
93	RequestEntry* entry = new RequestEntry;
94	if (entry == NULL)
95		return B_NO_MEMORY;
96
97	MutexLocker _(fRequestLock);
98	entry->fRequest = request;
99	entry->fNext = fRequests;
100	fRequests = entry;
101
102	return B_OK;
103}
104
105
106status_t
107Cookie::UnregisterRequest(RPC::Request* request)
108{
109	ASSERT(request != NULL);
110
111	MutexLocker _(fRequestLock);
112	RequestEntry* entry = fRequests;
113	RequestEntry* previous = NULL;
114	while (entry != NULL) {
115		if (entry->fRequest == request) {
116			if (previous == NULL)
117				fRequests = entry->fNext;
118			else
119				previous->fNext = entry->fNext;
120			delete entry;
121			break;
122		}
123
124		previous = entry;
125		entry = entry->fNext;
126	}
127
128	return B_OK;
129}
130
131
132status_t
133Cookie::CancelAll()
134{
135	release_sem(fSnoozeCancel);
136
137	MutexLocker _(fRequestLock);
138	RequestEntry* entry = fRequests;
139	while (entry != NULL) {
140		fFileSystem->Server()->WakeCall(entry->fRequest);
141		entry = entry->fNext;
142	}
143
144	return B_OK;
145}
146
147
148OpenStateCookie::OpenStateCookie(FileSystem* fileSystem)
149	:
150	Cookie(fileSystem)
151{
152}
153
154
155OpenFileCookie::OpenFileCookie(FileSystem* fileSystem)
156	:
157	OpenStateCookie(fileSystem),
158	fLocks(NULL)
159{
160}
161
162
163void
164OpenFileCookie::AddLock(LockInfo* lock)
165{
166	ASSERT(lock != NULL);
167
168	lock->fCookieNext = fLocks;
169	fLocks = lock;
170}
171
172
173void
174OpenFileCookie::RemoveLock(LockInfo* lock, LockInfo* previous)
175{
176	if (previous != NULL)
177		previous->fCookieNext = lock->fCookieNext;
178	else {
179		ASSERT(previous == NULL && fLocks == lock);
180		fLocks = lock->fCookieNext;
181	}
182}
183
184
185OpenDirCookie::OpenDirCookie(FileSystem* fileSystem)
186	:
187	Cookie(fileSystem),
188	fSnapshot(NULL)
189{
190}
191
192
193OpenDirCookie::~OpenDirCookie()
194{
195	if (fSnapshot != NULL)
196		fSnapshot->ReleaseReference();
197}
198
199
200OpenAttrCookie::OpenAttrCookie(FileSystem* fileSystem)
201	:
202	OpenStateCookie(fileSystem)
203{
204}
205
206