Firstly, the GPIO uAPI ioctl()s are synchronous, that is they will not return until the operation is complete. They are not asynchronous, such that you initiate the operation and wait for a completion notification.
So in response to your third question, there is no fd to wait on for a GPIO uAPI ioctl() to complete - the calling thread will not return from the ioctl() until the operation has completed.
(The readability of the fds in the uAPI is not related to the ioctl()s, but indicates an asynchronous event has occurred, and that the event details can be read from the file. For line request fds that is an edge event. For chip fds it is a change to a line's requested state - has it been requested or released or reconfigured.)
My initial reaction to your first question was that the GPIO uAPI ioctl()s, such as GPIO_V2_LINE_SET_VALUES_IOCTL, are effectively nonblocking. While they may involve mutexes covering shared state, at the end of the day they protect writes to registers controlling the hardware, and those would return almost immediately, so any contention would be fleeting and any overheads would be less than context switching between threads in userspace. Given that, you may as well just call it - even from within an epoll() loop.
For GPIOs hosted directly on SOCs and microcontrollers that is probably true, however for GPIO extender chips connected via I2C, or SPI, or what have you, the ioctl() will not return until the corresponding transaction completes. How long that takes depends on the bus etc, and whether that delay is significant to you depends on your application. It wouldn't block your event loop indefinitely, but it may stall it longer than you would like.
So in response to your first question, if you mean blocking indefinitely then, no they should not block indefinitely. But under some circumstances they could take an appreciable time to complete, and that may be significant to you.
I think that applies to the second question as well. Generally they can be assumed to be nonblocking, but it depends on the specific ioctl() and your application.
ioctlwill use a lock to complete safely. This will usually only make a difference when multiple concurrent calls toioctloccur from different threads. But typically we don't call that blocking. Usually the term "blocking" means waiting on a particular condition. For examplereadandrecvblock until data is available in the buffer.sendandwriteblock until enough space is available in the buffer. They don't block until data is sent. What mightGPIO_V2_LINE_SET_VALUES_IOCTLblock on?write()won't block even with a file open in blocking mode, provided the underlying "thing" is a file on a local filesystem. But I wouldn't put such a write call in anepoll()loop, because it could, theoretically, block the entire loop under some circumstances. This is the contract of eg.epoll()andwrite()andO_NONBLOCK— I can guarantee that I won't block an event loop if I use them correctly.ioctl()either way: either a documented way to use it that guarantees I won't block an event loop, OR documentation that it may block an event loop so that I can account for this.