Is It safe to issue multiple async_send_to to in one udp socket? - boost-asio

I am writing an udp broadcast server with boost::asio. Udp packets will be received from one source side and broadcasted to multiple destinations. Is it safe to do something like this in a single thread?
boost::asio::ip::udp::socket s;
MyHandler handler; // do nothing handler
MyBuffer buffer; // buffer is allocated on heap and managed by smart ptr
...
s.async_send_to(buffer, destination1, handler);
s.async_send_to(buffer, destination2, handler);
s.async_send_to(buffer, destination3, handler);
Or should I use blocking send_to instead? Or should I chain them, i.e, calling the second async_send_to in the completion handler of the first async_send_to?

The documentation says :
Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.
If the buffer is allocated on the stack (i.e., it is defined in the same block where the async_send is called) this is most likely broken. Because the call so async_send won't block and as soon as you return from this code snippet, the memory will be deallocated. You can make 'buffer' a class property to make sure that it remains valid for as long as you need it. But if the buffer is on the heap then you're fine, and the code will work as it is.

Related

What does the hasSpaceAvailable property on NSOutputStream mean?

I'm trying to wrap my head around the logic behind hasSpaceAvailable on NSOutputStream.
In my app, I'm sending large amounts of data (100MB) broken up into 4080byte chunks (hard limit) over a CFSocket managed by NSInput/output streams.
When I start writing the data, about a quarter way through hasSpaceAvailable suddenly becomes NO, and so I add the data to a queue. However, if I ignore that and try to write the data anyways, the write seems to work as the return value of write:maxLength: matches the maxLength parameter (4080).
What does the output stream have space for? As far as I can tell, when using UNIX/Berkley sockets there is no logic available to determine if the socket can be written to, you just write and determine if all of the data was written.
The documentation for the property states:
A boolean value that indicates whether the receiver can be written to. (read-only)
YES if the receiver can be written to or if a write must be attempted in order to determine if space is available, NO otherwise.
In my example where I'm seeing a NO, what factor is causing this result when I can still write to that socket.
I think the hasSpaceAvailable property just returns YES if the stream has sent a "space available" stream event since the last time you called the write method. You shouldn't poll that property, and it arguably shouldn't even exist. Instead, you should wait for a stream event on the output stream that says that there's space available for writing instead.
When that stream event occurs, it means that the outgoing packet queue has at least one byte fewer than the maximum number of bytes that the socket is configured to allow you to queue up. In other words, a send() or write() system call on the socket is guaranteed to write at least one byte without blocking, and the socket is guaranteed to be in a nonblocking mode.
Note that after you write data, the stream will send another space available event immediately if the stream's buffer can take more data (or after it has sent some data if the buffer is full).

asio - the design reason of async_write_some may not transmit all of the data

From user view, the property of "may not transmit all of the data" is a trouble thing. That will cause handler calls more than one time(may be).
The free function async_write ensure handler call only once, but it requires caller must call it in sequence or the data written will be interleaving. For network application usage, this is more bad than handler be called more than once.
If user want to handler called only once and data written is correct, user need to to do something.
I want to ask is: why asio not just make socket::async_write_some transmit all data?
I want to ask is: why asio not just make socket::async_write_some
transmit all data?
Opposed to async_write, socket::async_write_some is lower-level method.
The OS network stack is designed with send buffers and receive buffers. This buffers are required to be limited with some amount of memory. When you send many data over socket, receiving side can be more slow than sending and/or there can be network speed issues.
This is the reason why socket send buffers are limited and as a result system's syscalls like write or writev should be able to notify user program that system cannot accept chunk of data right now. With socket in async mode its even more critical. So, socket syscalls cannot work in async manner without signaling program to hold on.
So, the async_write_some as a mid-level wrapper to writev is required to support partial writes. In other hand async_write is composed operation and can call async_write_some many times in order to send buffers until operation is complete or possibly failed. It calls completion handler only once, not for each chunk of data passed to network stack.
If user want to handler called only once and data written is correct,
user need to to do something.
Nothing special, just to use async_write, not socket::async_write_some.

How to handle asynchronous errors in Go?

