mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-30 05:37:43 +00:00
Fix potential race condition caused by early unlocking
The lock should be kept between the point we read and the point we write Also, no need to pass SMSPlugin as a parameter, since enclossed classes already have access to its parent by default.
This commit is contained in:
parent
7db40ee20a
commit
bfadb84b9f
@ -163,18 +163,15 @@ public class SMSPlugin extends Plugin {
|
|||||||
private final Lock mostRecentTimestampLock = new ReentrantLock();
|
private final Lock mostRecentTimestampLock = new ReentrantLock();
|
||||||
|
|
||||||
private class MessageContentObserver extends ContentObserver {
|
private class MessageContentObserver extends ContentObserver {
|
||||||
final SMSPlugin mPlugin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a ContentObserver to watch the Messages database. onChange is called for
|
* Create a ContentObserver to watch the Messages database. onChange is called for
|
||||||
* every subscribed change
|
* every subscribed change
|
||||||
*
|
*
|
||||||
* @param parent Plugin which owns this observer
|
|
||||||
* @param handler Handler object used to make the callback
|
* @param handler Handler object used to make the callback
|
||||||
*/
|
*/
|
||||||
MessageContentObserver(SMSPlugin parent, Handler handler) {
|
MessageContentObserver(Handler handler) {
|
||||||
super(handler);
|
super(handler);
|
||||||
mPlugin = parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,29 +182,26 @@ public class SMSPlugin extends Plugin {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange) {
|
public void onChange(boolean selfChange) {
|
||||||
if (mPlugin.mostRecentTimestamp == 0) {
|
if (mostRecentTimestamp == 0) {
|
||||||
// Since the timestamp has not been initialized, we know that nobody else
|
// Since the timestamp has not been initialized, we know that nobody else
|
||||||
// has requested a message. That being the case, there is most likely
|
// has requested a message. That being the case, there is most likely
|
||||||
// nobody listening for message updates, so just drop them
|
// nobody listening for message updates, so just drop them
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lock so no one uses the mostRecentTimestamp between the moment we read it and the
|
||||||
|
// moment we update it. This is because reading the Messages DB can take long.
|
||||||
mostRecentTimestampLock.lock();
|
mostRecentTimestampLock.lock();
|
||||||
// Grab the mostRecentTimestamp into the local stack because reading the Messages
|
SMSHelper.Message message = SMSHelper.getNewestMessage(context);
|
||||||
// database could potentially be a long operation
|
|
||||||
long mostRecentTimestamp = mPlugin.mostRecentTimestamp;
|
|
||||||
mostRecentTimestampLock.unlock();
|
|
||||||
|
|
||||||
SMSHelper.Message message = SMSHelper.getNewestMessage(mPlugin.context);
|
if (message == null || message.date <= mostRecentTimestamp) {
|
||||||
|
// onChange can trigger many times for a single message. Don't make unnecessary noise
|
||||||
if (message.date <= mostRecentTimestamp) {
|
mostRecentTimestampLock.unlock();
|
||||||
// Our onChange often gets called many times for a single message. Don't make unnecessary
|
|
||||||
// noise
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the most recent counter
|
// Update the most recent counter
|
||||||
mostRecentTimestampLock.lock();
|
mostRecentTimestamp = message.date;
|
||||||
mPlugin.mostRecentTimestamp = message.date;
|
|
||||||
mostRecentTimestampLock.unlock();
|
mostRecentTimestampLock.unlock();
|
||||||
|
|
||||||
// Send the alert about the update
|
// Send the alert about the update
|
||||||
@ -281,7 +275,7 @@ public class SMSPlugin extends Plugin {
|
|||||||
context.registerReceiver(receiver, filter);
|
context.registerReceiver(receiver, filter);
|
||||||
|
|
||||||
Looper helperLooper = SMSHelper.MessageLooper.getLooper();
|
Looper helperLooper = SMSHelper.MessageLooper.getLooper();
|
||||||
ContentObserver messageObserver = new MessageContentObserver(this, new Handler(helperLooper));
|
ContentObserver messageObserver = new MessageContentObserver(new Handler(helperLooper));
|
||||||
SMSHelper.registerObserver(messageObserver, context);
|
SMSHelper.registerObserver(messageObserver, context);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user