Commit beeaa13f authored by gerd's avatar gerd

fix: avoiding races between read_e and write_e - for this we need to

serialize lazy transactions (I guess it was meant like this anyway)


git-svn-id: https://gps.dynxs.de/private/svn/app-plasma/trunk@645 55289a75-7b90-4627-9e07-ffb4263930b2
parent cf31acf6
......@@ -812,11 +812,17 @@ let current_user c = sync current_user_e c
let lazy_transaction c mc =
(* A lazily created transaction for read-only accesses (non-snapshot case) *)
let ser = Uq_engines.serializer c.esys in
( object(self)
val mutable state = None
val mutable starting = None
val mutable stopping = None
method serialized
: (unit -> unit Uq_engines.engine) -> unit Uq_engines.engine =
fun f ->
ser # serialized (fun _ -> f())
method get_tid_e() =
try
match state with
......@@ -967,8 +973,16 @@ let with_lazy_transaction_e c mc inode f =
Hashtbl.replace c.lazy_trans inode (lt, blc, n_users, t_create, None)
);
incr n_users;
Uq_engines.meta_engine(f lt blc)
++ (fun state ->
let out_state = ref `Aborted in
(* We need to serialize the execution of f, because only one user can
submit an fsys RPC call at a time
*)
lt#serialized
(fun () ->
Uq_engines.meta_engine(f lt blc)
>> (fun state -> out_state := state; `Done ())
)
++ (fun () ->
(* N.B. the contents of c.lazy_trans may be different now *)
decr n_users;
( if !n_users = 0 && not lt#snapshot then (
......@@ -988,9 +1002,13 @@ let with_lazy_transaction_e c mc inode f =
);
(eps_e (`Done ()) c.esys)
)
++ (fun () -> eps_e (state :> _ Uq_engines.engine_state) c.esys)
)
>> (fun _ ->
match !out_state with
| `Done st -> st
| `Error e -> `Error e
| `Aborted -> `Aborted
)
let with_new_nn_transaction_e c mc extract f =
......@@ -2738,8 +2756,13 @@ let rec snapshot_e ?(append=false) trans inode =
++ (fun init_ii ->
let cur_ii = ref init_ii in
let force_ii = ref false in
let ser = Uq_engines.serializer c.esys in
let lt =
( object(self)
method serialized
: (unit -> unit Uq_engines.engine) ->
unit Uq_engines.engine =
fun f -> ser # serialized (fun _ -> f())
method get_tid_e() = eps_e (`Done trans.tid) c.esys
method get_ii_e i force_flag =
let get_ii_from_server_e() =
......
......@@ -91,7 +91,9 @@ type ic_manager =
}
(* NB. lazy_transactions must not be cached here *)
class type lazy_transaction = object
method serialized : (unit->unit Uq_engines.engine) -> unit Uq_engines.engine
method get_tid_e : unit -> int64 Uq_engines.engine
method get_ii_e : int64 -> bool -> inodeinfo Uq_engines.engine
method invalidate_ii : int64 -> unit
......
......@@ -131,6 +131,7 @@ val disable : ic_manager -> unit
[snapshot] means that this is actually a snapshot transaction.
*)
class type lazy_transaction = object
method serialized : (unit->unit Uq_engines.engine) -> unit Uq_engines.engine
method get_tid_e : unit -> int64 Uq_engines.engine
method get_ii_e : int64 -> bool -> inodeinfo Uq_engines.engine
method invalidate_ii : int64 -> unit
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment