• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: shm_open and mmap: Invalid argument?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: shm_open and mmap: Invalid argument?


  • Subject: Re: shm_open and mmap: Invalid argument?
  • From: Tim Hewett <email@hidden>
  • Date: Mon, 21 Feb 2005 00:47:23 +0000

Mark,

It looks like off_t casting is a red herring, I deleted the cast in mine
and it still worked ok.

I am using mmap() on a real file, my shared memory is
file-backed. This is because the System V IPC is not great under
OS X in my experience and using file-backed shared memory seemed
the only option for the size of shared memory I need. System V IPC
semaphores were/(are?) the worst, under 10.2 they caused a dual CPU
Mac to panic every time, it seems to be well worth avoiding the subsystem
and use something a bit more universal.


Now that I know about the Posix shm_open() call (thanks to this thread)
I am now experimenting with it, for Ethan's benefit here are the results
as they seem to be different to what he reports:

1. For the process initially creating the shared memory, the shm_open()
works and the mmap() works (no "Invalid argument" error). I had been
calling shm_unlink() right after the shm_open() call, so that the shared
memory is always deleted after the last process using it terminates
(even if it crashes) but that was failing with EINVAL. It was moved to
after the mmap() and now works. That doesn't make much sense but
that is how it is, it seems as if Posix shared memory is in some kind of
limbo state meaning it can't be unlinked until after it has been mapped.

2. If an ordinary file path is used for shm_open(), it fails. Changing the
name to "/1" or similar makes it work fine.


3. The other processes sharing the shared memory in my application
are all child processes and they mmap() it using the file descriptor they
inherit from the main parent. Here I have the same problem as Ethan -
the mmap always fails with EINVAL, why this only happens in the
subprocesses is a mystery.


This is my experimental code:

Parent process (shared memory creator) - works fine:

    if ( (bufferFd = shm_open( "/1", O_RDWR | O_CREAT, 0700 )) == -1 ) {

	// Error handling here
	return;
    }

    if ( fcntl( bufferFd, F_SETFD, 1 ) == -1 ) {

	// Error handling here
    }

    if ( ftruncate( bufferFd, (off_t)size ) == -1 ) {

	// Error handling here
	return;
    }

    if ( (buf = mmap( NULL, (size_t)size, PROT_READ | PROT_WRITE,
		MAP_SHARED, bufferFd, 0 )) == (void *)-1 ) {

	// Error handling here
	return;
    }

    if ( mlock( (caddr_t)buf, (size_t)size ) == -1 ) {

	// Error handling here
	return;
    }

    if ( shm_unlink( "/1" ) == -1 ) {

	// Error handling here
    }


Child process - inherits shared memory file descriptor, mmap() returns EINVAL but the preceding call to fstat() works fine so the descriptor is being inherited ok (not much else can be wrong):

    if ( fstat( inherited_fd, &filestat ) == -1 ) {

	// Error handling here
	exit( -1 );
    }

    if ( (buf = mmap( NULL, filestat.st_size, PROT_READ | PROT_WRITE,
		MAP_SHARED, inherited_fd, (off_t)0 )) == (void *)-1 ) {

	// Error handling here
	exit( -1 );
    }


So this has kind of moved things along slightly, in that the creator can shm_open/fcntl/ftruncate/mmap/mlock/shm_unlink the shared memory, but the children can't mmap it yet even though they have successfully inherited the descriptor.

My OS is 10.3.8 incidentally, not tried 10.2 yet.

Tim.


On 20 Feb 2005, at 20:42, Mark Williamson wrote:

It looks like the final parameter to mmap() (i.e. an integer constant
of value 0) needs to be cast to type off_t to suit the mmap function
definition. The off_t type is a 64 bit "long long" while your constant
is 32 bits, Lord only knows what'll be in the other 32 bits received
by mmap()...

Did this work for you? I thought that casts were supposed to be done
automatically in these situations (assuming you included the right header
files!!!).


Cheers,
Mark


HTH,

Tim.

On 20 Feb 2005, at 20:03, email@hidden wrote:
I am trying to implement some shared memory between a set of processes.
I don't really care if it's file-backed or not -- these regions are
not going to be particularly large, I just want low latency
communication between the processes.


I've already got things working with the SysV interfaces shmget and
shmat, but Mac OS X is configured with a very low number of
concurrently active regions per process (I think 8?) and I don't want
other users to have to tinker with kernal configuration settings, so
I'm switching to the POSIX interface instead. (It was also quite
annoying that SysV regions are left in memory after all references are
gone. Further, OS X doesn't provide the ipcs utility, I had to
download it myself in order to kill the regions manually. (thanks to
whoever ported that utility... I had trouble finding it the first time
and I can't find it again now :( )


Anyway, now mmap always returns Invalid Argument when it is passed a
file descriptor produced by shm_open. I saw somewhere that OS X/darwin
doesn't support mmap with device files, does this imply no non-file
backed regions? Further, calls to close() and shm_unlink() after the
mmap error return Invalid Argument themselves, and then on the next run
(using the same name) shm_open returns File Exists. So it appears the
POSIX interface will also leave these regions floating around after the
process ends and all references are removed, although I had read
somewhere it wouldn't. (Especially annoying since I did make the calls
to close and shm_unlink)


What's going on?

Here's the code sample for the region in question:
int fd;
if(name.size()>=MAX_NAME_LEN)
cerr << "*** WARNING RCRegion named " << name << " will be clipped to
" << name.substr(0,MAX_NAME_LEN-2) << endl;
id.key[0]='/'; //one page I read said for best portability, names
should start with '/'... ?
strncpy(id.key+1,name.c_str(),MAX_NAME_LEN-2);
id.key[MAX_NAME_LEN-1]='\0';
cout << "Name is " << id.key << endl;
if(create) {
if((fd=shm_open(id.key,O_RDWR|O_CREAT|O_EXCL,0666))<0) {
perror("Getting new region (shm_open)");
exit(EXIT_FAILURE);
}
} else {
if((fd=shm_open(id.key,O_RDWR,0666))<0) {
perror("Getting existing region (shm_open)");
exit(EXIT_FAILURE);
}
}
cout << "fd is " << fd << endl;


base=static_cast<char*>(mmap(NULL,sz,PROT_READ|PROT_WRITE,MAP_SHARED, fd
,
0));
if (base == reinterpret_cast<char*>(-1)) {
perror("Attaching region (mmap)");
if(close(fd)<0)
perror("Warning: Closing temporary file descriptor from shm_open");
if(shm_unlink(id.key)<0)
perror("Warning: Shared memory unlink (shm_unlink)");
exit(EXIT_FAILURE);
}
if(close(fd)<0) {
perror("Warning: Closing temporary file descriptor from shm_open");
}


Thank you for your time!
   -ethan

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
mark.williamson@cl.c
am.ac.uk


This email sent to email@hidden


_______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
  • Follow-Ups:
    • Re: shm_open and mmap: Invalid argument?
      • From: Ethan Tira-Thompson <email@hidden>
References: 
 >Re: shm_open and mmap: Invalid argument? (From: Tim Hewett <email@hidden>)

  • Prev by Date: Re: shm_open and mmap: Invalid argument?
  • Next by Date: Reserving the Disk Space
  • Previous by thread: Re: shm_open and mmap: Invalid argument?
  • Next by thread: Re: shm_open and mmap: Invalid argument?
  • Index(es):
    • Date
    • Thread