Browse Source

Try to improve the use of SyscallConn.

Beoran 4 years ago
parent
commit
d1e7022d04
1 changed files with 34 additions and 14 deletions
  1. 34 14
      os/linux/input/input_linux.go

+ 34 - 14
os/linux/input/input_linux.go

@@ -20,6 +20,7 @@ type Device struct {
     FileName string 
     *os.File
     syscall.RawConn
+    FD uintptr
     // Cached device information
     Info struct { 
         Events          []SupportedEvent
@@ -54,27 +55,46 @@ func (d * Device) String() string {
                         d.Info.Rolls)
 }
 
+func (d *Device) SetNonblock(nonblocking bool) error {
+	var err error = nil
+	setnonblock := func(fd uintptr) {
+		err = unix.SetNonblock(int(fd), nonblocking)
+	}
+	err2 := d.Control(setnonblock)
+	if err2 != nil {
+		return err2
+	}
+	return err
+}
+
 func Open(name string) (*Device, error) {
     f, err := os.OpenFile(filepath.Join(Directory, name), 
         unix.O_ASYNC|unix.O_NONBLOCK|os.O_RDWR, 0666)
     if err != nil {
         return nil, err
     }
-    if err = unix.SetNonblock(int(f.Fd()), true); err != nil {
+        
+    rawConn, err := f.SyscallConn()
+    if err != nil {
         return nil, err
     }
-    flags, err := unix.FcntlInt(f.Fd(), unix.F_GETFL, 0);
-    if flags, err = unix.FcntlInt(f.Fd(), unix.F_SETFL, flags | unix.O_NONBLOCK); err != nil {
+    // this is cheating ,but avoid me from calling .Fd()
+    // Furthermore, this is unlikely to change for real ddevice files
+    var FD uintptr
+    err = rawConn.Control(func(fd uintptr) {
+		FD = fd
+	}) 	
+	if err != nil {
         return nil, err
     }
-    
-    rawConn, err := f.SyscallConn()
-    
-    if err != nil {
+    	        
+    device := &Device{FileName: name, File: f, RawConn: rawConn, FD: FD}
+        
+    if err = device.SetNonblock(true) ;  err != nil {
         return nil, err
     }
     
-    return &Device{FileName: name, File: f, RawConn: rawConn}, nil
+    return device, nil
 }
 
 func (d *Device) GatherInfo() error {
@@ -207,10 +227,10 @@ func (d * Device) Write(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
     var errno syscall.Errno = 0 
     var wrote uintptr = 0
     writer := func(fd uintptr) bool {
-        LogDebug("write: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
+        LogDebug("write: %d %d %d\n", uintptr(fd), uintptr(pointer), uintptr(size))
         wrote, _, errno = unix.Syscall(
             unix.SYS_WRITE,
-            uintptr(d.Fd()),
+            uintptr(fd),
             uintptr(pointer),
             uintptr(size))
         return errno != syscall.EAGAIN
@@ -501,9 +521,9 @@ func (driver *Driver) connectDevice(device * Device) {
     driver.Lock()
     defer driver.Unlock()
     driver.DevicesByName[device.FileName] = device
-    driver.DevicesByFd[int(device.Fd())] = device
+    driver.DevicesByFd[int(device.FD)] = device
     driver.Devices = append(driver.Devices, device)
-    pollfd := unix.PollFd{Fd: int32(device.Fd()), Events : unix.POLLIN}
+    pollfd := unix.PollFd{Fd: int32(device.FD), Events : unix.POLLIN}
     driver.fds = append(driver.fds, pollfd) 
     driver.Connect <- device
 }
@@ -512,12 +532,12 @@ func (driver *Driver) disconnectDevice(device * Device) {
     driver.Lock()
     defer driver.Unlock()
     delete(driver.DevicesByName, device.FileName)
-    delete(driver.DevicesByFd, int(device.Fd()))
+    delete(driver.DevicesByFd, int(device.FD))
     found := false
     var i int
     var pollfd unix.PollFd
     for i, pollfd = range driver.fds {
-        if pollfd.Fd == int32(device.Fd()) {
+        if pollfd.Fd == int32(device.FD) {
             found = true 
             break
         }