Index: peripherals/nic/w5100_internals.h =================================================================== --- peripherals/nic/w5100_internals.h (revision 4529) +++ peripherals/nic/w5100_internals.h (working copy) @@ -29,6 +29,12 @@ #ifndef FUSE_W5100_INTERNALS_H #define FUSE_W5100_INTERNALS_H +#ifdef WIN32 +#include + +#define POLLING_INTERVAL 100000 +#endif /* #ifdef WIN32 */ + typedef enum w5100_socket_mode { W5100_SOCKET_MODE_CLOSED = 0x00, W5100_SOCKET_MODE_TCP, Index: peripherals/nic/w5100_socket.c =================================================================== --- peripherals/nic/w5100_socket.c (revision 4529) +++ peripherals/nic/w5100_socket.c (working copy) @@ -28,14 +28,19 @@ #include "config.h" -#include -#include #include #include -#include #include #include +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* #ifdef WIN32 */ + #include "fuse.h" #include "ui/ui.h" #include "w5100.h" @@ -98,7 +103,7 @@ socket->datagram_count = 0; if( socket->fd != compat_socket_invalid ) { - close( socket->fd ); + compat_socket_close( socket->fd ); socket->fd = compat_socket_invalid; socket->socket_bound = 0; socket->ok_for_io = 0; @@ -172,7 +177,6 @@ int protocol = tcp ? IPPROTO_TCP : IPPROTO_UDP; const char *description = tcp ? "TCP" : "UDP"; int final_state = tcp ? W5100_SOCKET_STATE_INIT : W5100_SOCKET_STATE_UDP; - int one = 1; w5100_socket_clean( socket_obj ); @@ -183,10 +187,15 @@ return; } +#ifndef WIN32 + int one = 1; + + /* Win32 note: SO_REUSEADDR could be used to forcibly bind sockets already in use */ if( setsockopt( socket_obj->fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one) ) == -1 ) { printf("w5100: failed to set SO_REUSEADDR on socket %d; errno %d: %s\n", socket_obj->id, compat_socket_get_error(), strerror(compat_socket_get_error())); } +#endif socket_obj->state = final_state; @@ -301,7 +310,7 @@ { w5100_socket_acquire_lock( socket ); if( socket->fd != compat_socket_invalid ) { - close( socket->fd ); + compat_socket_close( socket->fd ); socket->fd = compat_socket_invalid; socket->socket_bound = 0; socket->ok_for_io = 0; @@ -569,7 +578,7 @@ printf("w5100: accepted connection from %s:%d on socket %d\n", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), socket->id); - if( close( socket->fd ) == -1 ) + if( compat_socket_close( socket->fd ) == -1 ) printf("w5100: error attempting to close fd %d for socket %d\n", socket->fd, socket->id); socket->fd = new_fd; Index: peripherals/nic/w5100.c =================================================================== --- peripherals/nic/w5100.c (revision 4529) +++ peripherals/nic/w5100.c (working copy) @@ -29,12 +29,17 @@ #include "config.h" #include -#include #include -#include #include #include +#ifdef WIN32 +#include +#else +#include +#include +#endif /* #ifdef WIN32 */ + #include "fuse.h" #include "ui/ui.h" #include "w5100.h" @@ -92,17 +97,25 @@ { nic_w5100_t *self = arg; int i; + fd_set readfds, writefds; + int max_fd; + +#ifdef WIN32 + struct timeval tv; + fd_set *readfds_p, *writefds_p; +#endif /* ifdef WIN32 */ while( !self->stop_io_thread ) { - fd_set readfds, writefds; int active; - int max_fd = self->pipe_read; + max_fd = -1; + FD_ZERO( &readfds ); + FD_ZERO( &writefds ); - FD_ZERO( &readfds ); +#ifndef WIN32 + max_fd = self->pipe_read; FD_SET( self->pipe_read, &readfds ); +#endif /* ifndef WIN32 */ - FD_ZERO( &writefds ); - for( i = 0; i < 4; i++ ) nic_w5100_socket_add_to_sets( &self->socket[i], &readfds, &writefds, &max_fd ); @@ -115,25 +128,55 @@ printf("w5100: io thread select\n"); +#ifndef WIN32 active = select( max_fd + 1, &readfds, &writefds, NULL, NULL ); printf("w5100: io thread wake; %d active\n", active); +#else + /* Set max wait time upto 0.1 sec if not IO is completed */ + tv.tv_sec = 0; + tv.tv_usec = POLLING_INTERVAL; + + readfds_p = ( readfds.fd_count )? &readfds : NULL; + writefds_p = ( writefds.fd_count )? &writefds : NULL; + /* Call select() only if there are pending sockets */ + if( readfds_p || writefds_p ) + { + active = select( max_fd + 1, readfds_p, writefds_p, NULL, &tv ); + + printf("w5100: io thread wake; %d active\n", active); + } + else { + active = 0; + usleep( tv.tv_usec ); + } +#endif /* ifndef WIN32 */ + if( active != -1 ) { +#ifndef WIN32 if( FD_ISSET( self->pipe_read, &readfds ) ) { char bitbucket; printf("w5100: discarding pipe data\n"); read( self->pipe_read, &bitbucket, 1 ); } +#endif /* ifndef WIN32 */ for( i = 0; i < 4; i++ ) nic_w5100_socket_process_io( &self->socket[i], readfds, writefds ); } - else if( errno == EBADF ) { +#ifndef WIN32 + else if( compat_socket_get_error() == EBADF ) { /* Do nothing - just loop again */ } +#else + else if( compat_socket_get_error() == WSAENOTSOCK ) { + /* Do nothing - just loop again */ + } +#endif /* ifndef WIN32 */ else { - printf("w5100: select returned unexpected errno %d: %s\n", errno, strerror(errno)); + printf("w5100: select returned unexpected errno %d: %s\n", + compat_socket_get_error(), strerror(compat_socket_get_error())); } } @@ -143,17 +186,28 @@ void nic_w5100_wake_io_thread( nic_w5100_t *self ) { +#ifndef WIN32 const char dummy = 0; write( self->pipe_write, &dummy, 1 ); +#endif /* ifndef WIN32 */ } nic_w5100_t* nic_w5100_alloc( void ) { int error; - int pipefd[2]; int i; +#ifndef WIN32 + int pipefd[2]; +#endif /* ifndef WIN32 */ + + error = compat_networking_init(); + if( error ) { + ui_error( UI_ERROR_ERROR, "Error initializing networking: %d", error ); + fuse_abort(); + } + nic_w5100_t *self = malloc( sizeof( *self ) ); if( !self ) { ui_error( UI_ERROR_ERROR, "%s:%d out of memory", __FILE__, __LINE__ ); @@ -165,6 +219,7 @@ nic_w5100_reset( self ); +#ifndef WIN32 error = pipe( pipefd ); if( error ) { ui_error( UI_ERROR_ERROR, "w5100: error %d creating pipe", error ); @@ -173,6 +228,7 @@ self->pipe_read = pipefd[0]; self->pipe_write = pipefd[1]; +#endif /* ifndef WIN32 */ self->stop_io_thread = 0; @@ -194,11 +250,18 @@ self->stop_io_thread = 1; nic_w5100_wake_io_thread( self ); +#ifdef WIN32 + /* wait IO thread wake up */ + usleep( 2 * POLLING_INTERVAL ); +#endif /* ifdef WIN32 */ + pthread_join( self->thread, NULL ); for( i = 0; i < 4; i++ ) nic_w5100_socket_reset( &self->socket[i] ); + compat_networking_end(); + free( self ); } } Index: configure.in =================================================================== --- configure.in (revision 4529) +++ configure.in (working copy) @@ -110,7 +110,7 @@ AC_MSG_RESULT($win32) if test "$win32" = yes; then AC_CHECK_HEADER(windows.h, - LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread"; + LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread -lws2_32"; AC_DEFINE([UI_WIN32], 1, [Defined if Win32 UI in use]) AC_DEFINE([WINVER], 0x0400, [Minimal supported version of Windows is 95 or NT4]) AC_DEFINE([_WIN32_IE], 0x400, [Internet Explorer is 4.0 or higher is required]) Index: compat.h =================================================================== --- compat.h (revision 4529) +++ compat.h (working copy) @@ -31,6 +31,10 @@ #include #include +#ifdef WIN32 +#include +#endif /* #ifdef WIN32 */ + /* Remove the gcc-specific incantations if we're not using gcc */ #ifdef __GNUC__ @@ -129,6 +133,8 @@ extern const compat_socket_t compat_socket_invalid; +int compat_networking_init( void ); +void compat_networking_end( void ); int compat_socket_close( compat_socket_t fd ); int compat_socket_get_error( void ); Index: compat/win32/socket.c =================================================================== --- compat/win32/socket.c (revision 4529) +++ compat/win32/socket.c (working copy) @@ -32,6 +32,35 @@ const compat_socket_t compat_socket_invalid = INVALID_SOCKET; int +compat_networking_init( void ) +{ + WORD wVersionRequested; + WSADATA wsaData; + int error; + + wVersionRequested = MAKEWORD( 2, 2 ); + error = WSAStartup( wVersionRequested, &wsaData ); + if( error ) { + return 1; + } + + printf("WSAStartup\n"); + if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { + WSACleanup(); + return 2; + } + + return 0; +} + +void +compat_networking_end( void ) +{ + printf("WSACleanup\n"); + WSACleanup(); +} + +int compat_socket_close( compat_socket_t fd ) { return closesocket( fd ); Index: compat/unix/socket.c =================================================================== --- compat/unix/socket.c (revision 4529) +++ compat/unix/socket.c (working copy) @@ -33,6 +33,17 @@ const compat_socket_t compat_socket_invalid = -1; int +compat_networking_init( void ) +{ + return 0; +} + +void +compat_networking_end( void ) +{ +} + +int compat_socket_close( compat_socket_t fd ) { return close( fd );