A thread always runs until it has exceeded its time slice or goes to waiting state. On systems that support thread priorities and preempting, a higher priority thread may also be able preempt a running thread with lower priority but that depends on the system. Going to waiting state means that a thread is waiting for some event to happen and won't be available for running until that event has happened, e.g. an I/O event or a timing event like sleeping for a certain amount of time.
Thread.pass
is what most other programming languages and operation systems call yielding but of course, using that term would be very misleading in Ruby for obvious reasons. It means that you tell the operation system to treat your thread as if its time slice was exceeded, giving other threads a chance to run immediately without having to wait for your thread to use up all of its time slice, to wait, or to be preempted. As your thread stays in run-able state when yielding (it is not considered waiting for anything), it is immediately available to run again, so it's not said that another thread will take over as the thread scheduler may consider your thread to still be the best candidate when deciding which thread to run next (especially if all other run-able threads have a lower priority).
But in case IO.select
has to block, this will put your thread into a waiting state and then it won't be available for running anymore, so in that case the thread scheduler has to pick another thread anyway and this is documented:
Calls select(2) system call. It monitors given arrays of IO objects, waits until one or more of IO objects are ready for reading, are ready for writing, and have pending exceptions respectively, and returns an array that contains arrays of those IO objects.
Waiting always means the thread stops running and whenever a thread stops running, some other run-able thread will take over.
But if your intention is to always give another thread a chance to run in the case of an error, no matter if select
would block or not (as it doesn't have to block, up to the point select
is called, the socket may be writable again and then it won't block), then it may really make sense to call Thread.pass
. Yet most programmers would probably not call it in that situation as if select
won't block, you usually want the write operation to be repeated again immediately (within the same time slice, if possible and if not, your thread will pass anyway).