Mail Archives: cygwin/2007/11/05/07:44:25
On 11/5/07, Corinna Vinschen wrote:
> On Nov 1 10:58, Corinna Vinschen wrote:
> > On Oct 31 14:26, Lev Bishop wrote:
> > > $ cat lev.c && gcc -o lev lev.c -Wall -Wextra && CYGWIN=server ./lev
> > > #include <stdio.h>
> > > #include <unistd.h>
> > > #include <sys/shm.h>
> > >
> > > int main(void)
> > > {
> > > int shmid;
> > > if ((shmid = shmget(IPC_PRIVATE, 100,IPC_CREAT | 0600 )) < 0 ||
> > > !shmat(shmid, NULL, 0) ||
> > > shmctl(shmid, IPC_RMID, NULL) < 0)
> > > puts("problems with shm!");
> > > fork();
> > > }
> > > lev.c: In function `main':
> > > lev.c:13: warning: control reaches end of non-void function
> > > 3 [main] lev 1924 c:\Documents and
> > > Settings\Lev\Desktop\mpd-0.13.0\lev.exe: *** fatal error -
> > > MapViewOfFileEx (0x3E0000), Win32 error 6. Terminating.
> > > 124 [main] lev 5076 fork: child 1924 - died waiting for dll
> > > loading, errno 11
> >
> > Thanks for the testcase. I'm surprised that nobody experienced this
> > problem before. Sorta holiday here, so I'll look into it next week.
>
> Ouch, ouch, ouch. shmctl(IPC_RMID) closed the handle to the shared
> memory, but neglected to remove the actual mappings as well as the
> bookkeeping structure. The result is that after a fork the child thinks
> there are still mappings which have to be duplicated into its own
> memory. But the handle has already been closed in the parent, so the
> MapViewOfFile call fails with "invalid handle".
>
> Unfortunately not many applications use shmctl(IPC_RMID) before creating
> a child process since usually the shared memory is meant to be... well,
> shared. That's why this didn't crop up more often, obviously.
Are you sure that you're interpreting IPC_RMID correctly? My
understanding is that you can still share the memory until you
actually remove the mapping. (Sort of like how you can unlink() a temp
file immediately after you open it, and continue to use it). I assumed
this was the reason for the create-map-remove pattern used by mpd.
From the linux man page:
IPC_RMID Mark the segment to be destroyed. The segment will only
actually be destroyed after the last process detaches it
(i.e., when the shm_nattch member of the associated strucā
ture shmid_ds is zero). The caller must be the owner or
creator, or be privileged. If a segment has been marked
for destruction, then the (non-standard) SHM_DEST flag of
the shm_perm.mode field in the associated data structure
retrieved by IPC_STAT will be set.
Lev
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -