diff --git a/include/libssh/poll.h b/include/libssh/poll.h index 5ac267e8..88a16a1e 100644 --- a/include/libssh/poll.h +++ b/include/libssh/poll.h @@ -153,8 +153,6 @@ 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); int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout); -ssh_poll_ctx ssh_get_global_poll_ctx(ssh_session session); -void ssh_free_global_poll_ctx(void); - +ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session); #endif /* POLL_H_ */ diff --git a/include/libssh/session.h b/include/libssh/session.h index 86188fa8..33ef8795 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -26,7 +26,7 @@ #include "libssh/pcap.h" #include "libssh/auth.h" #include "libssh/channels.h" - +#include "libssh/poll.h" typedef struct ssh_kbdint_struct* ssh_kbdint; /* These are the different states a SSH session can be into its life */ @@ -125,6 +125,7 @@ struct ssh_session_struct { struct ssh_packet_callbacks_struct default_packet_callbacks; struct ssh_list *packet_callbacks; struct ssh_socket_callbacks_struct socket_callbacks; + ssh_poll_ctx default_poll_ctx; /* options */ #ifdef WITH_PCAP ssh_pcap_context pcap_ctx; /* pcap debugging context */ diff --git a/src/init.c b/src/init.c index 5952e272..385cb7a4 100644 --- a/src/init.c +++ b/src/init.c @@ -74,7 +74,6 @@ int ssh_init(void) { */ int ssh_finalize(void) { ssh_threads_finalize(); - ssh_free_global_poll_ctx(); ssh_regex_finalize(); ssh_crypto_finalize(); ssh_socket_cleanup(); diff --git a/src/poll.c b/src/poll.c index 7942ea0b..20e3a4fc 100644 --- a/src/poll.c +++ b/src/poll.c @@ -33,6 +33,7 @@ #include "libssh/libssh.h" #include "libssh/poll.h" #include "libssh/socket.h" +#include "libssh/session.h" #ifndef SSH_POLL_CTX_CHUNK #define SSH_POLL_CTX_CHUNK 5 @@ -44,7 +45,7 @@ * * Add a generic way to handle sockets asynchronously. * - * It's based on poll objects, each of which store a socket, it's events and a + * It's based on poll objects, each of which store a socket, its events and a * callback, which gets called whenever an event is set. The poll objects are * attached to a poll context, which should be allocated on per thread basis. * @@ -55,9 +56,6 @@ * @{ */ -/** global poll context used for blocking operations */ -static ssh_poll_ctx global_poll_ctx; - struct ssh_poll_handle_struct { ssh_poll_ctx ctx; union { @@ -659,32 +657,19 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout) { return rc; } -/** @internal - * @brief returns a pointer to the global poll context. - * Allocates it if it does not exist. - * @param session an optional session handler, used to store the error - * message if needed. - * @returns pointer to the global poll context. +/** + * @internal + * @brief gets the default poll structure for the current session, + * when used in blocking mode. + * @param session SSH session + * @returns the default ssh_poll_ctx */ -ssh_poll_ctx ssh_get_global_poll_ctx(ssh_session session){ - if(global_poll_ctx != NULL) - return global_poll_ctx; - global_poll_ctx=ssh_poll_ctx_new(5); - if(global_poll_ctx == NULL && session != NULL){ - ssh_set_error_oom(session); - return NULL; - } - return global_poll_ctx; -} - -/** @internal - * @brief Deallocate the global poll context - */ -void ssh_free_global_poll_ctx(){ - if(global_poll_ctx != NULL){ - ssh_poll_ctx_free(global_poll_ctx); - global_poll_ctx=NULL; - } +ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session){ + if(session->default_poll_ctx != NULL) + return session->default_poll_ctx; + /* 2 is enough for the default one */ + session->default_poll_ctx = ssh_poll_ctx_new(2); + return session->default_poll_ctx; } /** @} */ diff --git a/src/session.c b/src/session.c index dbcb2809..cda01db8 100644 --- a/src/session.c +++ b/src/session.c @@ -178,6 +178,9 @@ void ssh_free(ssh_session session) { crypto_free(session->current_crypto); crypto_free(session->next_crypto); ssh_socket_free(session->socket); + if(session->default_poll_ctx){ + ssh_poll_ctx_free(session->default_poll_ctx); + } /* delete all channels */ while (session->channels) { ssh_channel_free(session->channels); @@ -365,7 +368,7 @@ int ssh_handle_packets(ssh_session session, int timeout) { ssh_poll_add_events(spoll_in, POLLIN | POLLERR); ctx=ssh_poll_get_ctx(spoll_in); if(ctx==NULL){ - ctx=ssh_get_global_poll_ctx(session); + ctx=ssh_poll_get_default_ctx(session); ssh_poll_ctx_add(ctx,spoll_in); if(spoll_in != spoll_out) ssh_poll_ctx_add(ctx,spoll_out);