Skip to content

CPU usage is high when using pty.js on Mac #38

@zcbenz

Description

@zcbenz

In node, the pty.js module works like this:

  1. ptyfork is called to create a pty.
  2. the fd returned by ptyfork is added to the events list.
  3. kevent listens to the events list.
  4. when there is new output in pty, kevent would return and let the application deal with the event.

However in atom-shell (on Mac), the renderer has its own message loop (NSRunLoop), we have to do some extra works to merge the NSRunnLoop and libuv, and so the pty.js should work like this:

  1. ptyfork is called to create a pty.
  2. the fd returned by ptyfork is added to the events list.
  3. kevent listens to the events list.
  4. atom-shell listens to node's kqueue's fd in new thread (by creating a new kqueue and adding node's kqueue to the new kqueue's events list).
  5. when there is new output in pty, atom-shell would get notified in the new thread and gives control to node's libuv loop
  6. node's kevent would return and let the application deal with the event.

Atom-shell's message loop integration works fine for nearly all cases, but there is some bug in darwin that make step 5 fail when using pty.js.

When the ptyfork is called and its fd is added to the events list, the kevent call in atom-shell will return immediately no matter whether there is new output in pty(in normal case the kevent call should only return when there is new events), so the kevent calls would eat up all the CPU. This should be a bug of darwin.

To fix it, I can make atom-shell polls node's kqueue in the new thread (now it polls its own kqueue), but then we would again face the one short events problem (see here for the discussion), and it would increase atom-shell's message loop integration's complexity a lot.

So I would not do hacks to the message loop integration for just pty.js on Mac now, until there are other cases need the change or we find a good workaround. To use pty.js, people can use child_process.fork to call it in node to get around of this bug for now.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions