safe_mutex.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // package safe_mutex -- безопасный мьютекс
  2. package safe_mutex
  3. import (
  4. "log"
  5. "sync"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/def_spec_base"
  7. )
  8. const (
  9. // Lock -- блокировка мьютекса
  10. Lock = def_spec_base.Num(1)
  11. // Unlock -- разблокировка мьютекса
  12. Unlock = def_spec_base.Num(0)
  13. // RLock -- блокировка мьютекса с чтением
  14. RLock = def_spec_base.Num(-1)
  15. )
  16. // MSafeMutex -- безопасный мьютекс.
  17. type MSafeMutex struct {
  18. block sync.Mutex // Блокирует операции мьютекса
  19. val sync.RWMutex // Фактическое значение мьютекса
  20. stateLock def_spec_base.Num // Значение блокировки
  21. }
  22. // MutSafeMutex -- возвращает новый безопасный мьютекс
  23. func MutSafeMutex() *MSafeMutex {
  24. sf := &MSafeMutex{}
  25. return sf
  26. }
  27. // Lock -- попытка захватить мьютекс
  28. func (sf *MSafeMutex) Lock() {
  29. sf.block.Lock()
  30. defer sf.block.Unlock()
  31. sf.val.Lock()
  32. sf.stateLock = 1
  33. }
  34. // Unlock -- освободить мьютекс
  35. func (sf *MSafeMutex) Unlock() {
  36. sf.block.Lock()
  37. defer sf.block.Unlock()
  38. if sf.stateLock == 0 {
  39. log.Println("ERROR MSafeMutex.Unlock(): mutex already free")
  40. return
  41. }
  42. sf.val.Unlock()
  43. sf.stateLock = 0
  44. }
  45. // RLock -- попытка захватить мьютекс
  46. func (sf *MSafeMutex) RLock() {
  47. sf.block.Lock()
  48. defer sf.block.Unlock()
  49. sf.val.RLock()
  50. sf.stateLock = -1
  51. }
  52. // RUnlock -- освободить мьютекс
  53. func (sf *MSafeMutex) RUnlock() {
  54. sf.block.Lock()
  55. defer sf.block.Unlock()
  56. if sf.stateLock == 0 {
  57. log.Println("ERROR MSafeMutex.Unlock(): mutex already free")
  58. return
  59. }
  60. sf.val.RUnlock()
  61. sf.stateLock = 0
  62. }
  63. // State -- возвращает признак захвата мьютекса
  64. func (sf *MSafeMutex) State() def_spec_base.Num {
  65. sf.block.Lock()
  66. defer sf.block.Unlock()
  67. return sf.stateLock
  68. }
  69. // IsFree -- возвращает признак свободного мьютекса
  70. func (sf *MSafeMutex) IsFree() def_spec_base.Bool {
  71. sf.block.Lock()
  72. defer sf.block.Unlock()
  73. return sf.stateLock == 0
  74. }