mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-09 09:54:25 +09:00
Added a global poll context
This commit is contained in:
@@ -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);
|
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);
|
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p);
|
||||||
int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout);
|
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_ */
|
#endif /* POLL_H_ */
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/socket.h"
|
#include "libssh/socket.h"
|
||||||
#include "libssh/dh.h"
|
#include "libssh/dh.h"
|
||||||
|
#include "libssh/poll.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -63,6 +63,7 @@ int ssh_init(void) {
|
|||||||
@returns 0 otherwise
|
@returns 0 otherwise
|
||||||
*/
|
*/
|
||||||
int ssh_finalize(void) {
|
int ssh_finalize(void) {
|
||||||
|
ssh_free_global_poll_ctx();
|
||||||
ssh_regex_finalize();
|
ssh_regex_finalize();
|
||||||
ssh_crypto_finalize();
|
ssh_crypto_finalize();
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
|
|||||||
@@ -39,6 +39,9 @@
|
|||||||
#define SSH_POLL_CTX_CHUNK 5
|
#define SSH_POLL_CTX_CHUNK 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** global poll context used for blocking operations */
|
||||||
|
static ssh_poll_ctx global_poll_ctx;
|
||||||
|
|
||||||
struct ssh_poll_handle_struct {
|
struct ssh_poll_handle_struct {
|
||||||
ssh_poll_ctx ctx;
|
ssh_poll_ctx ctx;
|
||||||
union {
|
union {
|
||||||
@@ -580,3 +583,31 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout) {
|
|||||||
|
|
||||||
return rc;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
#include "libssh/misc.h"
|
#include "libssh/misc.h"
|
||||||
#include "libssh/buffer.h"
|
#include "libssh/buffer.h"
|
||||||
|
#include "libssh/poll.h"
|
||||||
|
|
||||||
#define FIRST_CHANNEL 42 // why not ? it helps to find bugs.
|
#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);
|
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 ssh_handle_packets(ssh_session session) {
|
||||||
int w = 0;
|
ssh_poll_handle spoll;
|
||||||
int e = 0;
|
ssh_poll_ctx ctx;
|
||||||
int rc = -1;
|
if(session==NULL || session->socket==NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
enter_function();
|
enter_function();
|
||||||
|
spoll=ssh_socket_get_poll_handle(session->socket);
|
||||||
do {
|
ctx=ssh_poll_get_ctx(spoll);
|
||||||
rc = ssh_socket_poll(session->socket, &w, &e);
|
if(ctx==NULL){
|
||||||
if (rc <= 0) {
|
ctx=ssh_get_global_poll_ctx(session);
|
||||||
/* error or no data available */
|
ssh_poll_ctx_add(ctx,spoll);
|
||||||
leave_function();
|
}
|
||||||
return rc;
|
ssh_poll_ctx_dopoll(ctx,-1);
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
if (session->session_state != SSH_SESSION_STATE_ERROR)
|
||||||
|
return SSH_OK;
|
||||||
|
else
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user