Re: NSFileHandle readInBackground vs threading?

2011-11-13 Thread Alexander Bokovikov


On 09.11.2011, at 19:25, Scott Ribe wrote:

I'm not arguing the OP isn't seeing data lost, just that it cannot  
be happening the way he thinks it is if he's using any normal  
networking calls.


Thanks to everybody for your useful comments!
My local socket is opened in the client process just as

socket(AF_LOCAL, SOCK_STREAM, 0)

I'm getting the socket file handle, and use it for writing to the host  
process. I've tested the write process and as far as I can see, the  
data are written completely. The socket is never blocked by host  
process. So, I believe I need to dig the sending side.


Thank you.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSFileHandle readInBackground vs threading?

2011-11-09 Thread Don Quixote de la Mancha
Keep pointers to your packetBuffers in a circular buffer.  When a new
packet comes in, add it to the front of the buffer.  When you're ready
to process a packet, remove it from the end of the buffer.

Some testing should determine how big your buffer needs to be.

On anything but a real-time operating system, your entire process is
going to spend some time totally halted.  Incoming data will build up
either in the kernel's buffers on your local machine, or the sending
process will be unable to send data.  If you're using UNIX domain
sockets or TCP, the sending process will block.  If you're using UDP
or some other non-guaranteed-delivery protocol, your data will be
dropped on the floor.

If you're not familiar with circular buffers, you can keep your
packetBuffer pointers in some kind of array.  Keeping them in an
NSArray will enable them all to be released when the NSArray itself is
released.

You need two indices, called say head and tail.  head contains the
index of the next free packetBuffer.  Increment it when a packetBuffer
has been used, but when you get to the end of the array, set it to
zero.  tail will point to the last packetBuffer that contains valid
data.

Your queue is full when the head comes back around to be one element
behind the tail, so that incrementing the head will make it equal to
the tail.  At that point you really do need to block, or alternatively
keep reading packets but then dropping them on the receiving end.

A while back I wrote a very fast circular buffer for audio data that
is thread-safe.  It blocks the sending thread when it gets full, and
feeds silence to the output thread when the buffer is empty.
Alternatively simple change would enable the output thread to block
when the buffer is empty.

It doesn't *look* thread-safe but I am quite certain that it really is:

   http://www.oggfrog.com/free-music-software/source-code/

It is a C++ class called ZPCMQueue.  It depends on the ZooLib C++
cross-platform application framework, but it only really uses ZooLib's
platform-independent atomic arithmetic and thread synchronization
primitives.  It would be very easy to replace those with Cocoa's.

I'm pretty sure that part of Ogg Frog's code is published under the MIT License.
-- 
Don Quixote de la Mancha
Dulcinea Technologies Corporation
Software of Elegance and Beauty
http://www.dulcineatech.com
quix...@dulcineatech.com
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSFileHandle readInBackground vs threading?

2011-11-09 Thread Andreas Grosam

On Nov 8, 2011, at 5:54 PM, Alexander Bokovikov wrote:

 I have a need to read some data from a local socket, which serves for IPC. 
 And data may come very quickly, so (AFAIU) inner socket buffer might 
 overflow, so a portion of data might be lost.

This has been answered by previous posters already - but lets assume in your 
current approach data may possibly be lost when you are not able to consume 
them fast enough.

 I don't see a way how to define an inner system buffer size, so the only I 
 can is to do my best to read from the socket quickly enough. The problem is 
 that I need yet to process the incoming data, not only to read them. Now I'm 
 doing the next:
 
 - (void) readPacket:(NSNotification *)aNotification {
   [packetBuffer appendData:[[aNotification userInfo] 
 objectForKey:NSFileHandleNotificationDataItem]];
   [sockFileHandle readInBackgroundAndNotifyForModes:modesArray];
   [self processPacket];
 }

The problem here is, that you processes the data on the same thread where you 
consume it. This may cause the producer to block, and as a result, to discard 
new or old data eventually if some internal buffer size reach a limit.



You may try to schedule the processing of the data on a different thread. For 
instance, you can use a dispatch queue where you asynchronously schedule the 
processing of the data:

#include dispatch/dispatch.h

