core: Multi machine use of active_machines requires locking of index
Ensure multi machine access of other machine state information through iterating `active_machines` and retrieval of cached machines cannot have multiple threads update the state of machines simultaneously as this triggers a Machine Lock exception. Machine state information retrieved from the index, returns a locked object. Since iteration of active_machine, and retrieval of each machine from the cache can be triggered by any plugin, it is possible for another machine to inadvertently access the state and trigger an update, which the thread owning the machine is currently in the process of updating it already. This results in a Machine Locked exception occurring if the attempt to retrieve the cached state from the index occurs before the other thread calls release. Partially-Fixes: #6526
This commit is contained in:
parent
b0aec1d162
commit
36ad4d53cf
|
@ -109,6 +109,7 @@ module Vagrant
|
|||
@provider_options = provider_options
|
||||
@ui = Vagrant::UI::Prefixed.new(@env.ui, @name)
|
||||
@ui_mutex = Mutex.new
|
||||
@state_mutex = Mutex.new
|
||||
|
||||
# Read the ID, which is usually in local storage
|
||||
@id = nil
|
||||
|
@ -505,11 +506,17 @@ module Vagrant
|
|||
# master index.
|
||||
uuid = index_uuid
|
||||
if uuid
|
||||
entry = @env.machine_index.get(uuid)
|
||||
if entry
|
||||
entry.state = result.short_description
|
||||
@env.machine_index.set(entry)
|
||||
@env.machine_index.release(entry)
|
||||
# active_machines provides access to query this info on each machine
|
||||
# from a different thread, ensure multiple machines do not access
|
||||
# the locked entry simultaneously as this triggers a locked machine
|
||||
# exception.
|
||||
@state_mutex.synchronize do
|
||||
entry = @env.machine_index.get(uuid)
|
||||
if entry
|
||||
entry.state = result.short_description
|
||||
@env.machine_index.set(entry)
|
||||
@env.machine_index.release(entry)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue