// package kctx -- контекст ядра. package kctx import ( "context" "fmt" "sync" mKt "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes" mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kernel_keeper" "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kwg" ) // kCtx -- контекст ядра. type kCtx struct { mKt.ILocalCtx log mKt.ILogBuf ctxBg context.Context // Неотменяемый контекст ядра ctx context.Context // Отменяемый контекст ядра fnCancel func() // Функция отмены контекста ядра kernKeeper mKt.IKernelKeeper // Встроенный сторож отмены контекста системным сигналом kernWg mKt.IKernelWg // Встроенный ожидатель потока } var ( kernCtx *kCtx // Глобальный объект контекста приложения block sync.Mutex ) // GetKernelCtx -- возвращает контекст ядра. func GetKernelCtx() mKt.IResult[*kCtx] { block.Lock() defer block.Unlock() if kernCtx != nil { return mL1.NewRes(kernCtx) } ctxBg := context.Background() ctx, fnCancel := context.WithCancel(ctxBg) sf := &kCtx{ ctxBg: ctxBg, ctx: ctx, fnCancel: fnCancel, } resLocal := mL1.NewLocalCtx(sf.ctx) if resLocal.IsErr() { err := fmt.Errorf("GetKernelCtx(): in get local ctx, err=\n\t%w", resLocal.Err()) return mL1.NewErr[*kCtx](err) } sf.ILocalCtx = resLocal.Val() sf.log = sf.Log() sf.kernWg = kwg.GetKernelWg(sf.ctx) resKeep := kernel_keeper.GetKernelKeeper(sf.ctx, sf.fnCancel, sf.kernWg) if resKeep.IsErr() { sf.log.Err("GetKernelCtx(): in get kernel keeper, err=\n\t%w", resKeep.Err()) return nil } sf.kernKeeper = resKeep.Val() kernCtx = sf return mL1.NewRes(kernCtx) } // Keeper -- возвращает сторож системных сигналов. func (sf *kCtx) Keeper() mKt.IKernelKeeper { return sf.kernKeeper } // Wg -- возвращает ожидатель потоков. func (sf *kCtx) Wg() mKt.IKernelWg { return sf.kernWg } // Done -- блокирующий вызов ожидания отмены контекста ядра. func (sf *kCtx) Done() { <-sf.ctx.Done() sf.log.Debug("kCtx.Done()") } // CtxBg -- возвращает неотменяемый контекст ядра (лучше не использовать). func (sf *kCtx) CtxBg() context.Context { return sf.ctxBg } // Cancel -- отменяет контекст ядра. func (sf *kCtx) Cancel() { sf.fnCancel() sf.log.Debug("kCtx.Cancel()") }