{"action":"opened","issue":{"url":"https://api.github.com/repos/lionheart/openradar-mirror/issues/11726","repository_url":"https://api.github.com/repos/lionheart/openradar-mirror","labels_url":"https://api.github.com/repos/lionheart/openradar-mirror/issues/11726/labels{/name}","comments_url":"https://api.github.com/repos/lionheart/openradar-mirror/issues/11726/comments","events_url":"https://api.github.com/repos/lionheart/openradar-mirror/issues/11726/events","html_url":"https://github.com/lionheart/openradar-mirror/issues/11726","id":148542083,"number":11726,"title":"18707735: C++: std::async fails with \"mutex lock failed: Invalid argument\"","user":{"login":"openradar-mirror","id":13605213,"avatar_url":"https://avatars.githubusercontent.com/u/13605213?v=3","gravatar_id":"","url":"https://api.github.com/users/openradar-mirror","html_url":"https://github.com/openradar-mirror","followers_url":"https://api.github.com/users/openradar-mirror/followers","following_url":"https://api.github.com/users/openradar-mirror/following{/other_user}","gists_url":"https://api.github.com/users/openradar-mirror/gists{/gist_id}","starred_url":"https://api.github.com/users/openradar-mirror/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openradar-mirror/subscriptions","organizations_url":"https://api.github.com/users/openradar-mirror/orgs","repos_url":"https://api.github.com/users/openradar-mirror/repos","events_url":"https://api.github.com/users/openradar-mirror/events{/privacy}","received_events_url":"https://api.github.com/users/openradar-mirror/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/lionheart/openradar-mirror/labels/classification:serious%20bug","name":"classification:serious bug","color":"e11d21"},{"url":"https://api.github.com/repos/lionheart/openradar-mirror/labels/reproducible:always","name":"reproducible:always","color":"5319e7"},{"url":"https://api.github.com/repos/lionheart/openradar-mirror/labels/status:open","name":"status:open","color":"009800"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/lionheart/openradar-mirror/milestones/4","html_url":"https://github.com/lionheart/openradar-mirror/milestones/iOS%20SDK","labels_url":"https://api.github.com/repos/lionheart/openradar-mirror/milestones/4/labels","id":1237418,"number":4,"title":"iOS SDK","description":null,"creator":{"login":"openradar-mirror","id":13605213,"avatar_url":"https://avatars.githubusercontent.com/u/13605213?v=3","gravatar_id":"","url":"https://api.github.com/users/openradar-mirror","html_url":"https://github.com/openradar-mirror","followers_url":"https://api.github.com/users/openradar-mirror/followers","following_url":"https://api.github.com/users/openradar-mirror/following{/other_user}","gists_url":"https://api.github.com/users/openradar-mirror/gists{/gist_id}","starred_url":"https://api.github.com/users/openradar-mirror/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openradar-mirror/subscriptions","organizations_url":"https://api.github.com/users/openradar-mirror/orgs","repos_url":"https://api.github.com/users/openradar-mirror/repos","events_url":"https://api.github.com/users/openradar-mirror/events{/privacy}","received_events_url":"https://api.github.com/users/openradar-mirror/received_events","type":"User","site_admin":false},"open_issues":1861,"closed_issues":3,"state":"open","created_at":"2015-08-03T02:08:31Z","updated_at":"2016-04-15T03:01:27Z","due_on":null,"closed_at":null},"comments":0,"created_at":"2016-04-15T03:01:27Z","updated_at":"2016-04-15T03:01:27Z","closed_at":null,"body":"#### Description\n\nSummary:\r\nIn a platform-agnostic C++ library, we use std::async to divide work between threads. On iOS 7.1 (11D167), this can fail because locking an internal mutex results in an \"invalid argument\" error.\r\n\r\nWith launch policy set to std::launch::async, the failure is thrown from the std::async call site.\r\n\r\nIf we change the launch policy to std::launch::async|std::launch::deferred, the failure will be thrown at the callsite of get() for the resulting std::future.\r\n\r\nI do not appear to get a failure if I use only std::launch::deferred, but this renders makes std::async somewhat useless, as I want to use it for launching asynchronous tasks. However, on iOS there is no way to safely do so.\r\n\r\n(The library in question is written in platform-agnostic C++11 code, which is why this uses std::async and not iOS-specific functionality such as GCD or direct pthreads.)\r\n\r\nSteps to Reproduce:\r\n[[[ See attached AsyncTest.cpp ]]]\r\n\r\nOn an iPad MD328LL/A running iOS 7.1 (11D167), the application will terminate within about two minutes with \"libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument\"\r\n\r\nExpected Results:\r\nNo failures.\r\n\r\nActual Results:\r\n\"libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument\" if launch policy is std::launch::async or std::launch::async|std::launch::deferred.\r\n\r\nVersion:\r\niOS 7.1 (11D167)\r\n\r\nNotes:\r\nThis may be related to libc++ bug 19766, http://llvm.org/bugs/show_bug.cgi?id=19766 which was closed as \"File a bug with Apple\"\r\n\r\nConfiguration:\r\niPad MD328LL/A; Xcode 6.0.1 (6A317)\r\n\r\n\r\n[[[ AsyncTest.cpp:\r\n\r\n#include <cstdio>\r\n#include <cstdlib>\r\n#include <vector>\r\n#include <thread>\r\n#include <future>\r\n\r\nvoid threadFunc(uint32_t* begin, uint32_t* end)\r\n{\r\n   // \"Work\". In the real thing this is a more complicated algorithm.\r\n   for (; begin != end; ++begin)\r\n   {\r\n      *begin = *begin ^ 0xDEADBEEF;\r\n   }\r\n}\r\n\r\nvoid asyncTest()\r\n{\r\n   printf(\"Starting.\\n\");\r\n\r\n   std::vector<uint32_t> data(1024*1024);\r\n\r\n   // Fill with random data.\r\n   for (size_t i = 0; i < data.size(); ++i)\r\n      data[i] = rand();\r\n\r\n   for (int iteration = 0; ; ++iteration)\r\n   {\r\n      std::vector<std::future<void>> tasks;\r\n      const size_t kTaskCount = 8;\r\n\r\n      // Split up work into kTaskCount chunks.\r\n      for (size_t chunk = 0; chunk < kTaskCount; ++chunk)\r\n      {\r\n         // !!!\r\n         // This can fail due to:\r\n         //    std::system_error, \"mutex lock failed: Invalid argument\"\r\n         // from the call to std::async.\r\n         // !!!\r\n         tasks.push_back(\r\n            std::async(\r\n               std::launch::async,\r\n               threadFunc,\r\n               data.data() + (chunk * (data.size()/kTaskCount)),\r\n               data.data() + ((chunk+1) * (data.size()/kTaskCount))));\r\n      }\r\n\r\n      // Wait for completion.\r\n      // !!!\r\n      // This can fail due to:\r\n      //     std::system_error, \"mutex lock failed: Invalid argument\"\r\n      // if the call to std::async used std::launch::async|std::launch::deferred!\r\n      // !!!\r\n      for (auto& t : tasks)\r\n      {\r\n         t.get();\r\n      }\r\n   }\r\n}\r\n]]]\n\n-\nProduct Version: iOS 7.1\nCreated: 2014-10-20T14:52:33.396659\nOriginated: 2014-10-20T00:00:00\nOpen Radar Link: http://www.openradar.me/18707735"}}