blob: 2a16fdad1a0ee2e6912dd9b7bd20dc9713d0c2c9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package pool
import (
"context"
"sync/atomic"
"time"
"github.com/pkg/errors"
)
//go:generate go tool plc4xGenerator -type=future
type future struct {
cancelRequested atomic.Bool
interruptRequested atomic.Bool
completed atomic.Bool
errored atomic.Bool
err atomic.Value
}
func (f *future) Cancel(interrupt bool, err error) {
f.cancelRequested.Store(true)
f.interruptRequested.Store(interrupt)
if err != nil {
f.errored.Store(true)
f.err.Store(err)
}
}
func (f *future) complete() {
f.completed.Store(true)
}
// Canceled is returned on CompletionFuture.AwaitCompletion when a CompletionFuture was canceled
var Canceled = errors.New("Canceled")
func (f *future) AwaitCompletion(ctx context.Context) error {
for !f.completed.Load() && !f.errored.Load() && !f.cancelRequested.Load() && ctx.Err() == nil {
time.Sleep(10 * time.Millisecond)
}
if err := ctx.Err(); err != nil {
return err
}
if err, ok := f.err.Load().(error); ok {
return err
}
if f.cancelRequested.Load() {
return Canceled
}
return nil
}