- (void) readPacket:(NSNotification *)aNotification {
NSData* data = [[aNotification userInfo] 
objectForKey:NSFileHandleNotificationDataItem];
...
dispatch_async(myProcessDispatchQueue, ^{
[self processData:data];
};
}

myProcessDispatchQueue (dispatch_queue_t) shall be a serial queue, e.g. in your 
init method:

myProcessDispatchQueue = dispatch_queue_create(
   com.mycompany.myapp.data_processing
   DISPATCH_QUEUE_SERIAL);


One important thing to note here:
Since the second approach uses different threads which may possibly access the 
same object concurrently, we need to consider concurrency and possibly race 
conditions. Here, the local NSData object 'data' is not subject to race 
conditions. It is further assumed that -processData: will not violate these 
rules, that is, it shall not access ivars or globals which possibly could be 
accessed in a different thread as well without synchronization.


Possible issues that may arise here:
Individual data buffers will be generated much faster than they can be 
processed. This will cause the dispatch queue to queue up a lot of data buffers 
and tie up memory. There are solutions to avoid this, but this is more 
elaborated and requires a concurrent accessible queue which can block producers 
and consumers.


 
 where packetBuffer is the storage for incoming data and processPacket is 
 where data are processed.
 
 My question is:
 
 Isn't it better to do it in this way:
 
 - (void) readPacket:(NSNotification *)aNotification {
   [packetBuffer appendData:[[aNotification userInfo] 
 objectForKey:NSFileHandleNotificationDataItem]];
   [sockFileHandle readInBackgroundAndNotifyForModes:modesArray];
   [self performSelector:@selector(processPacket) withObject:nil 
 afterDelay:0];
 }

While this might work, this is likely not very efficient. This implicitly 
assumes, that for every readPacket: invocation, a corresponding processPacket 
method will be queued in the main thread and then *be executed in strict order* 
(if not, other issues may arise). If this actually works (because enforced by 
the run loop), this would result effectively in the same as your current 
approach above.


 
 Or is the multithreaded processing the only (or at least much better) 
 solution here?
I guess yes.

 If yes, then may I be sure that NSData appendData (see above) will never 
 relocate the initial portion of the data buffer, but only will add new data 
 to the end of buffer?
In other words, you are asking if the addresses of the bytes of the internal 
data remain stable if you append data to the NSMutableData object? When imagine 
how difficult this would be -  I would assume, NO it isn't.


 My data processing routine looks like the next:



 
   len = [packetBuffer length];
   ptr = [packetBuffer bytes];
   while (len = MIN_PACKET_SZ) {
   /// doing something with data pointed by ptr-
   ptr += _some_value;
   len -= _some_value;
}
 
 
 So, I need be sure that once reading the ptr, then increasing it, step by 
 step up to the len value, I'll always have valid data despite of how many 
 times append data will be called in another thread. What about this?

You'll likely need an approach, say a method that takes an NSData object that 
contains partial input, then process it, possibly safes internal state and 
returns. And this method can be invoked continuously to consume another NSData 
object in order to process the next partial input (taking the current state 
into 

Re: NSFileHandle readInBackground vs threading?

2011-11-09 Thread Scott Ribe
On Nov 8, 2011, at 11:45 PM, Kyle Sluder wrote:

 The kernel only has a certain amount of buffer space dedicated to each
 incoming TCP port. If the port gets flooded, it drops packets.

But this is TCP:

1) Flow control should generally prevent buffers from being overrun;

2) Even if packets are dropped, they should be resent;

3) On a local connection, there's really no way for the port to get flooded.

I'm not arguing the OP isn't seeing data lost, just that it cannot be happening 
the way he thinks it is if he's using any normal networking calls.

-- 
Scott Ribe
scott_r...@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


NSFileHandle readInBackground vs threading?

2011-11-08 Thread Alexander Bokovikov

Hi, All,

I have a need to read some data from a local socket, which serves for  
IPC. And data may come very quickly, so (AFAIU) inner socket buffer  
might overflow, so a portion of data might be lost. I don't see a way  
how to define an inner system buffer size, so the only I can is to do  
my best to read from the socket quickly enough. The problem is that I  
need yet to process the incoming data, not only to read them. Now I'm  
doing the next:


- (void) readPacket:(NSNotification *)aNotification {
	[packetBuffer appendData:[[aNotification userInfo]  
objectForKey:NSFileHandleNotificationDataItem]];

[sockFileHandle readInBackgroundAndNotifyForModes:modesArray];
[self processPacket];
}

where packetBuffer is the storage for incoming data and processPacket  
is where data are processed.


My question is:

Isn't it better to do it in this way:

