1 // StatisticsManager.cpp 2 3 #include "StatisticsManager.h" 4 5 #include <AutoLocker.h> 6 #include <HashMap.h> 7 #include <Message.h> 8 9 #include "DebugSupport.h" 10 #include "SecurityContext.h" 11 12 typedef HashMap<HashString, int32> UserCountMap; 13 14 // ShareStatistics 15 class StatisticsManager::ShareStatistics { 16 public: 17 ShareStatistics(const char* share) 18 : fShare(share), 19 fUsers() 20 { 21 } 22 23 ~ShareStatistics() 24 { 25 } 26 27 status_t Init() 28 { 29 return fUsers.InitCheck(); 30 } 31 32 const char* GetShare() const 33 { 34 return fShare.GetString(); 35 } 36 37 void AddUser(const char* user) 38 { 39 int32 count = 0; 40 if (fUsers.ContainsKey(user)) 41 count = fUsers.Get(user); 42 count++; 43 fUsers.Put(user, count); 44 } 45 46 void RemoveUser(const char* user) 47 { 48 if (!fUsers.ContainsKey(user)) 49 return; 50 51 int32 count = fUsers.Get(user); 52 count--; 53 if (count > 0) 54 fUsers.Put(user, count); 55 else 56 fUsers.Remove(user); 57 } 58 59 status_t GetStatistics(BMessage* statistics) 60 { 61 // add "mounted by" 62 for (UserCountMap::Iterator it = fUsers.GetIterator(); it.HasNext();) { 63 HashString user(it.Next().key); 64 status_t error = statistics->AddString("mounted by", 65 user.GetString()); 66 if (error != B_OK) 67 return error; 68 } 69 return B_OK; 70 } 71 72 private: 73 HashString fShare; 74 UserCountMap fUsers; 75 }; 76 77 // ShareStatisticsMap 78 struct StatisticsManager::ShareStatisticsMap 79 : HashMap<HashString, StatisticsManager::ShareStatistics*> { 80 }; 81 82 83 // constructor 84 StatisticsManager::StatisticsManager() 85 : fLock("statistics manager"), 86 fShareStatistics(NULL) 87 { 88 } 89 90 // destructor 91 StatisticsManager::~StatisticsManager() 92 { 93 // delete the share statistics 94 for (ShareStatisticsMap::Iterator it = fShareStatistics->GetIterator(); 95 it.HasNext();) { 96 ShareStatistics* statistics = it.Next().value; 97 delete statistics; 98 } 99 100 delete fShareStatistics; 101 } 102 103 // Init 104 status_t 105 StatisticsManager::Init() 106 { 107 // check lock 108 if (fLock.Sem() < 0) 109 return fLock.Sem(); 110 111 // create share info map 112 fShareStatistics = new(std::nothrow) ShareStatisticsMap; 113 if (!fShareStatistics) 114 return B_NO_MEMORY; 115 status_t error = fShareStatistics->InitCheck(); 116 if (error != B_OK) 117 return error; 118 119 return B_OK; 120 } 121 122 // CreateDefault 123 status_t 124 StatisticsManager::CreateDefault() 125 { 126 if (fManager) 127 return B_OK; 128 129 fManager = new(std::nothrow) StatisticsManager; 130 if (!fManager) 131 return B_NO_MEMORY; 132 status_t error = fManager->Init(); 133 if (error != B_OK) { 134 DeleteDefault(); 135 return error; 136 } 137 138 return B_OK; 139 } 140 141 // DeleteDefault 142 void 143 StatisticsManager::DeleteDefault() 144 { 145 if (fManager) { 146 delete fManager; 147 fManager = NULL; 148 } 149 } 150 151 // GetDefault 152 StatisticsManager* 153 StatisticsManager::GetDefault() 154 { 155 return fManager; 156 } 157 158 // UserRemoved 159 void 160 StatisticsManager::UserRemoved(User* user) 161 { 162 // the shares the user mounted should already have been unmounted 163 } 164 165 // ShareRemoved 166 void 167 StatisticsManager::ShareRemoved(Share* share) 168 { 169 if (!share) 170 return; 171 172 AutoLocker<Locker> locker(fLock); 173 174 ShareStatistics* statistics = fShareStatistics->Remove(share->GetName()); 175 delete statistics; 176 } 177 178 // ShareMounted 179 void 180 StatisticsManager::ShareMounted(Share* share, User* user) 181 { 182 if (!share || !user) 183 return; 184 185 AutoLocker<Locker> locker(fLock); 186 187 // get the statistics 188 ShareStatistics* statistics = fShareStatistics->Get(share->GetName()); 189 if (!statistics) { 190 // no statistics for this share yet: create 191 statistics = new(std::nothrow) ShareStatistics(share->GetName()); 192 if (!statistics) 193 return; 194 195 // add to the map 196 if (fShareStatistics->Put(share->GetName(), statistics) != B_OK) { 197 delete statistics; 198 return; 199 } 200 } 201 202 // add the user 203 statistics->AddUser(user->GetName()); 204 } 205 206 // ShareUnmounted 207 void 208 StatisticsManager::ShareUnmounted(Share* share, User* user) 209 { 210 if (!share || !user) 211 return; 212 213 AutoLocker<Locker> locker(fLock); 214 215 // get the statistics 216 ShareStatistics* statistics = fShareStatistics->Get(share->GetName()); 217 if (!statistics) 218 return; 219 220 // remove the user 221 statistics->RemoveUser(user->GetName()); 222 } 223 224 // GetUserStatistics 225 status_t 226 StatisticsManager::GetUserStatistics(User* user, BMessage* statistics) 227 { 228 if (!user) 229 return B_BAD_VALUE; 230 231 return GetUserStatistics(user->GetName(), statistics); 232 } 233 234 // GetUserStatistics 235 status_t 236 StatisticsManager::GetUserStatistics(const char* user, BMessage* _statistics) 237 { 238 if (!user || !_statistics) 239 return B_BAD_VALUE; 240 241 // nothing for now 242 243 return B_OK; 244 } 245 246 // GetShareStatistics 247 status_t 248 StatisticsManager::GetShareStatistics(Share* share, BMessage* statistics) 249 { 250 if (!share) 251 return B_BAD_VALUE; 252 253 return GetShareStatistics(share->GetName(), statistics); 254 } 255 256 // GetShareStatistics 257 status_t 258 StatisticsManager::GetShareStatistics(const char* share, BMessage* _statistics) 259 { 260 if (!share || !_statistics) 261 return B_BAD_VALUE; 262 263 AutoLocker<Locker> locker(fLock); 264 265 // get the statistics 266 ShareStatistics* statistics = fShareStatistics->Get(share); 267 if (!statistics) 268 return B_OK; 269 270 // get the users 271 return statistics->GetStatistics(_statistics); 272 } 273 274 275 // fManager 276 StatisticsManager* StatisticsManager::fManager = NULL; 277