Compare commits

...

4 Commits

Author SHA1 Message Date
Thomas Leonard
ad7149dc29
Merge pull request #612 from talex5/release
Prepare release
2023-08-29 11:36:01 +01:00
Thomas Leonard
9d5aadc3eb Prepare release 2023-08-29 11:30:14 +01:00
Thomas Leonard
610b4c0653
Merge pull request #611 from talex5/simple-copy
Add Eio.Flow.Pi.simple_copy
2023-08-29 10:40:23 +01:00
Thomas Leonard
51f33d4539 Add Eio.Flow.Pi.simple_copy
This provides an easy way to implement the copy API when there are no
optimisations you want to try.
2023-08-29 10:01:53 +01:00
5 changed files with 93 additions and 40 deletions

View File

@ -1,3 +1,66 @@
## v0.12
New features / API changes:
- Replace objects with variants (@talex5 @patricoferris #553 #605 #608, reviewed by @avsm).
Some potential users found object types confusing, so we now use an alternative scheme for OS resources.
For users of the resources, the only thing that changes is the types:
- Instead of taking an argument of type `#foo`, you should now take `_ foo`.
- Instead of returning a value of type `foo`, you should now return `foo_ty Eio.Resource.t`.
To provide your own implementation of an interface, you now provide a module rather than an object.
For example, to provide your own source flow, use `Eio.Flow.Pi.source (module My_source)`.
If you want to define your own interfaces, see the `Eio.Resource` module documentation.
- Add `Eio.Pool` (@talex5 @darrenldl #602, reviewed by @patricoferris).
A lock-free pool of resources. This is similar to `Lwt_pool`.
- Add `Eio.Lazy` (@talex5 #609, reviewed by @SGrondin).
If one fiber tries to force a lazy value while another is already doing it,
this will wait for the first one to finish rather than raising an exception (as `Stdlib.Lazy` does).
- Add `Eio.Path.native` (@talex5 #603, reviewed by @patricoferris).
This is useful when interacting with non-Eio libraries, for spawning sub-processes, and for displaying paths to users.
- Add `Flow.single_write` (@talex5 #598).
- Add `Eio.Flow.Pi.simple_copy` (@talex5 #611).
Provides an easy way to implement the `copy` operation when making your own sink.
- Eio_unix: add FD passing (@talex5 #522).
Allows opening a file and passing the handle over a Unix-domain socket.
- Add `Process.run ?is_success` to control definition of success (@SGrondin #586, reviewed by @talex5).
- Add `Eio_mock.Domain_manager` (@talex5 #610).
This mock domain manager runs everything in a single domain, allowing tests to remain deterministic.
- Add `Eio.Debug.with_trace_prefix` (@talex5 #610).
Allows prefixing all `traceln` output. The mock domain manager uses this to indicate which fake domain is running.
Bug fixes:
- Fork actions must not allocate (@talex5 #593).
When using multiple domains, child processes could get stuck if they forked while another domain held the malloc lock.
- eio_posix: ignore some errors writing to the wake-up pipe (@talex5 #600).
If the pipe is full or closed, the wake-up should simply be ignored.
Build/test fixes:
- Fix some MDX problems on Windows (@polytypic #597).
- The README depends on kcas (@talex5 #606).
- Clarify configuration for lib_eio_linux and enable tests on other arches (@dra27 #592).
- eio_linux tests: skip fixed buffer test if not available (@talex5 #604).
- eio_windows: update available line to win32 (@talex5 #588 #591).
## v0.11
New features / API changes:

View File

@ -23,8 +23,8 @@ module Pi = struct
module type SINK = sig
type t
val copy : t -> src:_ source -> unit
val single_write : t -> Cstruct.t list -> int
val copy : t -> src:_ source -> unit
end
module type SHUTDOWN = sig
@ -37,7 +37,6 @@ module Pi = struct
| Sink : ('t, (module SINK with type t = 't), [> sink_ty]) Resource.pi
| Shutdown : ('t, (module SHUTDOWN with type t = 't), [> shutdown_ty]) Resource.pi
let source (type t) (module X : SOURCE with type t = t) =
Resource.handler [H (Source, (module X))]
@ -59,6 +58,22 @@ module Pi = struct
H (Source, (module X));
H (Sink, (module X));
]
let simple_copy ~single_write t ~src:(Resource.T (src, src_ops)) =
let rec write_all buf =
if not (Cstruct.is_empty buf) then (
let sent = single_write t [buf] in
write_all (Cstruct.shift buf sent)
)
in
let module Src = (val (Resource.get src_ops Source)) in
try
let buf = Cstruct.create 4096 in
while true do
let got = Src.single_read src buf in
write_all (Cstruct.sub buf 0 got)
done
with End_of_file -> ()
end
open Pi
@ -153,20 +168,12 @@ let copy_string s = copy (string_source s)
module Buffer_sink = struct
type t = Buffer.t
let copy t ~src:(Resource.T (src, ops)) =
let module Src = (val (Resource.get ops Source)) in
let buf = Cstruct.create 4096 in
try
while true do
let got = Src.single_read src buf in
Buffer.add_string t (Cstruct.to_string ~len:got buf)
done
with End_of_file -> ()
let single_write t bufs =
let old_length = Buffer.length t in
List.iter (fun buf -> Buffer.add_bytes t (Cstruct.to_bytes buf)) bufs;
Buffer.length t - old_length
let copy t ~src = Pi.simple_copy ~single_write t ~src
end
let buffer_sink =

View File

@ -121,8 +121,13 @@ module Pi : sig
module type SINK = sig
type t
val copy : t -> src:_ source -> unit
val single_write : t -> Cstruct.t list -> int
val copy : t -> src:_ source -> unit
(** [copy t ~src] allows for optimising copy operations.
If you have no optimisations, you can use {!simple_copy} to implement this using {!single_write}. *)
end
module type SHUTDOWN = sig
@ -146,5 +151,8 @@ module Pi : sig
| Source : ('t, (module SOURCE with type t = 't), [> source_ty]) Resource.pi
| Sink : ('t, (module SINK with type t = 't), [> sink_ty]) Resource.pi
| Shutdown : ('t, (module SHUTDOWN with type t = 't), [> shutdown_ty]) Resource.pi
val simple_copy : single_write:('t -> Cstruct.t list -> int) -> 't -> src:_ source -> unit
(** [simple_copy ~single_write] implements {!SINK}'s [copy] API using [single_write]. *)
end

View File

@ -42,25 +42,7 @@ module Impl = struct
with Unix.Unix_error (code, name, arg) ->
raise (Err.wrap code name arg)
let write_all t bufs =
try
let rec loop = function
| [] -> ()
| bufs ->
let wrote = Low_level.writev t (Array.of_list bufs) in
loop (Cstruct.shiftv bufs wrote)
in
loop bufs
with Unix.Unix_error (code, name, arg) -> raise (Err.wrap code name arg)
let copy dst ~src =
let buf = Cstruct.create 4096 in
try
while true do
let got = Eio.Flow.single_read src buf in
write_all dst [Cstruct.sub buf 0 got]
done
with End_of_file -> ()
let copy t ~src = Eio.Flow.Pi.simple_copy ~single_write t ~src
let single_read t buf =
match Low_level.readv t [| buf |] with

View File

@ -45,14 +45,7 @@ module Impl = struct
write_all t bufs;
Cstruct.lenv bufs
let copy dst ~src =
let buf = Cstruct.create 4096 in
try
while true do
let got = Eio.Flow.single_read src buf in
write_all dst [Cstruct.sub buf 0 got]
done
with End_of_file -> ()
let copy t ~src = Eio.Flow.Pi.simple_copy ~single_write t ~src
let single_read t buf =
match Low_level.read_cstruct t buf with