From owner-freebsd-standards@FreeBSD.ORG Sun May 4 12:50:03 2014 Return-Path: Delivered-To: freebsd-standards@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 41F11B1F for ; Sun, 4 May 2014 12:50:03 +0000 (UTC) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2EBB01195 for ; Sun, 4 May 2014 12:50:03 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.8/8.14.8) with ESMTP id s44Co33F080872 for ; Sun, 4 May 2014 12:50:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.8/8.14.8/Submit) id s44Co3s1080871; Sun, 4 May 2014 12:50:03 GMT (envelope-from gnats) Date: Sun, 4 May 2014 12:50:03 GMT Message-Id: <201405041250.s44Co3s1080871@freefall.freebsd.org> To: freebsd-standards@FreeBSD.org Cc: From: Joris Giovannangeli Subject: Re: standards/189353: POSIX sem_unlink does not actually unlink the semaphore in the process context X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list Reply-To: Joris Giovannangeli List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 04 May 2014 12:50:03 -0000 The following reply was made to PR standards/189353; it has been noted by GNATS. From: Joris Giovannangeli To: Konstantin Belousov Cc: freebsd-gnats-submit@FreeBSD.org Subject: Re: standards/189353: POSIX sem_unlink does not actually unlink the semaphore in the process context Date: Sun, 04 May 2014 14:46:43 +0200 This is a multi-part message in MIME format. --------------010206030707030503040002 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit I've found this issue while implementing semaphores for dragonflyBSD, and at first i came with the same solution than yours. But it won't work when you do the same in two processes : unlink will only remove the caching on the process calling unlink, not all of them. See attached test case. It looks like glibc is using inodes numbers and dev number for that, which, while not being strictly correct (inodes can be reused), seems to work fine on linux. For dragonfly, i'm currently trying to keep filedescriptors opened in the nameinfo structure. This adds quite a bit of overhead, but this way you can check link count with fstat during a sem_open to see if the semaphore file still exist, and return the cached mapping only if st_nlink > 0. This solution at least should be strictly correct, but the inode solution could be fine in practice. Regards, joris --------------010206030707030503040002 Content-Type: text/x-csrc; name="sem_test.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="sem_test.c" #include #include #include #include #include #include #include #include #include int main() { pid_t pid; sem_t *sem1, *sem2; int error, saved_errno, status; int v1, v2; int pd[2]; char er[1]; char ok[1]; char buf[1]; size_t size; *er = 'X'; *ok = 'O'; if (pipe(pd) == -1) err(1, "Cannot create sync pipe"); sem1 = sem_open("/test-sem", O_CREAT | O_EXCL, S_IRWXU, 1); if (sem1 == SEM_FAILED) err(1,"Cannot create test /test-sem semaphore"); char c = getchar(); pid = fork(); if ( pid == -1) err(1, "Unable to fork test process"); if (pid == 0) { close(pd[0]); error = sem_unlink("/test-sem"); if (error) { perror("Cannot unlink semaphore /test-sem"); goto error; } sem2 = sem_open("/test-sem", O_CREAT | O_EXCL, S_IRWXU, 2); if (sem2 == SEM_FAILED) { perror("Cannot re-create semaphore /test-sem"); goto error; } write(pd[1], ok, 1); error = wait(&status); if (error && errno == EINTR) goto error; return(status); error: write(pd[1], er, 1); close(pd[1]); error = wait(&status); if (error && errno == EINTR) goto error; errx(1, "TEST UNRESOLVED"); return(1); } else { close(pd[1]); size = read(pd[0], buf, 1); if (size != 1) err(2, "process 2 cannot wait for process 1"); if (*buf == *er) errx(2, "Test error"); else { sem2 = sem_open("/test-sem", 0); if (sem2 == SEM_FAILED) err(2, "process 2 failed reopeing semaphore"); // sem_unlink("/test-sem"); sem_getvalue(sem1, &v1); sem_getvalue(sem2, &v2); printf("v1 = %d and v2 = %d\n", v1, v2); if (v1 == v2) { errx(2, "*** TEST FAILED. NOT POSIX ***"); } else { errx(0, "*** TEST SUCCESS. POSIX CONFORMANT ***"); } } } } --------------010206030707030503040002--