Let's take a look at the general case for the
io_open handler—it doesn't always
correspond to the client's open() call!
For example, consider the stat() and
access() client function calls:
_IO_CONNECT_COMBINE_CLOSE
For a stat() client call, we essentially perform the sequence
open(), fstat(), and close(). Note that if
we actually did that, three messages would be required. For performance reasons, we implement the
stat() function as one single combine message:
- Client call:
- stat()
- Message(s):
- _IO_CONNECT_COMBINE_CLOSE , _IO_STAT
- Callouts:
- io_open, io_lock_ocb, io_stat,
io_unlock_ocb, io_close
The _IO_CONNECT_COMBINE_CLOSE message causes the io_open
handler to be called. It then implicitly (at the end of processing for the combine message) causes
the io_close_ocb handler to be called.
_IO_CONNECT_COMBINE
For the access() function, the client's C library
will open a connection to the resource manager and perform a
stat() call. Then, based on the results of the
stat() call, the client's C library
access() may perform an optional
devctl() to get more information. In any event,
because access() opened the device, it must also
call close() to close it:
- Client call:
- access()
- Message(s):
- _IO_CONNECT_COMBINE , _IO_STAT,
_IO_DEVCTL (optional), _IO_CLOSE
- Callouts:
- io_open, io_lock_ocb, io_stat,
io_unlock_ocb, io_lock_ocb (optional),
io_devctl (optional), io_unlock_ocb (optional),
io_close
Notice how the
access() function opened the
pathname/device—it sent it an
_IO_CONNECT_COMBINE message along with the
_IO_STAT message.
This creates an OCB (when the
io_open handler is called),
locks the associated attribute structure (via
io_lock_ocb),
performs the stat (
io_stat),
and then unlocks the attributes structure (
io_unlock_ocb).
Note that we don't implicitly close the OCB—this is left for a later, explicit, message.
Contrast this handling with that of the plain
stat() above.
Note:
Note that close() (not ConnectDetach()) must follow
the message if we send a custom _IO_CONNECT_COMBINE message, even when MsgSend()
returns an error.