cron: hold job state in Cell/JsCell, take ThisPtr instead of *mut Self
What
Same treatment as #40002 for the three job types in src/runtime/api/cron.rs: CronRegisterJob / CronRemoveJob (the Bun.cron.register/remove subprocess state machines) and CronJob (in-process Bun.cron() timers).
CronRegisterJob/CronRemoveJob:state,process,stdout_reader/stderr_reader,remaining_fds,has_called_process_exit,exit_status,err_msg,tmp_pathmove intoCell/JsCell. Every method on the path tofinish()(maybe_finished,advance_state,on_reader_done/error,on_process_exit,start_*,spawn_*,spawn_cmd_generic/prepare) takesThisPtr<Self>and returns without touchingthisafter the call that may free it; theprepare_*helpers take&self.finishholds the singleheap::take. The pipe-reader and process-exit callbacks (macro-providedunsafebodies) build theThisPtrat entry.CronJobwas alreadyCell/JsCell; its helpers (release_pending_ref,finish_deferred_stop,self_stop,remove_from_list,schedule_next,on_timer_fire) move from*mut Self+ a privatefrom_ctx_ptrderef toThisPtr<Self>; the hand-rolledas_ctx_ptr/ref_guard/CronJobDerefOnDropare replaced bybun_ptr::AsCtxPtr,ThisPtr::ref_guardanddestroy_box_with.dispatch.rsbuilds theThisPtrin the timer-fire arm.- The
s!()macro inspawn_cmd_preparethat reborrowed the whole job as&mutacrossreader.start()(which can re-enteron_reader_errorand write sibling fields) is gone; the reader is driven through its own cell and the re-entrant writes land onCells.
unsafe count: cron.rs 124 → 34 (remaining: raw Process intrusive-refcount calls, the two heap::take frees, ThisPtr::new at the entry points, CronJob::deref, the jsc_host_abi! shims, spawn_process FFI).
Testing
Debug+ASAN build with cronie installed so the crontab paths actually run: cron.test.ts 82 pass / 35 skip (launchd/schtasks blocks), in-process-cron 27, cron-local-time 30, cron-parse 22 pass / 1 pre-existing debug-timing failure ("Feb 30 returns null quickly" asserts <50 ms; ~200 ms on any debug build, identical on main). Manual: PATH=/nonexistent register/remove reject synchronously with "crontab not found in PATH"; full register → crontab -l shows entry → remove → gone. bun scripts/rust-check-all.ts x86_64-pc-windows-msvc aarch64-apple-darwin: 2 ok (mac/windows arms type-check).