summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2009-12-11 21:11:23 +0100
committerAris Adamantiadis <aris@0xbadc0de.be>2009-12-11 21:11:23 +0100
commit80b6cf77b03a6a29f76bdb4768b2b2c6d7d37495 (patch)
tree418c1cea022addfb08152887f7c3f47ec0798d58
parent79b4bf4ac2811d868c7c27830fd5538e21cb33a8 (diff)
downloadlibssh-80b6cf77b03a6a29f76bdb4768b2b2c6d7d37495.tar.gz
libssh-80b6cf77b03a6a29f76bdb4768b2b2c6d7d37495.tar.xz
libssh-80b6cf77b03a6a29f76bdb4768b2b2c6d7d37495.zip
Added a global poll context
-rw-r--r--include/libssh/poll.h3
-rw-r--r--libssh/init.c3
-rw-r--r--libssh/poll.c31
-rw-r--r--libssh/session.c47
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;
}
/**