Search code examples
node.jswindowsusblibusb

cannot claim usb interface more than 64 times


I have an app that needs to maintain a long (indefinite) connection to a usb device and print a potentially unlimited number of times to it. So, it needs to make a lot of claims on the same device interface.

Eventually my app breaks because on the 65th claim I get a LIBUSB_ERROR_ACCESS error thrown. Is it possible to fix this with node-usb? Possibly related to

environment and hardware

windows 11 home insider preview
nodejs v11.0.0
node-usb v1.5.0
node-escpos v2

code

function testClaim() {
  const d = new USB();
  const p = new Printer(d, { encoding: 'Shift-JIS' });

  const loop = (curr = 0) => {
    console.log('LOOP', curr)

    if (curr === 50) {
      setTimeout(() => {
        d.open(() => d.reset(() => {
          console.log('RESET', curr)
          // should not require the user to do anything, needs to be able to print indefinitely
          loop(0)
        }))
      }, 1000);
      return;
    }

    d.open(() => {
      p.close(() => {
        loop(curr + 1)
      })
    })
  }

  loop();
}

testClaim();

Solution

  • I got around this by using a main thread to manage two child threads

    MAX_COUNT=6
    
    print 1 [thread]
    print 2 [thread]
    print 3 [thread, thread] # MAX_COUNT / 2, add the head
    print 4 [thread, thread]
    print 5 [thread, thread]
    print 6 [thread]         # MAX_COUNT, the head becomes the tail, delete the previous tail
    
    always print to the tail thread, it should always exist
    this lets you spin up the thread asynchronously
    

    Printing inside the forked thread doesn't seem to carry over to other threads so something in libusb or node-usb seems to be mutating the thread's memory, I'm not sure.