简体   繁体   English

WakeLock相关的Mandelbug:WakeLock.acquire()是否总是成功?

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

The Problem 问题

I've been developing for Android for quite some time now. 我已经为Android开发了相当一段时间。 One of the programs I've developed makes heavy use of WakeLocks . 我开发的程序之一大量使用了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. hasWakeLock()仅返回(wakeLock != null && wakeLock.isHeld())的结果,而wakeLockManager.newPartialWakeLock(DEBUG_TAG)封装标准的“获取PowerManager,然后返回唤醒锁”代码。 For the purposes of testing, the assert statements are JUnit assert methods so I think we can assume that they are correct. 出于测试目的,assert语句是JUnit assert方法,因此我认为我们可以假定它们是正确的。

The problem with the code is this: the final assertion - assertTrue(hasWakeLock()) - seems to fail every few weeks with very little explanation. 代码的问题是这样的:最终的断言assertTrue(hasWakeLock()) -每隔几周就会失败,几乎没有解释。 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 that on rare occasions takes effect just before the postcondition but after the call to acquire() , or that (3) acquire() is sometimes faulty. 这意味着我这里有三个可能的问题:(1)从来没有从PowerManager检索唤醒锁(2)我有一个并发问题,在极少数情况下,该问题仅在后置条件之前但在调用acquire() ,或者(3) acquire()有时有问题。

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 : 假设1:唤醒锁未返回

Were this the case then I would see a null pointer exception. 如果是这种情况,那么我会看到一个空指针异常。 It can't be that. 不可能是那样。

Hypothesis 2: I have a concurrency issue : 假设2:我有一个并发问题

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. 对参与获取和发布wakeLock的所有场所的刚刚进行的正式验证证明,使我坚信事实并非如此。 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 : 假设3:WakeLock.acquire()有错误, 尽管文档说什么,但有时它可能无法获取锁

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. 我不喜欢这个假说,因为所有的Android用户提供有一个人除了自己一定已经注意到了这一点,它几乎总是开发人员的代码,而不是库或OS的代码,这是错误的。 Then again, stranger things have happened and this might be a genuine Android bug, albeit a rarely exhibited one. 再说一次,奇怪的事情发生了,这可能是一个真正的Android错误,尽管很少出现。 If this hypothesis is true then acquire() is simply not acquiring the wake lock and this would explain the behaviour I'm seeing. 如果这个假设是正确的,那么acquire()根本就不会获得唤醒锁,这将解释我所看到的行为。

So StackOverflow, what could be causing this problem? 那么StackOverflow,可能是什么引起这个问题? What do you think is wrong? 你觉得错什么? Am I missing something obvious, or could this be a genuine problem with Android's wake locks? 我是否缺少明显的东西,或者这可能是Android唤醒锁的真正问题?

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! 我忽略了以下事实:可以从单独线程中的非同步位置调用相关方法-在高度多线程的环境中,这是一个明显的问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM