     parent = self()
     file = Path.expand(file)
 
-    if should_spawn?(output, file) do
-      {pid, ref} =
-        :erlang.spawn_monitor(fn ->
-          :erlang.put(:elixir_compiler_pid, parent)
-          :erlang.put(:elixir_compiler_file, file)
-
-          try do
-            case output do
-              {:compile, path} ->
-                :erlang.process_flag(:error_handler, Kernel.ErrorHandler)
-                :erlang.put(:elixir_compiler_dest, path)
-                :elixir_compiler.file_to_path(file, path, &each_file(&1, &2, parent))
-
-              :compile ->
-                :erlang.process_flag(:error_handler, Kernel.ErrorHandler)
-                :erlang.put(:elixir_compiler_dest, dest)
-                :elixir_compiler.file(file, &each_file(&1, &2, parent))
-
-              :require ->
-                :elixir_compiler.file(file, &each_file(&1, &2, parent))
-                :elixir_code_server.cast({:required, file})
-            end
-          catch
-            kind, reason ->
-              send(parent, {:file_error, self(), file, {kind, reason, __STACKTRACE__}})
+    {pid, ref} =
+      :erlang.spawn_monitor(fn ->
+        :erlang.put(:elixir_compiler_pid, parent)
+        :erlang.put(:elixir_compiler_file, file)
+
+        try do
+          case output do
+            {:compile, path} ->
+              :erlang.process_flag(:error_handler, Kernel.ErrorHandler)
+              :erlang.put(:elixir_compiler_dest, path)
+              :elixir_compiler.file_to_path(file, path, &each_file(&1, &2, parent))
+
+            :compile ->
+              :erlang.process_flag(:error_handler, Kernel.ErrorHandler)
+              :erlang.put(:elixir_compiler_dest, dest)
+              :elixir_compiler.file(file, &each_file(&1, &2, parent))
+
+            :require ->
+              case :elixir_code_server.call({:acquire, file}) do
+                :required ->
+                  send(parent, {:file_cancel, self()})
+
+                :proceed ->
+                  :elixir_compiler.file(file, &each_file(&1, &2, parent))
+                  :elixir_code_server.cast({:required, file})
+              end
           end
-
-          exit(:shutdown)
-        end)
-
-      timer_ref = Process.send_after(self(), {:timed_out, pid}, threshold * 1000)
-      files = [{pid, ref, file, timer_ref} | files]
-      spawn_workers(queue, spawned + 1, waiting, files, result, warnings, state)
-    else
-      spawn_workers(queue, spawned, waiting, files, result, warnings, state)
-    end
+        catch
+          kind, reason ->
+            send(parent, {:file_error, self(), file, {kind, reason, __STACKTRACE__}})
+        end
+
+        exit(:shutdown)
+      end)
+
+    timer_ref = Process.send_after(self(), {:timed_out, pid}, threshold * 1000)
+    files = [{pid, ref, file, timer_ref} | files]
+    spawn_workers(queue, spawned + 1, waiting, files, result, warnings, state)
   end
 
   # No more queue, nothing waiting, this cycle is done


      {:timed_out, child} ->
        case List.keyfind(files, child, 0) do
          {^child, _, file, _} ->
            state.each_long_compilation.(file)

          _ ->
            :ok
        end

        spawn_workers(queue, spawned, waiting, files, result, warnings, state)

        send(child, {ref, :ack})

        available =
          for {:module, _, ref, ^module, _defining, _deadlock?} <- waiting,
              do: {ref, :found}

        cancel_waiting_timer(files, child)
        result = [{:module, module} | result]
        spawn_workers(available ++ queue, spawned, waiting, files, result, warnings, state)

