let data = Utils.join_by_null [ new_path; watch.token; "" ] in
send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
-let find_next_tid con =
- let ret = con.next_tid in con.next_tid <- con.next_tid + 1; ret
+(* Search for a valid unused transaction id. *)
+let rec valid_transaction_id con proposed_id =
+ (* Clip proposed_id to the range [1, 0x7ffffffe] *)
+ let id = if proposed_id <= 0 || proposed_id >= 0x7fffffff then 1 else proposed_id in
+
+ if Hashtbl.mem con.transactions id then (
+ (* Outstanding transaction with this id. Try the next. *)
+ valid_transaction_id con (id + 1)
+ ) else
+ id
let start_transaction con store =
if !Define.maxtransaction > 0 && not (is_dom0 con)
&& Hashtbl.length con.transactions > !Define.maxtransaction then
raise Quota.Transaction_opened;
- let id = find_next_tid con in
+ let id = valid_transaction_id con con.next_tid in
+ con.next_tid <- id + 1;
let ntrans = Transaction.make id store in
Hashtbl.add con.transactions id ntrans;
Logging.start_transaction ~tid:id ~con:(get_domstr con);