Putting it all together: using handles with anonymous, revocable, and sealed shared memory objects

Updated: April 19, 2023

To retain the most control over a shared memory object, the creator must use a handle with an anonymous, revocable shared memory object.

Here's how:

  1. The creator creates an anonymous shared memory object by specifying SHM_ANON when it calls shm_open():
    fd = shm_open(SHM_ANON, ...);
    
  2. The creator backs the shared memory object with memory by calling shm_ctl() with physical memory, physically contiguous memory, or typed memory, specifying that it's a revocable object with the SHMCTL_REVOCABLE flag. For example:
    shm_ctl( fd, SHMCTL_PHYS | SHMCTL_REVOCABLE | SHMCTL_SEAL, phys_addr,
             size);
    

    You can set SHMCTL_REVOCABLE in a separate call to shm_ctl().

  3. The creator creates a handle via shm_create_handle(), passing the SHM_CREATE_HANDLE_OPT_NOFD flag and specifying the recipient's process ID:
    shm_create_handle( fd, recipient_pid, ..., &handle,
                       SHM_CREATE_HANDLE_OPT_NOFD);
    

    Do this after setting the SHMCTL_REVOCABLE flag; otherwise the recipient could try to guess the handle and map it before the shared memory object is marked as revocable.

  4. The creator gives the handle to the recipient process.
  5. The recipient maps the shared memory object via mmap_handle(), but it might not (see step 8).
  6. The recipient operates on the shared memory object.
  7. The creator decides the recipient is done, or the recipient tells the creator it's done with the shared memory object.
  8. The creator revokes the access to the shared memory object for the recipient by calling shm_revoke():
    shm_revoke(fd, recipient_pid);
    

    Any unused handles given to the recipient for that object are destroyed at the same time, in case the recipient didn't actually map the object.