[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gnustep-cvs] r26747 - in /libs/base/trunk: ChangeLog Source/Additio
From: |
Richard Frith-Macdonald |
Subject: |
Re: [Gnustep-cvs] r26747 - in /libs/base/trunk: ChangeLog Source/Additions/GSCompatibility.m Source/NSArray.m Source/NSDictionary.m Source/NSRunLoop.m Source/NSSerializer.m Source/NSSet.m Source/NSSortDescriptor.m |
Date: |
Sun, 6 Jul 2008 13:00:34 +0100 |
On 6 Jul 2008, at 12:37, Fred Kiefer wrote:
Hi Richard,
could you please explain this changes? As far as I can see you
replaces calls to getObjects: with a loop to get the elements of the
array individually. Does DO over ffi have problem with arrays? If so
is there anything we could do about it?
OK. Yes, you understand the change correctly, but it's nothing to do
with ffi, it applies to all use of distributed objects (and always has/
will).
This it to do with the way DO handles pointers.
When a Class or SEL is encoded, the name is what actually gets
encoded, and at the remote end a lookup converts the name into a
pointer to the Class/SEL.
When an object is encoded, the normal case is that a proxy reference
is encoded and a proxy is created at the remote end.
When a char* is encoded, the string (up to the nul terminator) is
encoded and sent to the remote side.
but ...
For all other pointers, the system encodes a single item of whatever
type is being pointed to, and copies that to the remote end, where
enough memory to decode that one item is allocated, the item is
decoded into it, and the pointer to that newly allocated memory is used.
It's done this way because the system cannot know whether a pointer is
the address of a single item or the address of a buffer containing
multiple items, so it always assumes that it's a single item (except
for the special case of char* which is assumed to be a nul terminated
string).
Now, a few methods in the API pass around pointers to buffers ... if
you send such a message to a proxy to an object on the other end of a
DO connection, it will only work correctly if your buffer is being
used for a single item.
If you are trying to pass multiple items to the remote end, only one
will actually be encoded, and when the code at the other end of the
connection attempts to access the second item in the buffer it will
actually be overrunning its local buffer.
Similarly, if the other end is supposed to be transferring multiple
items back in the buffer (and assuming that buffer overrun doesn't
crash it), you will actually only get one back, and the remainder of
your local buffer will contain uninitialised memory.
So ... when there is a possibility that an object is a proxy, it's
important to avoid using such methods and to take alternative
approaches.
Where you are designing an API for use over DO, you can make use of
the byref and bycopy keywords to control how objects are passed, and
when you are writing coders/decoders for your classes you can encode
the values in ivars explicitly with counts, so really the problem is
only with a few methods which pass pointers to buffers around, and
it's quite rare to encounter problems.
However, in the case of core libraries, I think we need to be
specially careful ... Riccardo's FTP application was designed to
operate without DO, but when he changed it to use DO for inter-thread
communications it ran into this issue, so I think we do need to guard
against it, even at the cost of a little performance.