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  }