Currently we're simply polling uv events while running [NSApp nextEventMatchingMask:], we should replace it with monitoring file descriptors with CFRunLoopAddSource.
Note that libuv is removing libev in the v0.9 branch, so we need to wait until it's done, since uv's underlying work may largely change.
I think I wrote the main loop with CFRunLoopAddSource in the past. Please find out why it's changed to polling.
If it hurt the performance pls fix it ASAP. We can't wait for upstream to transit from libev.
The removal of libev has been done in libuv's rm-ev branch yesterday, I'll implement the message loop integration with libuv's new implementation before the release of v0.3.2.
Please don't use that branch since it is still experimental, which could bring in problems.
And I don't think it would cost much effort to modify our code for the new libuv in the future -- they work in the same way basically.
libuv doesn't implement everything with libev, timers and idlers are implemented with its own code, that's why previous message loop integration fails. I'll solve this issue with current stable libuv.
In the new implementation, kqueue's backend fd is listened and we do uv_run in the callback. This makes most operations as fast as pure libuv message loop.
However kqueue is bugged on Mac, for some conditions, such as the first connection to socket created by listen, will not cause kqueue's backend fd to fire the callback. So there's still a polling every 500ms in case of such bugs. Node.js doesn't has this problem because it's always polling.
Because of the existence of polling, message loop's performance on Mac is not as good as on Windows and Linux, I tried to use node-tar to untar a 70mb file, nw's performance on Windows and Linux is as good as pure node process, however on Mac it is 50%~100% slower. After disabling polling, Mac is only 10%~20% slower, but some functions (like net.listen) will not work correctly because of kqueue's bug.
Close this because libuv may still use kqueue even after the removal of libev, so our implementation should be good enough.
why not put libuv loop in a separate thread, at same time keep libuv/node.js in the same context as render process? polling libuv in render loop is bad thing.
@sequoiar , mixing thread and dealing with context switch in callbacks and function calls is not as good as merging main loops. We've removed most of the polling by this commit, the performance is good now and we will continue to improve it.
the current CPU always has multi-cores/threads, so there should not be a context switch, just one process owns two threads: render is main thread, libuv is another.
in case node.js/libuv run heavy networking service, many events coming to render process/thread, then it may slow down render event processing, that increase response time from user input.
By "context" I mean the context in the Chromium/V8 stack, you'll have to post/delay the processing and wait for the other thread to pick up its work.
If you have any benchmark/test cases showing any problem, welcome to contribute.
btw, which is off-topic, when you have a multi-core CPU doesn't mean you don't have much 'context switch'. Run 'vmstat 1' and find the 'cs' value.
This fix made my OSX app much faster initially, but after I added in pty.js (a fork(3) binding), it got super slow. Every libuv event now has around 1000ms of latency. This is using 0.3.2.
I think we need to use the new uv_wait() to properly integrate. @indutny worked a lot on integrating with the OSX event loop using this.
Thanks for the info. We'll look into it. And help will be appreciated.
@creationix , we tried to fix the problem in the same way as 'uv_wait()'. We tested it and the result looks better. You can have a try here: https://s3.amazonaws.com/node-webkit/playground/nw_release_mac.zip
Much better, thanks! It performs about the same as linux as far as my eye can tell. Hopefully uv_wait() will land in libuv soon.
Hmm, something is very broken in my app though. Many operations freeze up the app and require me to reboot the process.
My app appears to die after an alert, confirm, or prompt dialog is used. Everything seems fine before that.
But I do not recommend using alert and other dialogs in real applications, since they will pause everything (including node.js functions), which is useful for debugging but would be a surprise for many people.
Make node tests run again after showing an alert dialog.
This change is for #82.
@creationix you can try our new fix at https://s3.amazonaws.com/node-webkit/playground/nw_release_mac.zip , it has passed our tests and should have fixed your problem, thanks for testing.
In initial testing, this seems to work. The UI freezes while the dialog is up as expected. When the dialog is dismissed, my program continues to run normally.
Also, I'm not sure if it was clear, but I expect the libuv event loop to be blocked while the dialog is up. It would be very surprising for my http server to keep accepting requests when the main thread is blocked by the nested event loop.
In the testing version of mac, we do block the libuv loop on dialog up (nested loop). We'll also ensure this behavior for Linux and Win. Will keep you posted.
turns out kqueue is not buggy for us because there is flaw in the libuv integration. The previous commit fixes delay in I/O and process.nextTick() widely seen.
The event loop on Mac was rewritten to fix this.