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 len = static_cast<uint64>(lock.l_len); 56 57 return fStart == start && (fLength == len 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() 71 : 72 fRequests(NULL), 73 fSnoozeCancel(create_sem(1, NULL)) 74 { 75 acquire_sem(fSnoozeCancel); 76 mutex_init(&fRequestLock, NULL); 77 } 78 79 80 Cookie::~Cookie() 81 { 82 delete_sem(fSnoozeCancel); 83 mutex_destroy(&fRequestLock); 84 } 85 86 87 status_t 88 Cookie::RegisterRequest(RPC::Request* req) 89 { 90 ASSERT(req != NULL); 91 92 RequestEntry* ent = new RequestEntry; 93 if (ent == NULL) 94 return B_NO_MEMORY; 95 96 MutexLocker _(fRequestLock); 97 ent->fRequest = req; 98 ent->fNext = fRequests; 99 fRequests = ent; 100 101 return B_OK; 102 } 103 104 105 status_t 106 Cookie::UnregisterRequest(RPC::Request* req) 107 { 108 ASSERT(req != NULL); 109 110 MutexLocker _(fRequestLock); 111 RequestEntry* ent = fRequests; 112 RequestEntry* prev = NULL; 113 while (ent != NULL) { 114 if (ent->fRequest == req) { 115 if (prev == NULL) 116 fRequests = ent->fNext; 117 else 118 prev->fNext = ent->fNext; 119 delete ent; 120 break; 121 } 122 123 prev = ent; 124 ent = ent->fNext; 125 } 126 127 return B_OK; 128 } 129 130 131 status_t 132 Cookie::CancelAll() 133 { 134 release_sem(fSnoozeCancel); 135 136 MutexLocker _(fRequestLock); 137 RequestEntry* ent = fRequests; 138 while (ent != NULL) { 139 fFileSystem->Server()->WakeCall(ent->fRequest); 140 ent = ent->fNext; 141 } 142 143 return B_OK; 144 } 145 146 147 OpenFileCookie::OpenFileCookie() 148 : 149 fLocks(NULL) 150 { 151 } 152 153 154 void 155 OpenFileCookie::AddLock(LockInfo* lock) 156 { 157 ASSERT(lock != NULL); 158 159 lock->fCookieNext = fLocks; 160 fLocks = lock; 161 } 162 163 164 void 165 OpenFileCookie::RemoveLock(LockInfo* lock, LockInfo* prev) 166 { 167 if (prev != NULL) 168 prev->fCookieNext = lock->fCookieNext; 169 else { 170 ASSERT(prev == NULL && fLocks == lock); 171 fLocks = lock->fCookieNext; 172 } 173 } 174 175 176 OpenDirCookie::~OpenDirCookie() 177 { 178 if (fSnapshot != NULL) 179 fSnapshot->ReleaseReference(); 180 } 181 182