예제 #1
0
func newInterval(ns uint64) (_ interval, err error) {
	fd, _, errno := syscall.Syscall(syscall.SYS_TIMERFD_CREATE, C.CLOCK_MONOTONIC, C.TFD_CLOEXEC, 0)
	if fd == ^uintptr(0) {
		err = errors.New("Couldn't create timerfd: " + errno.Error())
		return
	}
	defer func() {
		if err != nil {
			syscall.Close(int(fd))
		}
	}()

	tspec := C.struct_timespec{
		tv_sec:  C.__time_t(ns / 1000000000),
		tv_nsec: C.__syscall_slong_t(ns % 1000000000),
	}
	ispec := C.struct_itimerspec{
		it_interval: tspec,
		it_value:    tspec,
	}
	ret, _, errno := syscall.Syscall6(syscall.SYS_TIMERFD_SETTIME, fd, 0, reflect.ValueOf(&ispec).Pointer(), 0, 0, 0)
	if ret == ^uintptr(0) {
		err = errors.New("Couldn't set interval: " + errno.Error())
		return
	}

	return interval{os.NewFile(fd, "timerfd")}, nil
}
예제 #2
0
파일: ioctx.go 프로젝트: kallax/go-ceph-1
// Take a shared lock on an object.
func (ioctx *IOContext) LockShared(oid, name, cookie, tag, desc string, duration time.Duration, flags *byte) (int, error) {
	c_oid := C.CString(oid)
	c_name := C.CString(name)
	c_cookie := C.CString(cookie)
	c_tag := C.CString(tag)
	c_desc := C.CString(desc)

	var c_duration C.struct_timeval
	if duration != 0 {
		tv := syscall.NsecToTimeval(time.Now().Add(duration).UnixNano())
		c_duration = C.struct_timeval{tv_sec: C.__time_t(tv.Sec), tv_usec: C.__suseconds_t(tv.Usec)}
	}

	var c_flags C.uint8_t
	if flags != nil {
		c_flags = C.uint8_t(*flags)
	}

	defer C.free(unsafe.Pointer(c_oid))
	defer C.free(unsafe.Pointer(c_name))
	defer C.free(unsafe.Pointer(c_cookie))
	defer C.free(unsafe.Pointer(c_tag))
	defer C.free(unsafe.Pointer(c_desc))

	ret := C.rados_lock_shared(
		ioctx.ioctx,
		c_oid,
		c_name,
		c_cookie,
		c_tag,
		c_desc,
		&c_duration,
		c_flags)

	// 0 on success, negative error code on failure
	// -EBUSY if the lock is already held by another (client, cookie) pair
	// -EEXIST if the lock is already held by the same (client, cookie) pair

	switch ret {
	case 0:
		return int(ret), nil
	case -16: // EBUSY
		return int(ret), nil
	case -17: // EEXIST
		return int(ret), nil
	default:
		return int(ret), RadosError(int(ret))
	}
}
예제 #3
0
파일: sem.go 프로젝트: jmptrader/go-sysvipc
// Run applies a group of SemOps atomically.
func (ss *SemaphoreSet) Run(ops *SemOps, timeout time.Duration) error {
	var cto *C.struct_timespec
	if timeout >= 0 {
		cto = &C.struct_timespec{
			tv_sec:  C.__time_t(timeout / time.Second),
			tv_nsec: C.__syscall_slong_t(timeout % time.Second),
		}
	}

	var opptr *C.struct_sembuf
	if len(*ops) > 0 {
		opptr = &(*ops)[0]
	}

	rc, err := C.semtimedop(C.int(ss.id), opptr, C.size_t(len(*ops)), cto)
	if rc == -1 {
		return err
	}
	return nil
}