Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 733e6977 authored by Tom Taylor's avatar Tom Taylor
Browse files

Fix deadlock in PDU code

Bug 6257442

If PduPersister.load bails out early and throws an exception,
it will leave the uri it's working on in an updated-locked
state. With this change, the uri is removed from the updated
list in a finally clause. The other PDU function in
this file already does the correct thing.

Change-Id: I596bd46724282b245ddba109670f3cebd61ed57c
parent 78b0d9fa
Loading
Loading
Loading
Loading
+91 −86
Original line number Diff line number Diff line
@@ -519,7 +519,11 @@ public class PduPersister {
     * @throws MmsException Failed to load some fields of a PDU.
     */
    public GenericPdu load(Uri uri) throws MmsException {
        PduCacheEntry cacheEntry;
        GenericPdu pdu = null;
        PduCacheEntry cacheEntry = null;
        int msgBox = 0;
        long threadId = -1;
        try {
            synchronized(PDU_CACHE_INSTANCE) {
                if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
                    if (LOCAL_LOGV) {
@@ -545,8 +549,6 @@ public class PduPersister {
            PduHeaders headers = new PduHeaders();
            Set<Entry<Integer, Integer>> set;
            long msgId = ContentUris.parseId(uri);
        int msgBox;
        long threadId;

            try {
                if ((c == null) || (c.getCount() != 1) || !c.moveToFirst()) {
@@ -609,7 +611,6 @@ public class PduPersister {
                }
            }

        GenericPdu pdu = null;
            switch (msgType) {
            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
                pdu = new NotificationInd(headers);
@@ -658,16 +659,20 @@ public class PduPersister {
                throw new MmsException(
                        "Unrecognized PDU type: " + Integer.toHexString(msgType));
            }

        } finally {
            synchronized(PDU_CACHE_INSTANCE) {
                if (pdu != null) {
                    assert(PDU_CACHE_INSTANCE.get(uri) == null);
                    // Update the cache entry with the real info
                    cacheEntry = new PduCacheEntry(pdu, msgBox, threadId);
                    PDU_CACHE_INSTANCE.put(uri, cacheEntry);
                }
                PDU_CACHE_INSTANCE.setUpdating(uri, false);
                PDU_CACHE_INSTANCE.notifyAll(); // tell anybody waiting on this entry to go ahead
            return pdu;
            }
        }
        return pdu;
    }

    private void persistAddress(
            long msgId, int type, EncodedStringValue[] array) {