GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `events.once` leaks signal listener · Issue #43337 · nodejs/node

events.once leaks signal listener #43337

New issue
Copy link
New issue
Copy link
Closed
#43373
Closed
events.once leaks signal listener#43337
#43373
Copy link
Labels
confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.eventsIssues and PRs related to EventEmitter and the events module.Issues and PRs related to EventEmitter and the events module.

Description

@breavyn
breavyn
opened on Jun 7, 2022
Issue body actions

Version

v18.3.0

Platform

Linux

Subsystem

events

What steps will reproduce the bug?

const { EventEmitter, once } = require("events");

(async () => {
  const controller = new AbortController();
  const ee = new EventEmitter();

  setTimeout(() => {
    controller.abort();
  }, 500);

  while (true) {
    setTimeout(() => ee.emit("test"), 100);
    await once(ee, "test", { signal: controller.signal });

    console.dir(controller.signal);
  }
})();

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior?

No response

What do you see instead?

The signal abort listeners do not get removed.

AbortSignal {
  [Symbol(kEvents)]: SafeMap(1) [Map] { 'abort' => { size: 1, next: [Listener] } },
  [Symbol(events.maxEventTargetListeners)]: 10,
  [Symbol(events.maxEventTargetListenersWarned)]: false,
  [Symbol(kAborted)]: false,
  [Symbol(kReason)]: undefined
}
AbortSignal {
  [Symbol(kEvents)]: SafeMap(1) [Map] { 'abort' => { size: 2, next: [Listener] } },
  [Symbol(events.maxEventTargetListeners)]: 10,
  [Symbol(events.maxEventTargetListenersWarned)]: false,
  [Symbol(kAborted)]: false,
  [Symbol(kReason)]: undefined
}
AbortSignal {
  [Symbol(kEvents)]: SafeMap(1) [Map] { 'abort' => { size: 3, next: [Listener] } },
  [Symbol(events.maxEventTargetListeners)]: 10,
  [Symbol(events.maxEventTargetListenersWarned)]: false,
  [Symbol(kAborted)]: false,
  [Symbol(kReason)]: undefined
}
AbortSignal {
  [Symbol(kEvents)]: SafeMap(1) [Map] { 'abort' => { size: 4, next: [Listener] } },
  [Symbol(events.maxEventTargetListeners)]: 10,
  [Symbol(events.maxEventTargetListenersWarned)]: false,
  [Symbol(kAborted)]: false,
  [Symbol(kReason)]: undefined
}

Additional information

When listeners are added to EventTarget's in events.on and events.once, the listener gets wrapped. As AbortSignal is an EventTarget, this means the abort listener can never be removed.

node/lib/events.js

Lines 1011 to 1013 in b631086

// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen to `error` events here.
emitter.addEventListener(name, (arg) => { listener(arg); }, flags);

I confirmed that the listeners do get removed correctly when simply passing the listener in directly, however, I'm unsure if this will have any other consequences hinted at by the comment.

Activity

  1. daeyeon commented on Jun 11, 2022

    @daeyeon
    daeyeon
    on Jun 11, 2022
    Member
    More actions

    IMO, it's possible to directly pass the listener. Sent a PR for this. :-)

  2. F3n67u
    added
    eventsIssues and PRs related to EventEmitter and the events module.Issues and PRs related to EventEmitter and the events module.
    code-and-learnIssues related to the Code-and-Learn events and PRs submitted during the events.Issues related to the Code-and-Learn events and PRs submitted during the events.
    confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.
    and removed
    code-and-learnIssues related to the Code-and-Learn events and PRs submitted during the events.Issues related to the Code-and-Learn events and PRs submitted during the events.
    on Jun 11, 2022
  3. nodejs-github-bot
    closed this as completedin #43373on Jun 14, 2022
  4. nodejs-github-bot
    added a commit that references this issue on Jun 14, 2022

    events: fix adding abort listener in `events.once`

    f7d73d4
  5. danielleadams
    added a commit that references this issue on Jun 16, 2022

    events: fix adding abort listener in `events.once`

    0c5092c
  6. targos
    added a commit that references this issue on Jul 12, 2022

    events: fix adding abort listener in `events.once`

    3185c92
  7. targos
    added a commit that references this issue on Jul 31, 2022

    events: fix adding abort listener in `events.once`

    393c021
  8. guangwong
    added a commit that references this issue on Oct 10, 2022

    events: fix adding abort listener in `events.once`

    588ab30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.eventsIssues and PRs related to EventEmitter and the events module.Issues and PRs related to EventEmitter and the events module.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.