5

I am using Shared Memory in a Client-Server Model. When my Server gets killed off by the user by using sigkill instead of sigterm / sigint I can't do anything about it (as intended), but my Shared Memory Object and Semaphores still exist in /dev/shm/.

The next time I start my Server I want to create a new object with exactly the same name, and - as intented - this fails and I exit my program.

The user would need to remove the objects on his own - which is certainly not the best thing.

How can I handle this?

I could just call shm_open() without the O_EXCL flag, ultimately destroying the purpose of this flag. Because maybe there is already an instance of my server running and uses this object.

Pulseaudio seems to use a combination of digits to keep it's objects distinct and doesn't get affected by killing it with -9, so there seems to be a way.

Haini
  • 922
  • 2
  • 12
  • 28
  • 1
    Don't you have other means to identify a server process already running? A pid file, maybe? – moooeeeep Jan 10 '16 at 18:00
  • @moooeeeep That's why I ask how to deal with it - seems like a good start, but where should I locate such a file? – Haini Jan 10 '16 at 18:05

2 Answers2

5

One option is to use IPC_RMID (see this).

This options marks the shm segment for cleanup after the last process attached to it disappears.

For semaphores, you can look at robust mutexes. It does require you to code for an extra error case (when a process holding the mutex dies).

You also have the option of using file locks, which are released if the process terminates (see lockf()).

Ziffusion
  • 8,779
  • 4
  • 29
  • 57
  • Is it possible to obtain the shmid when using functions from SHM_OVERVIEW(7), e.g. the POSIX shared memory way? I can't see a way to get it, as System V shared memory operations and POSIX shared memory operations seem to work a little bit different. Still great input, it's not easy to get a grab of all the options I have. – Haini Jan 10 '16 at 19:44
  • Not sure if it would work for your use case, but if you can call `shm_unlink()` after all the processes have opened the `shm` by name, it has a similar effect of cleaning up the `shm` after the processes disappear. – Ziffusion Jan 10 '16 at 20:00
  • Sadly, I can't call shm_unlink() when I receive sigkill. Calling it any time before that would be a disaster as no new clients could open the SHM after calling it. Otherwise it would be a good trick. – Haini Jan 10 '16 at 20:11
  • The `pid` file route may be the best option for you. See [this](http://ftp.ics.uci.edu/pub/centos0/ics-custom-build/BUILD/rsyslog-3.19.7/tools/pidfile.c) for a decent example. – Ziffusion Jan 10 '16 at 20:14
  • Seems so, altough it's quite sad that I can't solve it your way. Excellent example, thanks! – Haini Jan 10 '16 at 20:16
  • Is the IPC_RMID option only for System V shared memory? – mpr May 22 '18 at 17:33
1

An outline of a possible server initialization:

Open pid file w/O_EXCL | O_WRONLY if success write pid close Open shm w/O_CREAT done

open pid file w/O_RDONLY read pid Use kill(0) to see if server alive If yes, exit If no, remove pid file Close pid, start at top again

Pid files are usually located in the /var/run dir and are named foobar.pid where foobar is the program name

John Hascall
  • 9,176
  • 6
  • 48
  • 72
  • So combined with this http://unix.stackexchange.com/questions/12815/what-are-pid-and-lock-files-for I see where this is heading. Seems like the proper thing to do. Thanks! Will accept this answer if nothing easier comes up in a few hours. – Haini Jan 10 '16 at 18:32