-
Notifications
You must be signed in to change notification settings - Fork 411
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Rudi Grinberg <me@rgrinberg.com> <!-- ps-id: bca90be1-43e5-4e3f-a56c-08901d4d4863 -->
- Loading branch information
Showing
6 changed files
with
201 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
dune_util | ||
csexp | ||
fiber | ||
threads.posix | ||
(re_export unix)) | ||
(foreign_stubs | ||
(language c) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
open Stdune | ||
|
||
type t = | ||
{ mutable bytes : Bytes.t (* underlying bytes *) | ||
; (* the position we can start reading from (until [pos_w]) *) | ||
mutable pos_r : int | ||
; (* the position we can start writing to (until [Bytes.length bytes - 1]) *) | ||
mutable pos_w : int | ||
; (* total number of bytes written to this buffer. 2^63 bytes should be | ||
enough for anybody *) | ||
mutable total_written : int | ||
} | ||
|
||
type flush_token = int | ||
|
||
(* We can't use [Out_channel] for writes on Linux because we want to disable | ||
sigpipes. Eventually we'll move to event based IO and ditch the threads, | ||
so we'll need this anyway *) | ||
|
||
let create () = | ||
{ bytes = Bytes.create 8192; pos_r = 0; pos_w = 0; total_written = 0 } | ||
|
||
let maybe_resize_to_fit t write_size = | ||
let buf_len = Bytes.length t.bytes in | ||
let capacity = buf_len - t.pos_w in | ||
if capacity < write_size then ( | ||
let needed = write_size - capacity - t.pos_r in | ||
let new_size = min buf_len needed in | ||
let bytes = Bytes.create new_size in | ||
Bytes.blit ~src:t.bytes ~src_pos:t.pos_r ~dst:bytes ~dst_pos:0 | ||
~len:(t.pos_w - t.pos_r); | ||
t.bytes <- bytes; | ||
t.pos_w <- t.pos_r; | ||
t.pos_r <- 0) | ||
|
||
let write_char_exn t c = | ||
Bytes.set t.bytes t.pos_w c; | ||
t.pos_w <- t.pos_w + 1 | ||
|
||
let write_string_exn t src = | ||
let len = String.length src in | ||
Bytes.blit_string ~src ~src_pos:0 ~dst:t.bytes ~dst_pos:t.pos_w ~len; | ||
t.pos_w <- t.pos_w + len | ||
|
||
let read t len = | ||
let pos_r = t.pos_r + len in | ||
assert (pos_r <= t.pos_w); | ||
t.pos_r <- pos_r; | ||
t.total_written <- t.total_written + len | ||
|
||
let length t = t.pos_w - t.pos_r | ||
|
||
let flush_token t = t.total_written + length t | ||
|
||
let flushed t token = t.total_written >= token | ||
|
||
let write_csexps = | ||
let rec loop t (csexp : Csexp.t) = | ||
match csexp with | ||
| Atom str -> | ||
write_string_exn t (string_of_int (String.length str)); | ||
write_char_exn t ':'; | ||
write_string_exn t str | ||
| List e -> | ||
write_char_exn t '('; | ||
List.iter ~f:(loop t) e; | ||
write_char_exn t ')' | ||
in | ||
fun t csexps -> | ||
let length = | ||
List.fold_left csexps ~init:0 ~f:(fun acc csexp -> | ||
acc + Csexp.serialised_length csexp) | ||
in | ||
maybe_resize_to_fit t length; | ||
List.iter ~f:(loop t) csexps | ||
|
||
let pos t = t.pos_r | ||
|
||
let bytes t = t.bytes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
(** A resizable IO buffer *) | ||
|
||
type t | ||
|
||
(** create a new io buffer *) | ||
val create : unit -> t | ||
|
||
(** [read t n] reads [n] bytes *) | ||
val read : t -> int -> unit | ||
|
||
(** [write t csexps] write [csexps] to [t] while resizing [t] as necessary *) | ||
val write_csexps : t -> Csexp.t list -> unit | ||
|
||
(** a flush token is used to determine when a write has been completely flushed *) | ||
type flush_token | ||
|
||
(** [flush_token t] will be flushed whenever everything in [t] will be written *) | ||
val flush_token : t -> flush_token | ||
|
||
(** [flushed t token] will return [true] once all the data that was present in | ||
[t] when [token] was created will be written *) | ||
val flushed : t -> flush_token -> bool | ||
|
||
(** underlying raw buffer *) | ||
val bytes : t -> Bytes.t | ||
|
||
(** [pos t] in [bytes t] to read *) | ||
val pos : t -> int | ||
|
||
(** [length t] the number of bytes to read [bytes t] *) | ||
val length : t -> int |