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 }