Skip to content

Day56 Learning Log

Objective

Today focused on Linux POSIX shared memory IPC.

The goal was to gradually build a complete event-driven IPC architecture using:

  • shared memory
  • process-shared mutex
  • eventfd
  • epoll
  • UNIX domain socket
  • SCM_RIGHTS fd passing

What I Built

Initial Shared Memory Demo

Started from the smallest POSIX shared memory flow:

shm_open()
ftruncate()
mmap()

Created a simple shared structure:

counter
message buffer

and verified parent/child shared memory behavior after fork.


Independent Process Shared Memory

Refactored the architecture into:

shm_writer
shm_reader

without fork inheritance.

The writer became the shared memory owner.

The reader independently attached to the existing shared memory object.

This helped clarify:

  • shared object lifetime
  • mmap attachment model
  • process isolation vs shared pages

Process-shared pthread Mutex

Added:

pthread_mutex_t

inside shared memory.

Learned:

  • mutex must be initialized after mmap()
  • mutex must reside inside shared memory
  • only owner process should initialize the mutex
  • reader processes only use existing mutex state

Also discovered that:

pthread_mutex_lock()
requires writable shared memory mapping

Using:

PROT_READ

caused segmentation fault / glibc abort.


Shared Memory Race Protection

Protected shared structure access using:

pthread_mutex_lock()
pthread_mutex_unlock()

Verified correct synchronization between writer and reader.


AF_UNIX Control Channel

Built a UNIX domain socket control channel.

Architecture:

writer = server
reader = client

Implemented reusable helper layer:

unix_socket_helper.h

SCM_RIGHTS File Descriptor Passing

Reused Day55 fd passing implementation:

sendmsg()
recvmsg()
SCM_RIGHTS

Successfully transferred:

eventfd

from writer to reader.

Also debugged an important issue:

listen socket fd != connected client socket fd

The fd passing operation must use the accepted client socket.


eventfd Notification Architecture

Integrated:

eventfd
epoll

into shared memory IPC.

Writer:

update shared memory
write(eventfd)

Reader:

epoll_wait()
read(eventfd)
consume shared memory

This converted the IPC architecture from polling into event-driven design.


Shared Activation State

Added shared state flag:

bool activation;

Used as graceful shutdown coordination between writer and reader.

Shutdown flow:

writer:
    activation = false
    notify eventfd

reader:
    wakeup
    detect shutdown
    cleanup

Important Debugging Issues

Mutex Corruption

Encountered glibc abort:

__pthread_tpp_change_priority assertion failed

Cause:

uninitialized shared memory pointer

inside stdin event handler.


Reader mmap Protection

Encountered segmentation fault when locking mutex.

Cause:

reader mmap used PROT_READ only

Fix:

PROT_READ | PROT_WRITE

FD Passing Failure

Encountered:

Transport endpoint is not connected

Cause:

fdpass_send_fd()
used listen socket fd
instead of accepted client fd

Key Concepts Learned

Shared Memory

  • independent process attachment
  • shared page mapping
  • shared object lifetime

pthread Mutex

  • process-shared synchronization
  • userspace synchronization object
  • futex-backed design

eventfd

  • kernel event counter
  • epoll integration
  • lightweight notification primitive

UNIX Socket

  • control path IPC
  • fd transfer
  • resource coordination

Final Architecture

shared memory = data path
eventfd       = notification path
unix socket   = control path

Result

Successfully built:

event-driven shared memory IPC

using:

  • POSIX shared memory
  • process-shared mutex
  • AF_UNIX socket
  • SCM_RIGHTS
  • eventfd
  • epoll