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
Race conditions #250
Comments
|
#2. On pthread_clean_push-- the man page indicates, "POSIX.1 permits pthread_cleanup_push() and pthread_cleanup_pop() to be implemented as macros that expand to text containing '{' and '}', respectively. For this reason, the caller must ensure that calls to these functions are paired within the same function, and at the same lexical nesting level. (In other words, a clean-up handler is only established during the execution of a specified section of code.)" What you're proposing doesn't sound like it conforms to that. #3. The size-specific ints, in this case uint8_t. |
I should have read the code first... I the concept of pthread_clean_push(), but there's still risk. When BarPlayerCleanup is called, the last thing it does is a memset() to zero out the player data. But there's no guarantee that that fully completes before the main thread sees that player_mode is now FREED, and starts up a new player. I think if the player thread was being spawned off with its own copy malloced copy of the player data, that'd be the way to go; each player would clean up after itself. But with this data-sharing between the main and player thread, I think doing the cleanup as part of the main thread is the way to go. On the signals: I didn't realize you could do thread-specific signals! I like it, but consider sigsuspend instead of pause() to ensure you only catch SIGCONT and not whatever other signals happen. |
|
Indeed that is how I misread the code. Reading it with BarPlayerCleanup looks good to me. You have an excellent coding style. Very legible, maintainable code. Perette |
Always run cleanup, ensure thread is joined and player struct is reset. See #250.
So, one and three are fixed and two is going to be fixed once I merge |
One. In main.c, BarMainPlayerCleanup is called on player mode==PLAYER_FINISHED_PLAYBACK.
A new song is started on mode >= PLAYER_FINISHED_PLAYBACK or == PLAYER_FREED.
But if mode == PLAYER_FINISHED_PLAYBACK in the start conditional (and it could, because the state changes from a separate thread) then Cleanup is never called. Which means a pthread leaks.
Suggested fixes:
a. Copy mode to a local variable, and check that in both cases.
b. (better, I think) Only start on app->player.mode == PLAYER_FREED. That ensures Cleanup has reset everything, and another spin around the main loop isn't expensive.
Two. Dealing with the pause mutex, as the thread shuts down, it's possible for the main thread to be just about to try the mutex, a context switch to occur, the audio thread to complete and destroy the mutex, then the main thread to then use the freed mutex.
Suggested fix: initialize/destroy the mutex as part of Start/Cleanup, outside the player thread.
Three. Not a race condition, but my older OS X system wants this header file included in waitress.c:
`
include <stdint.h>
`
The text was updated successfully, but these errors were encountered: