Skip to content

Commit

Permalink
fix: dead lock in map
Browse files Browse the repository at this point in the history
  • Loading branch information
darkskygit committed Aug 21, 2023
1 parent 4d4fe0f commit b482de4
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,29 @@
<key>HeadersPath</key>
<string>Headers</string>
<key>LibraryIdentifier</key>
<string>macos-arm64</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>liboctobase.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>macos</string>
<string>ios</string>
</dict>
<dict>
<key>HeadersPath</key>
<string>Headers</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>macos-arm64</string>
<key>LibraryPath</key>
<string>liboctobase.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<string>macos</string>
</dict>
</array>
<key>CFBundlePackageType</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ bool __swift_bridge__$Block$is_bool(void* self, void* key);
bool __swift_bridge__$Block$is_string(void* self, void* key);
bool __swift_bridge__$Block$is_float(void* self, void* key);
bool __swift_bridge__$Block$is_integer(void* self, void* key);
struct __private__OptionI64 __swift_bridge__$Block$get_bool(void* self, void* key);
struct __private__OptionBool __swift_bridge__$Block$get_bool(void* self, void* key);
void* __swift_bridge__$Block$get_string(void* self, void* key);
struct __private__OptionF64 __swift_bridge__$Block$get_float(void* self, void* key);
struct __private__OptionI64 __swift_bridge__$Block$get_integer(void* self, void* key);
Expand All @@ -114,7 +114,6 @@ void* __swift_bridge__$Workspace$search(void* self, void* query);
void* __swift_bridge__$Workspace$get_blocks_by_flavour(void* self, struct RustStr flavour);
void* __swift_bridge__$Workspace$get_search_index(void* self);
bool __swift_bridge__$Workspace$set_search_index(void* self, void* fields);
void* __swift_bridge__$Workspace$compare(void* self);
void* __swift_bridge__$Storage$new(void* path);
void* __swift_bridge__$Storage$new_with_log_level(void* path, void* level);
void* __swift_bridge__$Storage$error(void* self);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module RustXcframework {
header "SwiftBridgeCore.h"
header "jwst-swift.h"
header "jwst-core-swift.h"
export *
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ bool __swift_bridge__$Block$is_bool(void* self, void* key);
bool __swift_bridge__$Block$is_string(void* self, void* key);
bool __swift_bridge__$Block$is_float(void* self, void* key);
bool __swift_bridge__$Block$is_integer(void* self, void* key);
struct __private__OptionI64 __swift_bridge__$Block$get_bool(void* self, void* key);
struct __private__OptionBool __swift_bridge__$Block$get_bool(void* self, void* key);
void* __swift_bridge__$Block$get_string(void* self, void* key);
struct __private__OptionF64 __swift_bridge__$Block$get_float(void* self, void* key);
struct __private__OptionI64 __swift_bridge__$Block$get_integer(void* self, void* key);
Expand All @@ -114,7 +114,6 @@ void* __swift_bridge__$Workspace$search(void* self, void* query);
void* __swift_bridge__$Workspace$get_blocks_by_flavour(void* self, struct RustStr flavour);
void* __swift_bridge__$Workspace$get_search_index(void* self);
bool __swift_bridge__$Workspace$set_search_index(void* self, void* fields);
void* __swift_bridge__$Workspace$compare(void* self);
void* __swift_bridge__$Storage$new(void* path);
void* __swift_bridge__$Storage$new_with_log_level(void* path, void* level);
void* __swift_bridge__$Storage$error(void* self);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module RustXcframework {
header "SwiftBridgeCore.h"
header "jwst-swift.h"
header "jwst-core-swift.h"
export *
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ bool __swift_bridge__$Block$is_bool(void* self, void* key);
bool __swift_bridge__$Block$is_string(void* self, void* key);
bool __swift_bridge__$Block$is_float(void* self, void* key);
bool __swift_bridge__$Block$is_integer(void* self, void* key);
struct __private__OptionI64 __swift_bridge__$Block$get_bool(void* self, void* key);
struct __private__OptionBool __swift_bridge__$Block$get_bool(void* self, void* key);
void* __swift_bridge__$Block$get_string(void* self, void* key);
struct __private__OptionF64 __swift_bridge__$Block$get_float(void* self, void* key);
struct __private__OptionI64 __swift_bridge__$Block$get_integer(void* self, void* key);
Expand All @@ -114,7 +114,6 @@ void* __swift_bridge__$Workspace$search(void* self, void* query);
void* __swift_bridge__$Workspace$get_blocks_by_flavour(void* self, struct RustStr flavour);
void* __swift_bridge__$Workspace$get_search_index(void* self);
bool __swift_bridge__$Workspace$set_search_index(void* self, void* fields);
void* __swift_bridge__$Workspace$compare(void* self);
void* __swift_bridge__$Storage$new(void* path);
void* __swift_bridge__$Storage$new_with_log_level(void* path, void* level);
void* __swift_bridge__$Storage$error(void* self);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module RustXcframework {
header "SwiftBridgeCore.h"
header "jwst-swift.h"
header "jwst-core-swift.h"
export *
}
7 changes: 1 addition & 6 deletions apps/swift/OctoBaseSwift/Sources/OctoBase/jwst-swift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ extension BlockRef {
__swift_bridge__$Block$is_integer(ptr, { let rustString = key.intoRustString(); rustString.isOwned = false; return rustString.ptr }())
}

public func get_bool<GenericIntoRustString: IntoRustString>(_ key: GenericIntoRustString) -> Optional<Int64> {
public func get_bool<GenericIntoRustString: IntoRustString>(_ key: GenericIntoRustString) -> Optional<Bool> {
{ let val = __swift_bridge__$Block$get_bool(ptr, { let rustString = key.intoRustString(); rustString.isOwned = false; return rustString.ptr }()); if val.is_some { return val.val } else { return nil } }()
}

Expand Down Expand Up @@ -371,11 +371,6 @@ public class WorkspaceRefMut: WorkspaceRef {
super.init(ptr: ptr)
}
}
extension WorkspaceRefMut {
public func compare() -> Optional<RustString> {
{ let val = __swift_bridge__$Workspace$compare(ptr); if val != nil { return RustString(ptr: val!) } else { return nil } }()
}
}
public class WorkspaceRef {
var ptr: UnsafeMutableRawPointer

Expand Down
19 changes: 16 additions & 3 deletions libs/jwst-codec/src/doc/types/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ impl_type!(Map);

pub(crate) trait MapType: AsInner<Inner = YTypeRef> {
fn insert(&mut self, key: impl AsRef<str>, value: impl Into<Content>) -> JwstCodecResult {
let mut inner = self.as_inner().get().unwrap().write().unwrap();
// when we apply update, we may get write store then get ytype, so we ensure
// that everywhere, the write store is fetched before the write ytype to
// avoid deadlocks
let inner = self.as_inner().get().unwrap().read().unwrap();
let left = inner.map.as_ref().and_then(|map| {
map.get(key.as_ref())
.and_then(|struct_info| struct_info.left())
.map(|l| l.as_item())
});
if let Some(store) = inner.store.upgrade() {
drop(inner);

let mut store = store.write().unwrap();
let item = store.create_item(
value.into(),
Expand All @@ -27,6 +32,7 @@ pub(crate) trait MapType: AsInner<Inner = YTypeRef> {
Some(Parent::Type(self.as_inner().clone())),
Some(key.as_ref().into()),
);
let mut inner = self.as_inner().get().unwrap().write().unwrap();
store.integrate(Node::Item(item), 0, Some(&mut inner))?;
}

Expand Down Expand Up @@ -74,12 +80,19 @@ pub(crate) trait MapType: AsInner<Inner = YTypeRef> {
}

fn remove(&mut self, key: impl AsRef<str>) -> bool {
let mut inner = self.as_inner().get().unwrap().write().unwrap();
// when we apply update, we may get write store then get ytype, so we ensure
// that everywhere, the write store is fetched before the write ytype to
// avoid deadlocks
let inner = self.as_inner().get().unwrap().read().unwrap();
let node = inner.map.as_ref().and_then(|map| map.get(key.as_ref()));
if let Some(store) = inner.store.upgrade() {
let mut store = store.write().unwrap();
if let Some(item) = ItemRef::from(node).get() {
drop(inner);

let mut store = store.write().unwrap();
store.delete_set.add(item.id.client, item.id.clock, item.len());

let mut inner = self.as_inner().get().unwrap().write().unwrap();
DocStore::delete_item(item, Some(&mut inner));
return true;
}
Expand Down

0 comments on commit b482de4

Please sign in to comment.