Skip to content

Commit 8984d02

Browse files
committed
Update vendor
1 parent a3aa4df commit 8984d02

File tree

5 files changed

+238
-131
lines changed

5 files changed

+238
-131
lines changed

Diff for: example/vendor/cget/pkg/foonathan__debug_assert/install/lib/cmake/debug_assert/debug_assert-targets.cmake

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if(CMAKE_VERSION VERSION_LESS "3.1.0")
77
message(FATAL_ERROR "CMake >= 3.1.0 required")
88
endif()
99
cmake_policy(PUSH)
10-
cmake_policy(VERSION 3.1.0...3.27)
10+
cmake_policy(VERSION 3.1.0...3.28)
1111
#----------------------------------------------------------------
1212
# Generated CMake target import file.
1313
#----------------------------------------------------------------

Diff for: example/vendor/cget/pkg/pqrs-org__cpp-osx-iokit_hid_manager/install/include/pqrs/osx/iokit_hid_manager.hpp

+1-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

3-
// pqrs::osx::iokit_hid_manager v5.0
3+
// pqrs::osx::iokit_hid_manager v6.0
44

55
// (C) Copyright Takayama Fumihiko 2018.
66
// Distributed under the Boost Software License, Version 1.0.
@@ -57,12 +57,6 @@ class iokit_hid_manager final : public dispatcher::extra::dispatcher_client {
5757
});
5858
}
5959

