diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 5c7a6005b35..7d5c47cc5e0 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -352,6 +352,11 @@ defmodule Mix do * `MIX_INSTALL_DIR` *(since v1.12.0)* - specifies directory where `Mix.install/2` keeps install cache + * `MIX_OS_CONCURRENCY_LOCK` - when set to `0` or `false`, disables mix compilation locking. + While not recommended, this may be necessary in cases where hard links or TCP sockets are + not available. When opting for this behaviour, make sure to not start concurrent compilations + of the same project. + * `MIX_PATH` - appends extra code paths * `MIX_PROFILE` - a list of comma-separated Mix tasks to profile the time spent on diff --git a/lib/mix/lib/mix/sync/lock.ex b/lib/mix/lib/mix/sync/lock.ex index 5253d610e09..dc65e57713c 100644 --- a/lib/mix/lib/mix/sync/lock.ex +++ b/lib/mix/lib/mix/sync/lock.ex @@ -79,6 +79,10 @@ defmodule Mix.Sync.Lock do This function can also be called if this process already has the lock. In such case the function is executed immediately. + When the `MIX_OS_CONCURRENCY_LOCK` environment variable is set to + a falsy value, the lock is ignored and the function is executed + immediately. + ## Options * `:on_taken` - a one-arity function called if the lock is held @@ -96,9 +100,9 @@ defmodule Mix.Sync.Lock do path = Path.join([System.tmp_dir!(), "mix_lock", hash]) pdict_key = {__MODULE__, path} - has_lock? = Process.get(pdict_key) + has_lock? = Process.get(pdict_key, false) - if has_lock? do + if has_lock? or lock_disabled?() do fun.() else lock = lock(path, opts[:on_taken]) @@ -115,6 +119,8 @@ defmodule Mix.Sync.Lock do end end + defp lock_disabled?(), do: System.get_env("MIX_OS_CONCURRENCY_LOCK") in ~w(0 false) + defp lock(path, on_taken) do File.mkdir_p!(path) @@ -198,11 +204,12 @@ defmodule Mix.Sync.Lock do :invalidated {:error, reason} -> - raise File.LinkError, - reason: reason, - action: "create hard link", - existing: port_path, - new: lock_path + Mix.raise(""" + could not create hard link from #{port_path} to "#{lock_path}: #{:file.format_error(reason)}. + + Hard link support is required for Mix compilation locking. If your system \ + does not support hard links, set MIX_OS_CONCURRENCY_LOCK=0\ + """) end end