Skip to content

Commit

Permalink
Merge pull request #549 from talex5/socket-close
Browse files Browse the repository at this point in the history
Restore close to socket type
  • Loading branch information
talex5 authored Jun 8, 2023
2 parents 264a7d0 + cc400c2 commit d262afb
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 35 deletions.
8 changes: 4 additions & 4 deletions lib_eio/mock/eio_mock.mli
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ module Net : sig
type t = <
Eio.Net.t;
on_listen : Eio.Net.listening_socket Handler.t;
on_connect : <Eio.Net.stream_socket; Eio.Flow.close> Handler.t;
on_datagram_socket : <Eio.Net.datagram_socket; Eio.Flow.close> Handler.t;
on_connect : Eio.Net.stream_socket Handler.t;
on_datagram_socket : Eio.Net.datagram_socket Handler.t;
on_getaddrinfo : Eio.Net.Sockaddr.t list Handler.t;
on_getnameinfo : (string * string) Handler.t;
>
Expand All @@ -133,13 +133,13 @@ module Net : sig
val make : string -> t
(** [make label] is a new mock network. *)

val on_connect : t -> <Eio.Net.stream_socket; Eio.Flow.close; ..> Handler.actions -> unit
val on_connect : t -> <Eio.Net.stream_socket; ..> Handler.actions -> unit
(** [on_connect t actions] configures what to do when a client tries to connect somewhere. *)

val on_listen : t -> #Eio.Net.listening_socket Handler.actions -> unit
(** [on_listen t actions] configures what to do when a server starts listening for incoming connections. *)

val on_datagram_socket : t -> <Eio.Net.datagram_socket; Eio.Flow.close; ..> Handler.actions -> unit
val on_datagram_socket : t -> <Eio.Net.datagram_socket; ..> Handler.actions -> unit
(** [on_datagram_socket t actions] configures how to create datagram sockets. *)

val on_getaddrinfo : t -> Eio.Net.Sockaddr.t list Handler.actions -> unit
Expand Down
12 changes: 6 additions & 6 deletions lib_eio/mock/net.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ open Eio.Std
type t = <
Eio.Net.t;
on_listen : Eio.Net.listening_socket Handler.t;
on_connect : <Eio.Net.stream_socket; Eio.Flow.close> Handler.t;
on_datagram_socket : <Eio.Net.datagram_socket; Eio.Flow.close> Handler.t;
on_connect : Eio.Net.stream_socket Handler.t;
on_datagram_socket : Eio.Net.datagram_socket Handler.t;
on_getaddrinfo : Eio.Net.Sockaddr.t list Handler.t;
on_getnameinfo : (string * string) Handler.t;
>
Expand Down Expand Up @@ -56,15 +56,15 @@ let make label =
end

let on_connect (t:t) actions =
let as_socket x = (x :> <Eio.Net.stream_socket; Eio.Flow.close>) in
let as_socket x = (x :> Eio.Net.stream_socket) in
Handler.seq t#on_connect (List.map (Action.map as_socket) actions)

let on_listen (t:t) actions =
let as_socket x = (x :> <Eio.Net.listening_socket; Eio.Flow.close>) in
let as_socket x = (x :> Eio.Net.listening_socket) in
Handler.seq t#on_listen (List.map (Action.map as_socket) actions)

let on_datagram_socket (t:t) actions =
let as_socket x = (x :> <Eio.Net.datagram_socket; Eio.Flow.close>) in
let as_socket x = (x :> Eio.Net.datagram_socket) in
Handler.seq t#on_datagram_socket (List.map (Action.map as_socket) actions)

let on_getaddrinfo (t:t) actions = Handler.seq t#on_getaddrinfo actions
Expand All @@ -87,7 +87,7 @@ let listening_socket label =
let socket, addr = Handler.run on_accept in
Flow.attach_to_switch socket sw;
traceln "%s: accepted connection from %a" label Eio.Net.Sockaddr.pp addr;
(socket :> <Eio.Net.stream_socket; Eio.Flow.close>), addr
(socket :> Eio.Net.stream_socket), addr

