<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - std::mutex initialization is unsafe on iOS"
   href="http://llvm.org/bugs/show_bug.cgi?id=19766">19766</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::mutex initialization is unsafe on iOS
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.4
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Other
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>other
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>bstrong@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu, mclow.lists@gmail.com
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The std::mutex constructor initializes the pthread_mutex member with
PTHREAD_MUTEX_INITIALIZER (a macro intended to be used for initializing static
mutexes). This macro does not do real initialization, but instead sets a flag
that results in actual initialization being done on the first call to
pthread_mutex_lock().

On most modern pthreads implementations, this deferred initialization is thread
safe (i.e., if the first call to pthread_mutex_lock() occurs simultaneously on
two different threads, the right thing happens). Unfortunately, some
implementations, notably the one on iOS, do not do the right thing. 

For an example of an unsafe implementation of deferred initialization, see:
<<a href="http://www.opensource.apple.com/source/Libc/Libc-167/pthreads.subproj/pthread_mutex.c">http://www.opensource.apple.com/source/Libc/Libc-167/pthreads.subproj/pthread_mutex.c</a>>

The correct, portable way to initialize a pthread_mutex member variable is with
pthread_mutex_init() (as the libstdc++ and boost mutex implementations do).

The following code snippet will throw from mutex::lock() with libc++ on iOS (it
works with libc++ on OSX and linux and with libstdc++ and boost mutex
implementations on iOS):

<span class="quote">>></span >
  for (int i = 0; i < 1000; ++i) {
    std::array<std::mutex, 1000> mutexes;
    auto thread_fn = ([&mutexes]() {
      for (auto& m : mutexes) {
        m.lock();
        m.unlock();
      }
    });
    thread t1(thread_fn);
    thread t2(thread_fn);
    t1.join();
    t2.join();
  }
<<

This was tested with the libdc++ included with Xcode 5.1.1 on an iPad3 running
iOS 7.1.1.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>