Can you please link me to documentation for the functions you've mentioned here (and/or share an example)? I'm having a hard time finding anything about them.
[quote='789337022, DTS Engineer, /thread/756281?answerId=789337022#789337022']
My preferred mechanism to do this inter-thread bounce is the various -[NSThread perform*] methods.
[/quote]
Post
Replies
Boosts
Views
Activity
Thanks for the replies Quinn. Here's a little more explicit line of questioning.
The stream programming guide explicitly states:
You should never attempt to access a scheduled stream from a thread different than the one owning the stream’s run loop.
Given that statement, it seems to me that I want to be extremely explicit about scheduling those streams on a particular thread which is not the Main (assuming your goal is to have blocking operations off the Main). Not just using whichever thread happens to be the one owning RunLoop.current. It's pretty intuitive that RunLoop.current means "the current thread", that was always clear. However, the real question is "which thread is the 'current' one?" If I don't want my stream processing to happen on the Main thread, how do I do that if my only options are RunLoop.current or RunLoop.main? What if current is main?
I'm left with basically no idea how to schedule the streams on a thread intentionally. Obviously, I might have a better idea how to do that if I was an expert on your concurrency model, but alas I am not.
Is that recommendation in the stream programming guide not actually accurate? Or, if it is accurate, how can I achieve what I want with DispatchQueue or Thread. I'm not totally getting how this can be accomplished. I think a little example code would go a long way. Thanks!
[quote='789821022, jlucier, /thread/756281?answerId=789821022#789821022, /profile/jlucier']
I'm left with basically no idea how to schedule the streams on a thread intentionally. Obviously, I might have a better idea how to do that if I was an expert on your concurrency model, but alas I am not.
Is that recommendation in the stream programming guide not actually accurate? Or, if it is accurate, how can I achieve what I want with DispatchQueue or Thread. I'm not totally getting how this can be accomplished. I think a little example code would go a long way. Thanks!
[/quote]
Allow me to clarify a little bit here. I've figured out a couple of ways to schedule the streams on a specific thread, but I simultaneously need to be able to trigger bytes to be written to the output stream on that same thread owning the RunLoop.
It is not clear what is the best way to stitch together your concurrency primitives to achieve this, so that we never access the streams from the Main thread and we keep all RunLoop and stream I/O associated with our streams on a single, separate thread.
Thanks again for the reply and the detailed example. Very helpful!
One followup:
IMO it’s generally best to use the main thread for all your run loop sources, and then move stuff off the main thread only if you have evidence that it’s causing delays.
If this is your colloquial wisdom, how do we square this with the recommendations from the stream programming guide?
My train of thought goes as follows, and hopefully you can see where this breaks down:
Your recommendation is to use the Main thread for run loops generally. Let's assume we aren't special and fall into the general case, so maybe we should use Main.
That means the streams should get be scheduled (via schedule) on the Main thread.
The stream programming guide says that you should never access a stream from a thread other than the one owning its RunLoop. Ok, that also must happen on Main I suppose.
Read and write operations have the potential to cause indefinite blocking (apparently), which I suppose we just have to... tolerate as a risk?
If you have confidence that other EAAccessory users are successfully using the Main thread for scheduling their stream processing, I think that would be confidence enough for me. I am just getting the sense that I must be a bit crazy following this line of questioning. This threading / deadlock problem appears to be given absolutely zero attention in the EAAccessory guides, but explicitly warned about in the Stream programming guide, leaving me unsure about what is actually the recommended approach. If using Main is "fine" or "recommended", then I suppose that's what we'll keep doing.
That is quite helpful! Thank you. Did I miss that somewhere in the docs?
Can the same guarantee be made about the corresponding properties that exist on the stream classes? For instance, will checking hasSpaceAvailable before calling write guarantee no blocking the same as waiting for a hasSpaceAvailable event before writing?
The doc here suggests maybe not since a write may need to be attempted to find out? https://developer.apple.com/documentation/foundation/outputstream/1411335-hasspaceavailable
hasSpaceAvailable
true if the receiver can be written to or if a write must be attempted in order to determine if space is available, false otherwise.
This was a winding conversation, but I think I've got the information I need now. Thank you kindly for all the replies!