Subject: | Issue using IPC::ShareLite (using segment size of 0 to open existing shared memory segment) |
Date: | Wed, 5 Sep 2012 15:06:50 +0000 |
To: | "bug-IPC-ShareLite [...] rt.cpan.org" <bug-IPC-ShareLite [...] rt.cpan.org> |
From: | "Macke, Edward" <Edward.Macke [...] savvis.com> |
Distribution: IPC-ShareLite-0.17
Perl Version: perl 5, version 12, subversion 4 (v5.12.4) built for x86_64-linux-thread-multi
O/S: Linux dc2repappdv01.it.savvis.net 2.6.18-194.17.1.el5 #1 SMP Mon Sep 20 07:12:06 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
Description of issue:
The SysV shmget() C function allows one to retrieve the id of an existing shared memory segment for which the key is known but the size is not; ie:
shmid = shmget(key, 0, SHM_R);
is acceptable, provided the segment with this key already exists. However, one cannot use this paradigm with IPC::ShareLite:
use Test::More;
use IPC::SysV qw/SHM_RDONLY/;
use IPC::ShareLite;
my $ipc_key = 58972;
my $size = 80;
my $shmem;
eval {
$shmem = IPC::ShareLite->new(-key => $ipc_key,
-create => 'yes',
-destroy => 'no',
-exclusive => 'no',
-mode => 0700,
-size => $size);
};
isa_ok($shmem, "IPC::ShareLite", "IPC::ShareLite new create");
undef $shmem;
eval {
$shmem = IPC::ShareLite->new(-key => $ipc_key,
-create => 'no',
-destroy => 'no',
-exclusive => 'no',
-mode => SHM_RDONLY,
-size => 0,
);
};
isa_ok($shmem, "IPC::ShareLite", "IPC::ShareLite new reopen");
done_testing();
The first call to new() works, but the second call fails:
ok 1 - IPC::ShareLite new create isa IPC::ShareLite
not ok 2 - IPC::ShareLite new reopen isa IPC::ShareLite
# Failed test 'IPC::ShareLite new reopen isa IPC::ShareLite'
# at <test_code> line 28.
# IPC::ShareLite new reopen isn't defined
1..2
# Looks like you failed 1 test of 2.
Patch to fix the bug:
The following code (with fix shown) in sharestuff.c is the cause of the issue, as it changes a segmen_size value of 0 to SHM_SEGMENT_SIZE:
--- sharestuff.c.orig 2012-09-05 13:55:12.000000000 +0000
+++ sharestuff.c 2012-09-05 13:57:13.000000000 +0000
@@ -513,15 +513,10 @@
}
LOG1( "GET_EX_LOCK failed (%d)", errno );
return NULL;
}
- /* XXX IS THIS THE RIGHT THING TO DO? */
- if ( segment_size <= sizeof( Header ) ) {
- segment_size = SHM_SEGMENT_SIZE;
- }
-
Newxz( node, 1, Node );
if ( ( node->shmid = shmget( key, segment_size, flags ) ) < 0 ) {
LOG1( "shmget failed (%d)", errno );
return NULL;
I don't think there is a need to prevent small segment_size values; if they are invalid, the shmget() call should fail.
At the very least, a segment_size of 0 should be allowed, so that shared memory segments for which the key is known (but the size is not) may be used by IPC::ShareLite.
With this patch in place, the above code succeeds:
ok 1 - IPC::ShareLite new create isa IPC::ShareLite
ok 2 - IPC::ShareLite new reopen isa IPC::ShareLite
1..2
Let me know if you need additional information regarding the issue.
Thanks,
Ed Macke | Senior Software Development Engineer
Savvis, A CenturyLink Company
575 Maryville Centre Drive, Suite 400, Saint Louis, MO 63141
Office: 314.579.8622 | Mobile: 314.330.7656 | Fax: 314.579.8706
Email: edward.macke@savvis.com
www.savvis.com
This message contains information which may be confidential and/or privileged. Unless you are the intended recipient (or authorized to receive for the intended recipient), you may not read, use, copy or disclose to anyone the message or any information contained in the message. If you have received the message in error, please advise the sender by reply e-mail and delete the message and any attachment(s) thereto without retaining any copies.