...
  
    Source file
    src/runtime/netpoll_wasip1.go
  
  
    Documentation: runtime
  
     1  
     2  
     3  
     4  
     5  
     6  
     7  package runtime
     8  
     9  import "unsafe"
    10  
    11  
    12  
    13  
    14  
    15  
    16  
    17  
    18  
    19  
    20  
    21  
    22  
    23  
    24  
    25  
    26  
    27  
    28  
    29  
    30  
    31  
    32  
    33  
    34  
    35  
    36  const _EINTR = 27
    37  
    38  var (
    39  	evts []event
    40  	subs []subscription
    41  	pds  []*pollDesc
    42  	mtx  mutex
    43  )
    44  
    45  func netpollinit() {
    46  	
    47  	
    48  	
    49  	
    50  
    51  	subs = make([]subscription, 1, 128)
    52  	evts = make([]event, 0, 128)
    53  	pds = make([]*pollDesc, 0, 128)
    54  
    55  	timeout := &subs[0]
    56  	eventtype := timeout.u.eventtype()
    57  	*eventtype = eventtypeClock
    58  	clock := timeout.u.subscriptionClock()
    59  	clock.id = clockMonotonic
    60  	clock.precision = 1e3
    61  }
    62  
    63  func netpollIsPollDescriptor(fd uintptr) bool {
    64  	return false
    65  }
    66  
    67  func netpollopen(fd uintptr, pd *pollDesc) int32 {
    68  	lock(&mtx)
    69  
    70  	
    71  	
    72  
    73  	pds = append(pds, pd)
    74  
    75  	
    76  	
    77  	
    78  	
    79  	pd.user = uint32(disarmed)<<16 | uint32(disarmed)
    80  
    81  	unlock(&mtx)
    82  	return 0
    83  }
    84  
    85  const disarmed = 0xFFFF
    86  
    87  func netpollarm(pd *pollDesc, mode int) {
    88  	lock(&mtx)
    89  
    90  	var s subscription
    91  
    92  	s.userdata = userdata(uintptr(unsafe.Pointer(pd)))
    93  
    94  	fdReadwrite := s.u.subscriptionFdReadwrite()
    95  	fdReadwrite.fd = int32(pd.fd)
    96  
    97  	ridx := int(pd.user >> 16)
    98  	widx := int(pd.user & 0xFFFF)
    99  
   100  	if (mode == 'r' && ridx != disarmed) || (mode == 'w' && widx != disarmed) {
   101  		unlock(&mtx)
   102  		return
   103  	}
   104  
   105  	eventtype := s.u.eventtype()
   106  	switch mode {
   107  	case 'r':
   108  		*eventtype = eventtypeFdRead
   109  		ridx = len(subs)
   110  	case 'w':
   111  		*eventtype = eventtypeFdWrite
   112  		widx = len(subs)
   113  	}
   114  
   115  	if len(subs) == disarmed {
   116  		throw("overflow")
   117  	}
   118  
   119  	pd.user = uint32(ridx)<<16 | uint32(widx)
   120  
   121  	subs = append(subs, s)
   122  	evts = append(evts, event{})
   123  
   124  	unlock(&mtx)
   125  }
   126  
   127  func netpolldisarm(pd *pollDesc, mode int32) {
   128  	switch mode {
   129  	case 'r':
   130  		removesub(int(pd.user >> 16))
   131  	case 'w':
   132  		removesub(int(pd.user & 0xFFFF))
   133  	case 'r' + 'w':
   134  		removesub(int(pd.user >> 16))
   135  		removesub(int(pd.user & 0xFFFF))
   136  	}
   137  }
   138  
   139  func removesub(i int) {
   140  	if i == disarmed {
   141  		return
   142  	}
   143  	j := len(subs) - 1
   144  
   145  	pdi := (*pollDesc)(unsafe.Pointer(uintptr(subs[i].userdata)))
   146  	pdj := (*pollDesc)(unsafe.Pointer(uintptr(subs[j].userdata)))
   147  
   148  	swapsub(pdi, i, disarmed)
   149  	swapsub(pdj, j, i)
   150  
   151  	subs = subs[:j]
   152  }
   153  
   154  func swapsub(pd *pollDesc, from, to int) {
   155  	if from == to {
   156  		return
   157  	}
   158  	ridx := int(pd.user >> 16)
   159  	widx := int(pd.user & 0xFFFF)
   160  	if ridx == from {
   161  		ridx = to
   162  	} else if widx == from {
   163  		widx = to
   164  	}
   165  	pd.user = uint32(ridx)<<16 | uint32(widx)
   166  	if to != disarmed {
   167  		subs[to], subs[from] = subs[from], subs[to]
   168  	}
   169  }
   170  
   171  func netpollclose(fd uintptr) int32 {
   172  	lock(&mtx)
   173  	for i := 0; i < len(pds); i++ {
   174  		if pds[i].fd == fd {
   175  			netpolldisarm(pds[i], 'r'+'w')
   176  			pds[i] = pds[len(pds)-1]
   177  			pds = pds[:len(pds)-1]
   178  			break
   179  		}
   180  	}
   181  	unlock(&mtx)
   182  	return 0
   183  }
   184  
   185  func netpollBreak() {}
   186  
   187  func netpoll(delay int64) (gList, int32) {
   188  	lock(&mtx)
   189  
   190  	
   191  	
   192  	
   193  	pollsubs := subs
   194  	if delay >= 0 {
   195  		timeout := &subs[0]
   196  		clock := timeout.u.subscriptionClock()
   197  		clock.timeout = uint64(delay)
   198  	} else {
   199  		pollsubs = subs[1:]
   200  	}
   201  
   202  	if len(pollsubs) == 0 {
   203  		unlock(&mtx)
   204  		return gList{}, 0
   205  	}
   206  
   207  	evts = evts[:len(pollsubs)]
   208  	clear(evts)
   209  
   210  retry:
   211  	var nevents size
   212  	errno := poll_oneoff(&pollsubs[0], &evts[0], uint32(len(pollsubs)), &nevents)
   213  	if errno != 0 {
   214  		if errno != _EINTR {
   215  			println("errno=", errno, " len(pollsubs)=", len(pollsubs))
   216  			throw("poll_oneoff failed")
   217  		}
   218  		
   219  		
   220  		if delay > 0 {
   221  			unlock(&mtx)
   222  			return gList{}, 0
   223  		}
   224  		goto retry
   225  	}
   226  
   227  	var toRun gList
   228  	delta := int32(0)
   229  	for i := 0; i < int(nevents); i++ {
   230  		e := &evts[i]
   231  		if e.typ == eventtypeClock {
   232  			continue
   233  		}
   234  
   235  		hangup := e.fdReadwrite.flags&fdReadwriteHangup != 0
   236  		var mode int32
   237  		if e.typ == eventtypeFdRead || e.error != 0 || hangup {
   238  			mode += 'r'
   239  		}
   240  		if e.typ == eventtypeFdWrite || e.error != 0 || hangup {
   241  			mode += 'w'
   242  		}
   243  		if mode != 0 {
   244  			pd := (*pollDesc)(unsafe.Pointer(uintptr(e.userdata)))
   245  			netpolldisarm(pd, mode)
   246  			pd.setEventErr(e.error != 0, 0)
   247  			delta += netpollready(&toRun, pd, mode)
   248  		}
   249  	}
   250  
   251  	unlock(&mtx)
   252  	return toRun, delta
   253  }
   254  
View as plain text