mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-06-10 16:43:58 +02:00
183 lines
3.6 KiB
Go
183 lines
3.6 KiB
Go
package gobackend
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"sync"
|
|
)
|
|
|
|
// ErrDownloadCancelled is returned when a download is cancelled by the user.
|
|
var ErrDownloadCancelled = errors.New("download cancelled")
|
|
|
|
// ErrExtensionRequestCancelled is returned when a UI-driven extension request
|
|
// is superseded by a newer home/search request.
|
|
var ErrExtensionRequestCancelled = errors.New("extension request cancelled")
|
|
|
|
type cancelEntry struct {
|
|
ctx context.Context
|
|
cancel context.CancelFunc
|
|
canceled bool
|
|
refs int
|
|
}
|
|
|
|
var (
|
|
cancelMu sync.Mutex
|
|
cancelMap = make(map[string]*cancelEntry)
|
|
|
|
extensionRequestCancelMu sync.Mutex
|
|
extensionRequestCancelMap = make(map[string]*cancelEntry)
|
|
)
|
|
|
|
func initDownloadCancel(itemID string) context.Context {
|
|
if itemID == "" {
|
|
return context.Background()
|
|
}
|
|
|
|
cancelMu.Lock()
|
|
defer cancelMu.Unlock()
|
|
|
|
if entry, ok := cancelMap[itemID]; ok {
|
|
if entry.ctx == nil {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
entry.ctx = ctx
|
|
entry.cancel = cancel
|
|
if entry.canceled && entry.cancel != nil {
|
|
entry.cancel()
|
|
}
|
|
}
|
|
entry.refs++
|
|
return entry.ctx
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancelMap[itemID] = &cancelEntry{
|
|
ctx: ctx,
|
|
cancel: cancel,
|
|
canceled: false,
|
|
refs: 1,
|
|
}
|
|
return ctx
|
|
}
|
|
|
|
func cancelDownload(itemID string) {
|
|
if itemID == "" {
|
|
return
|
|
}
|
|
|
|
cancelMu.Lock()
|
|
entry, ok := cancelMap[itemID]
|
|
if ok {
|
|
entry.canceled = true
|
|
if entry.cancel != nil {
|
|
entry.cancel()
|
|
}
|
|
} else {
|
|
cancelMap[itemID] = &cancelEntry{canceled: true}
|
|
}
|
|
cancelMu.Unlock()
|
|
|
|
RemoveItemProgress(itemID)
|
|
}
|
|
|
|
func isDownloadCancelled(itemID string) bool {
|
|
if itemID == "" {
|
|
return false
|
|
}
|
|
|
|
cancelMu.Lock()
|
|
entry, ok := cancelMap[itemID]
|
|
canceled := ok && entry.canceled
|
|
cancelMu.Unlock()
|
|
return canceled
|
|
}
|
|
|
|
func clearDownloadCancel(itemID string) {
|
|
if itemID == "" {
|
|
return
|
|
}
|
|
|
|
cancelMu.Lock()
|
|
if entry, ok := cancelMap[itemID]; ok {
|
|
entry.refs--
|
|
if entry.refs <= 0 {
|
|
delete(cancelMap, itemID)
|
|
}
|
|
}
|
|
cancelMu.Unlock()
|
|
}
|
|
|
|
func initExtensionRequestCancel(requestID string) context.Context {
|
|
if requestID == "" {
|
|
return context.Background()
|
|
}
|
|
|
|
extensionRequestCancelMu.Lock()
|
|
defer extensionRequestCancelMu.Unlock()
|
|
|
|
if entry, ok := extensionRequestCancelMap[requestID]; ok {
|
|
if entry.ctx == nil {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
entry.ctx = ctx
|
|
entry.cancel = cancel
|
|
if entry.canceled && entry.cancel != nil {
|
|
entry.cancel()
|
|
}
|
|
}
|
|
entry.refs++
|
|
return entry.ctx
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
extensionRequestCancelMap[requestID] = &cancelEntry{
|
|
ctx: ctx,
|
|
cancel: cancel,
|
|
canceled: false,
|
|
refs: 1,
|
|
}
|
|
return ctx
|
|
}
|
|
|
|
func cancelExtensionRequest(requestID string) {
|
|
if requestID == "" {
|
|
return
|
|
}
|
|
|
|
extensionRequestCancelMu.Lock()
|
|
if entry, ok := extensionRequestCancelMap[requestID]; ok {
|
|
entry.canceled = true
|
|
if entry.cancel != nil {
|
|
entry.cancel()
|
|
}
|
|
} else {
|
|
extensionRequestCancelMap[requestID] = &cancelEntry{canceled: true}
|
|
}
|
|
extensionRequestCancelMu.Unlock()
|
|
}
|
|
|
|
func isExtensionRequestCancelled(requestID string) bool {
|
|
if requestID == "" {
|
|
return false
|
|
}
|
|
|
|
extensionRequestCancelMu.Lock()
|
|
entry, ok := extensionRequestCancelMap[requestID]
|
|
canceled := ok && entry.canceled
|
|
extensionRequestCancelMu.Unlock()
|
|
return canceled
|
|
}
|
|
|
|
func clearExtensionRequestCancel(requestID string) {
|
|
if requestID == "" {
|
|
return
|
|
}
|
|
|
|
extensionRequestCancelMu.Lock()
|
|
if entry, ok := extensionRequestCancelMap[requestID]; ok {
|
|
entry.refs--
|
|
if entry.refs <= 0 {
|
|
delete(extensionRequestCancelMap, requestID)
|
|
}
|
|
}
|
|
extensionRequestCancelMu.Unlock()
|
|
}
|