1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-02 01:17:52 +03:00

Use termination functions for event polling

This commit is contained in:
Aris Adamantiadis
2011-01-12 23:04:43 +01:00
parent a17472ff2b
commit 5b6f048197
3 changed files with 68 additions and 15 deletions

View File

@@ -158,8 +158,15 @@ struct ssh_session_struct {
char *ProxyCommand; char *ProxyCommand;
}; };
/** @internal
* @brief a termination function evaluates the status of an object
* @param user[in] object to evaluate
* @returns 1 if the polling routine should terminate, 0 instead
*/
typedef int (*ssh_termination_function)(void *user);
int ssh_handle_packets(ssh_session session, int timeout); int ssh_handle_packets(ssh_session session, int timeout);
int ssh_handle_packets_termination(ssh_session session, int timeout,
ssh_termination_function fct, void *user);
void ssh_socket_exception_callback(int code, int errno_code, void *user); void ssh_socket_exception_callback(int code, int errno_code, void *user);
#endif /* SESSION_H_ */ #endif /* SESSION_H_ */

View File

@@ -588,6 +588,21 @@ static void ssh_client_connection_callback(ssh_session session){
leave_function(); leave_function();
} }
/** @internal
* @brief describe under which conditions the ssh_connect function may stop
*/
static int ssh_connect_termination(void *user){
ssh_session session = (ssh_session)user;
switch(session->session_state){
case SSH_SESSION_STATE_ERROR:
case SSH_SESSION_STATE_AUTHENTICATING:
case SSH_SESSION_STATE_DISCONNECTED:
return 1;
default:
return 0;
}
}
/** /**
* @brief Connect to the ssh server. * @brief Connect to the ssh server.
* *
@@ -670,21 +685,15 @@ int ssh_connect(ssh_session session) {
ssh_log(session,SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work"); ssh_log(session,SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work");
pending: pending:
session->pending_call_state=SSH_PENDING_CALL_CONNECT; session->pending_call_state=SSH_PENDING_CALL_CONNECT;
while(session->session_state != SSH_SESSION_STATE_ERROR &&
session->session_state != SSH_SESSION_STATE_AUTHENTICATING &&
session->session_state != SSH_SESSION_STATE_DISCONNECTED){
/* loop until SSH_SESSION_STATE_BANNER_RECEIVED or
* SSH_SESSION_STATE_ERROR */
if(ssh_is_blocking(session)) if(ssh_is_blocking(session))
ssh_handle_packets(session,-1); ssh_handle_packets_termination(session,-1,ssh_connect_termination,session);
else else
ssh_handle_packets(session,0); ssh_handle_packets_termination(session,0,ssh_connect_termination, session);
ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state); ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
if(!ssh_is_blocking(session)){ if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
leave_function(); leave_function();
return SSH_AGAIN; return SSH_AGAIN;
} }
}
leave_function(); leave_function();
session->pending_call_state=SSH_PENDING_CALL_NONE; session->pending_call_state=SSH_PENDING_CALL_NONE;
if(session->session_state == SSH_SESSION_STATE_ERROR || session->session_state == SSH_SESSION_STATE_DISCONNECTED) if(session->session_state == SSH_SESSION_STATE_ERROR || session->session_state == SSH_SESSION_STATE_DISCONNECTED)

View File

@@ -395,6 +395,43 @@ int ssh_handle_packets(ssh_session session, int timeout) {
return SSH_ERROR; return SSH_ERROR;
} }
/**
* @internal
*
* @brief Poll the current session for an event and call the appropriate
* callbacks.
*
* This will block until termination fuction returns true, or timeout expired.
*
* @param[in] session The session handle to use.
*
* @param[in] timeout Set an upper limit on the time for which this function
* will block, in milliseconds. Specifying a negative value
* means an infinite timeout. This parameter is passed to
* the poll() function.
* @param[in] fct Termination function to be used to determine if it is
* possible to stop polling.
* @param[in] user User parameter to be passed to fct termination function.
* @return SSH_OK on success, SSH_ERROR otherwise.
*/
int ssh_handle_packets_termination(ssh_session session, int timeout,
ssh_termination_function fct, void *user){
int ret;
while(!fct(user)){
ret = ssh_handle_packets(session, timeout);
if(ret == SSH_ERROR)
return SSH_ERROR;
if(timeout == 0){
if(fct(user))
return SSH_OK;
else
return SSH_AGAIN;
}
/* TODO: verify that total timeout has not expired and then return SSH_AGAIN */
}
return ret;
}
/** /**
* @brief Get session status * @brief Get session status
* *