-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Swift 5: resolve Linux crash with concurrent access to socketHandlers #284
Conversation
The use of
|
@djones6. Try using a dispatch semaphore, that seems to be more efficient. I used it in an app I was working on before I retired, replacing an NSLock, and it seemed noticeably faster. Probably worth a shot. |
53efd57
to
9a0d1da
Compare
…e inner one changes
I've become convinced that changes to Dictionary in Swift 5 have exposed a problem with our code, since it accesses/modifies the socketHandlers dictionary on multiple threads. Though I have yet to nail down specifically what has changed, I gather from previous Swift 5 fixes relating to Dictionaries and ordering that there are some substantial changes under the covers. Attempting to separate the dictionary into separate parts didn't seem to help, and neither did reducing the number of epoll threads to 1. But locking definitely prevents the crash. This leads me to believe that the problem is concurrency related, but not in the way I thought. So I returned to evaluating various methods of locking to find the one with the lowest overhead. Here is a comparison of four different methods:
The read/write style of locking is much faster, almost indistinguishable from baseline. We could choose either of these methods, and I'm inclined to go with the Dispatch approach as although pthread_rwlock is perhaps a fraction faster, it's less readable and there's more scope for error. One other thing that came out of this experiment is that Swift 5 is way slower. This was a surprise, as with the work done to utf8 handling in 5, I expected to see gains here. This will need investigating separately. |
Add comments on public API Use isSwiftLogging() so that mapping between loggers is not duplicated
Description
Ensures that modifications to the
IncomingSocketManager.socketHandlers
dictionary are performed with exclusive access, using a DispatchQueue to access the dictionary inhandle()
,process()
andremoveIdleSockets()
.Also adds Travis for the GCD codepath on Linux.
Motivation and Context
With Swift 5, the Kitura test suite crashes intermittently (but frequently) while accessing the
socketHandlers
dictionary. I believe this is due to concurrent access but I haven't managed to get a clear picture from lldb so far. Adding locking around accesses to the dictionary avoids the problem.How Has This Been Tested?
Running under stress using a simple Kitura 'hello world' benchmark results in a crash almost immediately with Swift 5. I've confirmed that the process does not crash after applying this fix.
Checklist: