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 fOwner->fUseCount++; 40 } 41 42 43 LockInfo::~LockInfo() 44 { 45 fOwner->fUseCount--; 46 } 47 48 49 bool 50 LockInfo::operator==(const struct flock& lock) const 51 { 52 bool eof = lock.l_len + lock.l_start == OFF_MAX; 53 uint64 start = static_cast<uint64>(lock.l_start); 54 uint64 len = static_cast<uint64>(lock.l_len); 55 56 return fStart == start && (fLength == len 57 || (eof && fLength == UINT64_MAX)); 58 } 59 60 61 bool 62 LockInfo::operator==(const LockInfo& lock) const 63 { 64 return fOwner == lock.fOwner && fStart == lock.fStart 65 && fLength == lock.fLength && fType == lock.fType; 66 } 67 68 69 Cookie::Cookie() 70 : 71 fRequests(NULL), 72 fSnoozeCancel(create_sem(1, NULL)) 73 { 74 acquire_sem(fSnoozeCancel); 75 mutex_init(&fRequestLock, NULL); 76 } 77 78 79 Cookie::~Cookie() 80 { 81 delete_sem(fSnoozeCancel); 82 mutex_destroy(&fRequestLock); 83 } 84 85 86 status_t 87 Cookie::RegisterRequest(RPC::Request* req) 88 { 89 RequestEntry* ent = new RequestEntry; 90 if (ent == NULL) 91 return B_NO_MEMORY; 92 93 MutexLocker _(fRequestLock); 94 ent->fRequest = req; 95 ent->fNext = fRequests; 96 fRequests = ent; 97 98 return B_OK; 99 } 100 101 102 status_t 103 Cookie::UnregisterRequest(RPC::Request* req) 104 { 105 MutexLocker _(fRequestLock); 106 RequestEntry* ent = fRequests; 107 RequestEntry* prev = NULL; 108 while (ent != NULL) { 109 if (ent->fRequest == req) { 110 if (prev == NULL) 111 fRequests = ent->fNext; 112 else 113 prev->fNext = ent->fNext; 114 delete ent; 115 } 116 117 prev = ent; 118 ent = ent->fNext; 119 } 120 121 return B_OK; 122 } 123 124 125 status_t 126 Cookie::CancelAll() 127 { 128 release_sem(fSnoozeCancel); 129 130 MutexLocker _(fRequestLock); 131 RequestEntry* ent = fRequests; 132 while (ent != NULL) { 133 fFileSystem->Server()->WakeCall(ent->fRequest); 134 ent = ent->fNext; 135 } 136 137 return B_OK; 138 } 139 140 141 OpenFileCookie::OpenFileCookie() 142 : 143 fLocks(NULL) 144 { 145 } 146 147 148 void 149 OpenFileCookie::AddLock(LockInfo* lock) 150 { 151 lock->fCookieNext = fLocks; 152 fLocks = lock; 153 } 154 155 156 void 157 OpenFileCookie::RemoveLock(LockInfo* lock, LockInfo* prev) 158 { 159 if (prev != NULL) 160 prev->fCookieNext = lock->fCookieNext; 161 else 162 fLocks = lock->fCookieNext; 163 } 164 165 166 OpenDirCookie::~OpenDirCookie() 167 { 168 if (fSnapshot != NULL) 169 fSnapshot->ReleaseReference(); 170 } 171 172