comp.lang.ada
 help / color / mirror / Atom feed
* POSIX_Generic_Shared_Memory
@ 2004-09-20 17:23 Mattias Lindblad
  2004-09-22 14:52 ` POSIX_Generic_Shared_Memory Paul Colin Gloster
  2004-09-27 20:46 ` POSIX_Generic_Shared_Memory Mark Lorenzen
  0 siblings, 2 replies; 6+ messages in thread
From: Mattias Lindblad @ 2004-09-20 17:23 UTC (permalink / raw)


Hi,

I have found some problems when experimenting with the
POSIX_Generic_Shared_Memory package. Let's start with a code example to
illustrate my point:

---[shmserv.adb]---
with POSIX_Generic_Shared_Memory, POSIX_IO, POSIX_Memory_Mapping,
POSIX.Permissions;
with Ada.Text_IO;

procedure Shmserv is
type Data is record
I : Integer;
J : Integer;
end record;
package GSM is new Posix_Generic_Shared_Memory(Data);

Descriptor  : POSIX_IO.File_Descriptor;
Data_Access : GSM.Shared_Access;
begin
Descriptor := GSM.Open_Or_Create_And_Map_Shared_Memory
("/foo", POSIX_Memory_Mapping.Allow_Write,
POSIX.Permissions.Access_Permission_Set);
Data_Access := GSM.Access_Shared_Memory(Descriptor);
Data_Access.I := 1;
loop
Ada.Text_IO.Put_Line(Integer'Image(Data_Access.I));
delay(0.5);
end loop;
end Shmserv;
---[end shmserv.adb]---

---[shmcli.adb]---
with POSIX_Generic_Shared_Memory, POSIX_IO, POSIX_Memory_Mapping;

procedure Shmcli is
type Data is record
I : Integer;
J : Integer;
end record;
package GSM is new Posix_Generic_Shared_Memory(Data);

Descriptor  : POSIX_IO.File_Descriptor;
Data_Access : GSM.Shared_Access;
begin
Descriptor := GSM.Open_And_Map_Shared_Memory
("/foo", POSIX_Memory_Mapping.Allow_Write);
Data_Access := GSM.Access_Shared_Memory(Descriptor);
loop
Data_Access.I := Data_Access.I + 1;
delay(1.0);
end loop;
end Shmcli;
---[end shmcli.adb]---

The purpose of this example code is to let one process change data in a
shared memory area, while the other process monitors the shared data.
It accomplishes this by using the convenient
Open_(Or_Create_)And_Map_Shared_Memory functions.

However, the client raises a Storage_Error when trying to access the
shared data. I have found that this is because the Protection_Options
are passed straight through to Map_Memory, and in my case this leads to
a memory region that is write-only.

The obvious solution would of course be to set Protection_Options to
(Allow_Write + Allow_Read). Unfortunately, by doing this the
Open_Shared_Memory will be called with a mode of Read_Only. This feels
a bit weird, but follows the POSIX 1003.5b standard, 12.5.1.2(1): "If
the value of Protection is set to Allow_Write, Mode is Read_Write;
otherwise Mode is Read_Only." (From the 1996 version, I'm afraid I
haven't access to an updated version).

Is this really how it is supposed to work? In my opinion the standard
text should read "If the value of Protection *includes* Allow_Write
[...]".

I have only tried this with GNAT 3.15p and Florist. So I don't know if
this might be specific to this system or if it is more general.

Any ideas about this? Is it a bug in GNAT, the standard, both of them
or none of them (i.e. I'm not doing things the way I'm supposed to)?
Thanks,
Mattias




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: POSIX_Generic_Shared_Memory
  2004-09-20 17:23 POSIX_Generic_Shared_Memory Mattias Lindblad
@ 2004-09-22 14:52 ` Paul Colin Gloster
  2004-09-22 16:18   ` POSIX_Generic_Shared_Memory Mattias Lindblad
  2004-09-27 20:46 ` POSIX_Generic_Shared_Memory Mark Lorenzen
  1 sibling, 1 reply; 6+ messages in thread
From: Paul Colin Gloster @ 2004-09-22 14:52 UTC (permalink / raw)


Have you thought about not using POSIX at all, and simply using an Ada 
protected object procedure to write and a protected object function to 
read?



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: POSIX_Generic_Shared_Memory
  2004-09-22 14:52 ` POSIX_Generic_Shared_Memory Paul Colin Gloster
@ 2004-09-22 16:18   ` Mattias Lindblad
  0 siblings, 0 replies; 6+ messages in thread
From: Mattias Lindblad @ 2004-09-22 16:18 UTC (permalink / raw)


I'm afraid that protected objects are not a possible solution in the
situation at hand. However, I have two different workarounds for the
issue. One is a simple patch to the Florist lib (which of course would
not be very portable given that Florist follows the standard), the
other is to ignore the functions in POSIX_Generic_Shared_Memory and do
the relevant function calls manually.

A third solution would of course be to create wrappers for the
corresponding C functions, but I'm trying to avoid such things.

But while I can solve the problem, I'm still interested in hearing if I
should blame the standards committee, the Florist programmers or myself
:)




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: POSIX_Generic_Shared_Memory
  2004-09-20 17:23 POSIX_Generic_Shared_Memory Mattias Lindblad
  2004-09-22 14:52 ` POSIX_Generic_Shared_Memory Paul Colin Gloster
@ 2004-09-27 20:46 ` Mark Lorenzen
  2004-09-27 21:51   ` POSIX_Generic_Shared_Memory Ludovic Brenta
  2004-09-29 12:09   ` POSIX_Generic_Shared_Memory Mattias  Lindblad
  1 sibling, 2 replies; 6+ messages in thread
From: Mark Lorenzen @ 2004-09-27 20:46 UTC (permalink / raw)


"Mattias Lindblad" <ml_news@matli.net> writes:

> Hi,
> 
> I have found some problems when experimenting with the
> POSIX_Generic_Shared_Memory package. Let's start with a code example to
> illustrate my point:
> 

[example and decription removed]

> However, the client raises a Storage_Error when trying to access the
> shared data. I have found that this is because the Protection_Options
> are passed straight through to Map_Memory, and in my case this leads to
> a memory region that is write-only.
> 
> The obvious solution would of course be to set Protection_Options to
> (Allow_Write + Allow_Read). Unfortunately, by doing this the
> Open_Shared_Memory will be called with a mode of Read_Only. This feels
> a bit weird, but follows the POSIX 1003.5b standard, 12.5.1.2(1): "If
> the value of Protection is set to Allow_Write, Mode is Read_Write;
> otherwise Mode is Read_Only." (From the 1996 version, I'm afraid I
> haven't access to an updated version).
> 
> Is this really how it is supposed to work? In my opinion the standard
> text should read "If the value of Protection *includes* Allow_Write
> [...]".

The ISO/IEC 14519 standard says:

    [Open_And_Map_Shared_Memory] If the value of Protection is set to
    Allow_Write, Mode is Read_Write; otherwise Mode is Read_Only.

    [Open_Or_Create_And_Map_Shared_Memory] If the value of Protection
    is set to Allow_Write, Mode is Read_Write; otherwise Mode is
    Read_Only.

> 
> I have only tried this with GNAT 3.15p and Florist. So I don't know if
> this might be specific to this system or if it is more general.
> 
> Any ideas about this? Is it a bug in GNAT, the standard, both of them
> or none of them (i.e. I'm not doing things the way I'm supposed to)?

Looking at the source code for florist 3.5.0_20040403, it seems that
it is NOT florist, that is to blame. What version of florist do you use?

Try to look in the file posix-generic_shared_memory.adb for the two
functions you use and inspect that they contain the following statement:

      if Protection = POSIX.Memory_Mapping.Allow_Write then
         Mode := POSIX.IO.Read_Write;
      else Mode := POSIX.IO.Read_Only;
      end if;

> Thanks,
> Mattias

Regards,
- Mark Lorenzen



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: POSIX_Generic_Shared_Memory
  2004-09-27 20:46 ` POSIX_Generic_Shared_Memory Mark Lorenzen
@ 2004-09-27 21:51   ` Ludovic Brenta
  2004-09-29 12:09   ` POSIX_Generic_Shared_Memory Mattias  Lindblad
  1 sibling, 0 replies; 6+ messages in thread
From: Ludovic Brenta @ 2004-09-27 21:51 UTC (permalink / raw)


Mark Lorenzen writes:
> Looking at the source code for florist 3.5.0_20040403, it seems that
> it is NOT florist, that is to blame. What version of florist do you use?
>
> Try to look in the file posix-generic_shared_memory.adb for the two
> functions you use and inspect that they contain the following statement:
>
>       if Protection = POSIX.Memory_Mapping.Allow_Write then
>          Mode := POSIX.IO.Read_Write;
>       else Mode := POSIX.IO.Read_Only;
>       end if;

Florist 3.15p does contain these statements.  In case you ask: the
Debian package for Florist does not have any patches.

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: POSIX_Generic_Shared_Memory
  2004-09-27 20:46 ` POSIX_Generic_Shared_Memory Mark Lorenzen
  2004-09-27 21:51   ` POSIX_Generic_Shared_Memory Ludovic Brenta
@ 2004-09-29 12:09   ` Mattias  Lindblad
  1 sibling, 0 replies; 6+ messages in thread
From: Mattias  Lindblad @ 2004-09-29 12:09 UTC (permalink / raw)


> Try to look in the file posix-generic_shared_memory.adb for the two
> functions you use and inspect that they contain the following
statement:
>
>   if Protection = POSIX.Memory_Mapping.Allow_Write then
>       Mode := POSIX.IO.Read_Write;
>   else Mode := POSIX.IO.Read_Only;
>   end if;

Yes, this is what my versions look like. And yes, I agree that we
shouldn't really blame Florist for this. I would probably interpret the
standard in the same way.

Unfortunately, this leaves these functions practically unusable in my
opinion. However, I think it would be possible to change the
implementation to a usable version and still be compliant with the
standard. The standard does not mention anything about the protection
parameter that is sent to the intrinsic calls to Map_Memory. This means
that an implementation could set the protection options in the
Map_Memory call to (Allow_Read + Allow_Write) in the case where the
received protection parameter is Allow_Write. The only downside I can
think of is that you wouldn't be able to create a write-only shared
memory partition. In my opinion, this is definitely less of a problem
than the current situation where you cannot create a read-write
partition.

But ultimately, a better solution would be to change the text in the
standard to read something like "If Allow_Write is a subset of
Protection, Mode is Read_Write; otherwise Mode is Read_Only." This
would solve the problem in a better way. The protection options could
then be passed straight through to Map_Memory, which I think is the
most logical way. And I don't think a change of implementations to
support this would break any existing code. 

//Mattias




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-09-29 12:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-09-20 17:23 POSIX_Generic_Shared_Memory Mattias Lindblad
2004-09-22 14:52 ` POSIX_Generic_Shared_Memory Paul Colin Gloster
2004-09-22 16:18   ` POSIX_Generic_Shared_Memory Mattias Lindblad
2004-09-27 20:46 ` POSIX_Generic_Shared_Memory Mark Lorenzen
2004-09-27 21:51   ` POSIX_Generic_Shared_Memory Ludovic Brenta
2004-09-29 12:09   ` POSIX_Generic_Shared_Memory Mattias  Lindblad

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox