github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/funcid.go (about)

     1  package lang
     2  
     3  import (
     4  	"errors"
     5  	"sort"
     6  	"sync"
     7  	"sync/atomic"
     8  
     9  	"github.com/lmorg/murex/debug"
    10  )
    11  
    12  // FID (Function ID) table: ie table of murex `Process` processes
    13  type funcID struct {
    14  	list   map[uint32]*Process
    15  	init   map[uint32]*Process
    16  	mutex  sync.Mutex
    17  	latest uint32
    18  }
    19  
    20  // newFuncID creates new FID (Function ID) table of `Process`es
    21  func newFuncID() *funcID {
    22  	f := new(funcID)
    23  	f.init = make(map[uint32]*Process)
    24  	f.list = make(map[uint32]*Process)
    25  	return f
    26  }
    27  
    28  // Register process to assign it a FID (Function ID)
    29  func (f *funcID) Register(p *Process) (fid uint32) {
    30  	fid = atomic.AddUint32(&f.latest, 1)
    31  
    32  	f.mutex.Lock()
    33  	f.init[fid] = p
    34  	//f.mutex.Unlock()
    35  
    36  	p.Id = fid
    37  
    38  	//ptr := (*unsafe.Pointer)(unsafe.Pointer(&p.Variables.process))
    39  	//atomic.StorePointer(ptr, unsafe.Pointer(p))
    40  	p.Variables.process = p
    41  	f.mutex.Unlock()
    42  
    43  	return
    44  }
    45  
    46  // Executing moves the function from init to list
    47  func (f *funcID) Executing(fid uint32) error {
    48  
    49  	f.mutex.Lock()
    50  	p := f.init[fid]
    51  
    52  	if p == nil {
    53  		f.mutex.Unlock()
    54  		return errors.New("function ID not in init map")
    55  	}
    56  
    57  	delete(f.init, fid)
    58  	f.list[fid] = p
    59  	f.mutex.Unlock()
    60  
    61  	return nil
    62  }
    63  
    64  // Deregister removes function from the FID table
    65  func (f *funcID) Deregister(fid uint32) {
    66  	if debug.Enabled {
    67  		return
    68  	}
    69  
    70  	f.mutex.Lock()
    71  	delete(f.list, fid)
    72  	f.mutex.Unlock()
    73  }
    74  
    75  // Proc gets process by FID
    76  func (f *funcID) Proc(fid uint32) (*Process, error) {
    77  	if fid == 0 {
    78  		return nil, errors.New("FID 0 is reserved for the shell")
    79  	}
    80  
    81  	f.mutex.Lock()
    82  	p := f.list[fid]
    83  
    84  	if p != nil {
    85  		f.mutex.Unlock()
    86  		return p, nil
    87  	}
    88  
    89  	p = f.init[fid]
    90  	f.mutex.Unlock()
    91  
    92  	if p != nil {
    93  		return nil, errors.New("function hasn't started yet")
    94  	}
    95  
    96  	return nil, errors.New("function ID does not exist")
    97  }
    98  
    99  // fidList is the list of exported FIDs
   100  type fidList []*Process
   101  
   102  // Len returns the length of fidList - used purely for sorting FIDs
   103  func (f fidList) Len() int { return len(f) }
   104  
   105  // Less checks if one FID comes before another FID - used purely for sorting FIDs
   106  func (f fidList) Less(i, j int) bool { return f[i].Id < f[j].Id }
   107  
   108  // Swap alters the order of the exported FIDs - used purely for sorting FIDs
   109  func (f fidList) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
   110  
   111  // ListAll processes registered in the FID (Function ID) table - return as a ordered list
   112  func (f *funcID) ListAll() fidList {
   113  	f.mutex.Lock()
   114  	procs := make(fidList, len(f.list))
   115  	var i int
   116  	for _, p := range f.list {
   117  		procs[i] = p
   118  		i++
   119  	}
   120  	f.mutex.Unlock()
   121  
   122  	sort.Sort(procs)
   123  	return procs
   124  }