Skip to content

Conversation

@Tango992
Copy link
Member

@Tango992 Tango992 commented Aug 12, 2025

Closes #30405

Changes in this PR:

  • Fixes os.setPriority() on Windows.
  • Validates the function parameters correctly and constructs NodeSystemError on op call error.
  • Allows parallel/test-os-process-priority.js to pass.

Node.js 24.5.0:

node test-os.ts
SystemError [ERR_SYSTEM_ERROR]: A system error occurred: uv_os_setpriority returned EACCES (permission denied)
    at Module.setPriority (node:os:263:11)
    ... redacted ...
  code: 'ERR_SYSTEM_ERROR',
  info: {
    errno: -13,
    code: 'EACCES',
    message: 'permission denied',
    syscall: 'uv_os_setpriority'
  },
  errno: [Getter/Setter: -13],
  syscall: [Getter/Setter: 'uv_os_setpriority']
}

Deno 2.4.3:

deno -A test-os.ts                                                          
PermissionDenied: Permission denied (os error 13)
    at Module.setPriority (node:os:160:3)
    ... redacted ...
  name: "PermissionDenied",
  code: "EACCES"
}

This PR:

deno -A test-os.ts
SystemError: A system error occurred: uv_os_setpriority returned EACCES (permission denied)
    at __node_internal_captureLargerStackTrace (ext:deno_node/internal/errors.ts:156:5)
    ... redacted ...
  code: 'ERR_SYSTEM_ERROR',
  info: {
    errno: -13,
    code: 'EACCES',
    message: 'permission denied',
    syscall: 'uv_os_setpriority'
  },
  errno: [Getter/Setter: -13],
  syscall: [Getter/Setter: 'uv_os_setpriority']
}

Validates the function parameters correctly, and constructs NodeSystemError on op call error
@Tango992 Tango992 marked this pull request as draft August 12, 2025 15:21
@Tango992 Tango992 marked this pull request as ready for review August 13, 2025 01:22
@Tango992 Tango992 marked this pull request as draft August 13, 2025 01:32
@Tango992 Tango992 marked this pull request as ready for review August 13, 2025 01:46
@Tango992 Tango992 marked this pull request as draft August 13, 2025 02:01
@Tango992 Tango992 marked this pull request as ready for review August 13, 2025 13:12
Comment on lines 811 to 813
# NB(Tango992): Fails on CI specifically on macos-aarch64.
# Seems like the process priority can't be set correctly on CI.
# "parallel/test-os-process-priority.js" = {}
Copy link
Member Author

@Tango992 Tango992 Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For unknown reasons, the test seems to always fail on macos-aarch64 on CI, even though it works fine on my device with the same architecture.

These are the two jobs that failed with the same rejection:

It passes on linux CI which made me think it was macos-aarch64 specific. My speculation is our macos-aarch64 CI doesn't allow some processes to set priority levels by themself.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pining @willnewby for some help

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also - this might not be CI related, but rather a problem in implementation of op_node_os_set_priority

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChatGPT says that it might need root access (though it should return error if that's not the case)

Copy link
Member Author

@Tango992 Tango992 Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also - this might not be CI related, but rather a problem in implementation of op_node_os_set_priority

After digging into the op, I think it's because of our incorrect implementation of op_node_os_get_priority (not the op_node_os_set_priority):

pub fn get_priority(pid: u32) -> Result<i32, super::PriorityError> {
set_errno(Errno(0));
match (
// SAFETY: libc::getpriority is unsafe
unsafe { libc::getpriority(PRIO_PROCESS, pid as id_t) },
errno(),
) {
(-1, Errno(0)) => Ok(PRIORITY_HIGH),
(-1, _) => Err(std::io::Error::last_os_error().into()),
(priority, _) => Ok(priority),
}
}

Here's libuv's implementation:
https://github.com/libuv/libuv/blob/55376b044b74db40772e8a6e24d67a8673998e02/src/unix/core.c#L1533-L1547

I think this line is incorrect and explains why on macos CI, it always returns -14 (the value of PRIORITY_HIGH):

(-1, Errno(0)) => Ok(PRIORITY_HIGH),

Some reference from https://man7.org/linux/man-pages/man3/errno.3.html :

For some system calls and library functions (e.g.,
getpriority(2)), -1 is a valid return on success. In such cases,
a successful return can be distinguished from an error return by
setting errno to zero before the call, and then, if the call
returns a status that indicates that an error may have occurred,
checking to see if errno has a nonzero value.

@Tango992 Tango992 marked this pull request as draft August 14, 2025 02:31
@Tango992 Tango992 marked this pull request as ready for review August 14, 2025 05:59
@Tango992 Tango992 marked this pull request as draft August 14, 2025 06:55
@Tango992 Tango992 marked this pull request as ready for review August 14, 2025 08:01
@Tango992 Tango992 marked this pull request as draft August 14, 2025 08:21
@Tango992 Tango992 force-pushed the fix-node-fs-os-process-priority branch from 8981608 to 6f11a2b Compare August 18, 2025 15:33
@Tango992 Tango992 marked this pull request as ready for review August 18, 2025 15:33
Comment on lines +297 to +299
// Windows allows setting process priority without privilege escalation up to `PRIORITY_HIGH`.
// Setting to `PRIORITY_HIGHEST` will be silently reduced to `PRIORITY_HIGH`.
ignore: Deno.build.os === "windows",
Copy link
Member Author

@Tango992 Tango992 Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though documentation on Windows is quite scarce, I got this from here: https://github.com/nodejs/node/blob/591ba692bfe30408e6a67397e7d18bfa1b9c3561/test/parallel/test-os-process-priority.js#L131-L132

The reason why previously this test passes on Windows is because os.setPriority() always throw no matter what. See #30405

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds good, but does that mean we are not able to run some of the Node tests in our CI? Maybe we should add a way to ignore certain OSes in config.toml?

Copy link
Member Author

@Tango992 Tango992 Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to ignore certain OSes from our node compat tests, because the Windows' os.setPriority() issue is already addressed in this PR. I'll update the PR message so it covers that.

But having a way to ignore certain OSes from the node compat test sounds good to have.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #30439

Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@bartlomieju bartlomieju merged commit 9b1d8d5 into denoland:main Aug 18, 2025
21 checks passed
@Tango992 Tango992 deleted the fix-node-fs-os-process-priority branch August 18, 2025 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

node:os setPriority compatibility on windows

2 participants