gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/ipc/cgo/sem/sem.go (about) 1 package sem 2 3 // #cgo LDFLAGS: -static 4 // #include <errno.h> 5 // #include <time.h> 6 // #include <semaphore.h> 7 // 8 // #define Errno errno 9 import "C" 10 import ( 11 "syscall" 12 "time" 13 ) 14 15 type Sem struct { 16 sem C.sem_t 17 } 18 19 func New(pshared int, value uint) (*Sem, error) { 20 sem := new(Sem) 21 if err := sem.Init(pshared, value); err != nil { 22 return nil, err 23 } 24 return sem, nil 25 } 26 27 func (s *Sem) Init(pshared int, value uint) error { 28 if C.sem_init(&s.sem, C.int(pshared), C.uint(value)) == -1 { 29 return syscall.Errno(C.Errno) 30 } 31 return nil 32 } 33 34 func (s *Sem) Wait() error { 35 if C.sem_wait(&s.sem) == -1 { 36 return syscall.Errno(C.Errno) 37 } 38 return nil 39 } 40 41 func (s *Sem) TimedWait(t time.Time) error { 42 nsec := t.UnixNano() 43 ts := C.struct_timespec{ 44 tv_sec: C.time_t(nsec / 1e9), 45 tv_nsec: C.long(nsec % 1e9 / 1e3), 46 } 47 if C.sem_timedwait(&s.sem, &ts) == -1 { 48 return syscall.Errno(C.Errno) 49 } 50 return nil 51 } 52 53 func (s *Sem) TryWait() (ok bool, err error) { 54 if C.sem_trywait(&s.sem) == -1 { 55 if err := syscall.Errno(C.Errno); err != syscall.EAGAIN { 56 return false, err 57 } 58 return false, nil 59 } 60 return true, nil 61 } 62 63 func (s *Sem) Post() error { 64 if C.sem_post(&s.sem) == -1 { 65 return syscall.Errno(C.Errno) 66 } 67 return nil 68 } 69 70 func (s *Sem) GetValue() (int, error) { 71 var value C.int 72 if C.sem_getvalue(&s.sem, &value) == -1 { 73 return int(value), syscall.Errno(C.Errno) 74 } 75 return int(value), nil 76 } 77 78 func (s *Sem) Destroy() error { 79 if C.sem_destroy(&s.sem) == -1 { 80 return syscall.Errno(C.Errno) 81 } 82 return nil 83 }