diff options
Diffstat (limited to 'otherlibs/dynlink/dynlink_common.ml')
-rw-r--r-- | otherlibs/dynlink/dynlink_common.ml | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/otherlibs/dynlink/dynlink_common.ml b/otherlibs/dynlink/dynlink_common.ml index 6f4d8c0b4b..72e9e67303 100644 --- a/otherlibs/dynlink/dynlink_common.ml +++ b/otherlibs/dynlink/dynlink_common.ml @@ -346,30 +346,25 @@ module Make (P : Dynlink_platform_intf.S) = struct let load priv filename = init (); let filename = dll_filename filename in - match P.load ~filename ~priv with - | exception exn -> raise (DT.Error (Cannot_open_dynamic_library exn)) - | handle, units -> - try - with_lock (fun ({unsafe_allowed; _ } as global) -> - global.state <- check filename units global.state - ~unsafe_allowed - ~priv; - P.run_shared_startup handle; - ); - List.iter - (fun unit_header -> - (* Linked modules might call Dynlink themselves, - we need to release the lock *) - P.run Global.lock handle ~unit_header ~priv; - if not priv then with_lock (fun global -> - global.state <- set_loaded filename unit_header global.state - ) - ) - units; - P.finish handle - with exn -> - P.finish handle; - raise exn + let handle, units = P.load ~filename ~priv in + Fun.protect ~finally:(fun () -> P.finish handle) (fun () -> + with_lock (fun ({unsafe_allowed; _ } as global) -> + global.state <- check filename units global.state + ~unsafe_allowed + ~priv; + P.run_shared_startup handle; + ); + List.iter + (fun unit_header -> + (* Linked modules might call Dynlink themselves, + we need to release the lock *) + P.run Global.lock handle ~unit_header ~priv; + if not priv then with_lock (fun global -> + global.state <- set_loaded filename unit_header global.state + ) + ) + units + ) let loadfile filename = load false filename let loadfile_private filename = load true filename |