I am working on my first real Go project, a messaging API. I use channels to pass messages and other data between user goroutines and library goroutines that use a thread-unsafe, event-based C protocol library. For details https://github.com/apache/qpid-proton/blob/master/proton-c/bindings/go/README.md
My question is in 2 related parts:
1. What are common idioms for handling errors across channels?
The goroutine at one end blows up, how do I ensure the other end unblocks, gets an error value and doesn't get blocked again later?
For readers:
I can close the channel, but no error info.
I could pass a struct { data, error }
or use a second channel.
Pros & cons? Other ideas?
For writers: I can't close without a panic so I guess I need a second channel. Is this idiomatic?
select {
case sendChan <- data: sentOk()
case err := <- errChan: oops(err)
}
I also can't write after close so I need to store the error somewhere and check before trying to write. Any other approaches?
2. Exposing channels in APIs.
I need channels to pass error info: should I make those channels public fields or hide them in methods?
There is a tradeoff, and I don't have the experience to evaluate it:
Exposing channels lets users select directly, but it requires them to correctly impement the error handling patterns (check for errors before write, select for error as well as write). This seems complex and error-prone but maybe that because I'm not seasoned in go.
Hiding channels in a method simplifies and enforces correct use of the library. But now an async user must create their own goroutine and channel(s). They may just duplicate what the library does already, which is silly. Also there is an extra goroutine and channel on the path. Maybe that's not a big deal, but the data channel is the critical path for my library and I think it has to be hidden along with the error channel.
I could do both: expose the channels for power users and provide a simple method wrapper for people with simple needs. That's more to support but worth it if neither alone can fit all cases.
The standard net.Conn uses blocking methods, not channels, and I wrote goroutines to pump data to my C event-loop channel so I know it can be done, but I did not find it trivial. net.Conn is wrapping sytem calls not channels underneath so "exposing the channels" is not an option. Do any of the standard libraries export channels with error handling? (time.After doesn't count, there are no errors)
Thanks a lot!
Alan
Your question is a bit on the broad side but I'll try to give some guidance based on my experience writing highly concurrent code...
Personally I think making the channel a property of the object that gets initialized in a nice helpful NewMyObject() *MyObject method is good design pattern. It makes it so code using the object doesn't have to do boiler plate set up every time it wants to call some asynchronous method the type offers.
For readers: I can close the channel, but no error info. I could pass a struct { data, error } or use a second channel. Pros & cons? Other ideas?
Let the reader signal to return by closing the abort channel. The reader should simply use the temp, err := <-FromChannel paradigm and move on with execution if the data or error channel has closed. This should prevent the 'send on closed channel' panics error from the workers since they will close their channel and return. When err != nil the reader will know to move on.
For writers: I can't close without a panic so I guess I need a second channel. Is this idiomatic?
Yes. Sadly I was quite pissed of with the uni-directional behavior of channels and though it should be abstracted. Regardless, it's not. In my code I would not define this on the object that does work asynchronously. The paradigm I prefer is to use the closing signal (since sending a on a channel is not one-to-many, only one goroutine will read that). Instead, I allocate the abort channel in the calling code and if things need to shut down you close the abort channel and all the goroutines doing asynchronous work who are listening on that channel do their clean up and return. You should also use a WaitGroup so you can wait for the goroutines to return before moving on.
So my basic summary;
1) let the caller of asynchronous methods signal it's time to stop, not the other way around. A waitgroup is better used to coordinate their returns
2) use a sync.WaitGroup in the calling code to know when your goroutines are finished so you can move on
3) allocate your error channel in the calling code and take advantage of the one-to-many signal produced by closing the channel; if you send on a channel you allocate in the caller, only a single instance will read from it. If you put one on each instance you have to iterate a collection of instances to send the on each.
4) if you have a type that provide async methods that do work in the background, set up the channels to read off of in it's initializer, document the async methods saying where to listen for data, provide an example of a non-blocking select that passes an abort channel into the async method and listens on the methods data and error channels. If you need to kill a single routine you could accomplish this by closing one of the channels it owns rather than killing them all by closing the callers abort channel.
Hopefully that all makes sense.

UDP empty buffer ReceiveAsync

I used SocketClient.cs from this thread and very similar from msdn.
Can somebody tell me why buffer is empty after packets are received?
I have host aplication on windows 8, and then i send from Phone packet with some kind of information. Then host reply to me with new packet. Method 'Receive' receives empty information. Buffer is empty. How to fix that?
If you are not reacting to the Completed event of the SAEA object, no data has been received. If you are, then you received an empty message or your buffersize was 0. This is what the docs are telling you.
I had a look at the code in your link and found that it is using a ManualResetEvent with the SendToAsync method. I don't know why it is doing this but it may be one cause, depending on the timeout specified.
I guess not everyone is reading through the docs for the SAEA object, but you have to think about it as a thread synchronization object. It is sent to a thread, does its work there and signals finish, that just it. Maybe this is the issue with the code in your linked post, the thread that should receive the signal from the SAEA object is busy till the Reset method is called. If so, no event from the SAEA object that is working in another thread is getting through.
Also note that SendToAsync may return immediately with false if the result is available at the time of the call. You can examine the result right away. So you would safely call it like
if (!_socket.SendToAsync(myEventArgs))
ProcessResult(myEventArgs);
So the basic idea is: If you use the SocketAsyncEventArgs, don't use threading. The Async socket methods try to make the threading transparent to the user, and you would just add a threading layer on top of this. This is likely to get you in trouble.

