Compare commits

..

2 commits

4 changed files with 22 additions and 16 deletions

View file

@ -9,7 +9,9 @@ type t =
; branch : Git.Reference.t ; branch : Git.Reference.t
; store : Store.t ; store : Store.t
; mutable committed : Digestif.SHA1.t option ; mutable committed : Digestif.SHA1.t option
; mutable change_and_push_waiter : unit Lwt.t option ; mutable change_and_push_running : bool
; condition : unit Lwt_condition.t
; mutex : Lwt_mutex.t
; mutable head : Store.hash option } ; mutable head : Store.hash option }
let init_store () = let init_store () =
@ -102,7 +104,7 @@ let connect ctx endpoint =
init_store () >>= fun store -> init_store () >>= fun store ->
let store = to_invalid store in let store = to_invalid store in
let edn, branch = split_url endpoint in let edn, branch = split_url endpoint in
let t = { ctx ; edn ; branch ; store ; committed= None; change_and_push_waiter= None; head= None } in let t = { ctx ; edn ; branch ; store ; committed= None; change_and_push_running= false; condition= Lwt_condition.create (); mutex= Lwt_mutex.create (); head= None } in
pull t >>= fun r -> pull t >>= fun r ->
let _r = to_invalid r in let _r = to_invalid r in
Lwt.return t Lwt.return t
@ -370,7 +372,7 @@ let of_octets ctx ~remote data =
Result.fold ~ok:Fun.id ~error:(function `Msg msg -> failwith msg) >>= fun store -> Result.fold ~ok:Fun.id ~error:(function `Msg msg -> failwith msg) >>= fun store ->
analyze store data >>= fun head -> analyze store data >>= fun head ->
let edn, branch = split_url remote in let edn, branch = split_url remote in
Lwt.return_ok { ctx ; edn ; branch ; store ; committed= None; change_and_push_waiter= None; head; }) Lwt.return_ok { ctx ; edn ; branch ; store ; committed= None; change_and_push_running= false; condition= Lwt_condition.create (); mutex= Lwt_mutex.create (); head; })
(fun _exn -> (fun _exn ->
Lwt.return_error (`Msg "Invalid PACK file")) Lwt.return_error (`Msg "Invalid PACK file"))
@ -684,12 +686,13 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
[change_and_push_waiter] before we wait on the existing [change_and_push_waiter] before we wait on the existing
[change_and_push_waiter] task without any yield point in between to [change_and_push_waiter] task without any yield point in between to
ensure serializability. *) ensure serializability. *)
let th, wk = Lwt.wait () in let open Lwt.Syntax in
let th' = t.change_and_push_waiter in let* () = Lwt_mutex.with_lock t.mutex @@ fun () ->
t.change_and_push_waiter <- Some th; let rec await () =
( match th' with if t.change_and_push_running
| None -> Lwt.return_unit then Lwt_condition.wait ~mutex:t.mutex t.condition >>= await
| Some th -> th ) >>= fun () -> else begin t.change_and_push_running <- true; Lwt.return_unit end in
await () in
( let open Lwt_result.Infix in ( let open Lwt_result.Infix in
tree_root_hash_of_store t >>= fun tree_root_hash -> tree_root_hash_of_store t >>= fun tree_root_hash ->
let t' = { t with committed = Some tree_root_hash } in let t' = { t with committed = Some tree_root_hash } in
@ -722,12 +725,9 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
>|= Result.map_error >|= Result.map_error
(fun err -> `Msg (Fmt.str "error pushing %a" Store.pp_error err)) (fun err -> `Msg (Fmt.str "error pushing %a" Store.pp_error err))
>>= fun res -> >>= fun res ->
Lwt.wakeup_later wk () ; let* () = Lwt_mutex.with_lock t.mutex @@ fun () ->
(* (hannes) since some other task may have mutated the t.change_and_push_running <- false;
change_and_push_waiter, we only reset it to None if there's a physical Lwt_condition.signal t.condition ();
equality between its value and our created task above. *) Lwt.return_unit in
(match t.change_and_push_waiter with
| Some th' -> if th' == th then t.change_and_push_waiter <- None
| None -> ());
Lwt.return res Lwt.return res
end end

View file

@ -11,12 +11,14 @@ Batch operation
> exists /bar > exists /bar
> quit > quit
> quit > quit
> EOF
/bar exists as a value /bar exists as a value
$ mgit git://localhost/simple#main <<EOF $ mgit git://localhost/simple#main <<EOF
> list / > list /
> get /bar > get /bar
> get /foo > get /foo
> quit > quit
> EOF
- /bar - /bar
- /foo - /foo
00000000: 4769 7420 726f 636b 7321 Git rocks! 00000000: 4769 7420 726f 636b 7321 Git rocks!

View file

@ -9,6 +9,7 @@ Reading during batch operation
> get /bar > get /bar
> quit > quit
> quit > quit
> EOF
- /bar - /bar
00000000: 4769 7420 726f 636b 7321 Git rocks! 00000000: 4769 7420 726f 636b 7321 Git rocks!
$ cd simple $ cd simple

View file

@ -17,6 +17,7 @@ Simple test of our Git Key-Value store
> get /foo > get /foo
> save db.pack > save db.pack
> quit > quit
> EOF
00000000: 4865 6c6c 6f20 576f 726c 6421 0a Hello World!. 00000000: 4865 6c6c 6f20 576f 726c 6421 0a Hello World!.
$ tail -c20 db.pack | hxd.xxd $ tail -c20 db.pack | hxd.xxd
00000000: e4b2 3437 2e7e 3d7e 8508 3912 3d87 11cd ..47.~=~..9.=... 00000000: e4b2 3437 2e7e 3d7e 8508 3912 3d87 11cd ..47.~=~..9.=...
@ -24,6 +25,7 @@ Simple test of our Git Key-Value store
$ mgit git://localhost/simple db.pack <<EOF $ mgit git://localhost/simple db.pack <<EOF
> get /foo > get /foo
> quit > quit
> EOF
00000000: 4865 6c6c 6f20 576f 726c 6421 0a Hello World!. 00000000: 4865 6c6c 6f20 576f 726c 6421 0a Hello World!.
$ cd simple $ cd simple
$ echo "Git rocks!" > bar $ echo "Git rocks!" > bar
@ -35,6 +37,7 @@ Simple test of our Git Key-Value store
> get /bar > get /bar
> get /foo > get /foo
> quit > quit
> EOF
+ /bar + /bar
* / * /
00000000: 4769 7420 726f 636b 7321 0a Git rocks!. 00000000: 4769 7420 726f 636b 7321 0a Git rocks!.