|
From: Stephen S. <rad...@gm...> - 2017-04-25 21:05:49
|
On Wed, Apr 19, 2017 at 5:52 AM, Erik Ronström <er...@om...> wrote:
> Hi all,
>
> I have an OSC server, which ”answers” to incoming osc messages using lo_send_from. But I also need to send notifications to the client about things that don’t originate in incoming osc messages: hardware setup changes etc. So these messages are not sent from the liblo server thread. So far, I have been using a mutex to prevent threading issues, but my questions is if this is really needed, or if there is any way to avoid this setup!
>
> And another question: in the message handlers, I use the following pattern:
>
> int some_handler(const char *path, const char *types, lo_arg ** argv, int argc, lo_message message, void *user_data)
> {
> lo_send_from(lo_message_get_source(message), (lo_server)user_data, LO_TT_IMMEDIATE, …)
> }
>
> That is, I get the client address from the incoming message using lo_message_get_source. But when sending ”asynchronous” osc messages (i.e. not from a message handler), that is obviously not possible, and so far I have solved this by caching the address in one of the message handlers. That is hardly an optimal solution (for one thing, simply because I can’t send any such messages until that message handler has been called the first time). Is there a better way?
>
Hi, sorry for the delay. Using a mutex is fine. You can also avoid
threading issues by not using them at all. If you use the lo_server
interface instead of lo_server_thread, no threads will be created, and
you can check for new messages using lo_server_recv() or
lo_server_recv_noblock(). Any incoming messages will be dispatched
(i.e. the message handlers will be called) before these functions
return, on the same thread.
There is no way to get the message source without receiving a message,
so if you have no alternative way to get the destination where you'd
like to send a message, then storing the result of
lo_message_get_source(message) is indeed correct, except that the data
it points to may be temporary in the handler, so you should make a
copy using
char *url = lo_address_get_url(source);
lo_address stored_address = lo_address_new_from_url(url);
free(url);
How you store and organize these addresses (only one, or a queue, or a
limited array, or an expandable std::vector, etc) is up to you, and
depends on the use case.
Steve
|