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 16 LockOwner::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 29 LockOwner::~LockOwner() 30 { 31 mutex_destroy(&fLock); 32 } 33 34 35 LockInfo::LockInfo(LockOwner* owner) 36 : 37 fOwner(owner) 38 { 39 ASSERT(owner != NULL); 40 fOwner->fUseCount++; 41 } 42 43 44 LockInfo::~LockInfo() 45 { 46 fOwner->fUseCount--; 47 } 48 49 50 bool 51 LockInfo::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 62 bool 63 LockInfo::operator==(const LockInfo& lock) const 64 { 65 return fOwner == lock.fOwner && fStart == lock.fStart 66 && fLength == lock.fLength && fType == lock.fType; 67 } 68 69 70 Cookie::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 81 Cookie::~Cookie() 82 { 83 delete_sem(fSnoozeCancel); 84 mutex_destroy(&fRequestLock); 85 } 86 87 88 status_t 89 Cookie::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 106 status_t 107 Cookie::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 132 status_t 133 Cookie::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 148 OpenStateCookie::OpenStateCookie(FileSystem* fileSystem) 149 : 150 Cookie(fileSystem) 151 { 152 } 153 154 155 OpenFileCookie::OpenFileCookie(FileSystem* fileSystem) 156 : 157 OpenStateCookie(fileSystem), 158 fLocks(NULL) 159 { 160 } 161 162 163 void 164 OpenFileCookie::AddLock(LockInfo* lock) 165 { 166 ASSERT(lock != NULL); 167 168 lock->fCookieNext = fLocks; 169 fLocks = lock; 170 } 171 172 173 void 174 OpenFileCookie::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 185 OpenDirCookie::OpenDirCookie(FileSystem* fileSystem) 186 : 187 Cookie(fileSystem), 188 fSnapshot(NULL) 189 { 190 } 191 192 193 OpenDirCookie::~OpenDirCookie() 194 { 195 if (fSnapshot != NULL) 196 fSnapshot->ReleaseReference(); 197 } 198 199 200 OpenAttrCookie::OpenAttrCookie(FileSystem* fileSystem) 201 : 202 OpenStateCookie(fileSystem) 203 { 204 } 205 206