diff --git a/cmd/olliesrv/server.go b/cmd/olliesrv/server.go index 392fbca..c1ac51c 100644 --- a/cmd/olliesrv/server.go +++ b/cmd/olliesrv/server.go @@ -606,46 +606,47 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p // lives until the client disconnects or clunks the fid clientConnCtx := cs.ctx cs.mu.RUnlock() - if fidOK { + if !fidOK { + return errFcall(fc, "bad fid") + } + f.mu.Lock() + filter := f.eventFilter + eventCh := f.eventCh + f.mu.Unlock() + + // Create subscription on first read (filter defaults to "*" for all events) + if eventCh == nil { + if filter == "" { + filter = "*" + } + subCtx, cancel := context.WithCancel(clientConnCtx) + ch := session.SubscribeEventsFiltered(subCtx, filter) f.mu.Lock() - filter := f.eventFilter - eventCh := f.eventCh + f.eventFilter = filter + f.eventCh = ch + f.eventCancel = cancel f.mu.Unlock() + eventCh = ch + } - // Create subscription on first read (filter defaults to "*" for all events) - if eventCh == nil { - if filter == "" { - filter = "*" - } - subCtx, cancel := context.WithCancel(clientConnCtx) - ch := session.SubscribeEventsFiltered(subCtx, filter) - f.mu.Lock() - f.eventFilter = filter - f.eventCh = ch - f.eventCancel = cancel - f.mu.Unlock() - eventCh = ch + // Read from subscription — blocks until event arrives + select { + case ev, ok := <-eventCh: + if !ok { + return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: 0} } - - // Read from subscription — blocks until event arrives - select { - case ev, ok := <-eventCh: - if !ok { - return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: 0} - } - line := ev.Topic - if ev.Payload != "" { - line += " " + ev.Payload - } - content := []byte(line + "\n") - count := int(fc.Count) - if count > len(content) { - count = len(content) - } - return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(count), Data: content[:count]} - case <-ctx.Done(): - return errFcall(fc, "interrupted") + line := ev.Topic + if ev.Payload != "" { + line += " " + ev.Payload } + content := []byte(line + "\n") + count := int(fc.Count) + if count > len(content) { + count = len(content) + } + return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(count), Data: content[:count]} + case <-ctx.Done(): + return errFcall(fc, "interrupted") } }