// package kern_ctx -- контекст ядра. package kern_ctx import ( "context" "gitp78su.ipnodns.ru/svi/kern/v4/d0" "gitp78su.ipnodns.ru/svi/kern/v4/d1" "gitp78su.ipnodns.ru/svi/kern/v4/d1/local_ctx" "gitp78su.ipnodns.ru/svi/kern/v4/d2/kernel_keeper" "gitp78su.ipnodns.ru/svi/kern/v4/d2/kspec" "gitp78su.ipnodns.ru/svi/kern/v4/d2/kwg" ) // KernCtx -- контекст ядра. type KernCtx struct { *d1.LocalCtx log *d1.LogBuf ctxBg context.Context // Неотменяемый контекст ядра ctx context.Context // Отменяемый контекст ядра fnCancel func() // Функция отмены контекста ядра kernKeeper *kernel_keeper.KernKeeper // Встроенный сторож отмены контекста системным сигналом kernWg kspec.IKernelWg // Встроенный ожидатель потока } var ( kernCtx *KernCtx // Глобальный объект контекста приложения ctxBg context.Context internalCtx context.Context internalFnCancel func() block *d0.MSafeMutex ) func _init() { block = d0.MutSafeMutex() ctxBg = context.Background() internalCtx, internalFnCancel = context.WithCancel(ctxBg) } func init() { _init() } // GetIntenalCtx -- возвроащает внутренний контекст func GetInternalCtx() (context.Context, func()) { block.Lock() defer block.Unlock() return internalCtx, internalFnCancel } // GetKernCtx -- возвращает контекст ядра. func GetKernCtx() *KernCtx { block.Lock() defer block.Unlock() if kernCtx != nil { return kernCtx } owner := d0.LetOwner(1, "kern_ctx") sf := &KernCtx{ LocalCtx: local_ctx.NewLocalCtx(owner, internalCtx), ctxBg: ctxBg, ctx: internalCtx, fnCancel: internalFnCancel, } sf.log = sf.Log() sf.kernWg = kwg.GetKernelWg(sf.ctx) kKeep := kernel_keeper.GetKernelKeeper(sf.ctx, sf.fnCancel, sf.kernWg) sf.kernKeeper = kKeep kernCtx = sf return kernCtx } // Keeper -- возвращает сторож системных сигналов. func (sf *KernCtx) Keeper() *kernel_keeper.KernKeeper { return sf.kernKeeper } // Wg -- возвращает ожидатель потоков. func (sf *KernCtx) Wg() kspec.IKernelWg { return sf.kernWg } // AllDone -- блокирующий вызов ожидания отмены контекста ядра. func (sf *KernCtx) AllDone() { <-sf.ctx.Done() sf.log.Debug("kCtx.Done()") } // CtxBg -- возвращает неотменяемый контекст ядра (лучше не использовать). func (sf *KernCtx) CtxBg() context.Context { return sf.ctxBg } // Cancel -- отменяет контекст ядра. func (sf *KernCtx) Cancel() { sf.fnCancel() sf.log.Debug("kCtx.Cancel()") }