I was looking for a named mutex so that I could ensure mutual exclusion for the lifetime of a process (making sure only one process running per some set of properties). I didn't find one (looks like I might have not looked hard enough) and so I implemented my own pseudo named mutex in linux by using an abstract UNIX domain socket. Only a single bind() to that socket will succeed. The other nice thing is that the OS will cleanup the abstract UNIX domain socket if the process dies and thus doesn't cleanup the socket itself. Unfortunately I'm not sure of any way for you to "wait" on this pseudo mutex to become available.
An abstract UNIX domain socket is a UNIX domain socket whose name begins with a null byte. Beware though, I believe that the entire buffer is used as the name and thus you want to ensure that you don't just memcpy or strcpy a partial string into it, or if you do make sure you first fill the entire buffer with some character.
All but the first bind() will fail with an errno of EADDRINUSE.
// Create an abstract socket to use as a mutex.
int err;
int mutex_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (mutex_sock == -1)
{
err = errno;
printf("main, failed creating mutex socket: %s\n",
get_error_string(errno, error_string, sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed creating mutex socket: "
"%s", get_error_string(errno, error_string,
sizeof(error_string)));
errno = err;
goto done;
}
// Bind to abstract socket. We use this as a sort of named mutex.
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path + 1, socket_name, sizeof(addr.sun_path) - 2);
result = bind(mutex_sock, (struct sockaddr*) &addr, sizeof(addr));
if (result == -1)
{
err = errno;
if (errno == EADDRINUSE)
{
printf("main, failed bind to mutex socket: %s. "
"Another instance must be running.\n",
get_error_string(errno,
error_string, sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: "
"%s. "
"Another instance must be running.",
get_error_string(errno,
error_string, sizeof(error_string)));
}
else
{
printf("main, failed bind to mutex socket: %s\n",
get_error_string(errno, error_string,
sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: %s",
get_error_string(errno, error_string,
sizeof(error_string)));
}
errno = err;
goto done;
}
Thanks,
Nick
Mutex
is strictly used for inner-process thread synchronization, but in Windows for instance a named mutex can be access from other processes too -CreateMutex
– Catarrhine