Alternatives to dispatch_get_current_queue() for completion blocks in iOS 6?

I have a method that accepts a block and a completion block. The first block should run in the background, while the completion block should run in whatever queue the method was called.
For the latter I always used dispatch_get_current_queue(), but it seems like it's deprecated in iOS 6 or higher. What should I use instead?
The pattern of "run on whatever queue the caller was on" is appealing, but ultimately not a great idea. That queue could be a low priority queue, the main queue, or some other queue with odd properties.
My favorite approach to this is to say "the completion block runs on an implementation defined queue with these properties: x, y, z", and let the block dispatch to a particular queue if the caller wants more control than that. A typical set of properties to specify would be something like "serial, non-reentrant, and async with respect to any other application-visible queue".
** EDIT **
Catfish_Man put an example in the comments below, I'm just adding it to his answer.
- (void) aMethodWithCompletionBlock:(dispatch_block_t)completionHandler
{
dispatch_async(self.workQueue, ^{
[self doSomeWork];
dispatch_async(self.callbackQueue, completionHandler);
}
}
This is fundamentally the wrong approach for the API you are describing to take. If an API accepts a block and a completion block to run, the following facts need to be true:
The "block to run" should be run on an internal queue, e.g. a queue which is private to the API and hence entirely under that API's control. The only exception to this is if the API specifically declares that the block will be run on the main queue or one of the global concurrent queues.
The completion block should always be expressed as a tuple (queue, block) unless the same assumptions as for #1 hold true, e.g. the completion block will be run on a known global queue. The completion block should furthermore be dispatched async on the passed-in queue.
These are not just stylistic points, they're entirely necessary if your API is to be safe from deadlocks or other edge-case behavior that WILL otherwise hang you from the nearest tree someday. :-)
The other answers are great, but for the me the answer is structural. I have a method like this that's on a Singleton:
- (void) dispatchOnHighPriorityNonMainQueue:(simplest_block)block forceAsync:(BOOL)forceAsync {
if (forceAsync || [NSThread isMainThread])
dispatch_async_on_high_priority_queue(block);
else
block();
}
which has two dependencies, which are:
static void dispatch_async_on_high_priority_queue(dispatch_block_t block) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), block);
}
and
typedef void (^simplest_block)(void); // also could use dispatch_block_t
That way I centralize my calls to dispatch on the other thread.
You should be careful about your use of dispatch_get_current_queue in the first place. From the header file:
Recommended for debugging and logging purposes only:
The code
must not make any assumptions about the queue returned, unless it
is one of the global queues or a queue the code has itself created.
The code must not assume that synchronous execution onto a queue is
safe from deadlock if that queue is not the one returned by
dispatch_get_current_queue().
You could do either one of two things:
Keep a reference to the queue you originally posted on (if you created it via dispatch_queue_create), and use that from then on.
Use system defined queues via dispatch_get_global_queue, and keep a track of which one you're using.
Effectively whilst previously relying on the system to keep track of the queue you are on, you are going to have to do it yourself.
Apple had deprecated dispatch_get_current_queue(), but left a hole in another place, so we still able to get current dispatch queue:
if let currentDispatch = OperationQueue.current?.underlyingQueue {
print(currentDispatch)
// Do stuff
}
This works for main queue at least.
Note, that underlyingQueue property is available since iOS 8.
If you need to perform the completion block in the original queue, you also may use OperationQueue directly, I mean without GCD.
For those who still need in queue comparing, you could compare queues by their label or specifies.
Check this https://stackoverflow.com/a/23220741/1531141
This is a me too answer. So I will talk about our use case.
We have a services layer and the UI layer (among other layers). The services layer runs tasks in the background. (Data manipulation tasks, CoreData tasks, Network calls etc). The service layer has a couple operation queues to satisfy the needs of the UI layer.
The UI layer relies on the services layer to do its work and then run a success completion block. This block can have UIKit code in it. A simple use case is to get all messages from the server and reload the collection view.
Here we guarantee that the blocks that are passed into the services layer are dispatched on the queue on which the service was invoked on. Since dispatch_get_current_queue is a deprecated method, we use the NSOperationQueue.currentQueue to get the caller's current queue. Important note on this property.
Calling this method from outside the context of a running operation
typically results in nil being returned.
Since we always invoke our services on a known queue (Our custom queues and Main queue) this works well for us. We do have cases where serviceA can call serviceB which can call serviceC. Since we control where the first service call is being made from, we know the rest of the services will follow the same rules.
So NSOperationQueue.currentQueue will always return one of our Queues or the MainQueue.