diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2009-12-11 21:11:23 +0100 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2009-12-11 21:11:23 +0100 |
commit | 80b6cf77b03a6a29f76bdb4768b2b2c6d7d37495 (patch) | |
tree | 418c1cea022addfb08152887f7c3f47ec0798d58 | |
parent | 79b4bf4ac2811d868c7c27830fd5538e21cb33a8 (diff) | |
download | libssh-80b6cf77b03a6a29f76bdb4768b2b2c6d7d37495.tar.gz libssh-80b6cf77b03a6a29f76bdb4768b2b2c6d7d37495.tar.xz libssh-80b6cf77b03a6a29f76bdb4768b2b2c6d7d37495.zip |
Added a global poll context
-rw-r--r-- | include/libssh/poll.h | 3 | ||||
-rw-r--r-- | libssh/init.c | 3 | ||||
-rw-r--r-- | libssh/poll.c | 31 | ||||
-rw-r--r-- | libssh/session.c | 47 |
4 files changed, 56 insertions, 28 deletions
diff --git a/include/libssh/poll.h b/include/libssh/poll.h index 5d8bd3c..54a1348 100644 --- a/include/libssh/poll.h +++ b/include/libssh/poll.h @@ -98,7 +98,8 @@ 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); #endif /* POLL_H_ */ diff --git a/libssh/init.c b/libssh/init.c index bab9cdf..9a58429 100644 --- a/libssh/init.c +++ b/libssh/init.c @@ -25,7 +25,7 @@ #include "libssh/priv.h" #include "libssh/socket.h" #include "libssh/dh.h" - +#include "libssh/poll.h" #ifdef _WIN32 #include <winsock2.h> #endif @@ -63,6 +63,7 @@ int ssh_init(void) { @returns 0 otherwise */ int ssh_finalize(void) { + ssh_free_global_poll_ctx(); ssh_regex_finalize(); ssh_crypto_finalize(); #ifdef HAVE_LIBGCRYPT diff --git a/libssh/poll.c b/libssh/poll.c index 42da4aa..ac86750 100644 --- a/libssh/poll.c +++ b/libssh/poll.c @@ -39,6 +39,9 @@ #define SSH_POLL_CTX_CHUNK 5 #endif +/** global poll context used for blocking operations */ +static ssh_poll_ctx global_poll_ctx; + struct ssh_poll_handle_struct { ssh_poll_ctx ctx; union { @@ -580,3 +583,31 @@ 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. + */ +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; + } +} diff --git a/libssh/session.c b/libssh/session.c index cd25624..c03553c 100644 --- a/libssh/session.c +++ b/libssh/session.c @@ -34,6 +34,7 @@ #include "libssh/session.h" #include "libssh/misc.h" #include "libssh/buffer.h" +#include "libssh/poll.h" #define FIRST_CHANNEL 42 // why not ? it helps to find bugs. @@ -260,36 +261,30 @@ void ssh_set_fd_except(ssh_session session) { ssh_socket_set_except(session->socket); } -/** \warning I don't remember if this should be internal or not +/** @internal + * @brief polls the current session for an event and call the + * appropriate callbacks. Will block until one event happens. + * @param session session handle. + * @return SSH_OK if there are no error, SSH_ERROR otherwise. */ -/* looks if there is data to read on the socket and parse it. */ int ssh_handle_packets(ssh_session session) { - int w = 0; - int e = 0; - int rc = -1; - + ssh_poll_handle spoll; + ssh_poll_ctx ctx; + if(session==NULL || session->socket==NULL) + return SSH_ERROR; enter_function(); - - do { - rc = ssh_socket_poll(session->socket, &w, &e); - if (rc <= 0) { - /* error or no data available */ - leave_function(); - return rc; - } - - /* if an exception happened, it will be trapped by packet_read() */ - if ((packet_read(session) != SSH_OK) || - (packet_translate(session) != SSH_OK)) { - leave_function(); - return -1; - } - - packet_parse(session); - } while(rc > 0); - + spoll=ssh_socket_get_poll_handle(session->socket); + ctx=ssh_poll_get_ctx(spoll); + if(ctx==NULL){ + ctx=ssh_get_global_poll_ctx(session); + ssh_poll_ctx_add(ctx,spoll); + } + ssh_poll_ctx_dopoll(ctx,-1); leave_function(); - return rc; + if (session->session_state != SSH_SESSION_STATE_ERROR) + return SSH_OK; + else + return SSH_ERROR; } /** |