1 package expo.modules.updates.db
2 
3 import android.util.Log
4 
5 /**
6  * Wrapper class that provides a rudimentary locking mechanism for the database. This allows us to
7  * control what high-level operations involving the database can occur simultaneously. Most classes
8  * should access [UpdatesDatabase] through this class.
9  *
10  * Any process that calls `getDatabase` *must* manually release the lock by calling
11  * `releaseDatabase` in every possible case (success, error) as soon as it is finished.
12  *
13  * On iOS we use GCD queues as a more sophisticated way of achieving the same thing; we may also
14  * eventually want to migrate to a coroutine- or [Handler]-based system in lieu of this class.
15  */
16 class DatabaseHolder(private val mDatabase: UpdatesDatabase) {
17   private var isInUse = false
18 
19   @get:Synchronized
20   val database: UpdatesDatabase
21     get() {
22       while (isInUse) {
23         try {
24           (this as java.lang.Object).wait()
25         } catch (e: InterruptedException) {
26           Log.e(TAG, "Interrupted while waiting for database", e)
27         }
28       }
29       isInUse = true
30       return mDatabase
31     }
32 
33   @Synchronized
releaseDatabasenull34   fun releaseDatabase() {
35     isInUse = false
36     (this as java.lang.Object).notify()
37   }
38 
39   companion object {
40     private val TAG = DatabaseHolder::class.java.simpleName
41   }
42 }
43