开发者

WakeLock-related Mandelbug: does WakeLock.acquire() always succeed?

开发者 https://www.devze.com 2023-03-30 15:08 出处:网络
The Problem I\'ve been developing for Android for quite some time now. One of the programs I\'ve developed makes heavy use of WakeLocks. It usually perfectly (often for days or weeks at a time, a req

The Problem

I've been developing for Android for quite some time now. One of the programs I've developed makes heavy use of WakeLocks. It usually perfectly (often for days or weeks at a time, a requirement of the program), but very rarely I notice peculiar behaviour in this code:

acquireWakeLock(wakeLockManager)

    // Preconditions
    assertFalse("Wake lock already acquired.", hasWakeLock());
    assertNotNull("Wake lock manager not provided.", wakeLockManager);

    // Acquire a wake lock.
    wakeLock = wakeLockManager.newPartialWakeLock(DEBUG_TAG);
    wakeLock.acquire();

    // Postconditions
    assertTrue("Wake Lock should be held!", hasWakeLock());

Where hasWakeLock() simply returns the result of (wakeLock != null && wakeLock.isHeld()) and wakeLockManager.newPartialWakeLock(DEBUG_TAG) encapsulates the standard "get the PowerManager and then return a wake lock" code. For the purposes of testing, the assert statements are JUnit assert methods so I think we can assume that they are correct.

The problem with the code is this: the final assertion - assertTrue(hasWakeLock()) - seems to fail every few weeks with very little explanation. It means that I have three possible issues here: (1) the wake lock is never retrieved at all from the PowerManager (2) that I have a concurrency issue th开发者_开发百科at on rare occasions takes effect just before the postcondition but after the call to acquire(), or that (3) acquire() is sometimes faulty.

Investigation of the Problem

As stated above, I have three potential issues that may be occurring that I am investigating / have investigated:

Hypothesis 1: Wake Lock not returned:

Were this the case then I would see a null pointer exception. It can't be that.

Hypothesis 2: I have a concurrency issue:

A just-conducted formal verification proof of all places involved in acquiring and releasing wakeLock strongly leads me to believe that this is not the case. In the case that my proof is faulty then I may have a concurrency issue, but it is then truly insidious and difficult to find.

Hypothesis 3: WakeLock.acquire() is faulty, and despite what the documentation says it sometimes can fail to acquire the lock:

I dislike this hypothesis because with all of the Android users our there someone aside from myself must have noticed this by now and it is almost always the developer's code, not the library or OS code, that is faulty. Then again, stranger things have happened and this might be a genuine Android bug, albeit a rarely exhibited one. If this hypothesis is true then acquire() is simply not acquiring the wake lock and this would explain the behaviour I'm seeing.

So StackOverflow, what could be causing this problem? What do you think is wrong? Am I missing something obvious, or could this be a genuine problem with Android's wake locks?


It would appear that this was indeed a concurrency issue. I overlooked the fact that a relevant method could be called from a non-synchronized location in a separate thread - an obvious problem in a highly multithreaded environment!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号