Re: NSFileHandle readInBackground vs threading?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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