Solving deadlock in ContactProvider2

These two threads are deadlocked.

There are two locks involved: database lock (marked with D below and
the object lock on ContactsDatabaseHelper marked with H)

"Binder Thread #2" prio=5 tid=13 MONITOR
  | group="main" sCount=1 dsCount=0 s=N obj=0x44bee478 self=0x1205f8
  | sysTid=1439 nice=0 sched=0/0 cgrp=default handle=1201736
H at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:~149)
  at com.android.providers.contacts.ContactsDatabaseHelper.getMimeTypeId(ContactsDatabaseHelper.java:1512)
  at com.android.providers.contacts.ContactsDatabaseHelper.updateAllVisible(ContactsDatabaseHelper.java:1554)
  at com.android.providers.contacts.ContactsProvider2.beforeTransactionCommit(ContactsProvider2.java:1989)
  at com.android.providers.contacts.SQLiteContentProvider.onCommit(SQLiteContentProvider.java:216)
  at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:494)
D at com.android.providers.contacts.SQLiteContentProvider.insert(SQLiteContentProvider.java:96)
  at com.android.providers.contacts.ContactsProvider2.insert(ContactsProvider2.java:1941)
  at android.content.ContentProvider$Transport.insert(ContentProvider.java:150)
  at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:140)
  at android.os.Binder.execTransact(Binder.java:287)
  at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #1" prio=5 tid=11 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x44bea248 self=0x125480
  | sysTid=1438 nice=0 sched=0/0 cgrp=default handle=1145184
  at java.lang.Object.wait(Native Method)
  - waiting on <0x5319d0> (a java.lang.VMThread)
  at java.lang.Thread.parkFor(Thread.java:1535)
  at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
  at sun.misc.Unsafe.park(Unsafe.java:317)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:790)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:823)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
  at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:200)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
D at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:305)
  at android.database.sqlite.SQLiteStatement.simpleQueryForLong(SQLiteStatement.java:116)
H at com.android.providers.contacts.ContactsDatabaseHelper.getCachedId(ContactsDatabaseHelper.java:1478)
  at com.android.providers.contacts.ContactsDatabaseHelper.getMimeTypeId(ContactsDatabaseHelper.java:1513)
  at com.android.providers.contacts.ContactsProvider2.query(ContactsProvider2.java:3765)
  at android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:117)
  at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:98)
  at android.os.Binder.execTransact(Binder.java:287)
  at dalvik.system.NativeStart.run(Native Method)

Removing synchronization from the getCachedId method is benign. Worst case
some value would be read from the database twice - no biggie.

Bug: 2370192
Change-Id: Ia6606d5bf617a8d52daaa1e63f57aeeba6dd0437
1 file changed