{"action":"created","issue":{"url":"https://api.github.com/repos/ffi/ffi/issues/405","labels_url":"https://api.github.com/repos/ffi/ffi/issues/405/labels{/name}","comments_url":"https://api.github.com/repos/ffi/ffi/issues/405/comments","events_url":"https://api.github.com/repos/ffi/ffi/issues/405/events","html_url":"https://github.com/ffi/ffi/pull/405","id":55383458,"number":405,"title":"Fixed the spec for the FFI:Function's :blocking parameter","user":{"login":"DavidEGrayson","id":466764,"avatar_url":"https://avatars.githubusercontent.com/u/466764?v=3","gravatar_id":"","url":"https://api.github.com/users/DavidEGrayson","html_url":"https://github.com/DavidEGrayson","followers_url":"https://api.github.com/users/DavidEGrayson/followers","following_url":"https://api.github.com/users/DavidEGrayson/following{/other_user}","gists_url":"https://api.github.com/users/DavidEGrayson/gists{/gist_id}","starred_url":"https://api.github.com/users/DavidEGrayson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DavidEGrayson/subscriptions","organizations_url":"https://api.github.com/users/DavidEGrayson/orgs","repos_url":"https://api.github.com/users/DavidEGrayson/repos","events_url":"https://api.github.com/users/DavidEGrayson/events{/privacy}","received_events_url":"https://api.github.com/users/DavidEGrayson/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-01-24T20:19:21Z","updated_at":"2015-01-25T05:17:01Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/ffi/ffi/pulls/405","html_url":"https://github.com/ffi/ffi/pull/405","diff_url":"https://github.com/ffi/ffi/pull/405.diff","patch_url":"https://github.com/ffi/ffi/pull/405.patch"},"body":"Quick intro: FFI:Function can wrap a C function, and if the `:blocking` parameter is set to true then it should release MRI's global interpreter lock (GIL) when you call the function, allowing multiple blocking functions to run concurrently.\r\n\r\nYou can tell the old spec was bad because you could remove `:blocking => true` from the spec and it would still pass.  I fixed it so that it actually tests that multiple blocking functions will run concurrently.  If they are not running concurrently, the spec is guaranteed to take at least 10 seconds to finish and it will therefore fail."},"comment":{"url":"https://api.github.com/repos/ffi/ffi/issues/comments/71353164","html_url":"https://github.com/ffi/ffi/pull/405#issuecomment-71353164","issue_url":"https://api.github.com/repos/ffi/ffi/issues/405","id":71353164,"user":{"login":"DavidEGrayson","id":466764,"avatar_url":"https://avatars.githubusercontent.com/u/466764?v=3","gravatar_id":"","url":"https://api.github.com/users/DavidEGrayson","html_url":"https://github.com/DavidEGrayson","followers_url":"https://api.github.com/users/DavidEGrayson/followers","following_url":"https://api.github.com/users/DavidEGrayson/following{/other_user}","gists_url":"https://api.github.com/users/DavidEGrayson/gists{/gist_id}","starred_url":"https://api.github.com/users/DavidEGrayson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DavidEGrayson/subscriptions","organizations_url":"https://api.github.com/users/DavidEGrayson/orgs","repos_url":"https://api.github.com/users/DavidEGrayson/repos","events_url":"https://api.github.com/users/DavidEGrayson/events{/privacy}","received_events_url":"https://api.github.com/users/DavidEGrayson/received_events","type":"User","site_admin":false},"created_at":"2015-01-25T05:17:01Z","updated_at":"2015-01-25T05:17:01Z","body":"Ok, I found the last time the test had been changed:\r\n\r\nhttps://github.com/ffi/ffi/commit/c66961af7fcc44121a7d060734d300afd3120419\r\n\r\nThe old version of the test before that commit was not very good since it creates a new thread and asserts that the thread can start within 1 second, so if the machine is doing something else for one second at the wrong time then it could fail.  Also, it is not guaranteed to catch bugs that cause the function to run non-concurrently.\r\n\r\nThe propose change in this pull request just asserts that all the child threads can finish within 9 seconds, so I think it should be less likely to fail since the time frame is longer.\r\n\r\nStill, I agree that we can do better.\r\n\r\nIf we could make a variable that can be accessed atomically from multiple threads, it would be easy to verify that a function can run concurrently.  Do we have access to any threading libraries that might have a feature like that?  I would be tempted to use [GCC's atomic builtins](https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html) but does the FFI gem support running tests on compilers other than GCC?"}}