method close =
traceln "%s: closed" label
Expand Down
8 changes: 4 additions & 4 deletions lib_eio/net.ml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ module Sockaddr = struct
Format.fprintf f "udp:%a:%d" Ipaddr.pp_for_uri addr port
end

class virtual socket = object (_ : #Generic.t)
class virtual socket = object (_ : <Generic.t; Generic.close; ..>)
method probe _ = None
end

Expand All @@ -167,7 +167,7 @@ end

class virtual listening_socket = object (_ : <Generic.close; ..>)
inherit socket
method virtual accept : sw:Switch.t -> <stream_socket; Flow.close> * Sockaddr.stream
method virtual accept : sw:Switch.t -> stream_socket * Sockaddr.stream
end

type connection_handler = stream_socket -> Sockaddr.stream -> unit
Expand Down Expand Up @@ -202,13 +202,13 @@ let recv (t:#datagram_socket) = t#recv

class virtual t = object
method virtual listen : reuse_addr:bool -> reuse_port:bool -> backlog:int -> sw:Switch.t -> Sockaddr.stream -> listening_socket
method virtual connect : sw:Switch.t -> Sockaddr.stream -> <stream_socket; Flow.close>
method virtual connect : sw:Switch.t -> Sockaddr.stream -> stream_socket
method virtual datagram_socket :
reuse_addr:bool
-> reuse_port:bool
-> sw:Switch.t
-> [Sockaddr.datagram | `UdpV4 | `UdpV6]
-> <datagram_socket; Flow.close>
-> datagram_socket

method virtual getaddrinfo : service:string -> string -> Sockaddr.t list
method virtual getnameinfo : Sockaddr.t -> (string * string)
Expand Down
16 changes: 8 additions & 8 deletions lib_eio/net.mli
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ end

(** {2 Provider Interfaces} *)

class virtual socket : object
class virtual socket : object (<Generic.close; ..>)
inherit Generic.t
end

Expand All @@ -119,26 +119,26 @@ end

class virtual listening_socket : object (<Generic.close; ..>)
inherit socket
method virtual accept : sw:Switch.t -> <stream_socket; Flow.close> * Sockaddr.stream
method virtual accept : sw:Switch.t -> stream_socket * Sockaddr.stream
end

class virtual t : object
method virtual listen : reuse_addr:bool -> reuse_port:bool -> backlog:int -> sw:Switch.t -> Sockaddr.stream -> listening_socket
method virtual connect : sw:Switch.t -> Sockaddr.stream -> <stream_socket; Flow.close>
method virtual connect : sw:Switch.t -> Sockaddr.stream -> stream_socket
method virtual datagram_socket :
reuse_addr:bool
-> reuse_port:bool
-> sw:Switch.t
-> [Sockaddr.datagram | `UdpV4 | `UdpV6]
-> <datagram_socket; Flow.close>
-> datagram_socket

method virtual getaddrinfo : service:string -> string -> Sockaddr.t list
method virtual getnameinfo : Sockaddr.t -> (string * string)
end

(** {2 Out-bound Connections} *)

val connect : sw:Switch.t -> #t -> Sockaddr.stream -> <stream_socket; Flow.close>
val connect : sw:Switch.t -> #t -> Sockaddr.stream -> stream_socket
(** [connect ~sw t addr] is a new socket connected to remote address [addr].
The new socket will be closed when [sw] finishes, unless closed manually first. *)
Expand All @@ -148,7 +148,7 @@ val with_tcp_connect :
host:string ->
service:string ->
#t ->
(<stream_socket; Flow.close> -> 'b) ->
(stream_socket -> 'b) ->
'b
(** [with_tcp_connect ~host ~service t f] creates a tcp connection [conn] to [host] and [service] and executes
[f conn].
Expand Down Expand Up @@ -184,7 +184,7 @@ val listen : ?reuse_addr:bool -> ?reuse_port:bool -> backlog:int -> sw:Switch.t
val accept :
sw:Switch.t ->
#listening_socket ->
<stream_socket; Flow.close> * Sockaddr.stream
stream_socket * Sockaddr.stream
(** [accept ~sw socket] waits until a new connection is ready on [socket] and returns it.
The new socket will be closed automatically when [sw] finishes, if not closed earlier.
Expand Down Expand Up @@ -255,7 +255,7 @@ val datagram_socket :
-> sw:Switch.t
-> #t
-> [< Sockaddr.datagram | `UdpV4 | `UdpV6]
-> <datagram_socket; Flow.close>
-> datagram_socket
(** [datagram_socket ~sw t addr] creates a new datagram socket bound to [addr]. The new
socket will be closed when [sw] finishes.
Expand Down
4 changes: 2 additions & 2 deletions lib_eio/unix/net.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ let sockaddr_of_unix_datagram = function
let host = Ipaddr.of_unix host in
`Udp (host, port)

class virtual stream_socket = object (_ : <Resource.t; Eio.Flow.close; ..>)
class virtual stream_socket = object (_ : <Resource.t; ..>)
inherit Eio.Net.stream_socket
end

class virtual datagram_socket = object (_ : <Resource.t; Eio.Flow.close; ..>)
class virtual datagram_socket = object (_ : <Resource.t; ..>)
inherit Eio.Net.datagram_socket
end

Expand Down
4 changes: 2 additions & 2 deletions lib_eio/unix/net.mli
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ open Eio.Std
These extend the types in {!Eio.Net} with support for file descriptors. *)

class virtual stream_socket : object (<Resource.t; Eio.Flow.close; ..>)
class virtual stream_socket : object (<Resource.t; ..>)
inherit Eio.Net.stream_socket
end

class virtual datagram_socket : object (<Resource.t; Eio.Flow.close; ..>)
class virtual datagram_socket : object (<Resource.t; ..>)
inherit Eio.Net.datagram_socket
end

Expand Down
6 changes: 3 additions & 3 deletions lib_eio_linux/eio_linux.ml
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ let listening_socket fd = object
| Unix.ADDR_UNIX path -> `Unix path
| Unix.ADDR_INET (host, port) -> `Tcp (Eio_unix.Net.Ipaddr.of_unix host, port)
in
let flow = (flow client :> <Eio.Net.stream_socket; Eio.Flow.close>) in
let flow = (flow client :> Eio.Net.stream_socket) in
flow, client_addr

method! probe : type a. a Eio.Generic.ty -> a option = function
Expand All @@ -210,7 +210,7 @@ let connect ~sw connect_addr =
let sock_unix = Unix.socket ~cloexec:true (socket_domain_of connect_addr) Unix.SOCK_STREAM 0 in
let sock = FD.of_unix ~sw ~seekable:false ~close_unix:true sock_unix in
Low_level.connect sock addr;
(flow sock :> <Eio.Net.stream_socket; Eio.Flow.close>)
(flow sock :> Eio.Net.stream_socket)

let net = object
inherit Eio_unix.Net.t
Expand Down Expand Up @@ -269,7 +269,7 @@ let net = object
Unix.bind sock_unix addr
| `UdpV4 | `UdpV6 -> ()
end;
(datagram_socket sock :> <Eio.Net.datagram_socket; Eio.Flow.close>)
(datagram_socket sock :> Eio.Net.datagram_socket)

method getaddrinfo = Low_level.getaddrinfo
end
Expand Down
6 changes: 3 additions & 3 deletions lib_eio_posix/net.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ let listening_socket ~hook fd = object
| Unix.ADDR_UNIX path -> `Unix path
| Unix.ADDR_INET (host, port) -> `Tcp (Eio_unix.Net.Ipaddr.of_unix host, port)
in
let flow = (Flow.of_fd client :> <Eio.Net.stream_socket; Eio.Flow.close>) in
let flow = (Flow.of_fd client :> Eio.Net.stream_socket) in
flow, client_addr

method! probe : type a. a Eio.Generic.ty -> a option = function
Expand Down Expand Up @@ -118,7 +118,7 @@ let connect ~sw connect_addr =
let sock = Low_level.socket ~sw (socket_domain_of connect_addr) socket_type 0 in
try
Low_level.connect sock addr;
(Flow.of_fd sock :> <Eio.Net.stream_socket; Eio.Flow.close>)
(Flow.of_fd sock :> Eio.Net.stream_socket)
with Unix.Unix_error (code, name, arg) -> raise (Err.wrap code name arg)

let create_datagram_socket ~reuse_addr ~reuse_port ~sw saddr =
Expand All @@ -135,7 +135,7 @@ let create_datagram_socket ~reuse_addr ~reuse_port ~sw saddr =
)
| `UdpV4 | `UdpV6 -> ()
end;
(datagram_socket sock :> <Eio.Net.datagram_socket; Eio.Flow.close>)
(datagram_socket sock :> Eio.Net.datagram_socket)

let v = object
inherit Eio_unix.Net.t
Expand Down
6 changes: 3 additions & 3 deletions lib_eio_windows/net.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ let listening_socket ~hook fd = object
| Unix.ADDR_UNIX path -> `Unix path
| Unix.ADDR_INET (host, port) -> `Tcp (Eio_unix.Net.Ipaddr.of_unix host, port)
in
let flow = (Flow.of_fd client :> <Eio.Net.stream_socket; Eio.Flow.close>) in
let flow = (Flow.of_fd client :> Eio.Net.stream_socket) in
flow, client_addr

method! probe : type a. a Eio.Generic.ty -> a option = function
Expand Down Expand Up @@ -123,7 +123,7 @@ let connect ~sw connect_addr =
let sock = Low_level.socket ~sw (socket_domain_of connect_addr) socket_type 0 in
try
Low_level.connect sock addr;
(Flow.of_fd sock :> <Eio.Net.stream_socket; Eio.Flow.close>)
(Flow.of_fd sock :> Eio.Net.stream_socket)
with Unix.Unix_error (code, name, arg) -> raise (Err.wrap code name arg)

let create_datagram_socket ~reuse_addr ~reuse_port ~sw saddr =
Expand All @@ -140,7 +140,7 @@ let create_datagram_socket ~reuse_addr ~reuse_port ~sw saddr =
)
| `UdpV4 | `UdpV6 -> ()
end;
(datagram_socket sock :> <Eio.Net.datagram_socket; Eio.Flow.close>)
(datagram_socket sock :> Eio.Net.datagram_socket)

let v = object
inherit Eio_unix.Net.t
Expand Down
25 changes: 25 additions & 0 deletions tests/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,31 @@ Handling one UDP packet using IPv6:
- : unit = ()
```

It's not an error to close the socket before the handler returns:

```ocaml
# run @@ fun ~net sw ->
let addr = `Tcp (Eio.Net.Ipaddr.V4.loopback, 8083) in
let server = Eio.Net.listen net ~sw ~reuse_addr:true ~backlog:5 addr in
Fiber.both
(fun () ->
Eio.Net.accept_fork server ~sw ~on_error:raise @@ fun flow _addr ->
traceln "Server got connection";
Eio.Flow.copy_string "Hi" flow;
Eio.Flow.close flow
)
(fun () ->
traceln "Connecting to server...";
let flow = Eio.Net.connect ~sw net addr in
let msg = Eio.Buf_read.(parse_exn take_all) flow ~max_size:100 in
traceln "Client got %S" msg;
);;
+Connecting to server...
+Server got connection
+Client got "Hi"
- : unit = ()
```

## Unix interop

Extracting file descriptors from Eio objects:
Expand Down

0 comments on commit d262afb

Please sign in to comment.