github.com/alimy/mir/v4@v4.1.0/internal/internal.go (about) 1 // Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved. 2 // Use of this source code is governed by Apache License 2.0 that 3 // can be found in the LICENSE file. 4 5 package internal 6 7 import ( 8 "context" 9 "sync" 10 11 "github.com/alimy/mir/v4/core" 12 13 _ "github.com/alimy/mir/v4/internal/generator" 14 _ "github.com/alimy/mir/v4/internal/parser" 15 ) 16 17 type mirCtx struct { 18 context.Context 19 20 mu *sync.Mutex 21 err error 22 capacity int 23 ifaceChan chan *core.IfaceDescriptor 24 generatorDone chan struct{} 25 cancelFunc context.CancelFunc 26 } 27 28 // Err return cancel error 29 func (c *mirCtx) Err() error { 30 c.mu.Lock() 31 defer c.mu.Unlock() 32 33 return c.err 34 } 35 36 // ChanCapacity return ifaceChan's capacity 37 func (c *mirCtx) Capcity() int { 38 return c.capacity 39 } 40 41 // Cancel cancel mir's process logic with an error 42 func (c *mirCtx) Cancel(err error) { 43 c.mu.Lock() 44 defer c.mu.Unlock() 45 46 if c.err != nil { 47 c.err = err 48 c.cancelFunc() 49 } 50 } 51 52 // ParserDone indicate parser done 53 func (c *mirCtx) ParserDone() { 54 close(c.ifaceChan) 55 } 56 57 // GeneratorDone indicate generator done 58 func (c *mirCtx) GeneratorDone() { 59 close(c.generatorDone) 60 } 61 62 // Wait wait for end of process 63 func (c *mirCtx) Wait() error { 64 select { 65 case <-c.Done(): 66 case <-c.generatorDone: 67 } 68 return c.Err() 69 } 70 71 // Pipe return source/sink chan *IfaceDescriptor 72 func (c *mirCtx) Pipe() (<-chan *core.IfaceDescriptor, chan<- *core.IfaceDescriptor) { 73 return c.ifaceChan, c.ifaceChan 74 } 75 76 // NewMirCtx return a new mir's context instance 77 func NewMirCtx(capcity int) core.MirCtx { 78 ctx := &mirCtx{ 79 mu: &sync.Mutex{}, 80 capacity: capcity, 81 generatorDone: make(chan struct{}), 82 ifaceChan: make(chan *core.IfaceDescriptor, capcity), 83 } 84 ctx.Context, ctx.cancelFunc = context.WithCancel(context.Background()) 85 return ctx 86 }