Close duplicate OCB I/O function handler

Updated: May 06, 2022

Prototype:

int (*close_dup) ( resmgr_context_t *ctp,
                  io_close_t *msg,
                  RESMGR_OCB_T *ocb ) 

Classification:

I/O function

Default handler:

iofunc_close_dup_default()

Helper functions:

iofunc_close_dup()

Client functions:

close(), fclose()

Messages:

_IO_CLOSE

Data structure:

struct _io_close {
  uint16_t type;
  uint16_t combine_len;
};

typedef union {
  struct _io_close i;
} io_close_t;

Description:

This is the real function handler for the client's close() or fclose() function calls.

If you take over this function, you would almost always call iofunc_close_dup_default() in addition to the work you do. This is because the base layer keeps track of the number of open(), dup(), and close() messages issued for a particular OCB, and will then synthesize a close OCB I/O function handler outcall (see below) when the last close() message has been received for a particular OCB.

Note that the receive IDs present in ctp->rcvid may not necessarily match up with those passed to the open connect function handler. For example, when a client disconnects without sending _IO_CLOSE, the resource manager framework handles the resulting pulse and fakes an _IO_CLOSE message. Any attempt to reply directly to this message via ctp->rcvid (which should be 0), or to leave it “blocked” and reply later, will fail.

Note: If your resource manager leaves clients blocked (e.g., on read(), write(), or devctl() calls), you'll need to take over this function, so that you can keep track of which clients are blocked, and unblock them if necessary. For more information, see Unblocking if someone closes the file descriptor in the Unblocking Clients and Handling Interrupts chapter of Writing a Resource Manager.
CAUTION:
Unlike with most other I/O function handlers, the resource manager framework runs close_dup() without locking the OCB structure (ocb). If you need to modify fields in this structure and your server process is multi-threaded, you must serialize access to the structure to avoid race conditions. For more information, see the note about locking attribute structures in “Unblocking if someone closes a file descriptor” in Writing a Resource Manager.

Returns:

The status via the helper macro _RESMGR_STATUS().

Referenced by:

resmgr_io_funcs_t I/O table

Permission checking:

The default implementation iofunc_close_dup_default() calls the helper function iofunc_close_dup(), which does not do any permission checking.