- (void) readPacket:(NSNotification *)aNotification {
	[packetBuffer appendData:[[aNotification userInfo]  
objectForKey:NSFileHandleNotificationDataItem]];

[sockFileHandle readInBackgroundAndNotifyForModes:modesArray];
	[self performSelector:@selector(processPacket) withObject:nil  
afterDelay:0];

}

Or is the multithreaded processing the only (or at least much better)  
solution here? If yes, then may I be sure that NSData appendData (see  
above) will never relocate the initial portion of the data buffer, but  
only will add new data to the end of buffer? My data processing  
routine looks like the next:


len = [packetBuffer length];
ptr = [packetBuffer bytes];
while (len = MIN_PACKET_SZ) {
   /// doing something with data pointed by ptr-
ptr += _some_value;
len -= _some_value;
}


So, I need be sure that once reading the ptr, then increasing it, step  
by step up to the len value, I'll always have valid data despite of  
how many times append data will be called in another thread. What  
about this?


Thanks in advance.

-Alex
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSFileHandle readInBackground vs threading?

2011-11-08 Thread Scott Ribe
On Nov 8, 2011, at 9:54 AM, Alexander Bokovikov wrote:

 I have a need to read some data from a local socket, which serves for IPC. 
 And data may come very quickly, so (AFAIU) inner socket buffer might 
 overflow, so a portion of data might be lost. 

What makes you think that? If the buffers fill up, writes will block.

-- 
Scott Ribe
scott_r...@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSFileHandle readInBackground vs threading?

2011-11-08 Thread Alexander Bokovikov


On 09.11.2011, at 0:50, Scott Ribe wrote:


On Nov 8, 2011, at 9:54 AM, Alexander Bokovikov wrote:

I have a need to read some data from a local socket, which serves  
for IPC. And data may come very quickly, so (AFAIU) inner socket  
buffer might overflow, so a portion of data might be lost.


What makes you think that? If the buffers fill up, writes will block.


OK, then the same problem will appear at the other end of the socket.  
One way or another I need to read from the socket as fast as possible.  
And I have a real problem now. Sometimes data are lost when they come  
with high speed. Though I agree, that first I need to investigate what  
end of the socket has a bottle neck.


Thank you.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSFileHandle readInBackground vs threading?

2011-11-08 Thread Scott Ribe
On Nov 8, 2011, at 10:02 PM, Alexander Bokovikov wrote:

 Sometimes data are lost when they come with high speed.

I assume by local socket you mean either a UNIX domain socket or just a 
regular TCP socket on the local machine? If so, just using regular read  write 
calls there's no way for data to be lost  not delivered just because it's 
consumed slowly. There's something else going on. Either the sending end is 
discarding data and not even writing it, or the receiving is losing it after 
reading it.

-- 
Scott Ribe
scott_r...@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSFileHandle readInBackground vs threading?

2011-11-08 Thread Kyle Sluder
On Tue, Nov 8, 2011 at 9:43 PM, Scott Ribe scott_r...@elevated-dev.com wrote:
 I assume by local socket you mean either a UNIX domain socket or just a 
 regular TCP socket on the local machine? If so, just using regular read  
 write calls there's no way for data to be lost  not delivered just because 
 it's consumed slowly. There's something else going on. Either the sending end 
 is discarding data and not even writing it, or the receiving is losing it 
 after reading it.

The kernel only has a certain amount of buffer space dedicated to each
incoming TCP port. If the port gets flooded, it drops packets.

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSFileHandle readInBackground vs threading?

2011-11-08 Thread Ken Thomases
On Nov 9, 2011, at 12:45 AM, Kyle Sluder wrote:

 On Tue, Nov 8, 2011 at 9:43 PM, Scott Ribe scott_r...@elevated-dev.com 
 wrote:
 I assume by local socket you mean either a UNIX domain socket or just a 
 regular TCP socket on the local machine? If so, just using regular read  
 write calls there's no way for data to be lost  not delivered just because 
 it's consumed slowly. There's something else going on. Either the sending 
 end is discarding data and not even writing it, or the receiving is losing 
 it after reading it.
 
 The kernel only has a certain amount of buffer space dedicated to each
 incoming TCP port. If the port gets flooded, it drops packets.

But the protocol will compensate and recover.  And for purely local TCP, the 
writer will block rather than packets being lost.  That is, there aren't any 
actual packets.

That said, it's conceivable that OP is using UDP and/or datagram Unix-domain 
sockets, where data loss would be conceivable, but that would be silly in a 
case where you weren't actually hoping to take advantage of the potential data 
loss (throw away old data in preference to new data, for example).

Regards,
Ken

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com