1
1

Use termination functions for event polling

Этот коммит содержится в:
Aris Adamantiadis 2011-01-12 23:04:43 +01:00
родитель a17472ff2b
Коммит 5b6f048197
3 изменённых файлов: 68 добавлений и 15 удалений

Просмотреть файл

@ -158,8 +158,15 @@ struct ssh_session_struct {
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_termination(ssh_session session, int timeout,
ssh_termination_function fct, void *user);
void ssh_socket_exception_callback(int code, int errno_code, void *user);
#endif /* SESSION_H_ */

Просмотреть файл

@ -588,6 +588,21 @@ static void ssh_client_connection_callback(ssh_session session){
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.
*
@ -670,20 +685,14 @@ int ssh_connect(ssh_session session) {
ssh_log(session,SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work");
pending:
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))
ssh_handle_packets(session,-1);
else
ssh_handle_packets(session,0);
ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
if(!ssh_is_blocking(session)){
leave_function();
return SSH_AGAIN;
}
if(ssh_is_blocking(session))
ssh_handle_packets_termination(session,-1,ssh_connect_termination,session);
else
ssh_handle_packets_termination(session,0,ssh_connect_termination, session);
ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
leave_function();
return SSH_AGAIN;
}
leave_function();
session->pending_call_state=SSH_PENDING_CALL_NONE;

Просмотреть файл

@ -395,6 +395,43 @@ int ssh_handle_packets(ssh_session session, int timeout) {
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
*