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  }