Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1fe5b9f

Browse files
authored
Dont reset SharedRealm ptr (realm#4478)
- Keep the SharedRealm ptr valid when close it. To allow the is_closed checking could throw in the Object Store and it can be converted to a friendly Java exception. - Check if SharedRealm is closed when create collection iterator. Throw an ISE if it is. Fix realm#4471 .
1 parent 854275d commit 1fe5b9f

6 files changed

Lines changed: 49 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* Crash caused by JNI couldn't find `OsObject.notifyChangeListeners` when ProGuard is enabled (#4461).
1010
* Incompatible return type of `RealmSchema.getAll()` and `BaseRealm.getSchema()` (#4443).
1111
* Memory leaked when synced Realm was initialized (#4465).
12+
* An `IllegalStateException` will be thrown when starting iterating `OrderedRealmCollection` if the Realm is closed (#4471).
1213

1314
### Internal
1415

realm/realm-library/src/androidTest/java/io/realm/internal/CollectionTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,14 @@ public void onChange(Collection element) {
486486
addRowAsync();
487487
}
488488

489+
@Test
490+
public void collectionIterator_newInstance_throwsWhenSharedRealmIsClosed() {
491+
final Collection collection = new Collection(sharedRealm, table.where());
492+
sharedRealm.close();
493+
thrown.expect(IllegalStateException.class);
494+
new TestIterator(collection);
495+
}
496+
489497
@Test
490498
public void getMode() {
491499
Collection collection = new Collection(sharedRealm, table.where());

realm/realm-library/src/androidTest/java/io/realm/internal/SharedRealmTests.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ public void setUp() {
5353

5454
@After
5555
public void tearDown() {
56-
sharedRealm.close();
56+
if (sharedRealm != null) {
57+
sharedRealm.close();
58+
}
5759
}
5860

5961
@Test
@@ -100,6 +102,13 @@ public void isInTransaction() {
100102
assertFalse(sharedRealm.isInTransaction());
101103
}
102104

105+
@Test
106+
public void isInTransaction_returnFalseWhenRealmClosed() {
107+
sharedRealm.close();
108+
assertFalse(sharedRealm.isInTransaction());
109+
sharedRealm = null;
110+
}
111+
103112
@Test
104113
public void removeTable() {
105114
sharedRealm.beginTransaction();
@@ -231,4 +240,19 @@ public void onSchemaVersionChanged(long currentVersion) {
231240
assertTrue(listenerCalled.get());
232241
assertEquals(before + 1, schemaVersionFromListener.get());
233242
}
243+
244+
@Test
245+
public void isClosed() {
246+
sharedRealm.close();
247+
assertTrue(sharedRealm.isClosed());
248+
sharedRealm = null;
249+
}
250+
251+
@Test
252+
public void close_twice() {
253+
sharedRealm.close();
254+
sharedRealm.close();
255+
assertTrue(sharedRealm.isClosed());
256+
sharedRealm = null;
257+
}
234258
}

realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,9 @@ JNIEXPORT void JNICALL Java_io_realm_internal_SharedRealm_nativeCloseSharedRealm
225225

226226
auto shared_realm = *(reinterpret_cast<SharedRealm*>(shared_realm_ptr));
227227
// Close the SharedRealm only. Let the finalizer daemon thread free the SharedRealm
228-
shared_realm->close();
228+
if (!shared_realm->is_closed()) {
229+
shared_realm->close();
230+
}
229231
}
230232

231233
JNIEXPORT void JNICALL Java_io_realm_internal_SharedRealm_nativeBeginTransaction(JNIEnv* env, jclass,

realm/realm-library/src/main/java/io/realm/internal/Collection.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
@Keep
3333
public class Collection implements NativeObject {
3434

35+
private static final String CLOSED_REALM_MESSAGE =
36+
"This Realm instance has already been closed, making it unusable.";
37+
3538
private static class CollectionObserverPair<T> extends ObserverPairList.ObserverPair<T, Object> {
3639
public CollectionObserverPair(T observer, Object listener) {
3740
super(observer, listener);
@@ -94,6 +97,10 @@ public static abstract class Iterator<T> implements java.util.Iterator<T> {
9497
protected int pos = -1;
9598

9699
public Iterator(Collection collection) {
100+
if (collection.sharedRealm.isClosed()) {
101+
throw new IllegalStateException(CLOSED_REALM_MESSAGE);
102+
}
103+
97104
this.iteratorCollection = collection;
98105

99106
if (collection.isSnapshot) {

realm/realm-library/src/main/java/io/realm/internal/SharedRealm.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public interface SchemaVersionListener {
176176

177177
private final RealmConfiguration configuration;
178178

179-
private long nativePtr;
179+
final private long nativePtr;
180180
final Context context;
181181
private long lastSchemaVersion;
182182
private final SchemaVersionListener schemaChangeListener;
@@ -319,7 +319,7 @@ public long getLastSnapshotVersion() {
319319
}
320320

321321
public boolean isClosed() {
322-
return nativePtr == 0 || nativeIsClosed(nativePtr);
322+
return nativeIsClosed(nativePtr);
323323
}
324324

325325
public void writeCopy(File file, byte[] key) {
@@ -368,12 +368,9 @@ public void close() {
368368
realmNotifier.close();
369369
}
370370
synchronized (context) {
371-
if (nativePtr != 0) {
372-
nativeCloseSharedRealm(nativePtr);
373-
// It is OK to clear the nativePtr. It has been saved to the NativeObjectReference when adding to the
374-
// context.
375-
nativePtr = 0;
376-
}
371+
nativeCloseSharedRealm(nativePtr);
372+
// Don't reset the nativePtr since we still rely on Object Store to check if the given SharedRealm ptr
373+
// is closed or not.
377374
}
378375
}
379376

0 commit comments

Comments
 (0)