title: Rust Mutex is not working when using a callback function from multiple C threads created by `fork`
body: <p>I am using the C library Cuba which uses a callback function that is called from multiple threads created in C. The Cuba parallelization is based on the <code>fork</code>/<code>wait</code> POSIX functions instead of pthreads (<a href="https://arxiv.org/abs/1408.6373" rel="nofollow noreferrer">arxiv.org/abs/1408.6373</a>). It gives the current thread in the <code>core</code> parameter.</p>
  
  <p>I am trying to log results from this callback function to a screen and a file. If I use <code>println!</code> I get expected output, but if I use <code>slog</code> the output is mangled when I use a <code>Mutex</code> drain. If I use the <code>async</code> drain I get no output at all.</p>
  
  <p>Is the <code>Mutex</code> not locking since it can't see the function is actually called from another thread? I tried to recreate the problem with Rust threads, but couldn't. Preferably I'd like to get the <code>async</code> drain to work.</p>
  
  <p>Below is an example program that gives the problematic behaviour. The callback gets the last parameter of the <code>vegas</code> function as one of its arguments. This is a vector of clones of loggers. This way, each core should have its own copy of the logger:</p>
  
  <pre><code>#[macro_use]
  extern crate slog;
  extern crate cuba;
  extern crate slog_term;
  
  use slog::Drain;
  
  // this function is called from different c threads
  // `core` indicates which thread
  fn integrand(
      _x: &amp;[f64],
      _f: &amp;mut [f64],
      loggers: &amp;mut Vec&lt;slog::Logger&gt;,
      _nvec: usize,
      core: i32,
  ) -&gt; Result&lt;(), &amp;'static str&gt; {
      info!(loggers[core as usize], "A\nB\nC");
  
      Ok(())
  }
  
  fn main() {
      let decorator = slog_term::TermDecorator::new().build();
      let drain = slog_term::CompactFormat::new(decorator).build();
      let drain = std::sync::Mutex::new(drain).fuse();
  
      let log = slog::Logger::root(drain, o!());
  
      let mut integrator = cuba::CubaIntegrator::new(integrand);
      integrator.set_cores(10, 1000); // set 10 cores
  
      integrator.vegas(
          1,
          1,
          cuba::CubaVerbosity::Progress,
          0,
          vec![log.clone(); 11],
      );
  }
  </code></pre>
  
  <p>Output:</p>
  
  <pre class="lang-none prettyprint-override"><code>C 
  INFO Mar 26A
  B
  C 10:27
  :42.195 MarINFO 26  10:27A
  B
  C:42.195
   MarINFO 26  10:27A
  B
  C:42.195
   INFO A
  B
  C
  Mar 26 10:27:42.196 INFO A
  B
  C
  Mar 26 10:27:42.196 INFO A
  B
  C
  </code></pre>