1 /* 2 * Copyright 2001-2011, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Erik Jaesler (erik@cgsoftware.com) 7 * Axel Dörfler, axeld@pinc-software.de 8 */ 9 10 11 #include <DirectMessageTarget.h> 12 #include <TokenSpace.h> 13 14 #include <Autolock.h> 15 16 17 namespace BPrivate { 18 19 BTokenSpace gDefaultTokens; 20 // the default token space - all handlers will go into that one 21 22 23 BTokenSpace::BTokenSpace() 24 : 25 BLocker("token space"), 26 fTokenCount(1) 27 { 28 } 29 30 31 BTokenSpace::~BTokenSpace() 32 { 33 } 34 35 36 int32 37 BTokenSpace::NewToken(int16 type, void* object) 38 { 39 BAutolock locker(this); 40 41 token_info tokenInfo = { type, object, NULL }; 42 int32 token = fTokenCount; 43 44 try { 45 fTokenMap[token] = tokenInfo; 46 } catch (std::bad_alloc& exception) { 47 return -1; 48 } 49 50 fTokenCount++; 51 52 return token; 53 } 54 55 56 /*! 57 Inserts the specified token into the token space. If that token 58 already exists, it will be overwritten. 59 Don't mix NewToken() and this method unless you know what you're 60 doing. 61 */ 62 bool 63 BTokenSpace::SetToken(int32 token, int16 type, void* object) 64 { 65 BAutolock locker(this); 66 67 token_info tokenInfo = { type, object, NULL }; 68 69 try { 70 fTokenMap[token] = tokenInfo; 71 } catch (std::bad_alloc& exception) { 72 return false; 73 } 74 75 // this makes sure SetToken() plays more or less nice with NewToken() 76 if (token >= fTokenCount) 77 fTokenCount = token + 1; 78 79 return true; 80 } 81 82 83 bool 84 BTokenSpace::RemoveToken(int32 token) 85 { 86 BAutolock locker(this); 87 88 TokenMap::iterator iterator = fTokenMap.find(token); 89 if (iterator == fTokenMap.end()) 90 return false; 91 92 fTokenMap.erase(iterator); 93 return true; 94 } 95 96 97 /*! Checks whether or not the \a token exists with the specified 98 \a type in the token space or not. 99 */ 100 bool 101 BTokenSpace::CheckToken(int32 token, int16 type) const 102 { 103 BAutolock locker(const_cast<BTokenSpace&>(*this)); 104 105 TokenMap::const_iterator iterator = fTokenMap.find(token); 106 if (iterator != fTokenMap.end() && iterator->second.type == type) 107 return true; 108 109 return false; 110 } 111 112 113 status_t 114 BTokenSpace::GetToken(int32 token, int16 type, void** _object) const 115 { 116 if (token < 1) 117 return B_ENTRY_NOT_FOUND; 118 119 BAutolock locker(const_cast<BTokenSpace&>(*this)); 120 121 TokenMap::const_iterator iterator = fTokenMap.find(token); 122 if (iterator == fTokenMap.end() || iterator->second.type != type) 123 return B_ENTRY_NOT_FOUND; 124 125 *_object = iterator->second.object; 126 return B_OK; 127 } 128 129 130 status_t 131 BTokenSpace::SetHandlerTarget(int32 token, BDirectMessageTarget* target) 132 { 133 if (token < 1) 134 return B_ENTRY_NOT_FOUND; 135 136 BAutolock locker(const_cast<BTokenSpace&>(*this)); 137 138 TokenMap::iterator iterator = fTokenMap.find(token); 139 if (iterator == fTokenMap.end() || iterator->second.type != B_HANDLER_TOKEN) 140 return B_ENTRY_NOT_FOUND; 141 142 if (iterator->second.target != NULL) 143 iterator->second.target->Release(); 144 145 iterator->second.target = target; 146 if (target != NULL) 147 target->Acquire(); 148 149 return B_OK; 150 } 151 152 153 status_t 154 BTokenSpace::AcquireHandlerTarget(int32 token, BDirectMessageTarget** _target) 155 { 156 if (token < 1) 157 return B_ENTRY_NOT_FOUND; 158 159 BAutolock locker(const_cast<BTokenSpace&>(*this)); 160 161 TokenMap::const_iterator iterator = fTokenMap.find(token); 162 if (iterator == fTokenMap.end() || iterator->second.type != B_HANDLER_TOKEN) 163 return B_ENTRY_NOT_FOUND; 164 165 if (iterator->second.target != NULL) 166 iterator->second.target->Acquire(); 167 168 *_target = iterator->second.target; 169 return B_OK; 170 } 171 172 173 void 174 BTokenSpace::InitAfterFork() 175 { 176 // We need to reinitialize the locker to get a new semaphore 177 new (this) BTokenSpace(); 178 } 179 180 181 } // namespace BPrivate 182