event.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
  2. package event
  3. import (
  4. "math/rand"
  5. "sync"
  6. "time"
  7. )
  8. func init() {
  9. rand.Seed(time.Now().UnixNano())
  10. }
  11. type EventHandler func(v interface{}) error
  12. type Event struct {
  13. sync.RWMutex
  14. handlers map[int64]EventHandler
  15. }
  16. func (e *Event) Attach(handler EventHandler) int64 {
  17. e.Lock()
  18. defer e.Unlock()
  19. for {
  20. n := rand.Int63()
  21. _, ok := e.handlers[n]
  22. if !ok {
  23. e.handlers[n] = handler
  24. return n
  25. }
  26. }
  27. }
  28. func (e *Event) Detach(handle int64) {
  29. e.Lock()
  30. delete(e.handlers, handle)
  31. e.Unlock()
  32. }
  33. func (e *Event) DetachAll() {
  34. e.Lock()
  35. e.handlers = nil
  36. e.Unlock()
  37. }
  38. func (e *Event) publish(v interface{}) {
  39. e.Lock()
  40. for k, h := range e.handlers {
  41. // if call e.Lock() in h(v), should deadlock,
  42. // so must Unlock, and then Lock
  43. e.Unlock()
  44. if h(v) != nil {
  45. e.Detach(k)
  46. }
  47. e.Lock()
  48. }
  49. e.Unlock()
  50. }
  51. type EventPublisher struct {
  52. event Event
  53. }
  54. func (p *EventPublisher) Event() *Event {
  55. if p.event.handlers == nil {
  56. p.event.handlers = make(map[int64]EventHandler)
  57. }
  58. return &p.event
  59. }
  60. func (p *EventPublisher) Publish(v interface{}) {
  61. p.event.publish(v)
  62. }