60-
void async_rescan(void) {
61-
enqueue_to_dispatcher([this] {
62-
rescan();
63-
});
64-
}
65-
6660
void async_set_device_matched_delay(pqrs::dispatcher::duration value) {
6761
enqueue_to_dispatcher([this, value] {
6862
device_matched_delay_ = value;
@@ -191,12 +185,6 @@ class iokit_hid_manager final : public dispatcher::extra::dispatcher_client {
191185
device_matched_called_ids_.clear();
192186
}
193187

194-
void rescan(void) {
195-
for (const auto& m : service_monitors_) {
196-
m->async_invoke_service_matched();
197-
}
198-
}
199-
200188
std::shared_ptr<cf::run_loop_thread> run_loop_thread_;
201189
std::vector<cf::cf_ptr<CFDictionaryRef>> matching_dictionaries_;
202190
pqrs::dispatcher::duration device_matched_delay_;

Diff for: example/vendor/cget/pkg/pqrs-org__cpp-osx-iokit_service_monitor/install/include/pqrs/osx/iokit_service_monitor.hpp

+99-28
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#pragma once
22

3-
// pqrs::osx::iokit_service_monitor v5.0
3+
// pqrs::osx::iokit_service_monitor v6.0
44

55
// (C) Copyright Takayama Fumihiko 2018.
66
// Distributed under the Boost Software License, Version 1.0.
7-
// (See http://www.boost.org/LICENSE_1_0.txt)
7+
// (See https://www.boost.org/LICENSE_1_0.txt)
88

99
// `pqrs::osx::iokit_service_monitor` can be used safely in a multi-threaded environment.
1010

@@ -17,6 +17,7 @@
1717
#include <pqrs/osx/iokit_registry_entry.hpp>
1818
#include <pqrs/osx/iokit_types.hpp>
1919
#include <pqrs/osx/kern_return.hpp>
20+
#include <unordered_set>
2021

2122
namespace pqrs {
2223
namespace osx {
@@ -41,13 +42,16 @@ class iokit_service_monitor final : dispatcher::extra::dispatcher_client {
4142
: dispatcher_client(weak_dispatcher),
4243
run_loop_thread_(run_loop_thread),
4344
matching_dictionary_(matching_dictionary),
44-
notification_port_(nullptr) {
45+
notification_port_(nullptr),
46+
scan_timer_(*this) {
4547
}
4648

4749
virtual ~iokit_service_monitor(void) {
4850
// dispatcher_client
4951

50-
detach_from_dispatcher();
52+
detach_from_dispatcher([this] {
53+
scan_timer_.stop();
54+
});
5155

5256
// run_loop_thread
5357

@@ -76,26 +80,6 @@ class iokit_service_monitor final : dispatcher::extra::dispatcher_client {
7680
});
7781
}
7882

79-
void async_invoke_service_matched(void) {
80-
run_loop_thread_->enqueue(^{
81-
if (*matching_dictionary_) {
82-
io_iterator_t it = IO_OBJECT_NULL;
83-
CFRetain(*matching_dictionary_);
84-
kern_return r = IOServiceGetMatchingServices(type_safe::get(iokit_mach_port::null),
85-
*matching_dictionary_,
86-
&it);
87-
if (!r) {
88-
enqueue_to_dispatcher([this, r] {
89-
error_occurred("IOServiceGetMatchingServices is failed.", r);
90-
});
91-
} else {
92-
matched_callback(make_services(iokit_iterator(it)));
93-
IOObjectRelease(it);
94-
}
95-
}
96-
});
97-
}
98-
9983
private:
10084
// This method is executed in run_loop_thread_.
10185
void start(void) {
@@ -165,6 +149,69 @@ class iokit_service_monitor final : dispatcher::extra::dispatcher_client {
165149
}
166150
}
167151
}
152+
153+
//
154+
// Setup scan timer
155+
//
156+
157+
enqueue_to_dispatcher([this] {
158+
registry_entry_ids_.clear();
159+
160+
// There are rare cases where IOFirstMatchNotification and kIOTerminatedNotification are not triggered.
161+
// In such cases, service_terminated is never called for the terminated service.
162+
// To avoid this issue, periodic scans will be performed, and callbacks will be invoked for services that didn't receive the notification.
163+
164+
scan_timer_.start(
165+
[this] {
166+
if (*matching_dictionary_) {
167+
io_iterator_t it = IO_OBJECT_NULL;
168+
CFRetain(*matching_dictionary_);
169+
kern_return r = IOServiceGetMatchingServices(type_safe::get(iokit_mach_port::null),
170+
*matching_dictionary_,
171+
&it);
172+
if (!r) {
173+
enqueue_to_dispatcher([this, r] {
174+
error_occurred("IOServiceGetMatchingServices is failed.", r);
175+
});
176+
} else {
177+
auto services = make_services(iokit_iterator(it));
178+
IOObjectRelease(it);
179+
180+
// Call service_matched
181+
182+
for (const auto& s : services) {
183+
if (auto registry_entry_id = s.find_registry_entry_id()) {
184+
invoke_service_matched(*registry_entry_id, s);
185+
}
186+
}
187+
188+
// Call service_terminated
189+
190+
std::unordered_set<iokit_registry_entry_id::value_t> terminated_registry_entry_ids;
191+
192+
for (const auto stored_registry_entry_id : registry_entry_ids_) {
193+
bool found = false;
194+
for (const auto& s : services) {
195+
if (auto registry_entry_id = s.find_registry_entry_id()) {
196+
if (stored_registry_entry_id == *registry_entry_id) {
197+
found = true;
198+
}
199+
}
200+
}
201+
202+
if (!found) {
203+
terminated_registry_entry_ids.insert(stored_registry_entry_id);
204+
}
205+
}
206+
207+
for (const auto terminated_registry_entry_id : terminated_registry_entry_ids) {
208+
invoke_service_terminated(terminated_registry_entry_id);
209+
}
210+
}
211+
}
212+
},
213+
std::chrono::milliseconds(3000));
214+
});
168215
}
169216

170217
// This method is executed in run_loop_thread_.
@@ -180,6 +227,11 @@ class iokit_service_monitor final : dispatcher::extra::dispatcher_client {
180227
IONotificationPortDestroy(notification_port_);
181228
notification_port_ = nullptr;
182229
}
230+
231+
enqueue_to_dispatcher([this] {
232+
scan_timer_.stop();
233+
registry_entry_ids_.clear();
234+
});
183235
}
184236

185237
static void static_matched_callback(void* _Nonnull refcon, io_iterator_t iterator) {
@@ -195,16 +247,24 @@ class iokit_service_monitor final : dispatcher::extra::dispatcher_client {
195247
});
196248
}
197249

198-
void matched_callback(const std::vector<iokit_registry_entry>& services) const {
250+
void matched_callback(const std::vector<iokit_registry_entry>& services) {
199251
for (const auto& s : services) {
200252
if (auto registry_entry_id = s.find_registry_entry_id()) {
201253
enqueue_to_dispatcher([this, registry_entry_id, s] {
202-
service_matched(*registry_entry_id, s.get());
254+
invoke_service_matched(*registry_entry_id, s);
203255
});
204256
}
205257
}
206258
}
207259

260+
// This method is executed in the dispatcher thread.
261+
void invoke_service_matched(iokit_registry_entry_id::value_t registry_entry_id, iokit_registry_entry service) {
262+
if (!registry_entry_ids_.contains(registry_entry_id)) {
263+
registry_entry_ids_.insert(registry_entry_id);
264+
service_matched(registry_entry_id, service.get());
265+
}
266+
}
267+
208268
static void static_terminated_callback(void* _Nonnull refcon, io_iterator_t iterator) {
209269
auto self = static_cast<iokit_service_monitor*>(refcon);
210270
if (!self) {
@@ -218,16 +278,24 @@ class iokit_service_monitor final : dispatcher::extra::dispatcher_client {
218278
});
219279
}
220280

221-
void terminated_callback(const std::vector<iokit_registry_entry>& services) const {
281+
void terminated_callback(const std::vector<iokit_registry_entry>& services) {
222282
for (const auto& s : services) {
223283
if (auto registry_entry_id = s.find_registry_entry_id()) {
224284
enqueue_to_dispatcher([this, registry_entry_id] {
225-
service_terminated(*registry_entry_id);
285+
invoke_service_terminated(*registry_entry_id);
226286
});
227287
}
228288
}
229289
}
230290

291+
// This method is executed in the dispatcher thread.
292+
void invoke_service_terminated(iokit_registry_entry_id::value_t registry_entry_id) {
293+
if (registry_entry_ids_.contains(registry_entry_id)) {
294+
registry_entry_ids_.erase(registry_entry_id);
295+
service_terminated(registry_entry_id);
296+
}
297+
}
298+
231299
static std::vector<iokit_registry_entry> make_services(const iokit_iterator& iterator) {
232300
std::vector<iokit_registry_entry> services;
233301

@@ -249,6 +317,9 @@ class iokit_service_monitor final : dispatcher::extra::dispatcher_client {
249317
IONotificationPortRef _Nullable notification_port_;
250318
iokit_iterator matched_notification_;
251319
iokit_iterator terminated_notification_;
320+
321+
pqrs::dispatcher::extra::timer scan_timer_;
322+
std::unordered_set<iokit_registry_entry_id::value_t> registry_entry_ids_;
252323
};
253324
} // namespace osx
254325
} // namespace pqrs

0 commit comments

Comments
 (0)