diff --git a/include/libssh/poll.h b/include/libssh/poll.h index 8e30676e..478764b6 100644 --- a/include/libssh/poll.h +++ b/include/libssh/poll.h @@ -157,6 +157,7 @@ void ssh_poll_ctx_free(ssh_poll_ctx ctx); int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p); int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, struct ssh_socket_struct *s); void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p); +bool ssh_poll_is_locked(ssh_poll_handle p); int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout); ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session); int ssh_event_add_poll(ssh_event event, ssh_poll_handle p); diff --git a/src/poll.c b/src/poll.c index ee069293..3e356c49 100644 --- a/src/poll.c +++ b/src/poll.c @@ -682,6 +682,20 @@ void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p) } } +/** + * @brief Returns if a poll object is locked. + * + * @param p Pointer to an already allocated poll object. + * @returns true if the poll object is locked; false otherwise. + */ +bool ssh_poll_is_locked(ssh_poll_handle p) +{ + if (p == NULL) { + return false; + } + return p->lock_cnt > 0; +} + /** * @brief Poll all the sockets associated through a poll object with a * poll context. If any of the events are set after the poll, the diff --git a/src/socket.c b/src/socket.c index a31a4bfe..3e96decc 100644 --- a/src/socket.c +++ b/src/socket.c @@ -481,7 +481,7 @@ void ssh_socket_close(ssh_socket s) #endif } - if (s->poll_handle != NULL) { + if (s->poll_handle != NULL && !ssh_poll_is_locked(s->poll_handle)) { ssh_poll_free(s->poll_handle); s->poll_handle = NULL; }