mirror of https://github.com/XTLS/Xray-core
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
885 B
52 lines
885 B
package task |
|
|
|
import ( |
|
"context" |
|
|
|
"github.com/xtls/xray-core/common/signal/semaphore" |
|
) |
|
|
|
// OnSuccess executes g() after f() returns nil. |
|
func OnSuccess(f func() error, g func() error) func() error { |
|
return func() error { |
|
if err := f(); err != nil { |
|
return err |
|
} |
|
return g() |
|
} |
|
} |
|
|
|
// Run executes a list of tasks in parallel, returns the first error encountered or nil if all tasks pass. |
|
func Run(ctx context.Context, tasks ...func() error) error { |
|
n := len(tasks) |
|
s := semaphore.New(n) |
|
done := make(chan error, 1) |
|
|
|
for _, task := range tasks { |
|
<-s.Wait() |
|
go func(f func() error) { |
|
err := f() |
|
if err == nil { |
|
s.Signal() |
|
return |
|
} |
|
|
|
select { |
|
case done <- err: |
|
default: |
|
} |
|
}(task) |
|
} |
|
|
|
for i := 0; i < n; i++ { |
|
select { |
|
case err := <-done: |
|
return err |
|
case <-ctx.Done(): |
|
return ctx.Err() |
|
case <-s.Wait(): |
|
} |
|
} |
|
|
|
return nil |
|
}
|
|
|