Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leaking Socket / Pipe on Linux? #57

Closed
jeffbk opened this issue Feb 16, 2015 · 12 comments
Closed

Leaking Socket / Pipe on Linux? #57

jeffbk opened this issue Feb 16, 2015 · 12 comments
Assignees
Labels
Milestone

Comments

@jeffbk
Copy link

jeffbk commented Feb 16, 2015

Hi. Thank you for providing this really useful library to node js. I am running on Raspberry PI (Raspbian). It looks like there may be sockets / pipes leaking. I am creating a service that periodically attempts to connect to a bluetooth device. After running for a while, it starts to fail on connect (with an uncaught exception):

Error: Cannot create pipe for reading.
    at BluetoothSerialPort.connect (/home/pi/node_modules/bluetooth-serial-port/lib/bluetooth-serial-port.js:81:26)
    at tryConnect (/home/pi/repositories/nodeGateway/test/leak.js:20:14)
    at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

If you run the code below and check the file descriptors (FDs) owned by the process, you will see that each new connection attempt appears to be creating 3 FDs: 1 socket and 2 pipes (using ls -l /proc//fd). Three new FDs are created for each connection attempt and the previous attempt's FDs do not seem to be getting released. Continue running it until 1024 FDs are consumed to get the error. I am by no means a linux expert so I might not be interpreting these results correctly. Perhaps there is something I am doing incorrectly?

var BtSerial = require('bluetooth-serial-port');

var args = process.argv.slice(2);
var bdAddr = args[0];
var channel = args[1];

process.on('uncaughtException', function (error) {
    console.log(error.stack);
    process.exit(1);
});

var btSerial = new BtSerial.BluetoothSerialPort();

function tryConnect() {

    console.log('Connecting...');

    btSerial.connect(bdAddr, channel,
        function () {
            console.log('Connected');
            btSerial.close();
            setTimeout(tryConnect, 1000);
        },
        function () {
            console.log('Connect failed');
            btSerial.close();
            setTimeout(tryConnect, 1000);
        });

}

tryConnect();

NOTE: It does not seem to matter if a new BluetoothSerialPort is created for each connection attempt, or if a single BluetoothSerialPort is used for all connection attempts (as shown above).

Thank you again for providing this useful project.

@eelcocramer
Copy link
Owner

Thank you for your well documented report. I'll try to look into it somewhere this week.

@eelcocramer eelcocramer self-assigned this Feb 16, 2015
@eelcocramer
Copy link
Owner

In your logging do you see either Connected or Connect failed? I wonder if close gets called correctly.

@jeffbk
Copy link
Author

jeffbk commented Feb 17, 2015

Thanks for looking into this. I see the logging output and believe the close is being called in both cases. I was looking at the linux c code and it appears that two pipes are being open with the socket. However, it appears that these pipes are not being closed (at least as far as I could tell). If I get a chance I will try to put together a pull request. It may take me a bit as node modules are new to me and my c coding is a bit rusty... Thanks.

@eelcocramer
Copy link
Owner

Could very well that you pinpointed the issue. In what lines are the pipes created?

@jeffbk
Copy link
Author

jeffbk commented Feb 18, 2015

@eelcocramer
Copy link
Owner

I've commited a possible fix. Still need to test this myself but you can give it a try. Checkout branch issue57

@eelcocramer eelcocramer mentioned this issue Feb 18, 2015
@eelcocramer
Copy link
Owner

I've fixed the issue and merged the fix into master. Can you confirm and reopen the issue if it still exists?

@jeffbk
Copy link
Author

jeffbk commented Feb 18, 2015

Unfortunately my RPi is on loan at the moment, but I will test as soon as I get it back (later today). Sorry for the delay. Thanks for addressing so quickly.

@eelcocramer
Copy link
Owner

No problem. Let me know when you are ready.

@eelcocramer
Copy link
Owner

I've just released 1.2.2 with a fix for your issue. Please let me know if you still run into it.

@eelcocramer eelcocramer added this to the 1.2.2 milestone Feb 19, 2015
@jeffbk
Copy link
Author

jeffbk commented Feb 19, 2015

I've done some initial testing and the file descriptors are no longer being leaked (socket and pipes). Socket and pipes are being cleaned up in both the connect and connect failed cases. :) I will do a bit more extensive testing today. Thanks again.

@eelcocramer
Copy link
Owner

Thank you for the feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants