Retain run loop (#11241)

Conrad Irwin created

Contributes: #11168


https://developer.apple.com/documentation/corefoundation/1542428-cfrunloopgetcurrent
implies that we should be `CFRetain`ing the run loop.

Lets do that, and see if it reduces the number of crashes we see.

Release Notes:

- (maybe) Fix a rare crash in watching settings files.

Change summary

Cargo.lock                    | 1 +
crates/fsevent/Cargo.toml     | 1 +
crates/fsevent/src/fsevent.rs | 4 +++-
3 files changed, 5 insertions(+), 1 deletion(-)

Detailed changes

Cargo.lock 🔗

@@ -4088,6 +4088,7 @@ name = "fsevent"
 version = "0.1.0"
 dependencies = [
  "bitflags 2.4.2",
+ "core-foundation",
  "fsevent-sys 3.1.0",
  "parking_lot",
  "tempfile",

crates/fsevent/Cargo.toml 🔗

@@ -17,6 +17,7 @@ bitflags.workspace = true
 parking_lot.workspace = true
 
 [target.'cfg(target_os = "macos")'.dependencies]
+core-foundation.workspace = true
 fsevent-sys = "3.0.2"
 
 [dev-dependencies]

crates/fsevent/src/fsevent.rs 🔗

@@ -120,7 +120,8 @@ impl EventStream {
     {
         self.state.callback = Some(Box::new(f));
         unsafe {
-            let run_loop = cf::CFRunLoopGetCurrent();
+            let run_loop =
+                core_foundation::base::CFRetain(cf::CFRunLoopGetCurrent()) as *mut c_void;
             {
                 let mut state = self.lifecycle.lock();
                 match *state {
@@ -248,6 +249,7 @@ impl Drop for Handle {
         if let Lifecycle::Running(run_loop) = *state {
             unsafe {
                 cf::CFRunLoopStop(run_loop);
+                cf::CFRelease(run_loop)
             }
         }
         *state = Lifecycle::Stopped;