@@ -338,7 +338,6 @@ module Stub = struct
338
338
type connection
339
339
type result
340
340
341
- external conn_isnull : connection -> bool = "PQconn_isnull" [@@ noalloc]
342
341
external connect : string -> bool -> connection = "PQconnectdb_stub"
343
342
external finish : connection -> unit = "PQfinish_stub"
344
343
external reset : connection -> unit = "PQreset_stub"
@@ -955,9 +954,11 @@ module Connection (Mutex : Mutex) = struct
955
954
else Gc. finalise Stub. finish my_conn
956
955
in
957
956
let conn_mtx = Mutex. create () in
958
- let finishing = ref false in
957
+ let cancel_mtx = Mutex. create () in
958
+ let finished = ref false in
959
+ (* bool becomes true after deallocation *)
959
960
let check_null () =
960
- if ! finishing || Stub. conn_isnull my_conn then
961
+ if ! finished then
961
962
failwith " Postgresql.check_null: connection already finished"
962
963
in
963
964
let wrap_conn f =
@@ -969,11 +970,32 @@ module Connection (Mutex : Mutex) = struct
969
970
(* Check again in case the world has changed *)
970
971
f my_conn)
971
972
in
973
+ let wrap_cancel f =
974
+ protectx
975
+ ~f: (fun _ ->
976
+ Mutex. lock cancel_mtx;
977
+ check_null () ;
978
+ (* Check again in case the world has changed *)
979
+ f my_conn)
980
+ ~finally: (fun _ -> Mutex. unlock cancel_mtx)
981
+ in
982
+ let wrap_both f =
983
+ protectx
984
+ ~f: (fun _ ->
985
+ Mutex. lock conn_mtx;
986
+ Mutex. lock cancel_mtx;
987
+ check_null () ;
988
+ (* Check again in case the world has changed *)
989
+ f my_conn)
990
+ ~finally: (fun _ ->
991
+ Mutex. unlock cancel_mtx;
992
+ Mutex. unlock conn_mtx)
993
+ in
972
994
let signal_error conn =
973
995
raise (Error (Connection_failure (Stub. error_message conn)))
974
996
in
975
997
let request_cancel () =
976
- wrap_conn (fun _ ->
998
+ wrap_cancel (fun _ ->
977
999
match Stub. request_cancel my_conn with
978
1000
| None -> ()
979
1001
| Some err -> raise (Error (Cancel_failure err)))
@@ -999,9 +1021,9 @@ module Connection (Mutex : Mutex) = struct
999
1021
1000
1022
object (self (* Main routines *) )
1001
1023
method finish =
1002
- wrap_conn (fun c ->
1024
+ wrap_both (fun c ->
1003
1025
Stub. finish c;
1004
- finishing := true )
1026
+ finished := true )
1005
1027
1006
1028
method try_reset =
1007
1029
wrap_conn (fun conn ->
0 commit comments