mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
x.net: new net module (#6130)
This commit is contained in:
122
vlib/x/net/common.v
Normal file
122
vlib/x/net/common.v
Normal file
@ -0,0 +1,122 @@
|
||||
module net
|
||||
|
||||
import time
|
||||
|
||||
// Shutdown shutsdown a socket and closes it
|
||||
fn shutdown(handle int) ? {
|
||||
$if windows {
|
||||
C.shutdown(handle, C.SD_BOTH)
|
||||
socket_error(C.closesocket(handle))?
|
||||
} $else {
|
||||
C.shutdown(handle, C.SHUT_RDWR)
|
||||
socket_error(C.close(handle))?
|
||||
}
|
||||
|
||||
return none
|
||||
}
|
||||
|
||||
// Select waits for an io operation (specified by parameter `test`) to be available
|
||||
fn @select(handle int, test Select, timeout time.Duration) ?bool {
|
||||
set := C.fd_set{}
|
||||
|
||||
C.FD_ZERO(&set)
|
||||
C.FD_SET(handle, &set)
|
||||
|
||||
seconds := timeout.milliseconds() / 1000
|
||||
microseconds := timeout - (seconds * time.second)
|
||||
|
||||
mut tt := C.timeval{
|
||||
tv_sec: u64(seconds)
|
||||
tv_usec: u64(microseconds)
|
||||
}
|
||||
|
||||
mut timeval_timeout := &tt
|
||||
|
||||
// infinite timeout is signaled by passing null as the timeout to
|
||||
// select
|
||||
if timeout == infinite_timeout {
|
||||
timeval_timeout = &C.timeval(0)
|
||||
}
|
||||
|
||||
match test {
|
||||
.read {
|
||||
socket_error(C.@select(handle+1, &set, C.NULL, C.NULL, timeval_timeout))?
|
||||
}
|
||||
.write {
|
||||
socket_error(C.@select(handle+1, C.NULL, &set, C.NULL, timeval_timeout))?
|
||||
}
|
||||
.except {
|
||||
socket_error(C.@select(handle+1, C.NULL, C.NULL, &set, timeval_timeout))?
|
||||
}
|
||||
}
|
||||
|
||||
return C.FD_ISSET(handle, &set)
|
||||
}
|
||||
|
||||
// wait_for_common wraps the common wait code
|
||||
fn wait_for_common(
|
||||
handle int,
|
||||
deadline time.Time,
|
||||
timeout time.Duration,
|
||||
test Select) ? {
|
||||
if deadline.unix == 0 {
|
||||
// only accept infinite_timeout as a valid
|
||||
// negative timeout - it is handled in @select however
|
||||
if timeout < 0 && timeout != infinite_timeout {
|
||||
return err_timed_out
|
||||
}
|
||||
ready := @select(handle, test, timeout)?
|
||||
if ready {
|
||||
return none
|
||||
}
|
||||
return err_timed_out
|
||||
}
|
||||
// Convert the deadline into a timeout
|
||||
// and use that
|
||||
d_timeout := deadline.unix - time.now().unix
|
||||
if d_timeout < 0 {
|
||||
// deadline is in the past so this has already
|
||||
// timed out
|
||||
return err_timed_out
|
||||
}
|
||||
|
||||
ready := @select(handle, test, d_timeout)?
|
||||
if ready {
|
||||
return none
|
||||
}
|
||||
return err_timed_out
|
||||
}
|
||||
|
||||
// wait_for_write waits for a write io operation to be available
|
||||
fn wait_for_write(
|
||||
handle int,
|
||||
deadline time.Time,
|
||||
timeout time.Duration) ? {
|
||||
return wait_for_common(handle, deadline, timeout, .write)
|
||||
}
|
||||
|
||||
// wait_for_read waits for a read io operation to be available
|
||||
fn wait_for_read(
|
||||
handle int,
|
||||
deadline time.Time,
|
||||
timeout time.Duration) ? {
|
||||
return wait_for_common(handle, deadline, timeout, .read)
|
||||
}
|
||||
|
||||
// no_deadline should be given to functions when no deadline is wanted (i.e. all functions
|
||||
// return instantly)
|
||||
const (
|
||||
no_deadline = time.Time{unix: 0}
|
||||
)
|
||||
|
||||
// no_timeout should be given to functions when no timeout is wanted (i.e. all functions
|
||||
// return instantly)
|
||||
const (
|
||||
no_timeout = time.Duration(0)
|
||||
)
|
||||
|
||||
// infinite_timeout should be given to functions when an infinite_timeout is wanted (i.e. functions
|
||||
// only ever return with data)
|
||||
const (
|
||||
infinite_timeout = time.Duration(-1)
|
||||
)
|
Reference in New Issue
Block a user