Fix for client listener threads async callback deadlock #55
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Currently there is a potential deadlock in the Kinetic C Client, stemming from box_execute_cb. At the moment, client listener threads execute these user-defined callback functions. There are a limited number of listener threads spawned when the C Client starts (currently set to 4).
Here is how the client can deadlock currently: If the user blocks all listener threads and then executes a synchronous Kinetic command, the client will deadlock.
An example of how this can happen: A user writes a callback to lock each thread on a shared resource, and then do a PUT of that resource to the connected Kinetic drive. If one listener thread has the mutex, and the others are blocked waiting for the mutex, then only one listener thread is currently active. If this listener thread then tries to make a synchronous PUT, for example, then the last active thread will block on line 86 of the function KineticController_ExecuteOperation in the file kinetic_controller.c. The PUT will execute, but the PUT response message will never be read because all listener threads are blocked, thus deadlock.
My fix is to spawn a new thread per arbitrary user callback. A small design change, but it alleviates the listener threads of the responsibility of executing arbitrary user callback code, allowing listener threads to do what they were created to do: deal with incoming kinetic messages.