mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-30 04:20:53 +00:00
160987318d
Update Task-Race-Conditions.md with complete final assessment:
Results:
- 3 real data races found and fixed (Issues 1, 2, 4-NEW)
- 4 false alarms identified (Issues 3, 4, 5, 6)
- 1 low-severity logic race — won't-fix (Issue 7)
False alarm analysis:
- Issue 3: ResourcesSet map is protected indirectly by list.Lock()
(all callers hold list.Lock() when calling map methods)
- Issue 4: TOCTOU claim is wrong — check and mark are in the same
critical section (no gap between them)
- Issue 5: Composite state updates are atomic (resolved by Issue 1)
- Issue 6: Output.Write() is a no-op stub (doesn't access shared state)
Won't-fix rationale (Issue 7):
- WaitForTaskByID post-deletion requires user to simultaneously wait
for AND delete the same task (conflicting API calls)
- No data corruption or panic — just a confusing error message
- User-error scenario, not a code defect
73 lines
1.5 KiB
Go
73 lines
1.5 KiB
Go
package task
|
|
|
|
import (
|
|
"sync"
|
|
"sync/atomic"
|
|
|
|
"github.com/aptly-dev/aptly/aptly"
|
|
)
|
|
|
|
// State task is in
|
|
type State int
|
|
|
|
// Detail represents custom task details
|
|
type Detail struct {
|
|
atomic.Value
|
|
}
|
|
|
|
// PublishDetail represents publish task details
|
|
type PublishDetail struct {
|
|
*Detail
|
|
TotalNumberOfPackages int64
|
|
RemainingNumberOfPackages int64
|
|
}
|
|
|
|
type ProcessReturnValue struct {
|
|
Code int
|
|
Value interface{}
|
|
}
|
|
|
|
// Process is a function implementing the actual task logic
|
|
type Process func(out aptly.Progress, detail *Detail) (*ProcessReturnValue, error)
|
|
|
|
const (
|
|
// IDLE when task is waiting
|
|
IDLE State = iota
|
|
// RUNNING when task is running
|
|
RUNNING
|
|
// SUCCEEDED when task is successfully finished
|
|
SUCCEEDED
|
|
// FAILED when task failed
|
|
FAILED
|
|
)
|
|
|
|
// Task represents as task in a queue encapsulates process code
|
|
// All fields are protected by List.Mutex - access task fields only while holding list.Lock()
|
|
type Task struct {
|
|
output *Output
|
|
detail *Detail
|
|
process Process
|
|
processReturnValue *ProcessReturnValue
|
|
err error
|
|
Name string
|
|
ID int
|
|
State State
|
|
resources []string
|
|
wgTask *sync.WaitGroup
|
|
}
|
|
|
|
// NewTask creates new task
|
|
func NewTask(process Process, name string, ID int, resources []string, wgTask *sync.WaitGroup) *Task {
|
|
task := &Task{
|
|
output: NewOutput(),
|
|
detail: &Detail{},
|
|
process: process,
|
|
Name: name,
|
|
ID: ID,
|
|
State: IDLE,
|
|
resources: resources,
|
|
wgTask: wgTask,
|
|
}
|
|
return task
|
|
}
|