{"action":"created","issue":{"url":"https://api.github.com/repos/StephenCleary/AsyncEx/issues/62","repository_url":"https://api.github.com/repos/StephenCleary/AsyncEx","labels_url":"https://api.github.com/repos/StephenCleary/AsyncEx/issues/62/labels{/name}","comments_url":"https://api.github.com/repos/StephenCleary/AsyncEx/issues/62/comments","events_url":"https://api.github.com/repos/StephenCleary/AsyncEx/issues/62/events","html_url":"https://github.com/StephenCleary/AsyncEx/issues/62","id":179044431,"number":62,"title":"AsyncSemaphore FIFO guarantee","user":{"login":"bp74","id":1810450,"avatar_url":"https://avatars.githubusercontent.com/u/1810450?v=3","gravatar_id":"","url":"https://api.github.com/users/bp74","html_url":"https://github.com/bp74","followers_url":"https://api.github.com/users/bp74/followers","following_url":"https://api.github.com/users/bp74/following{/other_user}","gists_url":"https://api.github.com/users/bp74/gists{/gist_id}","starred_url":"https://api.github.com/users/bp74/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bp74/subscriptions","organizations_url":"https://api.github.com/users/bp74/orgs","repos_url":"https://api.github.com/users/bp74/repos","events_url":"https://api.github.com/users/bp74/events{/privacy}","received_events_url":"https://api.github.com/users/bp74/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-09-24T18:25:06Z","updated_at":"2016-09-24T19:09:39Z","closed_at":null,"body":"I was using the SemaphorSlim class from the .NET framework in my application, but the documentation says: _If multiple threads are blocked, there is no guaranteed order, such as FIFO or LIFO, that controls when threads enter the semaphore._\r\n\r\nSince the order is important in my application i was looking at the AsyncSemaphore class in your library. It uses a queue to store waiters, so you would assume that the order is guaranteed. After some research i think this is not the case and i would like to ask if you can confirm this.\r\n\r\nThe SemaphorSlim implementation (see link below) uses a double linked list which is protected by a lock, this is similar to the lock that protects your queue. A small test also shows that waiters are executed in a FIFO manner. \r\n\r\nhttp://referencesource.microsoft.com/#mscorlib/system/threading/SemaphoreSlim.cs,d57f52e0341a581f\r\n\r\nSo why does the documentation of SemaphorSlim say that the order is not guaranteed? I found a quote from Joe Duffy's \"Concurrent Programming on Windows\" book, which sounds like you'll usually get FIFO behavior from .NET monitors, but there are some situations where that won't occur.\r\n\r\n_Page 273 of the book says: \"Because monitors use kernel objects internally, they exhibit the same roughly-FIFO behavior that the OS synchronization mechanisms also exhibit (described in the previous chapter). Monitors are unfair, so if another thread sneaks in and acquires the lock before an awakened waiting thread tries to acquire the lock, the sneaky thread is permitted to acquire the lock.\"_\r\n\r\nTo make a long story short, you won't get an order guarantee from SemaphorSlim and AsyncSemaphore. All you get is a \"in most cases\" threads will enter the semaphore with a FIFO behavior, but it may happen that this is not the case. This is not a bug report, i just want to ask for confirmation. Thank you very much!\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/StephenCleary/AsyncEx/issues/comments/249382043","html_url":"https://github.com/StephenCleary/AsyncEx/issues/62#issuecomment-249382043","issue_url":"https://api.github.com/repos/StephenCleary/AsyncEx/issues/62","id":249382043,"user":{"login":"bp74","id":1810450,"avatar_url":"https://avatars.githubusercontent.com/u/1810450?v=3","gravatar_id":"","url":"https://api.github.com/users/bp74","html_url":"https://github.com/bp74","followers_url":"https://api.github.com/users/bp74/followers","following_url":"https://api.github.com/users/bp74/following{/other_user}","gists_url":"https://api.github.com/users/bp74/gists{/gist_id}","starred_url":"https://api.github.com/users/bp74/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bp74/subscriptions","organizations_url":"https://api.github.com/users/bp74/orgs","repos_url":"https://api.github.com/users/bp74/repos","events_url":"https://api.github.com/users/bp74/events{/privacy}","received_events_url":"https://api.github.com/users/bp74/received_events","type":"User","site_admin":false},"created_at":"2016-09-24T19:09:39Z","updated_at":"2016-09-24T19:09:39Z","body":"Well, after more testing i think the problem is of a theoretical nature. The lock actually only affects the enqueuing of the waiters. As soon as the waiter is enqueued the order can't change in both implementations (AsyncSemaphore and SemaphoreSlim). If multiple threads would try to enter the semaphore at the same time, the order can't be guaranteed anyway - and it would be crazy to write an application that assumes this :) "}}
{"actor":{"display_login":"bp74"}}