4

I'm currently working on a client that talk with a SSH server. Everything works well, but, because the server is quite slow to answer, I have to wait for it to send data. I have two choices, and I'd like to have your advice about what is the most efficient way to wait for the server.

Choice #1 :

while (!(ssh_channel_poll(*sshChannel,0)))
 ;

Choice #2 :

while (!(ssh_channel_poll(*sshChannel,0)))
  sleep(1);
alinsoar
  • 15,386
  • 4
  • 57
  • 74
Chouchenn
  • 63
  • 9

4 Answers4

8

Both alternatives are undesirable. Normally, you would use a blocking read. I assume it looks something like this (since you say you are waiting for the server):

while (!ssh_channel_poll(...)) { ... }
ssh_channel_read(...);

In this case, the poll is unnecessary. Just make sure the SSH connection is a blocking connection, and the read function will wait until data is available if none is available when you call it.

// This is all you need.
ssh_channel_read(...);
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • My favorite way is to do this asynchronously. I call an async_read() function, then register a callback which calls the async_read() function which registers the same callback. That gives you an infinite blocking loop. – Stewart Aug 28 '17 at 07:45
  • @Stewart: I think you're thinking of something else? This question is about libssh… – Dietrich Epp Aug 28 '17 at 07:56
  • Thanks for the answer. I should have been more explicit : I use the ssh_channel_poll() call to know how many bytes I need to malloc() in order to store the answer. If I use only ssh_channel_read() I have to use a fixed length buffer and I can't be sure it is big enough (except if I use a very huge buffer which is not the best thing I guess). – Chouchenn Aug 28 '17 at 10:26
  • @Chouchenn: That doesn't work, because more data can arrive between the time when you call `ssh_channel_poll` and the time when you call `ssh_channel_read`. So you have no way of knowing if the buffer is big enough anyway. – Dietrich Epp Aug 28 '17 at 11:19
2

I think use sleep instead of infinite loop because using infinite loop, you are wasting CPU Power and time. When using sleep, the CPU will be able to run other programs.

msc
  • 33,420
  • 29
  • 119
  • 214
  • 4
    The CPU can run other programs anyway, since the process will get preempted and its priority will be lowered. – Dietrich Epp Aug 28 '17 at 07:44
  • All the sleep() call does is to give up the time slice and make timing generally weird for the process. Meaning that if you do manage to read something shortly after entering the loop, you will have a strange, arbitrary delay before actually reading, which caused by the sleep(). And that's about all it does. – Lundin Aug 28 '17 at 11:45
1

You probably want to call the poll(2) system call (or the old select(2) one). Then you need to get the relevant file descriptor. Or use the ssh_channel_poll_timeout function or ssh_channel_select.

Look also into libssh poll functions.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
0

Clipping is not a good idea. With sleep(...) you don't use hardly your cpu like with empty while(...).