wgname.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. // package wgname -- ожидатель группы по имени для завершения
  2. package wgname
  3. import (
  4. "fmt"
  5. "sync"
  6. "wartank/pkg/components/safebool"
  7. )
  8. // WgName -- ожидатель группы завершения
  9. type WgName struct {
  10. dictName map[string]bool // Словарь имён потоков
  11. chEnd chan int // Канал сигнала закрытия ожидания
  12. isWork *safebool.SafeBool // Признак работы ожидания
  13. block sync.RWMutex
  14. }
  15. // NewWgName -- возвращает новый ожидатель группы
  16. func NewWgName() *WgName {
  17. sf := &WgName{
  18. dictName: make(map[string]bool),
  19. chEnd: make(chan int, 1),
  20. isWork: safebool.NewSafeBool(),
  21. }
  22. sf.isWork.Set()
  23. return sf
  24. }
  25. // Add -- добавляет имя в группу ожидания
  26. func (sf *WgName) Add(name string) error {
  27. sf.block.Lock()
  28. defer sf.block.Unlock()
  29. _, isOk := sf.dictName[name]
  30. if isOk {
  31. return fmt.Errorf("WgName.Add(): name %q already exists", name)
  32. }
  33. sf.dictName[name] = true
  34. return nil
  35. }
  36. // Done -- отмечает словарь ожидания готовности потока
  37. func (sf *WgName) Done(name string) error {
  38. sf.block.Lock()
  39. defer sf.block.Unlock()
  40. _, isOk := sf.dictName[name]
  41. if !isOk {
  42. return fmt.Errorf("WgName.Done(): name %q not exists", name)
  43. }
  44. delete(sf.dictName, name)
  45. if !sf.isWork.Get() {
  46. return nil
  47. }
  48. if len(sf.dictName) == 0 {
  49. sf.isWork.Reset()
  50. close(sf.chEnd)
  51. }
  52. return nil
  53. }
  54. // Wait -- ожидание закрытия группы
  55. func (sf *WgName) Wait() {
  56. <-sf.chEnd
  57. }