// KDiskDeviceUtils.h #ifndef _K_DISK_DEVICE_UTILS_H #define _K_DISK_DEVICE_UTILS_H #include #include #include namespace BPrivate { namespace DiskDevice { // helper functions // min template static inline const T& min(const T &a, const T &b) { if (a < b) return a; return b; } // max template static inline const T& max(const T &a, const T &b) { if (a < b) return b; return a; } // set_string static inline status_t set_string(char *&location, const char *newValue) { // unset old value if (location) { free(location); location = NULL; } // set new value status_t error = B_OK; if (newValue) { location = strdup(newValue); if (!location) error = B_NO_MEMORY; } return error; } // compare_string /*! \brief \c NULL aware strcmp(). \c NULL is considered the least of all strings. \c NULL equals \c NULL. \param str1 First string. \param str2 Second string. \return A value less than 0, if \a str1 is less than \a str2, 0, if they are equal, or a value greater than 0, if \a str1 is greater \a str2. */ static inline int compare_string(const char *str1, const char *str2) { if (str1 == NULL) { if (str2 == NULL) return 0; return 1; } else if (str2 == NULL) return -1; return strcmp(str1, str2); } // locking // AutoLockerStandardLocking template class AutoLockerStandardLocking { public: inline bool Lock(Lockable *lockable) { return lockable->Lock(); } inline void Unlock(Lockable *lockable) { lockable->Unlock(); } }; // AutoLockerReadLocking template class AutoLockerReadLocking { public: inline bool Lock(Lockable *lockable) { return lockable->ReadLock(); } inline void Unlock(Lockable *lockable) { lockable->ReadUnlock(); } }; // AutoLockerWriteLocking template class AutoLockerWriteLocking { public: inline bool Lock(Lockable *lockable) { return lockable->WriteLock(); } inline void Unlock(Lockable *lockable) { lockable->WriteUnlock(); } }; // AutoLocker template > class AutoLocker { private: typedef AutoLocker ThisClass; public: inline AutoLocker(Lockable *lockable, bool alreadyLocked = false) : fLockable(lockable), fLocked(fLockable && alreadyLocked) { if (!fLocked) _Lock(); } inline AutoLocker(Lockable &lockable, bool alreadyLocked = false) : fLockable(&lockable), fLocked(fLockable && alreadyLocked) { if (!fLocked) _Lock(); } inline ~AutoLocker() { _Unlock(); } inline void SetTo(Lockable *lockable, bool alreadyLocked) { _Unlock(); fLockable = lockable; fLocked = alreadyLocked; if (!fLocked) _Lock(); } inline void SetTo(Lockable &lockable, bool alreadyLocked) { SetTo(&lockable, alreadyLocked); } inline AutoLocker &operator=(Lockable *lockable) { SetTo(lockable); return *this; } inline AutoLocker &operator=(Lockable &lockable) { SetTo(&lockable); return *this; } inline bool IsLocked() const { return fLocked; } inline operator bool() const { return fLocked; } private: inline void _Lock() { if (fLockable) fLocked = fLocking.Lock(fLockable); } inline void _Unlock() { if (fLockable && fLocked) { fLocking.Unlock(fLockable); fLocked = false; } } private: Lockable *fLockable; bool fLocked; Locking fLocking; }; // instantiations class KDiskDevice; class KDiskDeviceManager; class KDiskSystem; class KPartition; typedef AutoLocker > DeviceReadLocker; typedef AutoLocker > DeviceWriteLocker; typedef AutoLocker ManagerLocker; // AutoLockerPartitionRegistration template class AutoLockerPartitionRegistration { public: inline bool Lock(KPartition *partition) { partition->Register(); return true; } inline void Unlock(KPartition *partition) { partition->Unregister(); } }; typedef AutoLocker > PartitionRegistrar; // AutoLockerDiskSystemLoading template class AutoLockerDiskSystemLoading { public: inline bool Lock(KDiskSystem *diskSystem) { return (diskSystem->Load() == B_OK); } inline void Unlock(KDiskSystem *diskSystem) { diskSystem->Unload(); } }; typedef AutoLocker > DiskSystemLoader; } // namespace DiskDevice } // namespace BPrivate using BPrivate::DiskDevice::set_string; using BPrivate::DiskDevice::AutoLocker; using BPrivate::DiskDevice::DeviceReadLocker; using BPrivate::DiskDevice::DeviceWriteLocker; using BPrivate::DiskDevice::ManagerLocker; using BPrivate::DiskDevice::PartitionRegistrar; using BPrivate::DiskDevice::DiskSystemLoader; #endif // _K_DISK_DEVICE_H