From cd1dccd849d2a837e40712fa559052a7c7cd019e Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 8 Apr 2005 23:40:50 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=5813 --- checkin_notes | 15 +++++++++++ client/net_xfer.C | 25 +++---------------- lib/error_numbers.h | 1 + lib/gui_rpc_client.C | 59 ++++++++++++++++++++++++++++++++------------ lib/gui_rpc_client.h | 3 ++- lib/network.C | 49 ++++++++++++++++++++++++++++++++++++ lib/network.h | 2 ++ 7 files changed, 116 insertions(+), 38 deletions(-) diff --git a/checkin_notes b/checkin_notes index 6d54d227a1..fc9a6f4e36 100755 --- a/checkin_notes +++ b/checkin_notes @@ -26927,3 +26927,18 @@ David 8 April 2005 lib/ gui_rpc_client.C +David 8 April 2005 + - Made library functions for creating a socket, + and for changing a socket to/from asynch mode + - GUI RPC client: allow for asynchronous connection. + First you call RPC_CLIENT::init(host, true), + then you call RPC_CLIENT::init_poll() + until it returns either zero (connected) + or a value other than ERR_RETRY (error) + + client/ + net_xfer.C + lib/ + error_numbers.h + gui_rpc_client.C,h + network.C,h diff --git a/client/net_xfer.C b/client/net_xfer.C index 85617cfe1b..0c07e4bea9 100644 --- a/client/net_xfer.C +++ b/client/net_xfer.C @@ -161,27 +161,10 @@ int NET_XFER::open_server() { retval = get_ip_addr(ipaddr); if (retval) return retval; - fd = ::socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { -#ifdef WIN32 - NetClose(); -#endif - return ERR_SOCKET; - } - -#ifdef WIN32 - unsigned long one = 1; - ioctlsocket(fd, FIONBIO, &one); -#else - int flags; - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) { - return ERR_FCNTL; - } - if (fcntl(fd, F_SETFL, flags|O_NONBLOCK) < 0 ) { - return ERR_FCNTL; - } -#endif + retval = boinc_socket(fd); + if (retval) return retval; + retval = boinc_socket_asynch(fd, true); + if (retval) return retval; addr.sin_family = AF_INET; addr.sin_port = htons(port); diff --git a/lib/error_numbers.h b/lib/error_numbers.h index 85688292ab..4e1c597434 100755 --- a/lib/error_numbers.h +++ b/lib/error_numbers.h @@ -144,3 +144,4 @@ #define ERR_WU_USER_RULE -196 #define ERR_ABORTED_VIA_GUI -197 #define ERR_INSUFFICIENT_RESOURCE -198 +#define ERR_RETRY -199 diff --git a/lib/gui_rpc_client.C b/lib/gui_rpc_client.C index 4f9f7e0eb7..8a9c6a9aea 100644 --- a/lib/gui_rpc_client.C +++ b/lib/gui_rpc_client.C @@ -40,6 +40,7 @@ #include "error_numbers.h" #include "miofile.h" #include "md5_file.h" +#include "network.h" #include "gui_rpc_client.h" using std::string; @@ -947,7 +948,7 @@ void RPC_CLIENT::close() { sock = 0; } -int RPC_CLIENT::init(const char* host) { +int RPC_CLIENT::init(const char* host, bool asynch) { int retval; sockaddr_in addr; addr.sin_family = AF_INET; @@ -968,30 +969,56 @@ int RPC_CLIENT::init(const char* host) { #endif } - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock <= 0) { - perror("socket"); - return ERR_SOCKET; - } - retval = connect(sock, (const sockaddr*)(&addr), sizeof(addr)); - if (retval) { -#ifdef _WIN32 - printf( "connect 1: Windows Socket Error '%d'\n", WSAGetLastError() ); -#endif - addr.sin_port = htons(GUI_RPC_PORT); + retval = boinc_socket(sock); + if (retval) return retval; + + if (asynch) { + boinc_socket_asynch(sock, true); + retval = connect(sock, (const sockaddr*)(&addr), sizeof(addr)); + } else { retval = connect(sock, (const sockaddr*)(&addr), sizeof(addr)); if (retval) { #ifdef _WIN32 - printf( "connect 2: Windows Socket Error '%d'\n", WSAGetLastError() ); + printf( "connect 1: Winsock error '%d'\n", WSAGetLastError() ); #endif - perror("connect"); - close(); - return ERR_CONNECT; + addr.sin_port = htons(GUI_RPC_PORT); + retval = connect(sock, (const sockaddr*)(&addr), sizeof(addr)); + if (retval) { +#ifdef _WIN32 + printf( "connect 2: Winsock error '%d'\n", WSAGetLastError() ); +#endif + perror("connect"); + close(); + return ERR_CONNECT; + } } } return 0; } +int RPC_CLIENT::init_poll() { + fd_set read_fds, write_fds, error_fds; + struct timeval tv; + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + FD_ZERO(&error_fds); + + FD_SET(sock, &read_fds); + FD_SET(sock, &write_fds); + FD_SET(sock, &error_fds); + + tv.tv_sec = tv.tv_usec = 0; + select(FD_SETSIZE, &read_fds, &write_fds, &error_fds, &tv); + if (FD_ISSET(sock, &error_fds)) return ERR_CONNECT; + if (FD_ISSET(sock, &read_fds)) { + boinc_socket_asynch(sock, false); + return 0; + } + return ERR_RETRY; + +} + int RPC_CLIENT::authorize(const char* passwd) { bool found=false; int retval; diff --git a/lib/gui_rpc_client.h b/lib/gui_rpc_client.h index 6ddd3131c2..056245129b 100644 --- a/lib/gui_rpc_client.h +++ b/lib/gui_rpc_client.h @@ -393,7 +393,8 @@ public: int get_reply(char*&); RPC_CLIENT(); ~RPC_CLIENT(); - int init(const char* host); + int init(const char* host, bool asynch=false); + int init_poll(); void close(); int authorize(const char* passwd); int get_state(CC_STATE&); diff --git a/lib/network.C b/lib/network.C index 3b9cd3ce92..7129873c11 100644 --- a/lib/network.C +++ b/lib/network.C @@ -21,11 +21,60 @@ #include "boinc_win.h" #else #include +#include #include +#include + #endif +#include "error_numbers.h" #include "network.h" +int boinc_socket(int& fd) { + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + perror("socket"); +#ifdef WIN32 + NetClose(); +#endif + return ERR_SOCKET; + } + return 0; +} + +int boinc_socket_asynch(int fd, bool asynch) { + if (asynch) { +#ifdef WIN32 + unsigned long one = 1; + ioctlsocket(fd, FIONBIO, &one); +#else + int flags; + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) { + return ERR_FCNTL; + } + if (fcntl(fd, F_SETFL, flags|O_NONBLOCK) < 0 ) { + return ERR_FCNTL; + } +#endif + } else { +#ifdef WIN32 + unsigned long zero = 0; + ioctlsocket(fd, FIONBIO, &zero); +#else + int flags; + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) { + return ERR_FCNTL; + } + if (fcntl(fd, F_SETFL, flags&(~O_NONBLOCK)) < 0 ) { + return ERR_FCNTL; + } +#endif + } + return 0; +} + void boinc_close_socket(int sock) { #ifdef _WIN32 closesocket(sock); diff --git a/lib/network.h b/lib/network.h index 3b66c7f387..a22544f4a9 100644 --- a/lib/network.h +++ b/lib/network.h @@ -17,6 +17,8 @@ // or write to the Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +extern int boinc_socket(int& sock); +extern int boinc_socket_asynch(int sock, bool asynch); extern void boinc_close_socket(int sock); extern int get_socket_error(int fd);