Skip to content
Open
Show file tree
Hide file tree
Changes from 10 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