Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/io/posix_event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ pub enum PollTag {
ParentDeathWatchdog,
LifecycleScriptSubprocessOutputReader,
MemoryPressure,
DnsConfig,
}

/// Compatibility module — call sites in `bun_runtime`/`bun_install` still spell
Expand All @@ -246,6 +247,7 @@ pub mod poll_tag {
pub const LIFECYCLE_SCRIPT_SUBPROCESS_OUTPUT_READER: PollTag =
PollTag::LifecycleScriptSubprocessOutputReader;
pub const MEMORY_PRESSURE: PollTag = PollTag::MemoryPressure;
pub const DNS_CONFIG: PollTag = PollTag::DnsConfig;
}

#[derive(Copy, Clone)]
Expand Down
8 changes: 8 additions & 0 deletions src/js/internal-for-testing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,14 @@ export const isMemoryPressureWatcherInstalled: () => boolean = $newCppFunction(
0,
);

export const dnsConfigGeneration: () => number = $newCppFunction(
"InternalForTesting.cpp",
"jsFunction_dnsConfigGeneration",
0,
);

export const dnsConfigChanged: () => void = $newCppFunction("InternalForTesting.cpp", "jsFunction_dnsConfigChanged", 0);

export const getEventLoopStats: () => { activeTasks: number; concurrentRef: number; numPolls: number } =
$newRustFunction("event_loop.rs", "getActiveTasks", 0);

Expand Down
13 changes: 13 additions & 0 deletions src/jsc/bindings/InternalForTesting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ JSC_DEFINE_HOST_FUNCTION(jsFunction_BunString_toThreadSafeRefCountDelta, (JSC::J

extern "C" void Bun__MemoryPressure__emit(JSC::JSGlobalObject* global, int level);
extern "C" bool Bun__MemoryPressure__isInstalled(JSC::JSGlobalObject* global);
extern "C" uint64_t Bun__DNSConfig__generation();
extern "C" void Bun__DNSConfig__bump();

// Synthetically fire process.on("memoryPressure") so tests can exercise the
// emit path without depending on real OS memory pressure.
Expand All @@ -124,4 +126,15 @@ JSC_DEFINE_HOST_FUNCTION(jsFunction_isMemoryPressureWatcherInstalled, (JSC::JSGl
return JSValue::encode(jsBoolean(Bun__MemoryPressure__isInstalled(defaultGlobalObject(globalObject))));
}

JSC_DEFINE_HOST_FUNCTION(jsFunction_dnsConfigGeneration, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
return JSValue::encode(jsNumber(static_cast<double>(Bun__DNSConfig__generation())));
}

JSC_DEFINE_HOST_FUNCTION(jsFunction_dnsConfigChanged, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
Bun__DNSConfig__bump();
return encodedJSUndefined();
}

}
2 changes: 2 additions & 0 deletions src/jsc/bindings/InternalForTesting.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ JSC_DECLARE_HOST_FUNCTION(jsFunction_BunString_toThreadSafeRefCountDelta);
JSC_DECLARE_HOST_FUNCTION(jsFunction_lowercaseHeaderNameSIMD);
JSC_DECLARE_HOST_FUNCTION(jsFunction_emitMemoryPressure);
JSC_DECLARE_HOST_FUNCTION(jsFunction_isMemoryPressureWatcherInstalled);
JSC_DECLARE_HOST_FUNCTION(jsFunction_dnsConfigGeneration);
JSC_DECLARE_HOST_FUNCTION(jsFunction_dnsConfigChanged);

}
12 changes: 12 additions & 0 deletions src/jsc/rare_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,11 @@ pub struct RareData {
/// `Box`; lazy-init on the first `process.on("memoryPressure", ...)` listener.
pub memory_pressure_watcher: Option<NonNull<c_void>>,

/// `bun_runtime::dns_jsc::config_watcher` FilePoll — erased; lazy-init on
/// this VM's first c-ares channel. Per-VM so a Worker's watcher dies with
/// the Worker instead of masking the main thread's.
pub dns_config_watcher: Option<NonNull<c_void>>,

/// Watch-mode restart needs to RST every listen socket so the new process
/// can rebind without `EADDRINUSE`. Written on the JS thread; drained on
/// the watcher thread — hence the mutex (PORTING.md §Concurrency: lock
Expand Down Expand Up @@ -325,6 +330,7 @@ impl Default for RareData {
mime_types: None,
node_fs_stat_watcher_scheduler: None,
memory_pressure_watcher: None,
dns_config_watcher: None,
listening_sockets_for_watch_mode: Mutex::new(Vec::new()),
temp_pipe_read_buffer: None,
s3_default_client: Strong::empty(),
Expand Down Expand Up @@ -635,6 +641,12 @@ impl RareData {
&mut self.memory_pressure_watcher
}

/// Raw slot — lazy-init body lives in `bun_runtime::dns_jsc::config_watcher`.
#[inline]
pub fn dns_config_watcher_slot(&mut self) -> &mut Option<NonNull<c_void>> {
&mut self.dns_config_watcher
}

// ── lazy-init: hot_map ─────────────────────────────────────────────────
pub fn hot_map(&mut self) -> &mut HotMap {
self.hot_map.get_or_insert_with(HotMap::init)
Expand Down
9 changes: 9 additions & 0 deletions src/runtime/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,15 @@ pub unsafe fn __bun_run_file_poll(poll: *mut FilePoll, size_or_offset: i64) {
// SAFETY: `poll` is live per `__bun_run_file_poll`'s contract.
crate::node::memory_pressure::on_poll(unsafe { &mut *poll }, size_or_offset);
}
#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos"))]
poll_tag::DNS_CONFIG => {
// SAFETY: `poll` is live per `__bun_run_file_poll`'s contract.
crate::dns_jsc::config_watcher::on_poll(unsafe { &mut *poll });
}
#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "macos")))]
poll_tag::DNS_CONFIG => {
debug_assert!(false, "DnsConfig poll on unsupported target");
}
poll_tag::PARENT_DEATH_WATCHDOG => {
let wd = owner_as!(bun_io::parent_death_watchdog::ParentDeathWatchdog);
// Mac-only — debug-assert elsewhere (Linux uses prctl(PR_SET_PDEATHSIG)).
Expand Down
Loading
Loading