-
Notifications
You must be signed in to change notification settings - Fork 960
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
Allow a ConcurrentCircularBuffer to be reinstated after being canceled. #1218
base: master
Are you sure you want to change the base?
Conversation
…d. Canceling allows one to signal threads that are waiting for a push or pop operation to simply stop waiting. But without a copy constructor, there was no way to undo the cancellation afterward in order to use the buffer again.
To avoid having to call |
I don't think that's a waterproof solution, Rich, as the main thread might want to cancel all operations in order to quit the secondary thread that's waiting to pop an item, but then a third thread might push a new item. The main thread would then not be able to terminate and the application would never quit. |
I suppose you're right. Pretty messy to have to remember to 'reset' a data structure, but then I guess so are multi-producer / multi-consumer queues in general. |
Oh and I do like that you added the bool return, so that the producer knows if he wasn't able to push anything and its not necessarily a failure. I did the same for audio::dsp::RingBuffer's read() and write() methods. |
Perhaps we can implement the |
…ts until all threads have canceled their operations, then 'uncancels' itself.
I think this is a better solution. The call to |
Here's a Gist that you can use to test it. Just copy-paste it over the BasicApp sample: |
Thanks for searching for a one-shot solution. I'll defer to Andrew's judgement on this one since he wrote the original thread-safe wrapper, although the first thing that jumps out at me is that you might end up blasting your cpu during the cancel on a big copy because of the |
@richardeakin thanks for your suggestion to use a condition variable instead of a sleep(0). It made the code even cleaner. |
I've tested this with 32 consumer threads and the main thread acting as a producer thread plus one additional producer thread that pushes a value every 1 milliseconds. Canceling from the main thread correctly signals all consumers to stop waiting. The call to Producers may still (try to) push during cancellation, but their call immediately returns To clarify the scenario in which you'd need functionality like this: imagine having a class that uses a separate thread to do some work. You want to be able to start and stop the thread during the execution of your app. The class uses the |
This looks good to me although I haven't tested (but it appears you have extensively!). Just to be clear, the wait here will wait until the next attempted push or pop, which might be indefinitely but this doesn't matter right? |
You're sharp, dude. I'll do a test to see what happens if there aren't any threads waiting for results. |
Canceling allows one to signal threads that are waiting for a push or pop operation to simply stop waiting. But without a copy constructor, there was no way to undo the cancellation afterward in order to use the buffer again.