openFrameworks icon indicating copy to clipboard operation
openFrameworks copied to clipboard

ofThreadChannel::clear() to clear the channel

Open artificiel opened this issue 1 year ago • 4 comments

title says it all; proves useful if unconsumed data in the channel is known to be stale

artificiel avatar Apr 30 '24 01:04 artificiel

@artificiel a clear method would be very helpful! Does it need a condition.notify_all(); if it is cleared?

What are your thoughts about a open() function, since the channel can be closed but not re-opened?

NickHardeman avatar May 09 '24 17:05 NickHardeman

condition.notify_all() = good question; i would assume the condition is to trigger a receive? in this case we're not flushing but abandoning the queue. but maybe, I'm not 100% sure...

I've been using it under fair load (12 instances pushing a total of 1000 msg/sec, and when the consuming thread is a bit busy, like when a gui window drag hiccup freezes the framerate for a fraction of a second, an irrecoverable backlog occurs. with the clear I haven't got crashes, and never "old" data.

for the open/close = also good question; I haven't been in a need of closing a channel — I guess that if there is a higher logic that connects/disconnects things, the access logic to the thread channel would be controlled there, more than within the thread channel itself?

so the question would be: why close the thread channel? (i.e. why use an internal state for a gate?) do you have examples of closed threadchannels?

(removing close() would even simplify the implementation, as the thread channel is born open (it's not a state based on something) and the only thing that can make closed=true is the close() message...)

artificiel avatar May 10 '24 02:05 artificiel

I'm also not sure about the condition.notify_all() ....

About the open/close, I am thinking specifically of ofxOscReceiver as outlined here( #7938

The osc thread would continue to try and push data to the thread channel ( when there was a lot of messages ) and we occasionally got a crash when deleting the shared_ptr to an ofxOscReceiver. I think calling stop() should have the close method so that the stop is immediate, blocks the other thread (if any) and will reject any new messages.

//--------------------------------------------------------------
void ofxOscReceiver::stop() {
	messagesChannel.clear();
	messagesChannel.close();
	listenSocket.reset();
}

Our implementation for the project in thread channel was

void open() {
	std::unique_lock<std::mutex> lock(mutex);
	closed = false;
	condition.notify_all();
}
void clear() {
	std::unique_lock<std::mutex> lock(mutex);
	std::queue<T> empty;
   	std::swap( queue, empty );
	condition.notify_all();
}

NickHardeman avatar May 10 '24 15:05 NickHardeman

Sorry for getting off topic of the PR, maybe we can carry on the open / close conversation here: https://github.com/openframeworks/openFrameworks/issues/7938

This PR looks good to me 👍

NickHardeman avatar May 10 '24 17:05 NickHardeman