Skip to content
Permalink
Browse files
Make sure return value of dispatch_source_create is memory managed co…
…rrectly

https://bugs.webkit.org/show_bug.cgi?id=241836
rdar://95625990

Reviewed by Chris Dumez.

* Source/WTF/wtf/cocoa/MemoryPressureHandlerCocoa.mm:
(WTF::memoryPressureEventSource):
(WTF::timerEventSource):
(WTF::MemoryPressureHandler::install):
(WTF::MemoryPressureHandler::uninstall):
(WTF::MemoryPressureHandler::holdOff):
* Source/WTF/wtf/threads/Signals.cpp:
(WTF::startMachExceptionHandlerThread):
* Source/WebKit/Shared/EntryPointUtilities/Cocoa/XPCService/XPCServiceEntryPoint.mm:
(WebKit::setOSTransaction):

Canonical link: https://commits.webkit.org/251745@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295740 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
achristensen07 committed Jun 22, 2022
1 parent 262ef2f commit a420713c48fca6aca7188f3536ae0324a3e2f963
Showing 2 changed files with 36 additions and 25 deletions.
@@ -49,8 +49,18 @@
}
}

static dispatch_source_t memoryPressureEventSource = nullptr;
static dispatch_source_t timerEventSource = nullptr;
static OSObjectPtr<dispatch_source_t>& memoryPressureEventSource()
{
static NeverDestroyed<OSObjectPtr<dispatch_source_t>> source;
return source.get();
}

static OSObjectPtr<dispatch_source_t>& timerEventSource()
{
static NeverDestroyed<OSObjectPtr<dispatch_source_t>> source;
return source.get();
}

static int notifyTokens[3];

// Disable memory event reception for a minimum of s_minimumHoldOffTime
@@ -66,15 +76,15 @@

void MemoryPressureHandler::install()
{
if (m_installed || timerEventSource)
if (m_installed || timerEventSource())
return;

dispatch_async(m_dispatchQueue.get(), ^{
auto memoryStatusFlags = DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL | DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN | DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL;
memoryPressureEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, memoryStatusFlags, m_dispatchQueue.get());
memoryPressureEventSource() = adoptOSObject(dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, memoryStatusFlags, m_dispatchQueue.get()));

dispatch_source_set_event_handler(memoryPressureEventSource, ^{
auto status = dispatch_source_get_data(memoryPressureEventSource);
dispatch_source_set_event_handler(memoryPressureEventSource().get(), ^{
auto status = dispatch_source_get_data(memoryPressureEventSource().get());
switch (status) {
// VM pressure events.
case DISPATCH_MEMORYPRESSURE_NORMAL:
@@ -101,7 +111,7 @@
if (m_shouldLogMemoryMemoryPressureEvents)
RELEASE_LOG(MemoryPressure, "Received memory pressure event %lu vm pressure %d", status, isUnderMemoryPressure());
});
dispatch_resume(memoryPressureEventSource);
dispatch_resume(memoryPressureEventSource().get());
});

// Allow simulation of memory pressure with "notifyutil -p org.WebKit.lowMemory"
@@ -140,14 +150,14 @@
return;

dispatch_async(m_dispatchQueue.get(), ^{
if (memoryPressureEventSource) {
dispatch_source_cancel(memoryPressureEventSource);
memoryPressureEventSource = nullptr;
if (memoryPressureEventSource()) {
dispatch_source_cancel(memoryPressureEventSource().get());
memoryPressureEventSource() = nullptr;
}

if (timerEventSource) {
dispatch_source_cancel(timerEventSource);
timerEventSource = nullptr;
if (timerEventSource()) {
dispatch_source_cancel(timerEventSource().get());
timerEventSource() = nullptr;
}
});

@@ -160,20 +170,20 @@
void MemoryPressureHandler::holdOff(Seconds seconds)
{
dispatch_async(m_dispatchQueue.get(), ^{
timerEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_dispatchQueue.get());
if (timerEventSource) {
dispatch_set_context(timerEventSource, this);
timerEventSource() = adoptOSObject(dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_dispatchQueue.get()));
if (timerEventSource()) {
dispatch_set_context(timerEventSource().get(), this);
// FIXME: The final argument `s_minimumHoldOffTime.seconds()` seems wrong.
// https://bugs.webkit.org/show_bug.cgi?id=183277
dispatch_source_set_timer(timerEventSource, dispatch_time(DISPATCH_TIME_NOW, seconds.seconds() * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, s_minimumHoldOffTime.seconds());
dispatch_source_set_event_handler(timerEventSource, ^{
if (timerEventSource) {
dispatch_source_cancel(timerEventSource);
timerEventSource = nullptr;
dispatch_source_set_timer(timerEventSource().get(), dispatch_time(DISPATCH_TIME_NOW, seconds.seconds() * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, s_minimumHoldOffTime.seconds());
dispatch_source_set_event_handler(timerEventSource().get(), ^{
if (timerEventSource().get()) {
dispatch_source_cancel(timerEventSource().get());
timerEventSource() = nullptr;
}
MemoryPressureHandler::singleton().install();
});
dispatch_resume(timerEventSource);
dispatch_resume(timerEventSource().get());
}
});
}
@@ -158,6 +158,7 @@
void setOSTransaction(OSObjectPtr<os_transaction_t>&& transaction)
{
static NeverDestroyed<OSObjectPtr<os_transaction_t>> globalTransaction;
static NeverDestroyed<OSObjectPtr<dispatch_source_t>> globalSource;

// Because we don't use RunningBoard on macOS, we leak an OS transaction to control the lifetime of our XPC
// services ourselves. However, one of the side effects of leaking this transaction is that the default SIGTERM
@@ -167,11 +168,11 @@ void setOSTransaction(OSObjectPtr<os_transaction_t>&& transaction)
// control our lifetime via process assertions instead of leaking this OS transaction.
static dispatch_once_t flag;
dispatch_once(&flag, ^{
auto sigTermSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGTERM, 0, dispatch_get_main_queue());
dispatch_source_set_event_handler(sigTermSource, ^{
globalSource.get() = adoptOSObject(dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGTERM, 0, dispatch_get_main_queue()));
dispatch_source_set_event_handler(globalSource.get().get(), ^{
exit(0);
});
dispatch_resume(sigTermSource);
dispatch_resume(globalSource.get().get());
});

globalTransaction.get() = WTFMove(transaction);

0 comments on commit a420713

Please sign in to comment.