|
20 | 20 |
|
21 | 21 | open Listext |
22 | 22 | open Xstringext |
| 23 | +open Threadext |
23 | 24 | open Fun |
24 | 25 |
|
25 | 26 | (* We treat versions as '.'-separated integer lists under the usual |
@@ -87,27 +88,47 @@ let update_from_query_result ~__context (self, r) query_result = |
87 | 88 |
|
88 | 89 | let is_v1 x = version_of_string x < [ 2; 0 ] |
89 | 90 |
|
| 91 | +let _serialize_reg = |
| 92 | + let lock = Mutex.create () in |
| 93 | + let holder = ref None in |
| 94 | + begin fun f -> |
| 95 | + match !holder with |
| 96 | + | Some t when t = Thread.self () -> |
| 97 | + (* inside a nested layer where the lock is held by myself *) |
| 98 | + f () |
| 99 | + | _ -> |
| 100 | + Mutex.execute lock begin fun () -> |
| 101 | + holder := Some (Thread.self ()); |
| 102 | + Pervasiveext.finally f (fun () -> holder := None) |
| 103 | + end |
| 104 | + end |
| 105 | + |
90 | 106 | let unregister_plugin ~__context query_result = |
91 | | - let open Storage_interface in |
92 | | - let driver = String.lowercase query_result.driver in |
93 | | - if is_v1 query_result.required_api_version then begin |
94 | | - info "Not unregistering SM plugin %s (required_api_version %s < 2.0)" driver query_result.required_api_version; |
95 | | - end else begin |
96 | | - let existing = List.map (fun (rf, rc) -> rc.API.sM_type, (rf, rc)) (Db.SM.get_all_records ~__context) in |
97 | | - if List.mem_assoc driver existing then begin |
98 | | - info "Unregistering SM plugin %s (version %s)" driver query_result.version; |
99 | | - try |
100 | | - Db.SM.destroy ~__context ~self:(fst (List.assoc driver existing)) |
101 | | - with _ -> () |
102 | | - end |
| 107 | + _serialize_reg begin fun () -> |
| 108 | + let open Storage_interface in |
| 109 | + let driver = String.lowercase query_result.driver in |
| 110 | + if is_v1 query_result.required_api_version then begin |
| 111 | + info "Not unregistering SM plugin %s (required_api_version %s < 2.0)" driver query_result.required_api_version; |
| 112 | + end else |
| 113 | + List.iter |
| 114 | + (fun (rf, rc) -> |
| 115 | + if rc.API.sM_type = driver then |
| 116 | + try |
| 117 | + info "Unregistering SM plugin %s (version %s)" driver query_result.version; |
| 118 | + Db.SM.destroy ~__context ~self:rf |
| 119 | + with e -> |
| 120 | + warn "Ignore unregistering SM plugin failure: %s" (Printexc.to_string e)) |
| 121 | + (Db.SM.get_all_records ~__context) |
103 | 122 | end |
104 | 123 |
|
105 | 124 | let register_plugin ~__context query_result = |
106 | | - let open Storage_interface in |
107 | | - let driver = String.lowercase query_result.driver in |
108 | | - if is_v1 query_result.required_api_version then begin |
109 | | - info "Not registering SM plugin %s (required_api_version %s < 2.0)" driver query_result.required_api_version; |
110 | | - end else begin |
111 | | - unregister_plugin ~__context query_result; |
112 | | - create_from_query_result ~__context query_result |
| 125 | + _serialize_reg begin fun () -> |
| 126 | + let open Storage_interface in |
| 127 | + let driver = String.lowercase query_result.driver in |
| 128 | + if is_v1 query_result.required_api_version then begin |
| 129 | + info "Not registering SM plugin %s (required_api_version %s < 2.0)" driver query_result.required_api_version; |
| 130 | + end else begin |
| 131 | + unregister_plugin ~__context query_result; |
| 132 | + create_from_query_result ~__context query_result |
| 133 | + end |
113 | 134 | end |
0 commit comments