1
0
Fork 0

Keep filters in ordered list, with most recent at head.

This commit is contained in:
Matt Goodall 2012-07-10 19:01:40 +01:00
parent c31efeffe5
commit 32bf10887c
1 changed files with 31 additions and 17 deletions

View File

@ -21,7 +21,7 @@ type XMPP struct {
// Incoming stanza filters. // Incoming stanza filters.
filterLock sync.Mutex filterLock sync.Mutex
nextFilterId FilterId nextFilterId FilterId
filters map[FilterId]filter filters []filter
} }
func newXMPP(jid JID, stream *Stream) *XMPP { func newXMPP(jid JID, stream *Stream) *XMPP {
@ -30,7 +30,6 @@ func newXMPP(jid JID, stream *Stream) *XMPP {
stream: stream, stream: stream,
in: make(chan interface{}), in: make(chan interface{}),
out: make(chan interface{}), out: make(chan interface{}),
filters: make(map[FilterId]filter),
} }
go x.sender() go x.sender()
go x.receiver() go x.receiver()
@ -76,34 +75,48 @@ func (x *XMPP) AddFilter(fn FilterFn) (FilterId, chan interface{}) {
// Protect against concurrent access. // Protect against concurrent access.
x.filterLock.Lock() x.filterLock.Lock()
defer x.filterLock.Lock() defer x.filterLock.Unlock()
// Create filter chan and add to map. // Allocate chan and id.
filterId := x.nextFilterId
x.nextFilterId ++
ch := make(chan interface{}) ch := make(chan interface{})
x.filters[filterId] = filter{fn, ch} id := x.nextFilterId
x.nextFilterId ++
return filterId, ch // Insert at head of filters list.
filters := make([]filter, len(x.filters)+1)
filters[0] = filter{id, fn, ch}
copy(filters[1:], x.filters)
x.filters = filters
return id, ch
} }
func (x *XMPP) RemoveFilter(id FilterId) error { func (x *XMPP) RemoveFilter(id FilterId) error {
// Protect against concurrent access. // Protect against concurrent access.
x.filterLock.Lock() x.filterLock.Lock()
defer x.filterLock.Lock() defer x.filterLock.Unlock()
// Find filter. // Find filter.
filter, ok := x.filters[id] for i, f := range x.filters {
if !ok { if f.id != id {
return id continue
} }
// Close filter channel and remove from map. // Close the channel.
close(filter.ch) close(f.ch)
delete(x.filters, id)
// Remove from list.
filters := make([]filter, len(x.filters)-1)
copy(filters, x.filters[:i])
copy(filters[i:], x.filters[i+1:])
x.filters = filters
return nil return nil
}
// Filter not found.
return id
} }
func IqResult(id string) FilterFn { func IqResult(id string) FilterFn {
@ -122,6 +135,7 @@ func IqResult(id string) FilterFn {
type FilterFn func(v interface{}) bool type FilterFn func(v interface{}) bool
type filter struct { type filter struct {
id FilterId
fn FilterFn fn FilterFn
ch chan interface{} ch chan interface{}
} }