#pragma once #include "../Interface/Thread.h" #include "../Interface/Mutex.h" #include "../Interface/ThreadPool.h" #include #include #include class ScopedMountedImage; class ImageMount : public IThread { public: void operator()(); static bool mount_image(int backupid, int partition, ScopedMountedImage& mounted_image, int64 timeoutms, bool& has_timeout, std::string& errmsg); static std::string get_mount_path(int backupid, int clientid, int partition, bool do_mount, ScopedMountedImage& mounted_image, int64 timeoutms, bool& has_timeout, std::string& errmsg); static bool unmount_images(int backupid); static void incrImageMounted(int backupid, int partition); static void decrImageMounted(int backupid, int partition); static bool lockImage(int backupid, int64 timeoutms); static void unlockImage(int backupid); static void mount_image_thread(int backupid, int partition, std::string& errmsg); private: struct SMountId { SMountId(int backupid, int partition) : backupid(backupid), partition(partition) {} int backupid; int partition; bool operator<(const SMountId& other) const { return std::make_pair(backupid, partition) < std::make_pair(other.backupid, other.partition); } }; static bool mount_image_int(int backupid, int partition, ScopedMountedImage& mounted_image, int64 timeoutms, bool& has_timeout, std::string& errmsg); static std::map mount_processes; static IMutex* mount_processes_mutex; static std::map mounted_images; static std::set locked_images; static IMutex* mounted_images_mutex; }; class ScopedMountedImage { public: ScopedMountedImage() : backupid(0), partition(0) {} ~ScopedMountedImage() { if (backupid != 0) { ImageMount::decrImageMounted(backupid, partition); } } void reset(int bid = 0, int part=0) { if (bid == backupid && part==partition) { return; } if (backupid != 0) { ImageMount::decrImageMounted(backupid, partition); } backupid = bid; partition = part; if (backupid != 0) { ImageMount::incrImageMounted(backupid, partition); } } private: int backupid; int partition; };