Discman
Loading...
Searching...
No Matches
drive_manager.cc
Go to the documentation of this file.
1
6
7 #include "drive_manager.h"
8
10 : _removable_fs(nullptr)
11 , _poller(new Poller(*this))
12 , _acceptable_fs_pat("^.+/sd[a-z]\\d+$") {
13 _dispatcher.connect(sigc::mem_fun(*this, &DriveManager::on_notification_from_poller));
14 _drive.signal_eject().connect(sigc::mem_fun(*this, &DriveManager::on_cddrive_eject));
15 _udisks2.signal_init().connect(sigc::mem_fun(*this, &DriveManager::on_udisks2_init));
16 _udisks2.signal_drive_added().connect(sigc::mem_fun(*this, &DriveManager::on_removable_added));
17 _udisks2.signal_drive_removed().connect(sigc::mem_fun(*this, &DriveManager::on_removable_removed));
18}
19
23
25 : _manager(manager)
26 , _exit(false)
27 , _thread(&DriveManager::Poller::poll, this) {
28
29}
31 _exit_lock.lock();
32 _exit = true;
33 _exit_lock.unlock();
34 _thread.join();
35}
36
38 while (true) {
39 _exit_lock.lock();
40 bool exit = _exit;
41 _exit_lock.unlock();
42
43 if (exit) return;
44
45 if (_manager._drive.present()) {
46 _manager._dispatcher.emit();
47 return;
48 }
49 }
50}
51
53 switch (drive) {
55 _drive.eject();
56 break;
58 default:
59 _removable_fs->unmount();
60 _udisks2.drive_for_filesystem(_removable_fs)->eject();
61 break;
62 }
63}
64
66 _sig_ejected.emit(Disc);
67
68 if (!_poller)
69 _poller = new Poller(*this);
70}
71
75
79
81 if (!_udisks2.filesystems().empty()) {
82 for (const auto& fs : _udisks2.filesystems()) {
83 if (std::regex_match(fs, _acceptable_fs_pat)) {
84 _removable_fs = _udisks2.filesystem(fs);
85 _removable_fs->signal_mounted().connect(sigc::mem_fun(*this, &DriveManager::on_removable_mounted));
86 _removable_fs->signal_unmounted().connect(sigc::mem_fun(*this, &DriveManager::on_removable_unmounted));
88 return;
89 }
90 }
91 }
92}
93
95 delete _poller;
96 _poller = nullptr;
97
98 _sig_inserted.emit(Disc);
99}
100
101void DriveManager::on_removable_added(const std::string& path) {
102 if (!_removable_fs) {
103 if (std::regex_match(path, _acceptable_fs_pat)) {
104 _removable_fs = _udisks2.filesystem(path);
105 if (!_removable_fs->mount_point().empty()) {
107 }
108 _removable_fs->signal_mounted().connect(sigc::mem_fun(*this, &DriveManager::on_removable_mounted));
109 _removable_fs->signal_unmounted().connect(sigc::mem_fun(*this, &DriveManager::on_removable_unmounted));
110 }
111 }
112}
113
114void DriveManager::on_removable_removed(const std::string& path) {
115 if (_removable_fs->path() == path) {
116 if (!_removable_fs->mount_point().empty()) {
118 }
119
120 delete _removable_fs;
121 _removable_fs = nullptr;
122
123 }
124}
125
126void DriveManager::on_removable_mounted(const std::string&) {
128}
129
133
135 return _drive.present();
136}
137
139 return !!_removable_fs && !_removable_fs->mount_point().empty();
140}
141
142UDisks2::Filesystem& DriveManager::removable() {
143 if (!is_removable_present()) {
144 throw NoDriveException();
145 }
146
147 return *_removable_fs;
148}
149
Abstracts the host's disc drive.
Definition cd_drive.h:39
The Poller uses a separate thread to poll the host for the presence of an audio CD.
Poller(DriveManager &manager)
Poller constructor.
~Poller()
Poller destructor.
bool _exit
Stores a request to exist poll().
DriveManager & _manager
The parent DriveManager.
void poll()
The execution loop performed by the thread.
std::mutex _exit_lock
Provides mutually exclusive access to the _exit member between the the application thread and the Pol...
std::thread _thread
The thread used to run poll().
sigc::signal< void(Drive)> sig_drive
"Inserted" and "Ejected" shared signal type.
void on_removable_added(const std::string &path)
Called when a new filesystem appears.
Drive
The two drives supported.
sig_drive signal_inserted()
Getter for ::_signal_inserted.
~DriveManager()
DriveManager destructor.
sig_drive _sig_inserted
Emitted when a drive is inserted.
std::regex _acceptable_fs_pat
Filters the filesystems reported by UDisks2 to acceptable ones.
void on_cddrive_eject()
Called when the disc drive successfully ejects.
bool is_disc_present() const
Returns the (cached) property of disc presence.
void on_removable_removed(const std::string &path)
Called when a filesystem is removed.
Glib::Dispatcher _dispatcher
Used to samely emit _sig_inserted for the disc drive.
sig_drive _sig_ejected
Emitted when a drive is removed.
Poller * _poller
When running, checks for the presence of a disc in _drive.
void on_udisks2_init()
Called when UDisks2 initializes the list of preregisterd drives and filesystems.
DriveManager()
DriveManager constructor.
CDDrive & disc_drive()
Returns the CDDrive associated with the disc drive.
bool is_removable_present() const
Returns the (cached) property of iPod presence.
UDisks2::Filesystem * _removable_fs
The filesystem associated with the iPod.
void eject(const Drive drive)
Eject one of the drives.
UDisks2::Manager _udisks2
UDisks2 provides access to removable disks.
CDDrive _drive
The disc drive.
sig_drive signal_ejected()
Getter for ::_signal_ejected.
void on_removable_mounted(const std::string &)
Called when the removable drive is mounted.
void on_notification_from_poller()
Called when _dispatcher is notified.
void on_removable_unmounted()
Called when the removable drive is unmounted.
UDisks2::Filesystem & removable()
Returns the UDisks2::Filesystem cassociated with the iPod.
Thrown when the assumption of the presence of a drive is false.