title: Handling InterruptedException while waiting for an exit signal (bug in Android?)
body: <p>I've come across the code below, and I'm wondering if it does exactly what I think it does:</p>
  
  <pre><code>synchronized(sObject) {
      mShouldExit = true;   
      sObject.notifyAll()    
      while (!mExited) {
        try {
             sObject.wait();
          } catch (InterruptedException ex) {
             Thread.currentThread().interrupt();
          }
       }
  }
  </code></pre>
  
  <p>About the context: there is another thread that checks for <code>mShouldExit</code> (inside the <code>sObject</code> monitor) and will exit in that case.</p>
  
  <p>This does not look to be a correct pattern to me. If an interrupt happens, it will set the interrupted status again, so when it returns to <code>sObject.wait()</code>, another InterruptedException will come etc. etc. etc. Therefore, it can never go to truly waiting state (<code>sObject.wait()</code>) i.e. it will never release the <code>sObject</code> monitor. This may result in an infinite loop, as the other thread cannot set mExiting to true, because it can never enter sObject's monitor. (So I think that the <code>interrupt()</code> call is an error, it must not be used here.) Am I missing something?</p>
  
  <p>Note that the code snippet is a part of the official Android framework source code.</p>
  
  <p><strong>UPDATE:</strong> actually, the situation is worse, because the same pattern is used in Android when your GL rendering starts. The official source code of <code>GLSurfaceView.GLThread.surfaceCreated()</code>:</p>
  
  <pre><code>   public void surfaceCreated() {
          synchronized(sGLThreadManager) {
              if (LOG_THREADS) {
                  Log.i("GLThread", "surfaceCreated tid=" + getId());
              }
              mHasSurface = true;
              sGLThreadManager.notifyAll();
              while((mWaitingForSurface) &amp;&amp; (!mExited)) {
                  try {
                      sGLThreadManager.wait();
                  } catch (InterruptedException e) {
                      Thread.currentThread().interrupt();
                  }
              }
          }
      }
  </code></pre>
  
  <p>You can reproduce the bug in a similar way: make sure your UI thread has its interrupted status flag yet, then add your GLSurfaceView and start the GL rendering (via <code>setRenderer(...)</code>, but on some devices, make sure your GLSurfaceView has <code>Visibility.VISIBLE</code> status, otherwise rendering will not start).</p>
  
  <p>If you follow the above steps, your UI thread will end up in an infinite loop, because the above-quoted code will keep generating an <code>InterruptedException</code> (due to <code>wait()</code>) and therefore the GL thread will never be able to set <code>mWaitingForSurface</code> to false.</p>
  
  <p>According to my tests, it seems that such an infinite loop <strong>will also result in an endless sequence of GC_CONCURRENT garbage collection</strong> (or, at least, such messages in logcat). Interesting, someone had an unknown poorly-defined issue on stackoverflow earlier which might be related:
  <a href="https://stackoverflow.com/questions/6591807/how-to-solve-gc-concurrent-freed">How to solve GC_concurrent freed?</a></p>
  
  <p>Isn't it possible that perhaps his UI thread had its interrupted flag set to true, and he was using a GLSurfaceView for the map he mentions? Just an assumption, a possible scenario.</p>