mirror of
https://github.com/discourse/discourse.git
synced 2025-05-31 11:58:33 +08:00
This reverts commit 4f677854d3df2555ddeaa1d02c228960d33e0248.
This commit is contained in:

committed by
GitHub

parent
8eb2147f1f
commit
8cc09fc668
@ -30,7 +30,7 @@ module Concurrency
|
||||
end
|
||||
|
||||
def choose_with_weights(*options)
|
||||
choose(*options.map(&:first))
|
||||
choose(options.map(&:first))
|
||||
end
|
||||
|
||||
def dead_end
|
||||
@ -147,11 +147,10 @@ module Concurrency
|
||||
def initialize(path)
|
||||
@path = path
|
||||
@tasks = []
|
||||
@time = 0
|
||||
end
|
||||
|
||||
def yield
|
||||
sleep(0)
|
||||
Fiber.yield
|
||||
end
|
||||
|
||||
def choose(*options)
|
||||
@ -162,86 +161,30 @@ module Concurrency
|
||||
@path.choose_with_weights(*options)
|
||||
end
|
||||
|
||||
def stop_other_tasks
|
||||
@tasts = @tasks.select! { |task| task[:fiber] == Fiber.current }
|
||||
end
|
||||
|
||||
def sleep(length)
|
||||
Fiber.yield(@time + length)
|
||||
end
|
||||
|
||||
def start_root(&blk)
|
||||
descriptor = {
|
||||
fiber: Fiber.new(&blk),
|
||||
run_at: 0
|
||||
}
|
||||
|
||||
@tasks << descriptor
|
||||
end
|
||||
|
||||
def spawn(&blk)
|
||||
descriptor = {
|
||||
fiber: Fiber.new(&blk),
|
||||
run_at: @time
|
||||
}
|
||||
|
||||
@tasks << descriptor
|
||||
|
||||
self.yield
|
||||
@tasks << Fiber.new(&blk)
|
||||
end
|
||||
|
||||
def run(sleep_order: false)
|
||||
def run
|
||||
until @tasks.empty?
|
||||
descriptor =
|
||||
if sleep_order
|
||||
@tasks.sort_by! { |x| x[:run_at] }
|
||||
run_at = @tasks.first[:run_at]
|
||||
@path.choose(*@tasks.take_while { |x| x[:run_at] == run_at })
|
||||
else
|
||||
@path.choose(*@tasks)
|
||||
end
|
||||
|
||||
@time = [@time, descriptor[:run_at]].max
|
||||
fiber = descriptor[:fiber]
|
||||
|
||||
begin
|
||||
run_at = fiber.resume
|
||||
rescue Exception
|
||||
end
|
||||
|
||||
if fiber.alive?
|
||||
descriptor[:run_at] = run_at
|
||||
else
|
||||
@tasks.delete(descriptor)
|
||||
task = @path.choose(*@tasks)
|
||||
task.resume
|
||||
unless task.alive?
|
||||
@tasks.delete(task)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def wait_done
|
||||
until @tasks.size == 1
|
||||
self.sleep(1e9)
|
||||
end
|
||||
end
|
||||
|
||||
def new_mutex
|
||||
Mutex.new(self)
|
||||
end
|
||||
end
|
||||
|
||||
def run_with_path(path, sleep_order: false)
|
||||
def run_with_path(path)
|
||||
execution = Execution.new(path)
|
||||
result = {}
|
||||
execution.start_root {
|
||||
result[:value] = @blk.call(execution)
|
||||
}
|
||||
execution.run(sleep_order: sleep_order)
|
||||
result = @blk.call(execution)
|
||||
execution.run
|
||||
result
|
||||
end
|
||||
|
||||
def run(sleep_order: false, **opts)
|
||||
Logic.run(**opts) do |path|
|
||||
run_with_path(path, sleep_order: sleep_order)
|
||||
end
|
||||
def run(**opts)
|
||||
Logic.run(**opts, &method(:run_with_path))
|
||||
end
|
||||
end
|
||||
|
||||
@ -307,45 +250,4 @@ module Concurrency
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
class Mutex
|
||||
def initialize(execution)
|
||||
@execution = execution
|
||||
@locked_by = nil
|
||||
end
|
||||
|
||||
def lock
|
||||
@execution.yield
|
||||
|
||||
fiber = Fiber.current
|
||||
while true
|
||||
if @locked_by.nil?
|
||||
@locked_by = fiber
|
||||
return
|
||||
elsif @locked_by == fiber
|
||||
raise ThreadError, "deadlock; recursive locking"
|
||||
else
|
||||
@execution.yield
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def unlock
|
||||
@execution.yield
|
||||
|
||||
if @locked_by != Fiber.current
|
||||
raise ThreadError, "Attempt to unlock a mutex which is locked by another thread"
|
||||
end
|
||||
@locked_by = nil
|
||||
end
|
||||
|
||||
def synchronize
|
||||
lock
|
||||
begin
|
||||
yield
|
||||
ensure
|
||||
unlock
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user