gnustep-dev
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]