Memory allocation for udp_recv_start callbacks

47 views
Skip to first unread message

David Landon

unread,
Aug 17, 2020, 10:01:19 PM8/17/20
to libuv
Hi all,

I've begun working on my first project using Libuv and I've reached the first hangup I couldn't resolve by either trying a million things or digging into the source code. 

MY GOAL:
My project runs in the Max/MSP coding environment (https://cycling74.com/). Their SDK API documentation can be found here.  Basically, I'm copying the audio signal (chunked into signal vectors by Max) from a callback that the audio card uses into a uv_buf_t and then using uv_udp_send to send that to a receiving program that copies the buffer in reverse to be used as playback on their separate machine/soundcard . So I'm trying to send audio from one user running Max/MSP to another, also running Max/MSP over the internet. 

MY QUESTION:
I've been successful sending small, single, test messages between the programs, and also successful copying the audio signal, which is an array of doubles representing the sample data, and using that for playback on the individual programs. But when I try to send the copied sample data via udp_send from one to the other, the programs crash. If I run _just_ the sending program, it is fine and reports no errors. When I instantiate the receiving program by itself, it also seems fine. What this tells me is that it has to do with memory allocation in either the on_alloc or on_recv callbacks that udp_recv_start uses. I've allocated memory for the size of  the signal vector in on_alloc (sys_getblksize() being part of the Max API which reports the signal vector size:

    buf->base = (char*)malloc(sizeof(double) * sys_getblksize());
    buf->len = sys_getblksize() * sizeof(double);

and free the buffer's base : free(buf->base); in the on_recv callback as per the documentation, but something about that doesn't seem right to me. How is the buffer getting passed between the two and does the freeing of memory in the recv_cb free the memory in the alloc_cb, or am I just VERY rapidly allocating memory without freeing it? 

I've got all of the code on GitHub here, for anyone that wants to take a look: https://github.com/dlandon86?tab=repositories. The send side of things is dl.netsend~ and receive dl.netreceive~. Its my first coding project... ever, so feel free to pick it apart! And I'm happy to give more info if it's required. I just don't want to make this post any longer than it needs to be. 

Thank you for your help!

Best,
David 

Ben Noordhuis

unread,
Aug 18, 2020, 4:47:16 AM8/18/20
to li...@googlegroups.com
I only had a quick look but it seems like you're using the same event
loop on multiple threads. Libuv functions in general are not
thread-safe, unless explicitly marked otherwise in the documentation.

David Landon

unread,
Aug 18, 2020, 12:51:48 PM8/18/20
to li...@googlegroups.com
Hi Ben,

Thanks a million(!) for taking a look. On the Max side of things, I'm attaching a toggle that outputs a 1 when turned on and a 0 when turned off. I then send each one a 1, starting with receive and then send, sending them both down the sock_connect function only once. On the send side of things, the loop closes out immediately after running through the sock_connect and subsequent thread_main functions. In fact, I'm not convinced this program even needs the loop to send via udp (is that possible?). 

On the receive side, I send the program a 1 and it connects and the loop stays running. I can keep sending "PING" messages to it and it receives them. If I then pass a zero to the program, it closes the loop the next time it receives a message (without actually pulling the message through).

In my limited understanding of how pthread_create works, I thought that I just had the loop running on a single, separate thread once I ran sock_connect and then the thread would close after I sent a 0 to the program and it received another message, thus closing the loop and returning from thread_main. Again, thus only 1 thread at a time. Is this not how it works? 

Thanks again for taking the time to look into this, I REALLY appreciate it. 

Best,
David 

--
You received this message because you are subscribed to the Google Groups "libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libuv+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/libuv/CAHQurc-ECQo7pBu7tfdA-H_YktjmwBHcB-DnVjY7hpPjFFYyeg%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages