Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

dgram.send() callback can be executed either sync or async #1456

Closed
joeshaw opened this issue Aug 4, 2011 · 7 comments
Closed

dgram.send() callback can be executed either sync or async #1456

joeshaw opened this issue Aug 4, 2011 · 7 comments
Labels

Comments

@joeshaw
Copy link

joeshaw commented Aug 4, 2011

There's no (good) way to tell if the callback you are passing into dgram.send() will be executed synchronously and recursively, or whether it'll be called async by the main loop. If you are expecting it to be deferred (as I was), you could easily hit a stack overflow. Consider the code:

// assume port & address are assigned
function sendChunk(socket, buffer, offset) {
    socket.send(buffer, offset, 1024, port, address, function(err) {
        if (err) throw err;

        offset += 1024;
        if (offset < buffer.length)
            sendChunk(socket, buffer, offset);
    });
}

With most other APIs in Node, the callback is executed in the main loop. With dgram.send() it's only async if a DNS lookup is required. Otherwise, it's inline and synchronous. In the code above, as long as address is an IP address and the buffer is large enough, it will crash with a stack overflow.

My buddy Havoc had a good blog post on this very topic a few days ago: http://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/ :)

@joeshaw
Copy link
Author

joeshaw commented Aug 4, 2011

As a broader question, is there a general convention in Node for whether callbacks are sync or async? I had generally assumed they were always async, and all the APIs I can think of that I used other than dgram.send() were. Is it just an aberration?

@joeshaw
Copy link
Author

joeshaw commented Aug 4, 2011

Looks like maybe a similar issue as to issue 1164 (#1164), and that would imply that sometimes a non-IP address value would also cause a sync callback.

@koichik
Copy link

koichik commented Aug 5, 2011

I agree. I think dgram's methods should invoke callback asynchronously.
And, addMembership()/removeMembership() need callback...

@koichik
Copy link

koichik commented Aug 21, 2011

Please review 09f753f.

@bnoordhuis
Copy link
Member

@koichik: can we hold this off for a few days? I'm integrating libuv UDP support into node and this patch would mess up my work. libuv always executes the callback asynchronously, by the way.

@koichik
Copy link

koichik commented Aug 22, 2011

@bnoordhuis

libuv always executes the callback asynchronously, by the way.

Awesome! I throw out this patch.

@joeshaw
Copy link
Author

joeshaw commented Aug 22, 2011

Probably still need the addMembership()/removeMembership() callbacks from the patch, though,

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants