kctx.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // package kctx -- контекст ядра.
  2. package kctx
  3. import (
  4. "context"
  5. "fmt"
  6. "sync"
  7. mL0 "gitp78su.ipnodns.ru/svi/kern/v4/lev0"
  8. mKt "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes"
  9. mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kernel_keeper"
  11. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kwg"
  12. )
  13. // kCtx -- контекст ядра.
  14. type kCtx struct {
  15. mKt.ILocalCtx
  16. log mKt.ILogBuf
  17. ctxBg context.Context // Неотменяемый контекст ядра
  18. ctx context.Context // Отменяемый контекст ядра
  19. fnCancel func() // Функция отмены контекста ядра
  20. kernKeeper mKt.IKernelKeeper // Встроенный сторож отмены контекста системным сигналом
  21. kernWg mKt.IKernelWg // Встроенный ожидатель потока
  22. }
  23. var (
  24. kernCtx *kCtx // Глобальный объект контекста приложения
  25. block sync.Mutex
  26. )
  27. // GetKernelCtx -- возвращает контекст ядра.
  28. func GetKernelCtx() *mL0.Result[*kCtx] {
  29. block.Lock()
  30. defer block.Unlock()
  31. if kernCtx != nil {
  32. return mL0.NewRes(kernCtx)
  33. }
  34. ctxBg := context.Background()
  35. ctx, fnCancel := context.WithCancel(ctxBg)
  36. sf := &kCtx{
  37. ctxBg: ctxBg,
  38. ctx: ctx,
  39. fnCancel: fnCancel,
  40. }
  41. resLocal := mL1.NewLocalCtx(sf.ctx)
  42. if resLocal.IsErr() {
  43. err := fmt.Errorf("GetKernelCtx(): in get local ctx, err=\n\t%w", resLocal.Err())
  44. return mL0.NewErr[*kCtx](err)
  45. }
  46. sf.ILocalCtx = resLocal.Val()
  47. sf.log = sf.Log()
  48. sf.kernWg = kwg.GetKernelWg(sf.ctx)
  49. resKeep := kernel_keeper.GetKernelKeeper(sf.ctx, sf.fnCancel, sf.kernWg)
  50. if resKeep.IsErr() {
  51. sf.log.Err("GetKernelCtx(): in get kernel keeper, err=\n\t%w", resKeep.Err())
  52. return nil
  53. }
  54. sf.kernKeeper = resKeep.Val()
  55. kernCtx = sf
  56. return mL0.NewRes(kernCtx)
  57. }
  58. // Keeper -- возвращает сторож системных сигналов.
  59. func (sf *kCtx) Keeper() mKt.IKernelKeeper {
  60. return sf.kernKeeper
  61. }
  62. // Wg -- возвращает ожидатель потоков.
  63. func (sf *kCtx) Wg() mKt.IKernelWg {
  64. return sf.kernWg
  65. }
  66. // Done -- блокирующий вызов ожидания отмены контекста ядра.
  67. func (sf *kCtx) Done() {
  68. <-sf.ctx.Done()
  69. sf.log.Debug("kCtx.Done()")
  70. }
  71. // CtxBg -- возвращает неотменяемый контекст ядра (лучше не использовать).
  72. func (sf *kCtx) CtxBg() context.Context {
  73. return sf.ctxBg
  74. }
  75. // Cancel -- отменяет контекст ядра.
  76. func (sf *kCtx) Cancel() {
  77. sf.fnCancel()
  78. sf.log.Debug("kCtx.Cancel()")
  79. }