Thread: [complement-svn] SF.net SVN: complement: [1829] branches/complement-sockios/explore
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2008-03-06 19:50:08
|
Revision: 1829 http://complement.svn.sourceforge.net/complement/?rev=1829&view=rev Author: complement Date: 2008-03-06 11:42:31 -0800 (Thu, 06 Mar 2008) Log Message: ----------- const casts for pthread_cond_* calls; add semaphore.h Modified Paths: -------------- branches/complement-sockios/explore/include/mt/condition_variable branches/complement-sockios/explore/lib/mt/ChangeLog Modified: branches/complement-sockios/explore/include/mt/condition_variable =================================================================== --- branches/complement-sockios/explore/include/mt/condition_variable 2008-02-28 18:15:40 UTC (rev 1828) +++ branches/complement-sockios/explore/include/mt/condition_variable 2008-03-06 19:42:31 UTC (rev 1829) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/02/25 13:09:15 ptr> +// -*- C++ -*- Time-stamp: <08/03/06 13:23:11 ptr> /* * Copyright (c) 1997-1999, 2002-2008 @@ -24,7 +24,11 @@ #include <mt/date_time> #include <mt/mutex> +#ifdef __FIT_PTHREADS +# include <semaphore.h> +#endif + namespace std { namespace tr2 { @@ -97,7 +101,7 @@ lock.lock(); #endif #ifdef __FIT_PTHREADS - int ret = pthread_cond_wait( &_cond, &lock.m->_M_lock ); + int ret = pthread_cond_wait( &_cond, const_cast<pthread_mutex_t *>(&lock.m->_M_lock) ); if ( ret ) { lock.lock(); // throw system_error @@ -119,7 +123,7 @@ ::timespec t; t.tv_sec = abs_time.seconds_since_epoch(); t.tv_nsec = static_cast<long>( abs_time.nanoseconds_since_epoch().count() % nanoseconds::ticks_per_second ); - int ret = pthread_cond_timedwait( &_cond, &lock.m->_M_lock, &t ); + int ret = pthread_cond_timedwait( &_cond, const_cast<pthread_mutex_t *>(&lock.m->_M_lock), &t ); if ( ret != 0 ) { if ( ret == ETIMEDOUT ) { return false; Modified: branches/complement-sockios/explore/lib/mt/ChangeLog =================================================================== --- branches/complement-sockios/explore/lib/mt/ChangeLog 2008-02-28 18:15:40 UTC (rev 1828) +++ branches/complement-sockios/explore/lib/mt/ChangeLog 2008-03-06 19:42:31 UTC (rev 1829) @@ -1,3 +1,8 @@ +2008-03-06 Petr Ovtchenkov <pt...@is...> + + * condition_variable: const casts for pthread_cond_* calls; + add semaphore.h. + 2008-02-26 Petr Ovtchenkov <pt...@is...> * thread, mutex, condition_variable, date_time: implementation This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-03-11 15:03:58
|
Revision: 1833 http://complement.svn.sourceforge.net/complement/?rev=1833&view=rev Author: complement Date: 2008-03-11 08:03:22 -0700 (Tue, 11 Mar 2008) Log Message: ----------- core implementation of new sockstream, that based on epoll and has uniform sockets management Modified Paths: -------------- branches/complement-sockios/explore/lib/sockios/Makefile.inc branches/complement-sockios/explore/lib/sockios/ut/Makefile.inc branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc Added Paths: ----------- branches/complement-sockios/explore/include/sockios/sockstream2 branches/complement-sockios/explore/include/sockios/sockstream2.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/_sp.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h Copied: branches/complement-sockios/explore/include/sockios/sockstream2 (from rev 1828, branches/complement-sockios/explore/include/sockios/sockstream) =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream2 (rev 0) +++ branches/complement-sockios/explore/include/sockios/sockstream2 2008-03-11 15:03:22 UTC (rev 1833) @@ -0,0 +1,766 @@ +// -*- C++ -*- Time-stamp: <08/03/07 01:16:27 ptr> + +/* + * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 + * Petr Ovtchenkov + * + * Portion Copyright (c) 1999-2001 + * Parallel Graphics Ltd. + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#ifndef __SOCKIOS_SOCKSTREAM2 +#define __SOCKIOS_SOCKSTREAM2 + +#ifndef __config_feature_h +#include <config/feature.h> +#endif + +#if !defined(__sun) && !defined(_WIN32) // i.e. __linux and __hpux +#include <sys/poll.h> // pollfd +#endif + +#include <mt/mutex> +#include <mt/condition_variable> +#include <mt/date_time> + +#include <netdb.h> +#include <netinet/in.h> + +#include <iosfwd> +#include <ios> +#include <streambuf> +#include <iostream> +#include <string> +#include <stdexcept> + +#ifdef WIN32 +# include <winsock2.h> +#else // WIN32 +# include <unistd.h> +# include <sys/types.h> +# if defined(__hpux) && !defined(_INCLUDE_XOPEN_SOURCE_EXTENDED) +# define _INCLUDE_XOPEN_SOURCE_EXTENDED +# endif +# include <sys/socket.h> +# if !defined(__UCLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +# include <stropts.h> +# endif +# ifdef __sun +# include <sys/conf.h> +# endif +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +# ifdef __hpux +// # ifndef socklen_t // HP-UX 10.01 +// typedef int socklen_t; +// # endif +# endif +# include <cerrno> +#endif // !WIN32 + +#include <sockios/netinfo.h> + +#ifdef STLPORT +_STLP_BEGIN_NAMESPACE +#else +namespace std { +#endif + +class sock_base2 +{ + public: + typedef unsigned long shutdownflg; +#ifdef __unix + typedef int socket_type; +#endif +#ifdef WIN32 + typedef SOCKET socket_type; +#endif + + enum stype { + sock_stream = SOCK_STREAM, // stream socket + sock_dgram = SOCK_DGRAM, // datagram socket + sock_raw = SOCK_RAW, // raw-protocol interface + sock_rdm = SOCK_RDM, // reliably-delivered message + sock_seqpacket = SOCK_SEQPACKET // sequenced packet stream + }; + + enum protocol { + local, // local to host (pipes, portals) + inet // internetwork: UDP, TCP, etc. + }; + + // Option flags per-socket. + enum so_t { + so_debug = SO_DEBUG, // turn on debugging info recording +#ifndef __linux + so_acceptconn = SO_ACCEPTCONN, // socket has had listen() +#endif + so_reuseaddr = SO_REUSEADDR, // allow local address reuse + so_keepalive = SO_KEEPALIVE, // keep connections alive + so_dontroute = SO_DONTROUTE, // just use interface addresses + so_broadcast = SO_BROADCAST, // permit sending of broadcast msgs +#ifndef __linux + so_useloopback = SO_USELOOPBACK, // bypass hardware when possible +#endif + so_linger = SO_LINGER, // linger on close if data present + so_oobinline = SO_OOBINLINE, // leave received OOB data in line + // Additional options, not kept in so_options. + so_sndbuf = SO_SNDBUF, // send buffer size + so_rcvbuf = SO_RCVBUF, // receive buffer size + so_sndlowat = SO_SNDLOWAT, // send low-water mark + so_rcvlowat = SO_RCVLOWAT, // receive low-water mark + so_sndtimeo = SO_SNDTIMEO, // send timeout + so_rcvtimeo = SO_RCVTIMEO, // receive timeout + so_error = SO_ERROR, // get error status and clear + so_type = SO_TYPE // get socket type +#ifdef __sun // indeed HP-UX 11.00 also has it, but 10.01 not + , + so_prototype = SO_PROTOTYPE // get/set protocol type +#endif + }; + + // Level number for (get/set)sockopt() to apply to socket itself. +// enum _level { +// sol_socket = SOL_SOCKET +// }; + + enum shutdownflags { + stop_in = 0x1, + stop_out = 0x2 + }; + +#ifdef WIN32 + class Init + { + // sometimes I need Init outside sock_base... + // private: + public: + __FIT_DECLSPEC Init(); + __FIT_DECLSPEC ~Init(); + + friend class sock_base; + }; + + protected: + __FIT_DECLSPEC sock_base(); + __FIT_DECLSPEC ~sock_base(); +#endif +}; + +class socket_timeout : + public std::exception +{ + public: + socket_timeout() + { } + + virtual char const *what() throw() + { return "socket timeout"; } +}; + +class socket_read_timeout : + public socket_timeout +{ + public: + socket_read_timeout() + { } + + virtual char const *what() throw() + { return "socket read timeout"; } +}; + +class socket_write_timeout : + public socket_timeout +{ + public: + socket_write_timeout() + { } + + virtual char const *what() throw() + { return "socket write timeout"; } +}; + +namespace detail { +template <class charT, class traits, class _Alloc> class sockmgr; +} // namespace detail + +template<class charT, class traits, class _Alloc> +class basic_socket +{ + protected: + basic_socket() : + _fd( -1 ), + _use_rdtimeout( false ), + _use_wrtimeout( false ), + _notify_close( false ) + { new( Init_buf ) Init(); } + + ~basic_socket() + { ((Init *)Init_buf)->~Init(); } + + bool is_open_unsafe() const + { return _fd != -1; } + sock_base2::socket_type fd_unsafe() const + { return _fd; } + + class Init + { + public: + Init() + { _guard( 1 ); } + ~Init() + { _guard( 0 ); } + + private: + static void _guard( int direction ); + static void __at_fork_prepare(); + static void __at_fork_child(); + static void __at_fork_parent(); + static int _count; + }; + + static char Init_buf[]; + + public: +#ifdef WIN32 + typedef u_short family_type; +#else +# ifdef sa_family_t + typedef sa_family_t family_type; +# else // HP-UX 10.01 + typedef unsigned short family_type; +# endif +#endif + + template <class Duration> + void rdtimeout( const Duration& ); + void rdtimeout() // infinite + { _use_rdtimeout = false; } + + template <class Duration> + void wrtimeout( const Duration& ); + void wrtimeout() // infinite + { _use_wrtimeout = false; } + + sock_base2::socket_type fd() const { return _fd;} + bool is_open() const + { return _fd != -1; } + + family_type family() const + { return /* is_open() ? */ _address.any.sa_family /* : 0 */; } + + int port() const + { return /* is_open() && */ _address.any.sa_family == AF_INET ? _address.inet.sin_port : 0; } + + unsigned long inet_addr() const + { return /* is_open() && */ _address.any.sa_family == AF_INET ? _address.inet.sin_addr.s_addr : 0; } + + const sockaddr_in& inet_sockaddr() const throw( std::domain_error ) + { + if ( _address.any.sa_family != AF_INET ) { + throw domain_error( "socket not belongs to inet type" ); + } + return /* is_open() && */ _address.inet; + } + + protected: + sock_base2::socket_type _fd; + + union sockaddr_t { + sockaddr_in inet; + sockaddr any; + } _address; + + std::tr2::milliseconds _rdtimeout; + std::tr2::milliseconds _wrtimeout; + bool _use_rdtimeout; + bool _use_wrtimeout; + bool _notify_close; + + static detail::sockmgr<charT,traits,_Alloc>* mgr; + friend class Init; +}; + +template<class charT, class traits, class _Alloc> +int basic_socket<charT,traits,_Alloc>::Init::_count = 0; + +template<class charT, class traits, class _Alloc> +void basic_socket<charT,traits,_Alloc>::Init::_guard( int direction ) +{ + static std::tr2::mutex _init_lock; + + if ( direction ) { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( _count++ == 0 ) { + basic_socket<charT,traits,_Alloc>::mgr = new detail::sockmgr<charT,traits,_Alloc>(); +// #ifdef __FIT__PTHREADS +// pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ); +// #endif +// _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); + } + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( --_count == 0 ) { + delete basic_socket<charT,traits,_Alloc>::mgr; + } + } +} + +template<class charT, class traits, class _Alloc> +void basic_socket<charT,traits,_Alloc>::Init::__at_fork_prepare() +{ } + +template<class charT, class traits, class _Alloc> +void basic_socket<charT,traits,_Alloc>::Init::__at_fork_child() +{ + if ( _count != 0 ) { + // stop mgr + delete basic_socket<charT,traits,_Alloc>::mgr; + basic_socket<charT,traits,_Alloc>::mgr = new detail::sockmgr<charT,traits,_Alloc>(); + } + // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); +} + +template<class charT, class traits, class _Alloc> +void basic_socket<charT,traits,_Alloc>::Init::__at_fork_parent() +{ } + +template<class charT, class traits, class _Alloc> +char basic_socket<charT,traits,_Alloc>::Init_buf[128]; + +template <class charT, class traits, class _Alloc> +detail::sockmgr<charT,traits,_Alloc>* basic_socket<charT,traits,_Alloc>::mgr; + +#ifdef STLPORT +_STLP_END_NAMESPACE +#else +} // namespace std +#endif + +#include <sockios/sp.h> + +#ifdef STLPORT +_STLP_BEGIN_NAMESPACE +#else +namespace std { +#endif + +template<class charT, class traits, class _Alloc> +class basic_sockbuf2 : + public basic_streambuf<charT, traits>, + public basic_socket<charT,traits,_Alloc> +{ + private: + typedef basic_socket<charT,traits,_Alloc> basic_socket_t; + + public: + typedef basic_ios<charT, traits> ios_type; + typedef basic_sockbuf2<charT, traits, _Alloc> sockbuf_type; + typedef typename traits::state_type state_t; + + public: + /* Inherited from basic_streambuf : */ + typedef charT char_type; + typedef typename traits::int_type int_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + typedef traits traits_type; + /* */ + + basic_sockbuf2() : + rdready( *this ), +#if !defined(STLPORT) && defined(__GNUC__) +#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) // hmm, 3.3.6 + _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), +#else // 4.1.1 + _mode( _S_in | _S_out ), +#endif // __GNUC__ +#else // STLPORT + _mode( 0 ), +#endif // STLPORT + _bbuf(0), + _ebuf(0), + _allocated( true ) + { } + + basic_sockbuf2( const char *hostname, int port, + sock_base2::stype type = sock_base2::sock_stream, + sock_base2::protocol prot = sock_base2::inet ) : + rdready( *this ), +#if !defined(STLPORT) && defined(__GNUC__) +#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) + _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), +#else // 4.1.1 + _mode( _S_in | _S_out ), +#endif // __GNUC__ +#else // STLPORT + _mode( 0 ), +#endif // STLPORT + _bbuf(0), + _ebuf(0), + _allocated( true ) + { open( hostname, port, type, prot ); } + + basic_sockbuf2( const in_addr& addr, int port, + sock_base2::stype type = sock_base2::sock_stream, + sock_base2::protocol prot = sock_base2::inet ) : + rdready( *this ), +#if !defined(STLPORT) && defined(__GNUC__) +#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) + _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), +#else // 4.1.1 + _mode( _S_in | _S_out ), +#endif // __GNUC__ +#else // STLPORT + _mode( 0 ), +#endif // STLPORT + _bbuf(0), + _ebuf(0), + _allocated( true ) + { open( addr, type, prot ); } + + virtual ~basic_sockbuf2() + { + close(); + _M_deallocate_block(); + } + + sockbuf_type *open( const char *hostname, int port, + sock_base2::stype type = sock_base2::sock_stream, + sock_base2::protocol prot = sock_base2::inet ); + + sockbuf_type *open( const in_addr& addr, int port, + sock_base2::stype type = sock_base2::sock_stream, + sock_base2::protocol prot = sock_base2::inet ); + + sockbuf_type *open( sock_base2::socket_type s, + sock_base2::stype t = sock_base2::sock_stream ); + + sockbuf_type *open( sock_base2::socket_type s, const sockaddr& addr, + sock_base2::stype t = sock_base2::sock_stream ); + + sockbuf_type *attach( sock_base2::socket_type s, + sock_base2::stype t = sock_base2::sock_stream ); + + sockbuf_type *attach( sock_base2::socket_type s, const sockaddr& addr, + sock_base2::stype t = sock_base2::sock_stream ); + + sockbuf_type *close(); + void shutdown( sock_base2::shutdownflg dir ); + + sock_base2::stype stype() const + { return _type; } + + protected: + virtual streamsize showmanyc() + { return this->egptr() - this->gptr(); } + + virtual int_type underflow(); + virtual int_type overflow( int_type c = traits::eof() ); + virtual int_type pbackfail( int_type c = traits::eof() ) + { + if ( !basic_socket_t::is_open() ) + return traits::eof(); + + if ( this->gptr() <= this->eback() ) { + return traits::eof(); + } + + this->gbump(-1); + if ( !traits::eq_int_type(c,traits::eof()) ) { + *this->gptr() = traits::to_char_type(c); + return c; + } + + return traits::not_eof(c); + } + + // Buffer managment and positioning: + virtual basic_streambuf<charT, traits> *setbuf(char_type *s, streamsize n ) + { + if ( s != 0 && n != 0 ) { + _M_deallocate_block(); + _allocated = false; + _bbuf = s; + _ebuf = s + n; + } + return this; + } + + virtual int sync(); + virtual streamsize xsputn(const char_type *s, streamsize n); + + private: // Helper functions + charT* _bbuf; + charT* _ebuf; + bool _allocated; // true, if _bbuf should be deallocated + + // Precondition: 0 < __n <= max_size(). + charT* _M_allocate( size_t __n ) { return _M_data_allocator.allocate(__n); } + void _M_deallocate( charT* __p, size_t __n ) + { if (__p) _M_data_allocator.deallocate(__p, __n); } + + void _M_allocate_block(size_t __n) + { + if ( _allocated ) { + if ( __n <= max_size() ) { + _bbuf = _M_allocate(__n); + _ebuf = _bbuf + __n; + // _STLP_ASSERT( __n > 0 ? _bbuf != 0 : _bbuf == 0 ); + } else + this->_M_throw_length_error(); + } + } + + void _M_deallocate_block() + { if ( _allocated ) _M_deallocate(_bbuf, _ebuf - _bbuf); } + + size_t max_size() const { return (size_t(-1) / sizeof(charT)) - 1; } + +#ifdef STLPORT + void _M_throw_length_error() const + { _STLP_THROW(length_error("basic_sockbuf2")); } +#else + void _M_throw_length_error() const + { throw length_error("basic_sockbuf2"); } +#endif + +#ifdef STLPORT + typedef typename _Alloc_traits<charT, _Alloc>::allocator_type allocator_type; +#else + typedef _Alloc allocator_type; +#endif + /* typedef __allocator<charT, _Alloc> _Alloc_type; */ + + /* _Alloc_type */ allocator_type _M_data_allocator; + + class rdready_t + { + public: + rdready_t( sockbuf_type& self ) : + b( self ) + { } + bool operator ()() const + { return b.showmanyc() != 0; } + private: + sockbuf_type& b; + } rdready; + + sockbuf_type *_open_sockmgr( sock_base2::socket_type s, const sockaddr& addr, + sock_base2::stype t = sock_base2::sock_stream ); + + private: + typedef basic_sockbuf2<charT,traits,_Alloc> _Self_type; + int (basic_sockbuf2<charT,traits,_Alloc>::*_xwrite)( const void *, size_t ); + int (basic_sockbuf2<charT,traits,_Alloc>::*_xread)( void *, size_t ); + int write( const void *buf, size_t n ) +#ifndef WIN32 + { return ::write( basic_socket_t::_fd, buf, n ); } +#else + { return ::send( basic_socket_t::_fd, (const char *)buf, n, 0 ); } +#endif + int send( const void *buf, size_t n ) +#ifdef WIN32 + { return ::send( basic_socket_t::_fd, (const char *)buf, n, 0 ); } +#else + { return ::send( basic_socket_t::_fd, buf, n, 0 ); } +#endif + int sendto( const void *buf, size_t n ) +#ifdef WIN32 + { return ::sendto( basic_socket_t::_fd, (const char *)buf, n, 0, &basic_socket_t::_address.any, sizeof( sockaddr_in ) ); } +#else + { return ::sendto( basic_socket_t::_fd, buf, n, 0, &basic_socket_t::_address.any, sizeof( sockaddr_in ) ); } +#endif + + int read( void *buf, size_t n ) +#ifdef WIN32 + { return ::recv( basic_socket_t::_fd, (char *)buf, n, 0 ); } +#else + { return ::read( basic_socket_t::_fd, buf, n ); } +#endif + int recv( void *buf, size_t n ) +#ifdef WIN32 + { return ::recv( basic_socket_t::_fd, (char *)buf, n, 0 ); } +#else + { return ::recv( basic_socket_t::_fd, buf, n, 0 ); } +#endif + int recvfrom( void *buf, size_t n ); + void __hostname(); + + ios_base::openmode _mode; + sock_base2::stype _type; + + std::tr2::mutex ulck; + std::tr2::condition_variable ucnd; + + friend class detail::sockmgr<charT,traits,_Alloc>; +}; + +template <class charT, class traits, class _Alloc> +class basic_sockstream2 : + public sock_base2, + public basic_iostream<charT,traits> +{ + public: + /* Inherited from basic_iostream + typedef charT char_type; + typedef typename traits::int_type int_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + */ + basic_sockstream2() : + sock_base2(), + basic_iostream<charT,traits>( 0 ) + { basic_ios<charT,traits>::init(&_sb); } + basic_sockstream2( const char *hostname, int port, + sock_base2::stype type = sock_base2::sock_stream, + sock_base2::protocol pro = sock_base2::inet ) : + sock_base2(), + basic_iostream<charT,traits>( 0 ) + { + basic_ios<charT,traits>::init(&_sb); + basic_iostream<charT,traits>::clear(); + if ( _sb.open( hostname, port, type, pro ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + basic_sockstream2( const in_addr& addr, int port, + sock_base2::stype type = sock_base2::sock_stream, + sock_base2::protocol pro = sock_base2::inet ) : + sock_base2(), + basic_iostream<charT,traits>( 0 ) + { + basic_ios<charT,traits>::init(&_sb); + basic_iostream<charT,traits>::clear(); + if ( _sb.open( addr, port, type, pro ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + basic_sockstream2( sock_base2::socket_type s, const sockaddr& addr, + sock_base2::stype type = sock_base2::sock_stream ) : + sock_base2(), + basic_iostream<charT,traits>( 0 ) + { + basic_ios<charT,traits>::init(&_sb); + basic_iostream<charT,traits>::clear(); + if ( _sb.open( s, addr, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + basic_sockstream2( sock_base2::socket_type s, + sock_base2::stype type = sock_base2::sock_stream ) : + sock_base2(), + basic_iostream<charT,traits>( 0 ) + { + basic_ios<charT,traits>::init(&_sb); + basic_iostream<charT,traits>::clear(); + if ( _sb.open( s, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + basic_sockbuf2<charT,traits,_Alloc>* rdbuf() const + { return const_cast<basic_sockbuf2<charT,traits,_Alloc>*>(&_sb); } + + bool is_open() const + { return _sb.is_open(); } + + void open( const char *hostname, int port, + sock_base2::stype type = sock_base2::sock_stream, + sock_base2::protocol pro = sock_base2::inet ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.open( hostname, port, type, pro ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void open( const in_addr& addr, int port, + sock_base2::stype type = sock_base2::sock_stream, + sock_base2::protocol pro = sock_base2::inet ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.open( addr, port, type, pro ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + // only for sock_stream : inet now! + void open( sock_base2::socket_type s, const sockaddr& addr, + sock_base2::stype type = sock_base2::sock_stream ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.open( s, addr, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void open( sock_base2::socket_type s, + sock_base2::stype type = sock_base2::sock_stream ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.open( s, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void attach( sock_base2::socket_type s, const sockaddr& addr, + sock_base2::stype type = sock_base2::sock_stream ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.attach( s, addr, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void attach( sock_base2::socket_type s, + sock_base2::stype type = sock_base2::sock_stream ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.attach( s, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void close() + { + if ( _sb.is_open() ) { + if ( _sb.close() == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit ); + } else { + basic_iostream<charT,traits>::clear(); + } + } + } + + void setoptions( sock_base2::so_t optname, bool on_off = true, + int __v = 0 ); + + private: + basic_sockbuf2<charT,traits,_Alloc> _sb; +}; + +typedef basic_sockbuf2<char,char_traits<char>,allocator<char> > sockbuf2; +// typedef basic_sockbuf2<wchar_t,char_traits<wchar_t>,allocator<wchar_t> > wsockbuf; +typedef basic_sockstream2<char,char_traits<char>,allocator<char> > sockstream2; +// typedef basic_sockstream<wchar_t,char_traits<wchar_t>,allocator<wchar_t> > wsockstream; + +#ifdef STLPORT +_STLP_END_NAMESPACE +#else +} // namespace std +#endif + +#ifndef __STL_LINK_TIME_INSTANTIATION +#include <sockios/sockstream2.cc> +#endif + +#endif // __SOCKIOS_SOCKSTREAM2 Copied: branches/complement-sockios/explore/include/sockios/sockstream2.cc (from rev 1828, branches/complement-sockios/explore/include/sockios/sockstream.cc) =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream2.cc (rev 0) +++ branches/complement-sockios/explore/include/sockios/sockstream2.cc 2008-03-11 15:03:22 UTC (rev 1833) @@ -0,0 +1,541 @@ +// -*- C++ -*- Time-stamp: <08/03/07 01:16:27 ptr> + +/* + * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 + * Petr Ovtchenkov + * + * Portion Copyright (c) 1999-2001 + * Parallel Graphics Ltd. + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#include <sockios/netinfo.h> + +#if defined(__unix) && !defined(__UCLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +# include <stropts.h> // for ioctl() call +#endif + +#include <fcntl.h> + +#ifdef STLPORT +_STLP_BEGIN_NAMESPACE +#else +namespace std { +#endif + +template<class charT, class traits, class _Alloc> +basic_sockbuf2<charT, traits, _Alloc> * +basic_sockbuf2<charT, traits, _Alloc>::open( const char *name, int port, + sock_base2::stype type, + sock_base2::protocol prot ) +{ return basic_sockbuf2<charT, traits, _Alloc>::open( std::findhost( name ), port, type, prot ); } + +template<class charT, class traits, class _Alloc> +basic_sockbuf2<charT, traits, _Alloc> * +basic_sockbuf2<charT, traits, _Alloc>::open( const in_addr& addr, int port, + sock_base2::stype type, + sock_base2::protocol prot ) +{ + if ( basic_socket_t::is_open() ) { + return 0; + } + try { + _mode = ios_base::in | ios_base::out; + _type = type; +#ifdef WIN32 + WSASetLastError( 0 ); +#endif + if ( prot == sock_base2::inet ) { + basic_socket_t::_fd = socket( PF_INET, type, 0 ); + if ( basic_socket_t::_fd == -1 ) { + throw std::runtime_error( "can't open socket" ); + } + basic_socket_t::_address.inet.sin_family = AF_INET; + // htons is a define at least in Linux 2.2.5-15, and it's expantion fail + // for gcc 2.95.3 +#if defined(linux) && defined(htons) && defined(__bswap_16) + basic_socket_t::_address.inet.sin_port = ((((port) >> 8) & 0xff) | (((port) & 0xff) << 8)); +#else + basic_socket_t::_address.inet.sin_port = htons( port ); +#endif // linux && htons + basic_socket_t::_address.inet.sin_addr = addr; + + // Generally, stream sockets may successfully connect() only once + if ( connect( basic_socket_t::_fd, &basic_socket_t::_address.any, sizeof( basic_socket_t::_address ) ) == -1 ) { + throw std::domain_error( "connect fail" ); + } + if ( type == sock_base2::sock_stream ) { + _xwrite = &_Self_type::write; + _xread = &_Self_type::read; + } else if ( type == sock_base2::sock_dgram ) { + _xwrite = &_Self_type::send; + _xread = &_Self_type::recv; + } + } else if ( prot == sock_base2::local ) { + basic_socket_t::_fd = socket( PF_UNIX, type, 0 ); + if ( basic_socket_t::_fd == -1 ) { + throw std::runtime_error( "can't open socket" ); + } + } else { // other protocols not implemented yet + throw std::invalid_argument( "protocol not implemented" ); + } + + if ( _bbuf == 0 ) { + struct ifconf ifc; + struct ifreq ifr; + ifc.ifc_len = sizeof(ifreq); + ifc.ifc_req = 𝔦 + int mtu = ((ioctl(basic_socket_t::_fd, SIOCGIFMTU, &ifc) < 0 ? 1500 : ifr.ifr_mtu) - 20 - (type == sock_base2::sock_stream ? 20 : 8 )) / sizeof(charT); + int qlen = ioctl(basic_socket_t::_fd, SIOCGIFTXQLEN, &ifc) < 0 ? 2 : ifr.ifr_qlen; + _M_allocate_block( type == sock_base2::sock_stream ? mtu * qlen * 2 : mtu * 2 ); + } + + if ( _bbuf == 0 ) { + throw std::length_error( "can't allocate block" ); + } + + if ( fcntl( basic_socket_t::_fd, F_SETFL, fcntl( basic_socket_t::_fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + throw std::runtime_error( "can't establish nonblock mode" ); + } + setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); + setg( this->epptr(), this->epptr(), this->epptr() ); + basic_socket_t::_notify_close = true; + basic_socket_t::mgr->push( *this ); + } + catch ( std::domain_error& ) { +#ifdef WIN32 + // _errno = WSAGetLastError(); + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return 0; + } + catch ( std::length_error& ) { +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return 0; + } + catch ( std::runtime_error& ) { +#ifdef WIN32 + // _errno = WSAGetLastError(); +#else +#endif + return 0; + } + catch ( std::invalid_argument& ) { + return 0; + } + + return this; +} + +template<class charT, class traits, class _Alloc> +basic_sockbuf2<charT, traits, _Alloc> * +basic_sockbuf2<charT, traits, _Alloc>::open( sock_base2::socket_type s, sock_base2::stype t ) +{ + if ( basic_socket_t::is_open() || s == -1 ) { + return 0; + } + + sockaddr sa; + socklen_t sl = sizeof(sa); + getsockname( s, &sa, &sl ); + + return basic_sockbuf<charT, traits, _Alloc>::open( s, sa, t ); +} + +template<class charT, class traits, class _Alloc> +basic_sockbuf2<charT, traits, _Alloc> * +basic_sockbuf2<charT, traits, _Alloc>::open( sock_base2::socket_type s, + const sockaddr& addr, + sock_base2::stype t ) +{ + basic_sockbuf2<charT, traits, _Alloc>* ret = _open_sockmgr( s, addr, t ); + if ( ret != 0 ) { + basic_socket_t::_notify_close = true; + basic_socket_t::mgr->push( *this ); + } + return ret; +} + +template<class charT, class traits, class _Alloc> +basic_sockbuf2<charT, traits, _Alloc> * +basic_sockbuf2<charT, traits, _Alloc>::_open_sockmgr( sock_base2::socket_type s, + const sockaddr& addr, + sock_base2::stype t ) +{ + if ( basic_socket_t::is_open() || s == -1 ) { + return 0; + } + basic_socket_t::_fd = s; + memcpy( (void *)&basic_socket_t::_address.any, (const void *)&addr, sizeof(sockaddr) ); + _mode = ios_base::in | ios_base::out; + _type = t; +#ifdef WIN32 + WSASetLastError( 0 ); +#endif + if ( t == sock_base2::sock_stream ) { + _xwrite = &_Self_type::write; + _xread = &_Self_type::read; + } else if ( t == sock_base2::sock_dgram ) { + _xwrite = &_Self_type::sendto; + _xread = &_Self_type::recvfrom; + } else { + basic_socket_t::_fd = -1; + return 0; // unsupported type + } + + if ( _bbuf == 0 ) { + struct ifconf ifc; + struct ifreq ifr; + ifc.ifc_len = sizeof(ifreq); + ifc.ifc_req = 𝔦 + int mtu = ((ioctl(basic_socket_t::_fd, SIOCGIFMTU, &ifc) < 0 ? 1500 : ifr.ifr_mtu) - 20 - (t == sock_base2::sock_stream ? 20 : 8 )) / sizeof(charT); + int qlen = ioctl(basic_socket_t::_fd, SIOCGIFTXQLEN, &ifc) < 0 ? 2 : ifr.ifr_qlen; + _M_allocate_block( t == sock_base2::sock_stream ? mtu * qlen * 2 : mtu * 2); + } + + if ( _bbuf == 0 ) { +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return 0; + } + + if ( fcntl( basic_socket_t::_fd, F_SETFL, fcntl( basic_socket_t::_fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + throw std::runtime_error( "can't establish nonblock mode" ); + } + setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); + setg( this->epptr(), this->epptr(), this->epptr() ); + + return this; +} + +template<class charT, class traits, class _Alloc> +basic_sockbuf2<charT, traits, _Alloc> * +basic_sockbuf2<charT, traits, _Alloc>::attach( sock_base2::socket_type s, + sock_base2::stype t ) +{ + if ( basic_socket_t::is_open() || s == -1 ) { + return 0; + } + + sockaddr sa; + socklen_t sl = sizeof(sa); + getsockname( s, &sa, &sl ); + + return basic_sockbuf<charT, traits, _Alloc>::attach( s, sa, t ); +} + +template<class charT, class traits, class _Alloc> +basic_sockbuf2<charT, traits, _Alloc> * +basic_sockbuf2<charT, traits, _Alloc>::attach( sock_base2::socket_type s, + const sockaddr& addr, + sock_base2::stype t ) +{ + if ( basic_socket_t::is_open() || s == -1 ) { + return 0; + } + + // _doclose = false; + return basic_sockbuf2<charT, traits, _Alloc>::open( dup(s), addr, t ); +} + +template<class charT, class traits, class _Alloc> +basic_sockbuf2<charT, traits, _Alloc> * +basic_sockbuf2<charT, traits, _Alloc>::close() +{ + if ( !basic_socket_t::is_open() ) + return 0; + + // if ( _doclose ) { +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + // } + + // _STLP_ASSERT( _bbuf != 0 ); + // put area before get area + setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); + setg( this->epptr(), this->epptr(), this->epptr() ); + + if ( basic_socket_t::_notify_close ) { + basic_socket_t::mgr->exit_notify( this, basic_socket_t::_fd ); + basic_socket_t::_notify_close = false; + } + + basic_socket_t::_fd = -1; + + return this; +} + +template<class charT, class traits, class _Alloc> +void basic_sockbuf2<charT, traits, _Alloc>::shutdown( sock_base2::shutdownflg dir ) +{ + if ( basic_socket_t::is_open() ) { + if ( (dir & (sock_base2::stop_in | sock_base2::stop_out)) == + (sock_base2::stop_in | sock_base2::stop_out) ) { + ::shutdown( basic_socket_t::_fd, 2 ); + } else if ( dir & sock_base2::stop_in ) { + ::shutdown( basic_socket_t::_fd, 0 ); + } else if ( dir & sock_base2::stop_out ) { + ::shutdown( basic_socket_t::_fd, 1 ); + } + } +} + +template<class charT, class traits, class _Alloc> +__FIT_TYPENAME basic_sockbuf2<charT, traits, _Alloc>::int_type +basic_sockbuf2<charT, traits, _Alloc>::underflow() +{ + if( !basic_socket_t::is_open() ) + return traits::eof(); + + std::tr2::unique_lock<std::tr2::mutex> lk( ulck ); + + if ( this->gptr() < this->egptr() ) + return traits::to_int_type(*this->gptr()); + + if ( this->egptr() == this->gptr() ) { // fullfilled: _ebuf == gptr() + setg( this->eback(), this->eback(), this->eback() ); + } + + // setg( this->eback(), this->eback(), this->eback() + offset ); + // wait on condition + if ( basic_socket_t::_use_rdtimeout ) { + ucnd.timed_wait( lk, basic_socket_t::_rdtimeout, rdready ); + } else { + ucnd.wait( lk, rdready ); + } + + return traits::to_int_type(*this->gptr()); +} + +template<class charT, class traits, class _Alloc> +__FIT_TYPENAME basic_sockbuf2<charT, traits, _Alloc>::int_type +basic_sockbuf2<charT, traits, _Alloc>::overflow( int_type c ) +{ + if ( !basic_socket_t::is_open() ) + return traits::eof(); + + if ( !traits::eq_int_type( c, traits::eof() ) && this->pptr() < this->epptr() ) { + sputc( traits::to_char_type(c) ); + return c; + } + + long count = this->pptr() - this->pbase(); + + if ( count ) { + count *= sizeof(charT); + long offset = (this->*_xwrite)( this->pbase(), count ); + if ( offset < 0 ) { + if ( errno == EAGAIN ) { + pollfd wpfd; + wpfd.fd = basic_socket_t::_fd; + wpfd.events = POLLOUT | POLLHUP | POLLWRNORM; + wpfd.revents = 0; + while ( poll( &wpfd, 1, basic_socket_t::_use_wrtimeout ? basic_socket_t::_wrtimeout.count() : -1 ) <= 0 ) { // wait infinite + if ( errno == EINTR ) { // may be interrupted, check and ignore + errno = 0; + continue; + } + return traits::eof(); + } + if ( (wpfd.revents & POLLERR) != 0 ) { + return traits::eof(); + } + offset = (this->*_xwrite)( this->pbase(), count ); + if ( offset < 0 ) { + return traits::eof(); + } + } else { + return traits::eof(); + } + } + if ( offset < count ) { + // MUST BE: (offset % sizeof(char_traits)) == 0 ! + offset /= sizeof(charT); + count /= sizeof(charT); + traits::move( this->pbase(), this->pbase() + offset, count - offset ); + // std::copy_backword( this->pbase() + offset, this->pbase() + count, this->pbase() ); + setp( this->pbase(), this->epptr() ); // require: set pptr + this->pbump( count - offset ); + if( !traits::eq_int_type(c,traits::eof()) ) { + sputc( traits::to_char_type(c) ); + } + + return traits::not_eof(c); + } + } + + setp( this->pbase(), this->epptr() ); // require: set pptr + if( !traits::eq_int_type(c,traits::eof()) ) { + sputc( traits::to_char_type(c) ); + } + + return traits::not_eof(c); +} + +template<class charT, class traits, class _Alloc> +int basic_sockbuf2<charT, traits, _Alloc>::sync() +{ + if ( !basic_socket_t::is_open() ) { + return -1; + } + + long count = this->pptr() - this->pbase(); + if ( count ) { + // _STLP_ASSERT( this->pbase() != 0 ); + count *= sizeof(charT); + long start = 0; + while ( count > 0 ) { + long offset = (this->*_xwrite)( this->pbase() + start, count ); + if ( offset < 0 ) { + if ( errno == EAGAIN ) { + pollfd wpfd; + wpfd.fd = basic_socket_t::_fd; + wpfd.events = POLLOUT | POLLHUP | POLLWRNORM; + wpfd.revents = 0; + while ( poll( &wpfd, 1, basic_socket_t::_use_wrtimeout ? basic_socket_t::_wrtimeout.count() : -1 ) <= 0 ) { // wait infinite + if ( errno == EINTR ) { // may be interrupted, check and ignore + errno = 0; + continue; + } + return -1; + } + if ( (wpfd.revents & POLLERR) != 0 ) { + return -1; + } + offset = (this->*_xwrite)( this->pbase() + start, count ); + if ( offset < 0 ) { + return -1; + } + } else { + return -1; + } + } + count -= offset; + start += offset; + } + setp( this->pbase(), this->epptr() ); // require: set pptr + } + + return 0; +} + +template<class charT, class traits, class _Alloc> +streamsize basic_sockbuf2<charT, traits, _Alloc>:: +xsputn( const char_type *s, streamsize n ) +{ + if ( !basic_socket_t::is_open() || s == 0 || n == 0 ) { + return 0; + } + + if ( this->epptr() - this->pptr() > n ) { + traits::copy( this->pptr(), s, n ); + this->pbump( n ); + } else { + streamsize __n_put = this->epptr() - this->pptr(); + traits::copy( this->pptr(), s, __n_put ); + this->pbump( __n_put ); + + if ( traits::eq_int_type(overflow(),traits::eof()) ) + return 0; + + setp( (char_type *)(s + __n_put), (char_type *)(s + n) ); + this->pbump( n - __n_put ); + + if ( traits::eq_int_type(overflow(),traits::eof()) ) { + setp( _bbuf, _bbuf + ((_ebuf - _bbuf) >> 1) ); + return 0; + } + setp( _bbuf, _bbuf + ((_ebuf - _bbuf) >> 1) ); + } + return n; +} + +template<class charT, class traits, class _Alloc> +int basic_sockbuf2<charT, traits, _Alloc>::recvfrom( void *buf, size_t n ) +{ +#if defined(_WIN32) || (defined(__hpux) && !defined(_INCLUDE_POSIX1C_SOURCE)) + int sz = sizeof( sockaddr_in ); +#else + socklen_t sz = sizeof( sockaddr_in ); +#endif + + typename basic_socket_t::sockaddr_t addr; + +#ifdef __FIT_POLL + pollfd pfd; + pfd.fd = basic_socket_t::_fd; + pfd.events = POLLIN; +#endif // __FIT_POLL + do { +#ifdef __FIT_POLL + pfd.revents = 0; + if ( poll( &pfd, 1, /* _timeout */ -1 ) > 0 ) { // wait infinite + // get address of caller only + char buff[32]; + ::recvfrom( basic_socket_t::_fd, buff, 32, MSG_PEEK, &addr.any, &sz ); + } else { + return 0; // poll wait infinite, so it can't return 0 (timeout), so it return -1. + } +#endif // __FIT_POLL + if ( memcmp( &basic_socket_t::_address.inet, &addr.inet, sizeof(sockaddr_in) ) == 0 ) { +#ifdef WIN32 + return ::recvfrom( basic_socket_t::_fd, (char *)buf, n, 0, &basic_socket_t::_address.any, &sz ); +#else + return ::recvfrom( basic_socket_t::_fd, buf, n, 0, &basic_socket_t::_address.any, &sz ); +#endif + } + xmt::Thread::yield(); + } while ( true ); + + return 0; // never +} + +template<class charT, class traits, class _Alloc> +void basic_sockstream2<charT, traits, _Alloc>::setoptions( sock_base2::so_t optname, bool on_off, int __v ) +{ +#ifdef __unix + if ( _sb.is_open() ) { + if ( optname != sock_base2::so_linger ) { + int turn = on_off ? 1 : 0; + if ( setsockopt( _sb.fd(), SOL_SOCKET, (int)optname, (const void *)&turn, + (socklen_t)sizeof(int) ) != 0 ) { + this->setstate( ios_base::failbit ); + } + } else { + linger l; + l.l_onoff = on_off ? 1 : 0; + l.l_linger = __v; + if ( setsockopt( _sb.fd(), SOL_SOCKET, (int)optname, (const void *)&l, + (socklen_t)sizeof(linger) ) != 0 ) { + this->setstate( ios_base::failbit ); + } + } + } else { + this->setstate( ios_base::failbit ); + } +#endif // __unix +} + +#ifdef STLPORT +_STLP_END_NAMESPACE +#else +} // namespace std +#endif + Added: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h (rev 0) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-03-11 15:03:22 UTC (rev 1833) @@ -0,0 +1,697 @@ +// -*- C++ -*- Time-stamp: <08/03/07 01:40:59 ptr> + +/* + * Copyright (c) 2008 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License Version 3.0 + * + */ + +#ifndef __SOCKIOS_SP_H +#define __SOCKIOS_SP_H + +#include <sys/epoll.h> + +#ifndef EPOLLRDHUP +# define EPOLLRDHUP 0x2000 +#endif + +#include <fcntl.h> + +#include <cerrno> +#include <mt/thread> +#include <mt/mutex> + +#ifdef STLPORT +# include <unordered_map> +# include <unordered_set> +// # include <hash_map> +// # include <hash_set> +// # define __USE_STLPORT_HASH +# define __USE_STLPORT_TR1 +#else +# if defined(__GNUC__) && (__GNUC__ < 4) +# include <ext/hash_map> +# include <ext/hash_set> +# define __USE_STD_HASH +# else +# include <tr1/unordered_map> +# include <tr1/unordered_set> +# define __USE_STD_TR1 +# endif +#endif + +#include <sockios/sockstream> + +namespace std { + +template <class charT, class traits, class _Alloc> class basic_sockbuf2; +template <class charT, class traits, class _Alloc> class basic_sockstream2; +template <class charT, class traits, class _Alloc> class sock_processor_base; + +namespace detail { + +template<class charT, class traits, class _Alloc> +class _sock_processor_base : + public sock_base2, + public basic_socket<charT,traits,_Alloc> +{ + private: + typedef basic_socket<charT,traits,_Alloc> basic_socket_t; + + protected: + _sock_processor_base() : + _mode( ios_base::in | ios_base::out ), + _state( ios_base::goodbit ) + { } + + virtual ~_sock_processor_base() + { + _sock_processor_base::close(); + } + + public: + void open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ); + void open( unsigned long addr, int port, sock_base2::stype type, sock_base2::protocol prot ); + void open( int port, sock_base2::stype type, sock_base2::protocol prot ); + + virtual void close(); + + protected: + void setoptions_unsafe( sock_base2::so_t optname, bool on_off = true, int __v = 0 ); + + public: + bool is_open() const + { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); return basic_socket_t::is_open_unsafe(); } + bool good() const + { return _state == ios_base::goodbit; } + + sock_base2::socket_type fd() const + { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); sock_base2::socket_type tmp = basic_socket_t::fd_unsafe(); return tmp; } + + void shutdown( sock_base2::shutdownflg dir ); + void setoptions( sock_base2::so_t optname, bool on_off = true, int __v = 0 ) + { + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + setoptions_unsafe( optname, on_off, __v ); + } + + private: + _sock_processor_base( const _sock_processor_base& ); + _sock_processor_base& operator =( const _sock_processor_base& ); + + private: + unsigned long _mode; // open mode + unsigned long _state; // state flags + + protected: + std::tr2::mutex _fd_lck; + // xmt::condition _loop_cnd; +}; + +template<class charT, class traits, class _Alloc> +void _sock_processor_base<charT,traits,_Alloc>::open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ) +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( basic_socket_t::is_open_unsafe() ) { + return; + } + _mode = ios_base::in | ios_base::out; + _state = ios_base::goodbit; +#ifdef WIN32 + ::WSASetLastError( 0 ); +#endif + if ( prot == sock_base2::inet ) { + basic_socket_t::_fd = socket( PF_INET, type, 0 ); + if ( basic_socket_t::_fd == -1 ) { + _state |= ios_base::failbit | ios_base::badbit; + return; + } + // _open = true; + basic_socket_t::_address.inet.sin_family = AF_INET; + basic_socket_t::_address.inet.sin_port = htons( port ); + basic_socket_t::_address.inet.sin_addr.s_addr = addr.s_addr; + + if ( type == sock_base2::sock_stream || type == sock_base2::sock_seqpacket ) { + // let's try reuse local address + setoptions_unsafe( sock_base2::so_reuseaddr, true ); + } + + if ( ::bind( basic_socket_t::_fd, &basic_socket_t::_address.any, sizeof(basic_socket_t::_address) ) == -1 ) { + _state |= ios_base::failbit; +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return; + } + + if ( type == sock_base2::sock_stream || type == sock_base2::sock_seqpacket ) { + // I am shure, this is socket of type SOCK_STREAM | SOCK_SEQPACKET, + // so don't check return code from listen + ::listen( basic_socket_t::_fd, SOMAXCONN ); + basic_socket_t::mgr->push( dynamic_cast<sock_processor_base<charT,traits,_Alloc>&>(*this) ); + } + } else if ( prot == sock_base2::local ) { + return; + } else { + return; + } + _state = ios_base::goodbit; + + return; +} + +template<class charT, class traits, class _Alloc> +void _sock_processor_base<charT,traits,_Alloc>::open( unsigned long addr, int port, sock_base2::stype type, sock_base2::protocol prot ) +{ + in_addr _addr; + _addr.s_addr = htonl( addr ); + _sock_processor_base::open( _addr, port, type, prot ); +} + +template<class charT, class traits, class _Alloc> +void _sock_processor_base<charT,traits,_Alloc>::open( int port, sock_base2::stype type, sock_base2::protocol prot ) +{ + _sock_processor_base::open(INADDR_ANY, port, type, prot); +} + +template<class charT, class traits, class _Alloc> +void _sock_processor_base<charT,traits,_Alloc>::close() +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( !basic_socket_t::is_open_unsafe() ) { + return; + } +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::shutdown( basic_socket_t::_fd, 2 ); + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; +} + +template<class charT, class traits, class _Alloc> +void _sock_processor_base<charT,traits,_Alloc>::shutdown( sock_base2::shutdownflg dir ) +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( basic_socket_t::is_open_unsafe() ) { + if ( (dir & (sock_base2::stop_in | sock_base2::stop_out)) == + (sock_base2::stop_in | sock_base2::stop_out) ) { + ::shutdown( basic_socket_t::_fd, 2 ); + } else if ( dir & sock_base2::stop_in ) { + ::shutdown( basic_socket_t::_fd, 0 ); + } else if ( dir & sock_base2::stop_out ) { + ::shutdown( basic_socket_t::_fd, 1 ); + } + } +} + +template<class charT, class traits, class _Alloc> +void _sock_processor_base<charT,traits,_Alloc>::setoptions_unsafe( sock_base2::so_t optname, bool on_off, int __v ) +{ +#ifdef __unix + if ( basic_socket_t::is_open_unsafe() ) { + if ( optname != sock_base2::so_linger ) { + int turn = on_off ? 1 : 0; + if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&turn, + (socklen_t)sizeof(int) ) != 0 ) { + _state |= ios_base::failbit; + } + } else { + linger l; + l.l_onoff = on_off ? 1 : 0; + l.l_linger = __v; + if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&l, + (socklen_t)sizeof(linger) ) != 0 ) { + _state |= ios_base::failbit; + } + + } + } else { + _state |= ios_base::failbit; + } +#endif // __unix +} + +} // namespace detail + +template <class charT, class traits, class _Alloc> +class sock_processor_base : + public detail::_sock_processor_base<charT,traits,_Alloc> +{ + private: + typedef detail::_sock_processor_base<charT,traits,_Alloc> sp_base_t; + + public: + typedef basic_sockstream2<charT,traits,_Alloc> sockstream_t; + + struct adopt_new_t { }; + struct adopt_close_t { }; + struct adopt_data_t { }; + + sock_processor_base() + { } + + explicit sock_processor_base( int port, sock_base2::stype t = sock_base2::sock_stream ) + { + sp_base_t::open( port, t, sock_base2::inet ); + } + + + virtual void operator ()( sockstream_t& s, const adopt_new_t& ) = 0; + virtual void operator ()( sockstream_t& s, const adopt_close_t& ) = 0; + virtual void operator ()( sockstream_t& s, const adopt_data_t& ) = 0; +}; + +typedef sock_processor_base<char,char_traits<char>,allocator<char> > sock_basic_processor; + +namespace detail { + +template<class charT, class traits, class _Alloc> +class sockmgr +{ + private: + typedef basic_sockstream2<charT,traits,_Alloc> sockstream_t; + typedef basic_sockbuf2<charT,traits,_Alloc> sockbuf_t; + typedef sock_processor_base<charT,traits,_Alloc> socks_processor_t; + + enum { + listener, + // tcp_stream, + tcp_buffer, + rqstop, + rqstart + }; + + struct fd_info + { + enum { + listener = 0x1, + level_triggered = 0x2, + owner = 0x4, + buffer = 0x8 + }; + + unsigned flags; + union { + sockstream_t* s; + sockbuf_t* b; + } s; + socks_processor_t *p; + }; + + struct ctl { + int cmd; + union { + int fd; + void *ptr; + } data; + }; + + static void _loop( sockmgr *me ) + { me->io_worker(); } + + public: + sockmgr( int hint = 1024, int ret = 512 ) : + n_ret( ret ) + { + efd = epoll_create( hint ); + if ( efd < 0 ) { + // throw system_error( errno ) + } + pipe( pipefd ); // check err + // cfd = pipefd[1]; + + epoll_event ev_add; + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; + ev_add.data.fd = pipefd[0]; + epoll_ctl( efd, EPOLL_CTL_ADD, pipefd[0], &ev_add ); + + _worker = new std::tr2::thread( _loop, this ); + + // ctl _ctl; + // _ctl.cmd = rqstart; + + // write( pipefd[1], &_ctl, sizeof(ctl) ); + } + + ~sockmgr() + { + if ( _worker->joinable() ) { + ctl _ctl; + _ctl.cmd = rqstop; + + write( pipefd[1], &_ctl, sizeof(ctl) ); + + _worker->join(); + } + close( pipefd[1] ); + close( pipefd[0] ); + close( efd ); + delete _worker; + } + + void push( socks_processor_t& p ) + { + ctl _ctl; + _ctl.cmd = listener; + _ctl.data.ptr = static_cast<void *>(&p); + + write( pipefd[1], &_ctl, sizeof(ctl) ); + } + +#if 0 + void push( sockstream_t& s ) + { + ctl _ctl; + _ctl.cmd = tcp_stream; + _ctl.data.ptr = static_cast<void *>(&s); + + write( pipefd[1], &_ctl, sizeof(ctl) ); + } +#endif + + void push( sockbuf_t& s ) + { + ctl _ctl; + _ctl.cmd = tcp_buffer; + _ctl.data.ptr = static_cast<void *>(&s); + + errno = 0; + int r = write( pipefd[1], &_ctl, sizeof(ctl) ); + } + + void exit_notify( sockbuf_t* b, int fd ) + { + fd_info info = { 0, reinterpret_cast<sockstream_t*>(b), 0 }; + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + closed_queue[fd] = info; + } + + private: + sockmgr( const sockmgr& ) + { } + sockmgr& operator =( const sockmgr& ) + { return *this; } + + void io_worker(); + + int efd; + int pipefd[2]; + std::tr2::thread *_worker; + const int n_ret; + +#ifdef __USE_STLPORT_HASH + typedef std::hash_map<int,fd_info> fd_container_type; +#endif +#ifdef __USE_STD_HASH + typedef __gnu_cxx::hash_map<int, fd_info> fd_container_type; +#endif +#if defined(__USE_STLPORT_TR1) || defined(__USE_STD_TR1) + typedef std::tr1::unordered_map<int, fd_info> fd_container_type; +#endif + + fd_container_type descr; + fd_container_type closed_queue; + std::tr2::mutex cll; +}; + +template<class charT, class traits, class _Alloc> +void sockmgr<charT,traits,_Alloc>::io_worker() +{ + epoll_event ev[n_ret]; + +/* + ctl _xctl; + int r = read( pipefd[0], &_xctl, sizeof(ctl) ); + + if ( _xctl.cmd == rqstart ) { + std::cerr << "io_worker fine" << std::endl; + } else { + std::cerr << "io_worker not fine, " << r << ", " << errno << std::endl; + } +*/ + + for ( ; ; ) { + int n = epoll_wait( efd, &ev[0], n_ret, -1 ); + if ( n < 0 ) { + if ( errno == EINTR ) { + continue; + } + // throw system_error + } + for ( int i = 0; i < n; ++i ) { + if ( ev[i].data.fd == pipefd[0] ) { + epoll_event ev_add; + ctl _ctl; + int r = read( pipefd[0], &_ctl, sizeof(ctl) ); + if ( r < 0 ) { + // throw system_error + } else if ( r == 0 ) { + return; + } + + switch ( _ctl.cmd ) { + case listener: + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = static_cast<socks_processor_t*>(_ctl.data.ptr)->fd(); + if ( ev_add.data.fd >= 0 ) { + fd_info new_info = { fd_info::listener, 0, static_cast<socks_processor_t*>(_ctl.data.ptr) }; + descr[ev_add.data.fd] = new_info; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { + descr.erase( ev_add.data.fd ); + // throw system_error + } + } + break; +#if 0 + case tcp_stream: + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = static_cast<sockstream_t*>(_ctl.data.ptr)->rdbuf()->fd(); + if ( ev_add.data.fd >= 0 ) { + fd_info new_info = { 0, static_cast<sockstream_t*>(_ctl.data.ptr), 0 }; + descr[ev_add.data.fd] = new_info; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { + descr.erase( ev_add.data.fd ); + // throw system_error + } + } + break; +#endif + case tcp_buffer: + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = static_cast<sockbuf_t*>(_ctl.data.ptr)->fd(); + if ( ev_add.data.fd >= 0 ) { + fd_info new_info = { fd_info::buffer, static_cast<sockstream_t* /* sockbuf_t* */ >(_ctl.data.ptr), 0 }; + descr[ev_add.data.fd] = new_info; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { + descr.erase( ev_add.data.fd ); + // throw system_error + } + } + break; + case rqstop: + return; + break; + } + + continue; + } + + typename fd_container_type::iterator ifd = descr.find( ev[i].data.fd ); + if ( ifd == descr.end() ) { + throw std::logic_error( "file descriptor in epoll, but not in descr[]" ); + } + + fd_info& info = ifd->second; + if ( info.flags & fd_info::listener ) { + if ( ev[i].events & EPOLLRDHUP ) { + epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ); + // walk through descr and detach every .p ? + descr.erase( ifd ); + } else if ( ev[i].events & EPOLLIN ) { + sockaddr addr; + socklen_t sz = sizeof( sockaddr_in ); + + int fd = accept( ev[i].data.fd, &addr, &sz ); + if ( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + throw std::runtime_error( "can't establish nonblock mode" ); + } + sockstream_t* s; + + try { + s = new sockstream_t(); + if ( s->rdbuf()->_open_sockmgr( fd, addr ) ) { + epoll_event ev_add; + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = fd; + fd_info new_info = { fd_info::owner, s, info.p }; + descr[fd] = new_info; + + if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { + std::cerr << "Accept, add " << fd << ", errno " << errno << std::endl; + descr.erase( fd ); + // throw system_error + } + (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); + } else { + std::cerr << "Accept, delete " << fd << std::endl; + delete s; + } + } + catch ( const std::bad_alloc& ) { + // nothing + } + catch ( ... ) { + descr.erase( fd ); + delete s; + } + } + } else { + if ( ev[i].events & EPOLLIN ) { + if ( (info.flags & fd_info::owner) == 0 ) { + // marginal case: me not owner (registerd via push(), + // when I owner, I know destroy point), + // already closed, but I not see closed event yet; + // object may be deleted already, so I can't + // call b->egptr() etc. here + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev[i].data.fd ); + if ( closed_ifd != closed_queue.end() ) { + closed_queue.erase( closed_ifd ); + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error + } + descr.erase( ifd ); + continue; + } + } + sockbuf_t* b = (info.flags & fd_info::buffer != 0) ? info.s.b : info.s.s->rdbuf(); + errno = 0; + for ( ; ; ) { + if ( b->_ebuf == b->egptr() ) { + // process extract data from buffer too slow for us! + if ( (info.flags & fd_info::level_triggered) == 0 ) { + epoll_event xev; + xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; + xev.data.fd = ev[i].data.fd; + in... [truncated message content] |
From: <com...@us...> - 2008-03-26 10:57:23
|
Revision: 1834 http://complement.svn.sourceforge.net/complement/?rev=1834&view=rev Author: complement Date: 2008-03-26 03:57:21 -0700 (Wed, 26 Mar 2008) Log Message: ----------- mutex: add rw_mutex_ip typedef; condition_variable: fix wrong typedef for barrier_ip; thread, thread.cc: __at_fork_* handlers moved into Init; added fork call; on fork down thread's ids to bad id, except thread that call fork; set __at_fork_* handlers only once; lock all threads mutexes before fork and release all ones after---safe fork; shm.h: based on JTC1/SC22/WG21 threads interfaces, but still in xmt namespace for compatibility; ut/mt_test.cc, ut/mt_test.h, ut/shm_test.h, ut/shm_test.cc: move shared memory test suite into separate file; ut/mt_test_wg21.h, ut/mt_test_wg21.cc: test for fork; libxmt: version 2.0.1. Modified Paths: -------------- branches/complement-sockios/explore/include/mt/condition_variable branches/complement-sockios/explore/include/mt/mutex branches/complement-sockios/explore/include/mt/shm.h branches/complement-sockios/explore/include/mt/thread branches/complement-sockios/explore/lib/mt/ChangeLog branches/complement-sockios/explore/lib/mt/Makefile.inc branches/complement-sockios/explore/lib/mt/thread.cc branches/complement-sockios/explore/lib/mt/ut/Makefile.inc branches/complement-sockios/explore/lib/mt/ut/mt_test.cc branches/complement-sockios/explore/lib/mt/ut/mt_test.h branches/complement-sockios/explore/lib/mt/ut/mt_test_suite.cc branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.cc branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.h Added Paths: ----------- branches/complement-sockios/explore/lib/mt/ut/shm_test.cc branches/complement-sockios/explore/lib/mt/ut/shm_test.h Modified: branches/complement-sockios/explore/include/mt/condition_variable =================================================================== --- branches/complement-sockios/explore/include/mt/condition_variable 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/include/mt/condition_variable 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/06 13:23:11 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 10:18:13 ptr> /* * Copyright (c) 1997-1999, 2002-2008 @@ -768,7 +768,7 @@ }; typedef __barrier<false> barrier; -typedef __barrier<false> barrier_ip; +typedef __barrier<true> barrier_ip; } // namespace tr2 Modified: branches/complement-sockios/explore/include/mt/mutex =================================================================== --- branches/complement-sockios/explore/include/mt/mutex 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/include/mt/mutex 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/02/24 23:48:23 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 10:20:36 ptr> /* * Copyright (c) 1997-1999, 2002-2008 @@ -831,6 +831,7 @@ typedef __mutex<true,true> recursive_mutex_ip; #ifdef __FIT_RWLOCK typedef __rw_mutex<false> rw_mutex; +typedef __rw_mutex<true> rw_mutex_ip; #endif // __FIT_RWLOCK #ifdef __FIT_PTHREAD_SPINLOCK typedef __spinlock<false,false> spinlock; Modified: branches/complement-sockios/explore/include/mt/shm.h =================================================================== --- branches/complement-sockios/explore/include/mt/shm.h 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/include/mt/shm.h 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,7 +1,7 @@ -// -*- C++ -*- Time-stamp: <07/08/03 09:47:53 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 10:37:01 ptr> /* - * Copyright (c) 2006, 2007 + * Copyright (c) 2006-2008 * Petr Ovtchenkov * * Licensed under the Academic Free License version 3.0 @@ -25,6 +25,9 @@ #include <mt/xmt.h> +#include <mt/mutex> +#include <mt/condition_variable> + namespace xmt { struct shm_base @@ -94,12 +97,22 @@ __SPEC_FULL(is_ipc_sharable,float,true); __SPEC_FULL(is_ipc_sharable,double,true); __SPEC_FULL(is_ipc_sharable,long double,true); + __SPEC_FULL(is_ipc_sharable,xmt::__condition<true>,true); __SPEC_FULL(is_ipc_sharable,xmt::__semaphore<true>,true); __SPEC_FULL(is_ipc_sharable,xmt::__barrier<true>,true); __SPEC_FULL(is_ipc_sharable,xmt::shared_mutex,true); __SPEC_FULL(is_ipc_sharable,xmt::shared_recursive_mutex,true); +__SPEC_FULL(is_ipc_sharable,std::tr2::condition_variable_ip,true); +__SPEC_FULL(is_ipc_sharable,std::tr2::condition_variable_any_ip,true); +__SPEC_FULL(is_ipc_sharable,std::tr2::semaphore_ip,true); +__SPEC_FULL(is_ipc_sharable,std::tr2::barrier_ip,true); +__SPEC_FULL(is_ipc_sharable,std::tr2::mutex_ip,true); +__SPEC_FULL(is_ipc_sharable,std::tr2::recursive_mutex_ip,true); +__SPEC_FULL(is_ipc_sharable,std::tr2::rw_mutex_ip,true); + + #undef __SPEC_FULL #undef __SPEC_ @@ -307,7 +320,7 @@ template <class T> void named( const T& obj, int name ) { - xmt::basic_lock<__mutex<false,true> > lk( _lock ); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( _lock ); if ( _last == 255 ) { throw std::range_error( "too many named objects" ); } @@ -332,7 +345,7 @@ template <class T> T& named( int name ) { - xmt::basic_lock<__mutex<false,true> > lk( _lock ); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( _lock ); for ( int i = 0; _nm_table[i].name != -1; ++i ) { if ( _nm_table[i].name == name ) { ++_nm_table[i].count; @@ -345,7 +358,7 @@ template <class T> const T& named( int name ) const { - xmt::basic_lock<__mutex<false,true> > lk( _lock ); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( _lock ); for ( int i = 0; _nm_table[i].name != -1; ++i ) { if ( _nm_table[i].name == name ) { ++_nm_table[i].count; @@ -358,7 +371,7 @@ template <class T> void release( int name ) { - xmt::basic_lock<__mutex<false,true> > lk( _lock ); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( _lock ); for ( int i = 0; _nm_table[i].name != -1; ++i ) { if ( _nm_table[i].name == name ) { if ( --_nm_table[i].count == 0 ) { @@ -375,7 +388,7 @@ int count( int name ) const throw() { - xmt::basic_lock<__mutex<false,true> > lk( _lock ); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( _lock ); for ( int i = 0; _nm_table[i].name != -1; ++i ) { if ( _nm_table[i].name == name ) { return _nm_table[i].count; @@ -395,7 +408,7 @@ shm_name_mgr& operator =( const shm_name_mgr& ) { return *this; } - xmt::__mutex<false,true> _lock; + std::tr2::mutex_ip _lock; struct _name_rec { int name; @@ -424,7 +437,7 @@ { uint64_t _magic; size_type _first; - xmt::__mutex<false,true> _lock; + std::tr2::mutex_ip _lock; size_type _nm; }; @@ -466,8 +479,9 @@ pointer p = _seg.address(); if ( p != reinterpret_cast<pointer>(-1) && (force || _seg.count() <= 1) ) { + using namespace std::tr2; _master *m = reinterpret_cast<_master *>( _seg.address() ); - (&m->_lock)->~__mutex<false,true>(); + (&m->_lock)->~mutex_ip(); if ( m->_nm != 0 ) { reinterpret_cast<shm_name_mgr<_Inst> *>(reinterpret_cast<char *>(p) + m->_nm)->~shm_name_mgr<_Inst>(); } @@ -484,7 +498,7 @@ if ( p != reinterpret_cast<pointer>(-1) ) { _master *m = reinterpret_cast<_master *>( p ); if ( m->_nm == 0 ) { - xmt::basic_lock<xmt::__mutex<false,true> > lk( m->_lock ); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( m->_lock ); void *nm = _traverse( &m->_first, sizeof(shm_name_mgr<_Inst>) ); m->_nm = reinterpret_cast<char *>(nm) - reinterpret_cast<char *>(p); return *new ( nm ) shm_name_mgr<_Inst>(); @@ -500,7 +514,7 @@ { _master *m = reinterpret_cast<_master *>( _seg.address() ); if ( m != reinterpret_cast<_master *>(-1) ) { - xmt::basic_lock<xmt::__mutex<false,true> > lk( m->_lock ); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( m->_lock ); return _traverse( &m->_first, n ); } @@ -516,8 +530,8 @@ static void init( _master& m ) { m._magic = MAGIC; - new ( &m._lock ) xmt::__mutex<false,true>(); - xmt::basic_lock<xmt::__mutex<false,true> > lk( m._lock ); + new ( &m._lock ) std::tr2::mutex_ip(); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( m._lock ); m._first = sizeof( _master ); m._nm = 0; _fheader& h = *new ( reinterpret_cast<char *>(&m) + sizeof(_master) ) _fheader(); @@ -539,7 +553,7 @@ n = std::max( n + (__align - n % __align) % __align, sizeof(_fheader) ); _master *m = reinterpret_cast<_master *>( _seg.address() ); if ( m != reinterpret_cast<_master *>(-1) && (reinterpret_cast<char *>(p) - reinterpret_cast<char *>(_seg.address())) < (_seg.max_size() + sizeof(_master) + sizeof(_aheader) ) ) { - xmt::basic_lock<xmt::__mutex<false,true> > lk( m->_lock ); + std::tr2::lock_guard<std::tr2::mutex_ip> lk( m->_lock ); _aheader *a = reinterpret_cast<_aheader *>( reinterpret_cast<char *>(p) - sizeof(_aheader) ); size_type off = reinterpret_cast<char *>(p) - reinterpret_cast<char *>(_seg.address()); if ( m->_first == 0 ) { Modified: branches/complement-sockios/explore/include/mt/thread =================================================================== --- branches/complement-sockios/explore/include/mt/thread 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/include/mt/thread 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/02/25 16:11:00 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 01:58:08 ptr> /* * Copyright (c) 1997-1999, 2002-2008 @@ -78,6 +78,8 @@ }; #endif // !_WIN32 +__FIT_DECLSPEC void fork() throw( fork_in_parent, std::runtime_error ); + class thread_base { public: @@ -135,6 +137,7 @@ friend class thread_base; friend id get_id(void); + // friend __FIT_DECLSPEC void fork() throw( fork_in_parent, std::runtime_error ); }; enum { @@ -161,6 +164,9 @@ Init(); ~Init(); private: + static void __at_fork_prepare(); + static void __at_fork_parent(); + static void __at_fork_child(); static int& _count; }; @@ -203,6 +209,7 @@ std::string _stack_on_create; #endif friend class Init; + friend __FIT_DECLSPEC void fork() throw( fork_in_parent, std::runtime_error ); }; template <unsigned F, size_t S> @@ -605,11 +612,18 @@ // trick to declare thread_base::id get_id() as friend in thread_base::id thread_base::id get_id(); +pid_t getpid(); +pid_t getppid(); + namespace this_thread { - // std::thread_base::id get_id(); - using tr2::get_id; +using tr2::fork; +__FIT_DECLSPEC void become_daemon() throw( fork_in_parent, std::runtime_error ); + +// std::thread_base::id get_id(); +using tr2::get_id; + inline void yield() { #ifdef __FIT_PTHREADS Modified: branches/complement-sockios/explore/lib/mt/ChangeLog =================================================================== --- branches/complement-sockios/explore/lib/mt/ChangeLog 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/ChangeLog 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,3 +1,29 @@ +2008-03-26 Petr Ovtchenkov <pt...@is...> + + * mutex: add rw_mutex_ip typedef; + + * condition_variable: fix wrong typedef for barrier_ip; + + * thread, thread.cc: __at_fork_* handlers moved into Init; + added fork call; on fork down thread's ids to bad id, + except thread that call fork; set __at_fork_* handlers + only once; lock all threads mutexes before fork and + release all ones after---safe fork; + + * shm.h: based on JTC1/SC22/WG21 threads interfaces, but + still in xmt namespace for compatibility; + + * note: implementation of threads interfaces are close + to JTC1/SC22/WG21 C++ 0x working draft, see + http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2008/n2521.pdf + + * ut/mt_test.cc, ut/mt_test.h, ut/shm_test.h, ut/shm_test.cc: + move shared memory test suite into separate file; + + * ut/mt_test_wg21.h, ut/mt_test_wg21.cc: test for fork; + + * libxmt: version 2.0.1. + 2008-03-06 Petr Ovtchenkov <pt...@is...> * condition_variable: const casts for pthread_cond_* calls; Modified: branches/complement-sockios/explore/lib/mt/Makefile.inc =================================================================== --- branches/complement-sockios/explore/lib/mt/Makefile.inc 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/Makefile.inc 2008-03-26 10:57:21 UTC (rev 1834) @@ -3,7 +3,7 @@ LIBNAME = xmt MAJOR = 2 MINOR = 0 -PATCH = 0 +PATCH = 1 SRC_CC = xmt.cc thr_mgr.cc time.cc uid.cc shm.cc callstack.cc system_error.cc thread.cc \ date_time.cc SRC_C = fl.c Modified: branches/complement-sockios/explore/lib/mt/thread.cc =================================================================== --- branches/complement-sockios/explore/lib/mt/thread.cc 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/thread.cc 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/02/25 16:08:25 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 02:02:03 ptr> /* * Copyright (c) 1997-1999, 2002-2008 @@ -41,17 +41,77 @@ #include <stdio.h> #include <syscall.h> +#ifdef STLPORT +// # include <unordered_map> +# include <unordered_set> +// # include <hash_map> +// # include <hash_set> +// # define __USE_STLPORT_HASH +# define __USE_STLPORT_TR1 +#else +# if defined(__GNUC__) && (__GNUC__ < 4) +// # include <ext/hash_map> +# include <ext/hash_set> +# define __USE_STD_HASH +# else +// # include <tr1/unordered_map> +# include <tr1/unordered_set> +# define __USE_STD_TR1 +# endif +#endif + + #ifdef WIN32 # pragma warning( disable : 4290) // using namespace std; #endif +#if defined(__USE_STLPORT_HASH) || defined(__USE_STLPORT_TR1) || defined(__USE_STD_TR1) +# define __HASH_NAMESPACE std +#endif +#if defined(__USE_STD_HASH) +# define __HASH_NAMESPACE __gnu_cxx +#endif + +namespace __HASH_NAMESPACE { + +#ifdef __USE_STD_TR1 +namespace tr1 { +#endif + +template <> +struct hash<std::tr2::thread_base*> +{ + size_t operator()(const std::tr2::thread_base* __x) const + { return reinterpret_cast<size_t>(__x); } +}; + +#ifdef __USE_STD_TR1 +} +#endif + +} // namespace __HASH_NAMESPACE + + namespace std { namespace tr2 { namespace detail { +#ifdef __USE_STLPORT_HASH +typedef std::hash_set<thread_base*> thread_pool_t; +#endif +#ifdef __USE_STD_HASH +typedef __gnu_cxx::hash_set<thread_base*> thread_pool_t; +#endif +#if defined(__USE_STLPORT_TR1) || defined(__USE_STD_TR1) +typedef std::tr1::unordered_set<thread_base*> thread_pool_t; +#endif + +static mutex thrpool_lock; +static thread_pool_t thread_pool; + int Init_count = 0; // problem: ::getpid() really return cached value, so pid returned may be @@ -141,45 +201,6 @@ return user_words + __idx + 1; } - -void __at_fork_prepare() -{ -#ifdef __FIT_PTHREADS - if ( Init_count > 0 ) { - _uw_save = pthread_getspecific( _mt_key ); - } -#endif -} - -void __at_fork_parent() -{ -} - -void __at_fork_child() -{ -#ifdef __FIT_PTHREADS - if ( Init_count > 0 ) { - // otherwise we do it in Thread::Init::Init() below -# if !(defined(__FreeBSD__) || defined(__OpenBSD__)) - // I am misunderstand this point, Solaris 7 require this (to be restored) - - // pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ); - - // while Linux (and other) inherit this setting from parent process? - // At least Linux glibc 2.2.5 try to made lock in recursive - // call of pthread_atfork -# else -// should be fixed... -# endif // !(__FreeBSD__ || __OpenBSD__) - pthread_key_create( &_mt_key, 0 ); // take new key - pthread_setspecific( _mt_key, _uw_save ); // store preserved user words array - _uw_save = 0; - // Note, that only calling thread inherited when we use POSIX: - Init_count = 1; // i.e. only ONE (calling) thread... - } -#endif -} - } // namespace detail } // namespace tr2 } // namespace std @@ -196,6 +217,7 @@ char *Init_buf[32]; int& thread_base::Init::_count( detail::Init_count ); // trick to avoid friend declarations +bool _at_fork_set = false; const std::string msg1( "Can't create thread" ); const std::string msg2( "Can't fork" ); @@ -213,8 +235,11 @@ if ( _count++ == 0 ) { #ifdef __FIT_PTHREADS # if !(defined(__FreeBSD__) || defined(__OpenBSD__)) - if ( pthread_atfork( detail::__at_fork_prepare, detail::__at_fork_parent, detail::__at_fork_child ) ) { - throw std::runtime_error( "Problems with pthread_atfork" ); + if ( !_at_fork_set ) { // call only once + if ( pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ) ) { + throw std::runtime_error( "Problems with pthread_atfork" ); + } + _at_fork_set = true; } # endif // !(__FreeBSD__ || __OpenBSD__) pthread_key_create( &detail::_mt_key, 0 ); @@ -253,6 +278,73 @@ # endif // !(__FreeBSD__ || __OpenBSD__) #endif // __FIT_UITHREADS || _PTHREADS +void thread_base::Init::__at_fork_prepare() +{ +#ifdef __FIT_PTHREADS + detail::_F_lock.lock(); + detail::thrpool_lock.lock(); + + if ( detail::Init_count > 0 ) { + detail::_uw_save = pthread_getspecific( detail::_mt_key ); + } + + for ( detail::thread_pool_t::const_iterator i = detail::thread_pool.begin(); i != detail::thread_pool.end(); ++i ) { + if ( (*i)->_id != _bad_thread_id ) { + const_cast<thread_base*>(*i)->_id_lock.lock(); + } + } + +#endif +} + +void thread_base::Init::__at_fork_parent() +{ +#ifdef __FIT_PTHREADS + for ( detail::thread_pool_t::const_iterator i = detail::thread_pool.begin(); i != detail::thread_pool.end(); ++i ) { + if ( (*i)->_id != _bad_thread_id ) { + const_cast<thread_base*>(*i)->_id_lock.unlock(); + } + } + + detail::thrpool_lock.unlock(); + detail::_F_lock.unlock(); +#endif +} + +void thread_base::Init::__at_fork_child() +{ +#ifdef __FIT_PTHREADS + for ( detail::thread_pool_t::const_iterator i = detail::thread_pool.begin(); i != detail::thread_pool.end(); ++i ) { + if ( (*i)->_id != _bad_thread_id ) { + const_cast<thread_base*>(*i)->_id_lock.unlock(); + } + } + + detail::thrpool_lock.unlock(); + + if ( detail::Init_count > 0 ) { + // otherwise we do it in Thread::Init::Init() below +# if !(defined(__FreeBSD__) || defined(__OpenBSD__)) + // I am misunderstand this point, Solaris 7 require this (to be restored) + + // pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ); + + // while Linux (and other) inherit this setting from parent process? + // At least Linux glibc 2.2.5 try to made lock in recursive + // call of pthread_atfork +# else +// should be fixed... +# endif // !(__FreeBSD__ || __OpenBSD__) + pthread_key_create( &detail::_mt_key, 0 ); // take new key + pthread_setspecific( detail::_mt_key, detail::_uw_save ); // store preserved user words array + detail::_uw_save = 0; + // Note, that only calling thread inherited when we use POSIX: + detail::Init_count = 1; // i.e. only ONE (calling) thread... + } + detail::_F_lock.unlock(); +#endif +} + thread_base::id::id() : _id( _bad_thread_id ) { } @@ -262,6 +354,9 @@ _id( _bad_thread_id ) { new( Init_buf ) Init(); + + lock_guard<mutex> lk( detail::thrpool_lock ); + detail::thread_pool.insert( this ); } __FIT_DECLSPEC @@ -269,6 +364,9 @@ { if ( joinable() ) { thread_base::join(); + } else { + lock_guard<mutex> lk( detail::thrpool_lock ); + detail::thread_pool.erase( this ); } ((Init *)Init_buf)->~Init(); @@ -294,6 +392,12 @@ #endif // __FIT_WIN32THREADS #ifdef __FIT_PTHREADS pthread_join( _id, 0 ); + + { + lock_guard<mutex> lk(detail::thrpool_lock); + detail::thread_pool.erase( this ); + } + _id = _bad_thread_id; // lock not required here, only one thread #endif // PTHREADS } @@ -306,14 +410,44 @@ if ( pthread_detach( _id ) ) { // throw system_error; } + { + lock_guard<mutex> lk(detail::thrpool_lock); + for ( detail::thread_pool_t::const_iterator i = detail::thread_pool.begin(); i != detail::thread_pool.end(); ++i ) { + if ( (*i)->_id == _id ) { + detail::thread_pool.erase( i ); + break; + } + } + } _id = _bad_thread_id; #endif } +pid_t getpid() +{ + return detail::_pid; +} + +pid_t getppid() +{ + return detail::_ppid; +} + +thread_base::id get_id() +{ +#ifdef __FIT_PTHREADS + return thread_base::id( pthread_self() ); +#endif +#ifdef __FIT_WIN32THREADS + return thread_base::id( GetCurrentThread() ); +#endif +} + +__FIT_DECLSPEC void fork() throw( fork_in_parent, std::runtime_error ) { #ifdef __unix - // MT_REENTRANT( detail::_F_lock, _1 ); + thread_base::id fthr = this_thread::get_id(); fork_in_parent f( ::fork() ); if ( f.pid() > 0 ) { throw f; @@ -323,15 +457,29 @@ } detail::_ppid = detail::_pid; detail::_pid = syscall( SYS_getpid ); + + // lock not required: it in child and only one thread yet + for ( detail::thread_pool_t::const_iterator i = detail::thread_pool.begin(); i != detail::thread_pool.end(); ) { + if ( (*i)->get_id() != fthr ) { + const_cast<thread_base*>(*i)->_id = _bad_thread_id; + detail::thread_pool.erase( i++ ); + } else { + ++i; + } + } + #endif } +namespace this_thread +{ + __FIT_DECLSPEC void become_daemon() throw( fork_in_parent, std::runtime_error ) { #ifdef __unix try { - std::tr2::fork(); + std::tr2::this_thread::fork(); ::chdir( "/var/tmp" ); // for CWD: if not done, process remain with same WD // and don't allow unmount volume, for example @@ -353,29 +501,6 @@ #endif } -pid_t getpid() -{ - return detail::_pid; -} - -pid_t getppid() -{ - return detail::_ppid; -} - -thread_base::id get_id() -{ -#ifdef __FIT_PTHREADS - return thread_base::id( pthread_self() ); -#endif -#ifdef __FIT_WIN32THREADS - return thread_base::id( GetCurrentThread() ); -#endif -} - -namespace this_thread -{ - #if 0 std::thread_base::id get_id() { Modified: branches/complement-sockios/explore/lib/mt/ut/Makefile.inc =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/Makefile.inc 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/ut/Makefile.inc 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,7 +1,7 @@ -# -*- makefile -*- Time-stamp: <08/02/15 22:36:40 ptr> +# -*- makefile -*- Time-stamp: <08/03/26 10:12:36 ptr> PRGNAME = mt_ut SRC_CC = unit_test.cc timespec.cc \ signal-1.cc signal-3.cc \ - mt_test.cc mt_test_suite.cc \ + mt_test.cc shm_test.cc mt_test_suite.cc \ mt_test_wg21.cc Modified: branches/complement-sockios/explore/lib/mt/ut/mt_test.cc =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/mt_test.cc 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/ut/mt_test.cc 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/09/14 22:10:35 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 10:09:40 ptr> /* * Copyright (c) 2006, 2007 @@ -516,454 +516,7 @@ return EXAM_RESULT; } -/* ****************************************************** */ - -int EXAM_IMPL(shm_test::shm_segment) -{ - const char fname[] = "/tmp/mt_test.shm"; - try { - xmt::detail::__shm_alloc<0> seg( 5000, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); - - EXAM_CHECK( seg.address() != reinterpret_cast<void *>(-1) ); - seg.deallocate(); - EXAM_CHECK( seg.address() == reinterpret_cast<void *>(-1) ); - - EXAM_REQUIRE( !fs::exists( fname ) ); - - seg.allocate( fname, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); - EXAM_CHECK( seg.address() != reinterpret_cast<void *>(-1) ); - seg.deallocate(); - EXAM_CHECK( seg.address() == reinterpret_cast<void *>(-1) ); - EXAM_CHECK( fs::exists( fname ) ); // well, now I don't remove ref file, because shm segment may be created with another way - - // not exclusive, should pass - seg.allocate( fname, 1024, xmt::shm_base::create, 0660 ); - EXAM_CHECK( seg.address() != reinterpret_cast<void *>(-1) ); - try { - // This instance has segment in usage, should throw - seg.allocate( fname, 1024, 0, 0660 ); - EXAM_CHECK( false ); - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_CHECK( true ); // Ok - } - - /* - - I will treat another instanse (<1>) as interface to another - segment, so this sample not work. - - try { - // But this is another instanse, it's ok: - xmt::detail::__shm_alloc<1> seg1( fname, 1024, 0, 0660 ); - BOOST_CHECK( seg1.address() != reinterpret_cast<void *>(-1) ); - // Don't call seg1.deallocate() here, it destroy - } - catch ( xmt::shm_bad_alloc& err ) { - BOOST_CHECK( false ); // Fail - } - */ - - seg.deallocate(); - EXAM_CHECK( seg.address() == reinterpret_cast<void *>(-1) ); - - // ---- - try { - // exclusive, should throw - seg.allocate( fname, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); - EXAM_CHECK( false ); // Fail, should throw - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_CHECK( true ); // Ok - } - EXAM_CHECK( fs::exists( fname ) ); - // ---- - - fs::remove( fname ); - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_ERROR( err.what() ); - } - - return EXAM_RESULT; -} - -/* ****************************************************** */ - -int EXAM_IMPL(shm_test::shm_alloc) -{ - const char fname[] = "/tmp/mt_test.shm"; - try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 7000, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); - - { - xmt::allocator_shm<char,0> shmall; - size_t sz = shmall.max_size(); - // two blocks - char *ch1 = shmall.allocate( 3500 ); - EXAM_CHECK( ch1 != 0 ); - char *ch2 = shmall.allocate( 3500 ); - EXAM_CHECK( ch2 != 0 ); - try { - // try to allocate third block, not enough room - char *ch3 = shmall.allocate( 8 * 1024 - 7000 ); - EXAM_CHECK( false ); - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_CHECK( true ); - } - // free first blocks - shmall.deallocate( ch1, 3500 ); - ch1 = shmall.allocate( 3500 ); - // allocate [first] block again - EXAM_CHECK( ch1 != 0 ); - // free second block - shmall.deallocate( ch2, 3500 ); - // allocate [second] block again - ch2 = shmall.allocate( 3500 ); - EXAM_CHECK( ch2 != 0 ); - // free both blocks - shmall.deallocate( ch1, 3500 ); - shmall.deallocate( ch2, 3500 ); - // allocate big block, enough for initial memory chunk - ch1 = shmall.allocate( 7000 ); - EXAM_CHECK( ch1 != 0 ); - // free it - shmall.deallocate( ch1, 7000 ); - // allocate block of maximum size - ch1 = shmall.allocate( sz ); - EXAM_CHECK( ch1 != 0 ); - // free it - shmall.deallocate( ch1, sz ); - // allocate block, enough for initial memory chunk - ch1 = shmall.allocate( 7000 ); - EXAM_CHECK( ch1 != 0 ); - // free it - shmall.deallocate( ch1, 7000 ); - ch1 = shmall.allocate( 3000 ); - EXAM_CHECK( ch1 != 0 ); - ch2 = shmall.allocate( 400 ); - EXAM_CHECK( ch2 != 0 ); - char *ch3 = shmall.allocate( 3500 ); - EXAM_CHECK( ch3 != 0 ); - shmall.deallocate( ch1, 3000 ); - shmall.deallocate( ch2, 400 ); - shmall.deallocate( ch3, 3500 ); - ch1 = shmall.allocate( sz ); - EXAM_CHECK( ch1 != 0 ); - shmall.deallocate( ch1, sz ); - } - seg.deallocate(); - fs::remove( fname ); - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_ERROR( err.what() ); - } - - return EXAM_RESULT; -} - - /* ****************************************************** - * This test is similar mt_test::fork() above, but instead plain shm_* - * functions it use allocator based on shared memory segment - */ -int EXAM_IMPL(shm_test::fork_shm) -{ - const char fname[] = "/tmp/mt_test.shm"; - try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); - xmt::allocator_shm<char,0> shm; - - xmt::__condition<true>& fcnd = *new( shm.allocate( sizeof(xmt::__condition<true>) ) ) xmt::__condition<true>(); - fcnd.set( false ); - try { - xmt::fork(); - - try { - - // Child code - fcnd.try_wait(); - - } - catch ( ... ) { - } - - exit( 0 ); - } - catch ( xmt::fork_in_parent& child ) { - try { - EXAM_CHECK( child.pid() > 0 ); - - fcnd.set( true ); - - int stat = -1; - EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); - if ( WIFEXITED(stat) ) { - EXAM_CHECK( WEXITSTATUS(stat) == 0 ); - } else { - EXAM_ERROR( "child interrupted" ); - } - } - catch ( ... ) { - } - } - catch ( ... ) { - } - - (&fcnd)->~__condition<true>(); - shm.deallocate( reinterpret_cast<char *>(&fcnd), sizeof(xmt::__condition<true>) ); - seg.deallocate(); - fs::remove( fname ); - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_ERROR( err.what() ); - } - - return EXAM_RESULT; -} - -/* ****************************************************** - * Test: how to take named object in shared memory segment - */ -int EXAM_IMPL(shm_test::shm_named_obj) -{ - const char fname[] = "/tmp/mt_test.shm"; - enum { - test_Condition_Object = 1 - }; - try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); - xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - - xmt::allocator_shm<xmt::__condition<true>,0> shm; - - xmt::__condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__condition<true>(); - nm.named( fcnd, test_Condition_Object ); - fcnd.set( false ); - - try { - xmt::fork(); - - int eflag = 0; - - try { - - // Child code - xmt::shm_alloc<0> seg_ch; - - if ( seg_ch.max_size() == 0 ) { // just illustration, if seg and seg_ch - // (really xmt::shm_alloc<0>) - // in totally different address spaces - // in our case xmt::shm_name_mgr<0> instance derived from parent - // process - seg.allocate( fname, 4*4096, 0, 0660 ); - } - - xmt::shm_name_mgr<0>& nm_ch = seg_ch.name_mgr(); - xmt::__condition<true>& fcnd_ch = nm_ch.named<xmt::__condition<true> >( test_Condition_Object ); - fcnd_ch.set( true ); - } - catch ( const xmt::shm_bad_alloc& err ) { - EXAM_ERROR_ASYNC_F( err.what(), eflag ); - } - catch ( const std::invalid_argument& err ) { - EXAM_ERROR_ASYNC_F( err.what(), eflag ); - } - catch ( ... ) { - EXAM_ERROR_ASYNC_F( "Fail in child", eflag ); - } - - exit( eflag ); - } - catch ( xmt::fork_in_parent& child ) { - try { - EXAM_CHECK( child.pid() > 0 ); - - fcnd.try_wait(); - - int stat = -1; - EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); - if ( WIFEXITED(stat) ) { - EXAM_CHECK( WEXITSTATUS(stat) == 0 ); - } else { - EXAM_ERROR( "child interrupted" ); - } - } - catch ( ... ) { - EXAM_ERROR( "Fail in parent" ); - } - } - catch ( ... ) { - EXAM_ERROR( "Fail in fork" ); - } - - (&fcnd)->~__condition<true>(); - shm.deallocate( &fcnd, 1 ); - seg.deallocate(); - fs::remove( fname ); - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_ERROR( err.what() ); - } - - return EXAM_RESULT; -} - -/* ****************************************************** - */ -const char shm_test::fname1[] = "/tmp/mt_test.shm.1"; - -shm_test::shm_test() -{ - try { - seg1.allocate( fname1, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_ERROR_ASYNC( err.what() ); - } -} - -/* ****************************************************** - */ -shm_test::~shm_test() -{ - seg1.deallocate(); - fs::remove( fname1 ); -} - -/* ****************************************************** - */ - -int EXAM_IMPL(shm_test::shm_named_obj_more) -{ - enum { - ObjName = 1 - }; - - try { - xmt::shm_name_mgr<1>& nm = seg1.name_mgr(); - - xmt::allocator_shm<xmt::__condition<true>,1> shm; - - xmt::__condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__condition<true>(); - nm.named( fcnd, ObjName ); - fcnd.set( false ); - - try { - xmt::fork(); - - int eflag = 0; - - try { - xmt::shm_name_mgr<1>& nm_ch = seg1.name_mgr(); - xmt::allocator_shm<xmt::__condition<true>,1> shm_ch; - xmt::__condition<true>& fcnd_ch = nm_ch.named<xmt::__condition<true> >( ObjName ); - fcnd_ch.set( true ); - nm_ch.release<xmt::__condition<true> >( ObjName ); - } - catch ( const std::invalid_argument& err ) { - EXAM_ERROR_ASYNC_F( err.what(), eflag ); - } - exit( eflag ); - } - catch ( xmt::fork_in_parent& child ) { - fcnd.try_wait(); - int stat = -1; - EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); - if ( WIFEXITED(stat) ) { - EXAM_CHECK( WEXITSTATUS(stat) == 0 ); - } else { - EXAM_ERROR( "child interrupted" ); - } - } - nm.release<xmt::__condition<true> >( ObjName ); // fcnd should be destroyed here - - xmt::__condition<true>& fcnd1 = *new ( shm.allocate( 1 ) ) xmt::__condition<true>(); - nm.named( fcnd1, ObjName ); // ObjName should be free here - fcnd1.set( false ); - - try { - xmt::fork(); - - int eflag = 0; - - try { - xmt::shm_name_mgr<1>& nm_ch = seg1.name_mgr(); - xmt::allocator_shm<xmt::__condition<true>,1> shm_ch; - xmt::__condition<true>& fcnd_ch = nm_ch.named<xmt::__condition<true> >( ObjName ); - fcnd_ch.set( true ); - nm_ch.release<xmt::__condition<true> >( ObjName ); - } - catch ( const std::invalid_argument& err ) { - EXAM_ERROR_ASYNC_F( err.what(), eflag ); - } - - exit( eflag ); - } - catch ( xmt::fork_in_parent& child ) { - fcnd1.try_wait(); - int stat = -1; - EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); - if ( WIFEXITED(stat) ) { - EXAM_CHECK( WEXITSTATUS(stat) == 0 ); - } else { - EXAM_ERROR( "child interrupted" ); - } - } - nm.release<xmt::__condition<true> >( ObjName ); // fcnd should be destroyed here - - xmt::allocator_shm<xmt::__barrier<true>,1> shm_b; - xmt::__barrier<true>& b = *new ( shm_b.allocate( 1 ) ) xmt::__barrier<true>(); - - nm.named( b, ObjName ); // ObjName should be free here - - try { - xmt::fork(); - - int eflag = 0; - try { - xmt::shm_name_mgr<1>& nm_ch = seg1.name_mgr(); - xmt::allocator_shm<xmt::__barrier<true>,1> shm_ch; - xmt::__barrier<true>& b_ch = nm_ch.named<xmt::__barrier<true> >( ObjName ); - b_ch.wait(); - nm_ch.release<xmt::__barrier<true> >( ObjName ); - } - catch ( const std::invalid_argument& err ) { - EXAM_ERROR_ASYNC_F( err.what(), eflag ); - } - - exit( eflag ); - } - catch ( xmt::fork_in_parent& child ) { - b.wait(); - int stat = -1; - EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); - if ( WIFEXITED(stat) ) { - EXAM_CHECK( WEXITSTATUS(stat) == 0 ); - } else { - EXAM_ERROR( "child interrupted" ); - } - } - nm.release<xmt::__barrier<true> >( ObjName ); // barrier should be destroyed here - } - catch ( xmt::shm_bad_alloc& err ) { - EXAM_ERROR( err.what() ); - } - catch ( const std::invalid_argument& err ) { - EXAM_ERROR( err.what() ); - } - - return EXAM_RESULT; -} - -/* ****************************************************** * Thread pool (aka ThreadMgr) test. * * Start 200 threads under ThreadMgr; check that all threads Modified: branches/complement-sockios/explore/lib/mt/ut/mt_test.h =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/mt_test.h 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/ut/mt_test.h 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,7 +1,7 @@ -// -*- C++ -*- Time-stamp: <07/09/05 00:02:19 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 10:08:36 ptr> /* - * Copyright (c) 2006, 2007 + * Copyright (c) 2006-2008 * Petr Ovtchenkov * * Licensed under the Academic Free License Version 3.0 @@ -37,22 +37,4 @@ // static int x; }; -class shm_test -{ - public: - shm_test(); - ~shm_test(); - - int EXAM_DECL(shm_segment); - int EXAM_DECL(shm_alloc); - int EXAM_DECL(fork_shm); - int EXAM_DECL(shm_named_obj); - - int EXAM_DECL(shm_named_obj_more); - - private: - xmt::shm_alloc<1> seg1; - static const char fname1[]; -}; - #endif // __MT_TEST_H Modified: branches/complement-sockios/explore/lib/mt/ut/mt_test_suite.cc =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/mt_test_suite.cc 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/ut/mt_test_suite.cc 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/02/25 12:17:54 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 10:12:21 ptr> /* * Copyright (c) 2006-2008 @@ -10,6 +10,7 @@ #include "mt_test_suite.h" #include "mt_test.h" +#include "shm_test.h" #include "mt_test_wg21.h" #include <config/feature.h> @@ -41,7 +42,6 @@ exam::test_suite::test_case_type tc[3]; // t.add( &mt_test::callstack, test, "callstack" ); - tc[0] = t.add( &mt_test::barrier, test, "mt_test::barrier" ); tc[1] = t.add( &mt_test::join_test, test, "mt_test::join_test" ); tc[2] = t.add( &mt_test::yield, test, "mt_test::yield", @@ -74,6 +74,7 @@ t.add( &mt_test_wg21::mutex_test, test_wg21, "mt_test_wg21::mutex_test" ); t.add( &mt_test_wg21::barrier, test_wg21, "mt_test_wg21::barrier" ); t.add( &mt_test_wg21::semaphore, test_wg21, "mt_test_wg21::semaphore" ); + t.add( &mt_test_wg21::fork, test_wg21, "mt_test_wg21::fork" ); return t.girdle(); }; Modified: branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.cc =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.cc 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.cc 2008-03-26 10:57:21 UTC (rev 1834) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/02/25 13:01:59 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 01:53:46 ptr> /* * Copyright (c) 2006-2008 @@ -19,6 +19,10 @@ #include <iostream> +#include <sys/wait.h> +#include <sys/ipc.h> +#include <sys/shm.h> + int EXAM_IMPL(mt_test_wg21::date_time) { // using namespace std::tr2; @@ -202,3 +206,111 @@ return EXAM_RESULT; } + +int EXAM_IMPL(mt_test_wg21::fork) +{ + // trivial fork + + int v = 3; + try { + std::tr2::this_thread::fork(); + + try { + + // Child code + EXAM_CHECK_ASYNC( v == 3 ); + + v = 5; + } + catch ( ... ) { + } + + exit( 0 ); + } + catch ( std::tr2::fork_in_parent& child ) { + try { + EXAM_CHECK( child.pid() > 0 ); + + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + EXAM_CHECK( v == 3 ); + } + catch ( ... ) { + } + } + catch ( ... ) { + } + + + // less trivial fork: check interprocess communication via shared memory + + shmid_ds ds; + int id = shmget( 5000, 1024, IPC_CREAT | IPC_EXCL | 0600 ); + EXAM_REQUIRE( id != -1 ); + // if ( id == -1 ) { + // cerr << "Error on shmget" << endl; + // } + EXAM_REQUIRE( shmctl( id, IPC_STAT, &ds ) != -1 ); + // if ( shmctl( id, IPC_STAT, &ds ) == -1 ) { + // cerr << "Error on shmctl" << endl; + // } + void *buf = shmat( id, 0, 0 ); + EXAM_REQUIRE( buf != reinterpret_cast<void *>(-1) ); + // if ( buf == reinterpret_cast<void *>(-1) ) { + // cerr << "Error on shmat" << endl; + // } + + int& x = *new( buf ) int(4); + + EXAM_CHECK( x == 4 ); + + try { + std::tr2::this_thread::fork(); + + try { + + // Child code + EXAM_CHECK_ASYNC( v == 3 ); + + v = 5; + + EXAM_CHECK_ASYNC( x == 4 ); + + x = 6; + } + catch ( ... ) { + } + + exit( 0 ); + } + catch ( std::tr2::fork_in_parent& child ) { + try { + EXAM_CHECK( child.pid() > 0 ); + + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + EXAM_CHECK( v == 3 ); + EXAM_CHECK( x == 6 ); + } + catch ( ... ) { + } + } + catch ( ... ) { + } + + shmdt( buf ); + shmctl( id, IPC_RMID, &ds ); + + return EXAM_RESULT; +} + Modified: branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.h =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.h 2008-03-11 15:03:22 UTC (rev 1833) +++ branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.h 2008-03-26 10:57:21 UTC (rev 1834) @@ -24,6 +24,7 @@ int EXAM_DECL(mutex_test); int EXAM_DECL(barrier); int EXAM_DECL(semaphore); + int EXAM_DECL(fork); private: // static xmt::Thread::ret_t thread_entry_call( void * ); Copied: branches/complement-sockios/explore/lib/mt/ut/shm_test.cc (from rev 1832, branches/complement-sockios/explore/lib/mt/ut/mt_test.cc) =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/shm_test.cc (rev 0) +++ branches/complement-sockios/explore/lib/mt/ut/shm_test.cc 2008-03-26 10:57:21 UTC (rev 1834) @@ -0,0 +1,474 @@ +// -*- C++ -*- Time-stamp: <08/03/26 10:11:58 ptr> + +/* + * Copyright (c) 2006, 2007 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License Version 3.0 + * + */ + +#include "shm_test.h" + +#include <mt/xmt.h> +#include <mt/shm.h> + + +#include <sys/shm.h> +#include <sys/wait.h> + +#include <signal.h> + +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> + +#include <iostream> + +using namespace std; +namespace fs = boost::filesystem; + +int EXAM_IMPL(shm_test::shm_segment) +{ + const char fname[] = "/tmp/mt_test.shm"; + try { + xmt::detail::__shm_alloc<0> seg( 5000, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + + EXAM_CHECK( seg.address() != reinterpret_cast<void *>(-1) ); + seg.deallocate(); + EXAM_CHECK( seg.address() == reinterpret_cast<void *>(-1) ); + + EXAM_REQUIRE( !fs::exists( fname ) ); + + seg.allocate( fname, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + EXAM_CHECK( seg.address() != reinterpret_cast<void *>(-1) ); + seg.deallocate(); + EXAM_CHECK( seg.address() == reinterpret_cast<void *>(-1) ); + EXAM_CHECK( fs::exists( fname ) ); // well, now I don't remove ref file, because shm segment may be created with another way + + // not exclusive, should pass + seg.allocate( fname, 1024, xmt::shm_base::create, 0660 ); + EXAM_CHECK( seg.address() != reinterpret_cast<void *>(-1) ); + try { + // This instance has segment in usage, should throw + seg.allocate( fname, 1024, 0, 0660 ); + EXAM_CHECK( false ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_CHECK( true ); // Ok + } + + /* + + I will treat another instanse (<1>) as interface to another + segment, so this sample not work. + + try { + // But this is another instanse, it's ok: + xmt::detail::__shm_alloc<1> seg1( fname, 1024, 0, 0660 ); + BOOST_CHECK( seg1.address() != reinterpret_cast<void *>(-1) ); + // Don't call seg1.deallocate() here, it destroy + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK( false ); // Fail + } + */ + + seg.deallocate(); + EXAM_CHECK( seg.address() == reinterpret_cast<void *>(-1) ); + + // ---- + try { + // exclusive, should throw + seg.allocate( fname, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + EXAM_CHECK( false ); // Fail, should throw + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_CHECK( true ); // Ok + } + EXAM_CHECK( fs::exists( fname ) ); + // ---- + + fs::remove( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR( err.what() ); + } + + return EXAM_RESULT; +} + +/* ****************************************************** */ + +int EXAM_IMPL(shm_test::shm_alloc) +{ + const char fname[] = "/tmp/mt_test.shm"; + try { + xmt::shm_alloc<0> seg; + + seg.allocate( fname, 7000, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + + { + xmt::allocator_shm<char,0> shmall; + size_t sz = shmall.max_size(); + // two blocks + char *ch1 = shmall.allocate( 3500 ); + EXAM_CHECK( ch1 != 0 ); + char *ch2 = shmall.allocate( 3500 ); + EXAM_CHECK( ch2 != 0 ); + try { + // try to allocate third block, not enough room + char *ch3 = shmall.allocate( 8 * 1024 - 7000 ); + EXAM_CHECK( false ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_CHECK( true ); + } + // free first blocks + shmall.deallocate( ch1, 3500 ); + ch1 = shmall.allocate( 3500 ); + // allocate [first] block again + EXAM_CHECK( ch1 != 0 ); + // free second block + shmall.deallocate( ch2, 3500 ); + // allocate [second] block again + ch2 = shmall.allocate( 3500 ); + EXAM_CHECK( ch2 != 0 ); + // free both blocks + shmall.deallocate( ch1, 3500 ); + shmall.deallocate( ch2, 3500 ); + // allocate big block, enough for initial memory chunk + ch1 = shmall.allocate( 7000 ); + EXAM_CHECK( ch1 != 0 ); + // free it + shmall.deallocate( ch1, 7000 ); + // allocate block of maximum size + ch1 = shmall.allocate( sz ); + EXAM_CHECK( ch1 != 0 ); + // free it + shmall.deallocate( ch1, sz ); + // allocate block, enough for initial memory chunk + ch1 = shmall.allocate( 7000 ); + EXAM_CHECK( ch1 != 0 ); + // free it + shmall.deallocate( ch1, 7000 ); + ch1 = shmall.allocate( 3000 ); + EXAM_CHECK( ch1 != 0 ); + ch2 = shmall.allocate( 400 ); + EXAM_CHECK( ch2 != 0 ); + char *ch3 = shmall.allocate( 3500 ); + EXAM_CHECK( ch3 != 0 ); + shmall.deallocate( ch1, 3000 ); + shmall.deallocate( ch2, 400 ); + shmall.deallocate( ch3, 3500 ); + ch1 = shmall.allocate( sz ); + EXAM_CHECK( ch1 != 0 ); + shmall.deallocate( ch1, sz ); + } + seg.deallocate(); + fs::remove( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR( err.what() ); + } + + return EXAM_RESULT; +} + + +/* ****************************************************** + * This test is similar mt_test::fork() above, but instead plain shm_* + * functions it use allocator based on shared memory segment + */ +int EXAM_IMPL(shm_test::fork_shm) +{ + const char fname[] = "/tmp/mt_test.shm"; + try { + xmt::shm_alloc<0> seg; + + seg.allocate( fname, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + xmt::allocator_shm<char,0> shm; + + xmt::__condition<true>& fcnd = *new( shm.allocate( sizeof(xmt::__condition<true>) ) ) xmt::__condition<true>(); + fcnd.set( false ); + try { + xmt::fork(); + + try { + + // Child code + fcnd.try_wait(); + + } + catch ( ... ) { + } + + exit( 0 ); + } + catch ( xmt::fork_in_parent& child ) { + try { + EXAM_CHECK( child.pid() > 0 ); + + fcnd.set( true ); + + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + } + catch ( ... ) { + } + } + catch ( ... ) { + } + + (&fcnd)->~__condition<true>(); + shm.deallocate( reinterpret_cast<char *>(&fcnd), sizeof(xmt::__condition<true>) ); + seg.deallocate(); + fs::remove( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR( err.what() ); + } + + return EXAM_RESULT; +} + +/* ****************************************************** + * Test: how to take named object in shared memory segment + */ +int EXAM_IMPL(shm_test::shm_named_obj) +{ + const char fname[] = "/tmp/mt_test.shm"; + enum { + test_Condition_Object = 1 + }; + try { + xmt::shm_alloc<0> seg; + + seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + xmt::shm_name_mgr<0>& nm = seg.name_mgr(); + + xmt::allocator_shm<xmt::__condition<true>,0> shm; + + xmt::__condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__condition<true>(); + nm.named( fcnd, test_Condition_Object ); + fcnd.set( false ); + + try { + xmt::fork(); + + int eflag = 0; + + try { + + // Child code + xmt::shm_alloc<0> seg_ch; + + if ( seg_ch.max_size() == 0 ) { // just illustration, if seg and seg_ch + // (really xmt::shm_alloc<0>) + // in totally different address spaces + // in our case xmt::shm_name_mgr<0> instance derived from parent + // process + seg.allocate( fname, 4*4096, 0, 0660 ); + } + + xmt::shm_name_mgr<0>& nm_ch = seg_ch.name_mgr(); + xmt::__condition<true>& fcnd_ch = nm_ch.named<xmt::__condition<true> >( test_Condition_Object ); + fcnd_ch.set( true ); + } + catch ( const xmt::shm_bad_alloc& err ) { + EXAM_ERROR_ASYNC_F( err.what(), eflag ); + } + catch ( const std::invalid_argument& err ) { + EXAM_ERROR_ASYNC_F( err.what(), eflag ); + } + catch ( ... ) { + EXAM_ERROR_ASYNC_F( "Fail in child", eflag ); + } + + exit( eflag ); + } + catch ( xmt::fork_in_parent& child ) { + try { + EXAM_CHECK( child.pid() > 0 ); + + fcnd.try_wait(); + + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + } + catch ( ... ) { + EXAM_ERROR( "Fail in parent" ); + } + } + catch ( ... ) { + EXAM_ERROR( "Fail in fork" ); + } + + (&fcnd)->~__condition<true>(); + shm.deallocate( &fcnd, 1 ); + seg.deallocate(); + fs::remove( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR( err.what() ); + } + + return EXAM_RESULT; +} + +/* ****************************************************** + */ +const char shm_test::fname1[] = "/tmp/mt_test.shm.1"; + +shm_test::shm_test() +{ + try { + seg1.allocate( fname1, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR_ASYNC( err.what() ); + } +} + +/* ****************************************************** + */ +shm_test::~shm_test() +{ + seg1.deallocate(); + fs::remove( fname1 ); +} + +/* ****************************************************** + */ + +int EXAM_IMPL(shm_test::shm_named_obj_more) +{ + enum { + ObjName = 1 + }; + + try { + xmt::shm_name_mgr<1>& nm = seg1.name_mgr(); + + xmt::allocator_shm<xmt::__condition<true>,1> shm; + + xmt::__condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__condition<true>(); + nm.named( fcnd, ObjName ); + fcnd.set( false ); + + try { + xmt::fork(); + + int eflag = 0; + + try { + xmt::shm_name_mgr<1>& nm_ch = seg1.name_mgr(); + xmt::allocator_shm<xmt::__condition<true>,1> shm_ch; + xmt::__condition<true>& fcnd_ch = nm_ch.named<xmt::__condition<true> >( ObjName ); + fcnd_ch.set( true ); + nm_ch.release<xmt::__condition<true> >( ObjName ); + } + catch ( const std::invalid_argument& err ) { + EXAM_ERROR_ASYNC_F( err.what(), eflag ); + } + exit( eflag ); + } + catch ( xmt::fork_in_parent& child ) { + fcnd.try_wait(); + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + } + nm.release<xmt::__condition<true> >( ObjName ); // fcnd should be destroyed here + + xmt::__condition<true>& fcnd1 = *new ( shm.allocate( 1 ) ) xmt::__condition<true>(); + nm.named( fcnd1, ObjName ); // ObjName should be free here + fcnd1.set( false ); + + try { + xmt::fork(); + + int eflag = 0; + + try { + xmt::shm_name_mgr<1>& nm_ch = seg1.name_mgr(); + xmt::allocator_shm<xmt::__condition<true>,1> shm_ch; + xmt::__condition<true>& fcnd_ch = nm_ch.named<xmt::__condition<true> >( ObjName ); + fcnd_ch.set( true ); + nm_ch.release<xmt::__condition<true> >( ObjName ); + } + catch ( const std::invalid_argument& err ) { + EXAM_ERROR_ASYNC_F( err.what(), eflag ); + } + + exit( eflag ); + } + catch ( xmt::fork_in_parent& child ) { + fcnd1.try_wait(); + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + } + nm.release<xmt::__condition<true> >( ObjName ); // fcnd should be destroyed here + + xmt::allocator_shm<xmt::__barrier<true>,1> shm_b; + xmt::__barrier<true>& b = *new ( shm_b.allocate( 1 ) ) xmt::__barrier<true>(); + + nm.named( b, ObjName ); // ObjName should be free here + + try { + xmt::fork(); + + int eflag = 0; + try { + xmt::shm_name_mgr<1>& nm_ch = seg1.name_mgr(); + xmt::allocator_shm<xmt::__barrier<true>,1> shm_ch; + xmt::__barrier<true>& b_ch = nm_ch.named<xmt::__barrier<true> >( ObjName ); + b_ch.wait(); + nm_ch.release<xmt::__barrier<true> >( ObjName ); + } + catch ( const std::invalid_argument& err ) { + EXAM_ERROR_ASYNC_F( err.what(), eflag ); + } + + exit( eflag ); + } + catch ( xmt::fork_in_parent& child ) { + b.wait(); + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + } + nm.release<xmt::__barrier<true> >( ObjName ); // barrier should be destroyed here + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR( err.what() ); + } + catch ( const std::invalid_argument& err ) { + EXAM_ERROR( err.what() ); + } + + return EXAM_RESULT; +} + Copied: branches/complement-sockios/explore/lib/mt/ut/shm_test.h (from rev 1832, branches/complement-sockios/explore/lib/mt/ut/mt_test.h) =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/shm_test.h (rev 0) +++ branches/complement-sockios/explore/lib/mt/ut/shm_test.h 2008-03-26 10:57:21 UTC (rev 1834) @@ -0,0 +1,37 @@ +// -*- C++ -*- Time-stamp: <08/03/26 10:10:18 ptr> + +/* + * Copyright (c) 2006, 2007 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License Version 3.0 + * + */ + +#ifndef __SHM_TEST_H +#define __SHM_TEST_H + +#define FIT_EXAM + +#include <exam/suite.h> +#include <mt/shm.h> + +class shm_test +{ + public: + shm_test(); + ~shm_test(); + + int EXAM_DECL(shm_segment); + int EXAM_DECL(shm_alloc); + int EXAM_DECL(fork_shm); + int EXAM_DECL(shm_named_obj); + + int EXAM_DECL(shm_named_obj_more); + + private: + xmt::shm_alloc<1> seg1; + static const char fname1[]; +}; + +#endif // __SHM_TEST_H This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-03-26 11:10:48
|
Revision: 1835 http://complement.svn.sourceforge.net/complement/?rev=1835&view=rev Author: complement Date: 2008-03-26 04:10:43 -0700 (Wed, 26 Mar 2008) Log Message: ----------- connection processor implemented Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sockstream2 branches/complement-sockios/explore/include/sockios/sockstream2.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc Modified: branches/complement-sockios/explore/include/sockios/sockstream2 =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream2 2008-03-26 10:57:21 UTC (rev 1834) +++ branches/complement-sockios/explore/include/sockios/sockstream2 2008-03-26 11:10:43 UTC (rev 1835) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/07 01:16:27 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 09:54:59 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -222,6 +222,7 @@ static void __at_fork_child(); static void __at_fork_parent(); static int _count; + static bool _at_fork; }; static char Init_buf[]; @@ -290,6 +291,9 @@ int basic_socket<charT,traits,_Alloc>::Init::_count = 0; template<class charT, class traits, class _Alloc> +bool basic_socket<charT,traits,_Alloc>::Init::_at_fork = false; + +template<class charT, class traits, class _Alloc> void basic_socket<charT,traits,_Alloc>::Init::_guard( int direction ) { static std::tr2::mutex _init_lock; @@ -298,9 +302,14 @@ std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); if ( _count++ == 0 ) { basic_socket<charT,traits,_Alloc>::mgr = new detail::sockmgr<charT,traits,_Alloc>(); -// #ifdef __FIT__PTHREADS -// pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ); -// #endif +#ifdef __FIT_PTHREADS + if ( !_at_fork ) { // call only once + if ( pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ) ) { + // throw system_error; + } + _at_fork = true; + } +#endif // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); } } else { @@ -313,7 +322,8 @@ template<class charT, class traits, class _Alloc> void basic_socket<charT,traits,_Alloc>::Init::__at_fork_prepare() -{ } +{ +} template<class charT, class traits, class _Alloc> void basic_socket<charT,traits,_Alloc>::Init::__at_fork_child() Modified: branches/complement-sockios/explore/include/sockios/sockstream2.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream2.cc 2008-03-26 10:57:21 UTC (rev 1834) +++ branches/complement-sockios/explore/include/sockios/sockstream2.cc 2008-03-26 11:10:43 UTC (rev 1835) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/07 01:16:27 ptr> +// -*- C++ -*- Time-stamp: <08/03/18 09:51:28 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -285,7 +285,7 @@ template<class charT, class traits, class _Alloc> void basic_sockbuf2<charT, traits, _Alloc>::shutdown( sock_base2::shutdownflg dir ) { - if ( basic_socket_t::is_open() ) { + if ( basic_socket_t::is_open_unsafe() ) { if ( (dir & (sock_base2::stop_in | sock_base2::stop_out)) == (sock_base2::stop_in | sock_base2::stop_out) ) { ::shutdown( basic_socket_t::_fd, 2 ); Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-03-26 10:57:21 UTC (rev 1834) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-03-26 11:10:43 UTC (rev 1835) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/07 01:40:59 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 09:55:19 ptr> /* * Copyright (c) 2008 @@ -22,6 +22,7 @@ #include <cerrno> #include <mt/thread> #include <mt/mutex> +#include <mt/condition_variable> #ifdef STLPORT # include <unordered_map> @@ -43,6 +44,8 @@ #endif #include <sockios/sockstream> +#include <deque> +#include <functional> namespace std { @@ -270,6 +273,313 @@ typedef sock_processor_base<char,char_traits<char>,allocator<char> > sock_basic_processor; +template <class Connect, class charT = char, class traits = std::char_traits<charT>, class _Alloc = std::allocator<charT>, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& ) = &Connect::connect > +class connect_processor : + public sock_processor_base<charT,traits,_Alloc> +{ + private: + typedef sock_processor_base<charT,traits,_Alloc> base_t; + + class Init + { + public: + Init() + { _guard( 1 ); } + ~Init() + { _guard( 0 ); } + + private: + static void _guard( int direction ); + static void __at_fork_prepare(); + static void __at_fork_child(); + static void __at_fork_parent(); + static int _count; + }; + + static char Init_buf[]; + + public: + connect_processor() : + not_empty( *this ), + _in_work( false ), + ploop( loop, this ) + { new( Init_buf ) Init(); } + + explicit connect_processor( int port ) : + base_t( port, sock_base2::sock_stream ), + not_empty( *this ), + _in_work( false ), + ploop( loop, this ) + { new( Init_buf ) Init(); } + + ~connect_processor() + { + connect_processor::close(); + if ( ploop.joinable() ) { + ploop.join(); + } + ((Init *)Init_buf)->~Init(); + } + + virtual void close(); + + void wait() + { if ( ploop.joinable() ) { ploop.join(); } } + + private: + virtual void operator ()( typename base_t::sockstream_t& s, const typename base_t::adopt_new_t& ); + virtual void operator ()( typename base_t::sockstream_t& s, const typename base_t::adopt_close_t& ); + virtual void operator ()( typename base_t::sockstream_t& s, const typename base_t::adopt_data_t& ); + + + static void loop( connect_processor* me ) + { me->worker(); } + + void worker(); + + private: + struct processor + { + processor() : + c(0), + s(0) + { } + processor( Connect* __c, typename sock_processor_base<charT,traits,_Alloc>::sockstream_t* __s ) : + c(__c), + s(__s) + { } + processor( const processor& p ) : + c( p.c ), + s( p.s ) + { } + + processor& operator =( const processor& p ) + { c = p.c; s = p.s; return *this; } + + Connect* c; + typename sock_processor_base<charT,traits,_Alloc>::sockstream_t* s; + + bool operator ==( const processor& p ) const + { return s == p.s; } + bool operator ==( const typename sock_processor_base<charT,traits,_Alloc>::sockstream_t* st ) const + { return const_cast<const typename sock_processor_base<charT,traits,_Alloc>::sockstream_t*>(s) == st; } + +/* + struct equal_to : + public std::binary_function<processor, typename sock_processor_base<charT,traits,_Alloc>::sockstream_t*, bool> + { + bool operator()(const processor& __x, const typename sock_processor_base<charT,traits,_Alloc>::sockstream_t* __y) const + { return __x == __y; } + }; +*/ + }; + + bool pop_ready( processor& ); + +#ifdef __USE_STLPORT_HASH + typedef std::hash_map<typename base_t::sockstream_t*,Connect*> worker_pool_t; +#endif +#ifdef __USE_STD_HASH + typedef __gnu_cxx::hash_map<typename base_t::sockstream_t*,Connect*> worker_pool_t; +#endif +#if defined(__USE_STLPORT_TR1) || defined(__USE_STD_TR1) + typedef std::tr1::unordered_map<typename base_t::sockstream_t*,Connect*> worker_pool_t; +#endif + typedef std::deque<processor> ready_pool_t; + + struct _not_empty + { + _not_empty( connect_processor& p ) : + me( p ) + { } + + bool operator()() const + { return !me.ready_pool.empty(); } + + connect_processor& me; + } not_empty; + + worker_pool_t worker_pool; + ready_pool_t ready_pool; + volatile bool _in_work; + std::tr2::mutex wklock; + std::tr2::mutex rdlock; + std::tr2::condition_variable cnd; + std::tr2::mutex inwlock; + std::tr2::condition_variable cnd_inwk; + std::tr2::thread ploop; + + friend struct _not_empty; +}; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +int connect_processor<Connect, charT, traits, _Alloc, C>::Init::_count = 0; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::_guard( int direction ) +{ + static std::tr2::mutex _init_lock; + + if ( direction ) { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( _count++ == 0 ) { + +// #ifdef __FIT__PTHREADS +// pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ); +// #endif +// _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); + } + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( --_count == 0 ) { + + } + } +} + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_prepare() +{ } + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_child() +{ + if ( _count != 0 ) { + + } + // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); +} + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_parent() +{ } + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +char connect_processor<Connect, charT, traits, _Alloc, C>::Init_buf[128]; + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::close() +{ + base_t::close(); + + { + std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); + _in_work = false; // <--- set before cnd.notify_one(); (below in this func) + } + + std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); + ready_pool.push_back( processor() ); // make ready_pool not empty + // std::cerr << "=== " << ready_pool.size() << std::endl; + cnd.notify_one(); +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_new_t& ) +{ + Connect* c = new Connect( s ); + if ( s.rdbuf()->in_avail() ) { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( processor( c, &s ) ); + cnd.notify_one(); + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + worker_pool[&s] = c; + } +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_close_t& ) +{ + { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + typename worker_pool_t::iterator i = worker_pool.find( &s ); + if ( i != worker_pool.end() ) { + delete i->second; + // std::cerr << "oops\n"; + worker_pool.erase( i ); + return; + } + } + + Connect* c = 0; + { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + typename ready_pool_t::iterator j = std::find( ready_pool.begin(), ready_pool.end(), /* std::bind2nd( typename processor::equal_to(), &s ) */ &s ); + if ( j != ready_pool.end() ) { + // std::cerr << "oops 2\n"; + c = j->c; + ready_pool.erase( j ); + } + } + if ( c != 0 ) { + (c->*C)( s ); + delete c; + } +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_data_t& ) +{ + Connect* c; + + { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + typename worker_pool_t::const_iterator i = worker_pool.find( &s ); + if ( i == worker_pool.end() ) { + return; + } + c = i->second; + worker_pool.erase( i ); + } + + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( processor( c, &s ) ); + cnd.notify_one(); + // std::cerr << "notify data " << (void *)c << " " << ready_pool.size() << std::endl; +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +bool connect_processor<Connect, charT, traits, _Alloc, C>::pop_ready( processor& p ) +{ + { + std::tr2::unique_lock<std::tr2::mutex> lk( rdlock ); + + cnd.wait( lk, not_empty ); + p = ready_pool.front(); // it may contain p.c == 0, p.s == 0, if !in_work() + ready_pool.pop_front(); + // std::cerr << "pop 1\n"; + if ( p.c == 0 ) { // wake up, but _in_work may be still true here (in processor pipe?), + return false; // even I know that _in_work <- false before notification... + } // so, check twice + } + + // std::cerr << "pop 2\n"; + + std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); + return _in_work ? true : false; +} + + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::worker() +{ + _in_work = true; + + processor p; + + while ( pop_ready( p ) ) { + // std::cerr << "worker 1\n"; + (p.c->*C)( *p.s ); + if ( p.s->rdbuf()->in_avail() ) { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( p ); + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + worker_pool[p.s] = p.c; + } + } +} + namespace detail { template<class charT, class traits, class _Alloc> @@ -424,7 +734,7 @@ template<class charT, class traits, class _Alloc> void sockmgr<charT,traits,_Alloc>::io_worker() { - epoll_event ev[n_ret]; + epoll_event ev[/*n_ret*/ 512 ]; /* ctl _xctl; @@ -437,22 +747,28 @@ } */ + try { for ( ; ; ) { - int n = epoll_wait( efd, &ev[0], n_ret, -1 ); + int n = epoll_wait( efd, &ev[0], /* n_ret */ 512, -1 ); if ( n < 0 ) { if ( errno == EINTR ) { continue; } // throw system_error } + // std::cerr << "epoll see " << n << std::endl; for ( int i = 0; i < n; ++i ) { + // std::cerr << "epoll i = " << i << std::endl; if ( ev[i].data.fd == pipefd[0] ) { + // std::cerr << "on pipe\n"; epoll_event ev_add; ctl _ctl; int r = read( pipefd[0], &_ctl, sizeof(ctl) ); if ( r < 0 ) { // throw system_error + // std::cerr << "Read pipe\n"; } else if ( r == 0 ) { + // std::cerr << "Read pipe 0\n"; return; } @@ -461,6 +777,10 @@ ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; ev_add.data.fd = static_cast<socks_processor_t*>(_ctl.data.ptr)->fd(); if ( ev_add.data.fd >= 0 ) { + if ( fcntl( ev_add.data.fd, F_SETFL, fcntl( ev_add.data.fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + // std::cerr << "xxx " << errno << " " << std::tr2::getpid() << std::endl; + throw std::runtime_error( "can't establish nonblock mode on listener" ); + } fd_info new_info = { fd_info::listener, 0, static_cast<socks_processor_t*>(_ctl.data.ptr) }; descr[ev_add.data.fd] = new_info; if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { @@ -496,12 +816,14 @@ } break; case rqstop: + // std::cerr << "Stop request\n"; return; break; } continue; } + // std::cerr << "#\n"; typename fd_container_type::iterator ifd = descr.find( ev[i].data.fd ); if ( ifd == descr.end() ) { @@ -510,49 +832,67 @@ fd_info& info = ifd->second; if ( info.flags & fd_info::listener ) { + // std::cerr << "%\n"; if ( ev[i].events & EPOLLRDHUP ) { epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ); // walk through descr and detach every .p ? descr.erase( ifd ); + // std::cerr << "Remove listener EPOLLRDHUP\n"; } else if ( ev[i].events & EPOLLIN ) { sockaddr addr; socklen_t sz = sizeof( sockaddr_in ); - int fd = accept( ev[i].data.fd, &addr, &sz ); - if ( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { - throw std::runtime_error( "can't establish nonblock mode" ); - } - sockstream_t* s; + for ( ; ; ) { + int fd = accept( ev[i].data.fd, &addr, &sz ); + if ( fd < 0 ) { + if ( (errno == EINTR) || (errno == ECONNABORTED) /* || (errno == ERESTARTSYS) */ ) { + continue; + } + if ( !(errno == EAGAIN || errno == EWOULDBLOCK) ) { + // std::cerr << "Accept, listener " << ev[i].data.fd << ", errno " << errno << std::endl; + // throw system_error ? + } + break; + } + // std::cerr << "listener accept " << fd << std::endl; + if ( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + throw std::runtime_error( "can't establish nonblock mode" ); + } + sockstream_t* s; - try { - s = new sockstream_t(); - if ( s->rdbuf()->_open_sockmgr( fd, addr ) ) { - epoll_event ev_add; - ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - ev_add.data.fd = fd; - fd_info new_info = { fd_info::owner, s, info.p }; - descr[fd] = new_info; + try { + s = new sockstream_t(); + if ( s->rdbuf()->_open_sockmgr( fd, addr ) ) { + epoll_event ev_add; + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = fd; + fd_info new_info = { fd_info::owner, s, info.p }; + descr[fd] = new_info; - if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { - std::cerr << "Accept, add " << fd << ", errno " << errno << std::endl; - descr.erase( fd ); - // throw system_error + if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { + // std::cerr << "Accept, add " << fd << ", errno " << errno << std::endl; + descr.erase( fd ); + // throw system_error + } + (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); + } else { + // std::cerr << "Accept, delete " << fd << std::endl; + delete s; } - (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); - } else { - std::cerr << "Accept, delete " << fd << std::endl; + } + catch ( const std::bad_alloc& ) { + // nothing + } + catch ( ... ) { + descr.erase( fd ); delete s; } } - catch ( const std::bad_alloc& ) { - // nothing - } - catch ( ... ) { - descr.erase( fd ); - delete s; - } + } else { + // std::cerr << "listener: " << std::hex << ev[i].events << std::dec << std::endl; } } else { + // std::cerr << "not listener\n"; if ( ev[i].events & EPOLLIN ) { if ( (info.flags & fd_info::owner) == 0 ) { // marginal case: me not owner (registerd via push(), @@ -620,6 +960,7 @@ b->setg( b->eback(), b->gptr(), b->egptr() + offset ); b->ucnd.notify_one(); if ( info.p != 0 ) { + // std::cerr << "data here" << std::endl; (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); } } else { @@ -675,12 +1016,53 @@ } } } + } + catch ( std::exception& e ) { + std::cerr << e.what() << std::endl; + } } } //detail } // namesapce std +#if defined(__USE_STLPORT_HASH) || defined(__USE_STLPORT_TR1) || defined(__USE_STD_TR1) +# define __HASH_NAMESPACE std +#endif +#if defined(__USE_STD_HASH) +# define __HASH_NAMESPACE __gnu_cxx +#endif + +namespace __HASH_NAMESPACE { + +#ifdef __USE_STD_TR1 +namespace tr1 { +#endif + +template <class charT, class traits, class _Alloc> +struct hash<std::basic_sockstream2<charT, traits, _Alloc>* > +{ + size_t operator()(const std::basic_sockstream2<charT, traits, _Alloc>* __x) const + { return reinterpret_cast<size_t>(__x); } +}; + +#ifdef __USE_STD_TR1 +} +#endif + +#if defined(__GNUC__) && (__GNUC__ < 4) +template<> +struct hash<void *> +{ + size_t operator()(const void *__x) const + { return reinterpret_cast<size_t>(__x); } +}; +#endif // __GNUC__ < 4 + +} // namespace __HASH_NAMESPACE + +#undef __HASH_NAMESPACE + #ifdef __USE_STLPORT_HASH # undef __USE_STLPORT_HASH #endif Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-03-26 10:57:21 UTC (rev 1834) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-03-26 11:10:43 UTC (rev 1835) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/06 23:31:13 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 11:48:40 ptr> /* * @@ -14,6 +14,8 @@ #include <sockios/sockstream2> #include <mt/mutex> +#include <sys/wait.h> +#include <mt/shm.h> using namespace std; using namespace std::tr2; @@ -28,33 +30,6 @@ /* ************************************************************ */ -class worker -{ - public: - worker( sockstream& ) - { lock_guard<mutex> lk(lock); ++cnt; ++visits; } - - ~worker() - { lock_guard<mutex> lk(lock); --cnt; } - - void connect( sockstream& ) - { } - - void close() - { } - - static int get_visits() - { lock_guard<mutex> lk(lock); return visits; } - - static mutex lock; - static int cnt; - static int visits; -}; - -mutex worker::lock; -int worker::cnt = 0; -int worker::visits = 0; - class simple_mgr : public sock_basic_processor { @@ -145,7 +120,7 @@ return EXAM_RESULT; } -int EXAM_IMPL(sockios2_test::ctor_dtor) +int EXAM_IMPL(sockios2_test::connect_disconnect) { { simple_mgr srv( 2008 ); @@ -211,82 +186,261 @@ } } -#if 0 - // Check, that number of ctors of Cnt is the same as number of called dtors - // i.e. all created Cnt was released. + return EXAM_RESULT; +} + +class worker +{ + public: + worker( sockstream2& ) + { lock_guard<mutex> lk(lock); ++cnt; ++visits; cnd.notify_one(); } + + ~worker() + { lock_guard<mutex> lk(lock); --cnt; } + + void connect( sockstream2& s ) + { lock_guard<mutex> lk(lock); getline( s, line ); ++rd; line_cnd.notify_one(); } + +// void close() +// { } + + static int get_visits() + { lock_guard<mutex> lk(lock); return visits; } + + static mutex lock; + static int cnt; + static /* volatile */ int visits; + static condition_variable cnd; + static string line; + static condition_variable line_cnd; + static int rd; + // static barrier b; +}; + +mutex worker::lock; +int worker::cnt = 0; +/* volatile */ int worker::visits = 0; +condition_variable worker::cnd; +string worker::line; +condition_variable worker::line_cnd; +int worker::rd = 0; + +// barrier worker::b; + +// void stopper( connect_processor<worker>* prss ) +// { +// b.wait(); +// prss->close(); +// } + +bool visits_counter1() +{ + return worker::visits == 1; +} + +bool visits_counter2() +{ + return worker::visits == 2; +} + +bool rd_counter1() +{ + return worker::rd == 1; +} + +int EXAM_IMPL(sockios2_test::processor_core) +{ { - sockmgr_stream_MP<Cnt> srv( port ); + connect_processor<worker> prss( 2008 ); + EXAM_CHECK( prss.good() ); + EXAM_CHECK( prss.is_open() ); + { - sockstream s1( "localhost", port ); + sockstream2 s( "localhost", 2008 ); - EXAM_CHECK( s1.good() ); - EXAM_CHECK( s1.is_open() ); + EXAM_CHECK( s.good() ); + EXAM_CHECK( s.is_open() ); - s1 << "1234" << endl; +// for ( int i = 0; i < 64; ++i ) { // give chance to process it +// std::tr2::this_thread::yield(); +// } + unique_lock<mutex> lk( worker::lock ); + + worker::cnd.timed_wait( lk, milliseconds( 100 ), visits_counter1 ); + + EXAM_CHECK( worker::visits == 1 ); + worker::visits = 0; + } + } + { + lock_guard<mutex> lk( worker::lock ); + EXAM_CHECK( worker::cnt == 0 ); + } + + { + connect_processor<worker> prss( 2008 ); + + EXAM_CHECK( prss.good() ); + EXAM_CHECK( prss.is_open() ); + + { + sockstream2 s1( "localhost", 2008 ); + EXAM_CHECK( s1.good() ); EXAM_CHECK( s1.is_open() ); - while ( Cnt::get_visits() == 0 ) { - xmt::Thread::yield(); - } - Cnt::lock.lock(); - EXAM_CHECK( Cnt::cnt == 1 ); - Cnt::lock.unlock(); - } - srv.close(); - srv.wait(); + sockstream2 s2( "localhost", 2008 ); - Cnt::lock.lock(); - EXAM_CHECK( Cnt::cnt == 0 ); - Cnt::visits = 0; - Cnt::lock.unlock(); + EXAM_CHECK( s2.good() ); + EXAM_CHECK( s2.is_open() ); + +// for ( int i = 0; i < 1024; ++i ) { // give chance to process it +// std::tr2::this_thread::yield(); +// } + unique_lock<mutex> lk( worker::lock ); + + worker::cnd.timed_wait( lk, milliseconds( 100 ), visits_counter2 ); + + EXAM_CHECK( worker::visits == 2 ); + worker::visits = 0; + } } + { + lock_guard<mutex> lk( worker::lock ); + EXAM_CHECK( worker::cnt == 0 ); + } - Cnt::lock.lock(); - EXAM_CHECK( Cnt::cnt == 0 ); - Cnt::lock.unlock(); + // check before sockstream2 was closed { - sockmgr_stream_MP<Cnt> srv( port ); + connect_processor<worker> prss( 2008 ); + EXAM_CHECK( prss.good() ); + EXAM_CHECK( prss.is_open() ); + { - sockstream s1( "localhost", port ); - sockstream s2( "localhost", port ); + sockstream2 s1( "localhost", 2008 ); EXAM_CHECK( s1.good() ); EXAM_CHECK( s1.is_open() ); - EXAM_CHECK( s2.good() ); - EXAM_CHECK( s2.is_open() ); - s1 << "1234" << endl; - s2 << "1234" << endl; + s1 << "Hello, world!" << endl; + unique_lock<mutex> lk( worker::lock ); + worker::cnd.timed_wait( lk, milliseconds( 100 ), rd_counter1 ); + + // cerr << worker::line << endl; + EXAM_CHECK( worker::line == "Hello, world!" ); + worker::line = ""; + worker::rd = 0; + } + } + + + EXAM_CHECK( worker::line == "" ); + + // check after sockstream2 was closed, i.e. ensure, that all data available read before close + { + connect_processor<worker> prss( 2008 ); + + EXAM_CHECK( prss.good() ); + EXAM_CHECK( prss.is_open() ); + + { + sockstream2 s1( "localhost", 2008 ); + EXAM_CHECK( s1.good() ); EXAM_CHECK( s1.is_open() ); - EXAM_CHECK( s2.good() ); - EXAM_CHECK( s2.is_open() ); - while ( Cnt::get_visits() < 2 ) { - xmt::Thread::yield(); - } - Cnt::lock.lock(); - EXAM_CHECK( Cnt::cnt == 2 ); - Cnt::lock.unlock(); + + s1 << "Hello, world!" << endl; } - srv.close(); - srv.wait(); + unique_lock<mutex> lk( worker::lock ); + worker::cnd.timed_wait( lk, milliseconds( 100 ), rd_counter1 ); - Cnt::lock.lock(); - EXAM_CHECK( Cnt::cnt == 0 ); - Cnt::lock.unlock(); + // cerr << worker::line << endl; + EXAM_CHECK( worker::line == "Hello, world!" ); + worker::line = ""; + worker::rd = 0; } - Cnt::lock.lock(); - EXAM_CHECK( Cnt::cnt == 0 ); - Cnt::lock.unlock(); -#endif + EXAM_CHECK( worker::line == "" ); return EXAM_RESULT; } + +int EXAM_IMPL(sockios2_test::fork) +{ + const char fname[] = "/tmp/sockios2_test.shm"; + + /* You must work very carefully with sockets, theads and fork: it unsafe in principle + and no way to make it safe. Never try to pass _opened_ connection via fork. + Here I create sockstream, but without connection (it check that io processing + loop in underlying sockmgr finish and restart smoothly in child process). + */ + sockstream2 s; + + // worker::lock.lock(); + worker::visits = 0; + // worker::lock.unlock(); + + try { + xmt::shm_alloc<0> seg; + seg.allocate( fname, 4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + + xmt::allocator_shm<barrier_ip,0> shm; + barrier_ip& b = *new ( shm.allocate( 1 ) ) barrier_ip(); + + try { + + EXAM_CHECK( worker::visits == 0 ); + + this_thread::fork(); + { + connect_processor<worker> prss( 2008 ); + + EXAM_CHECK_ASYNC( worker::visits == 0 ); + + b.wait(); // -- align here + + EXAM_CHECK_ASYNC( prss.good() ); + EXAM_CHECK_ASYNC( prss.is_open() ); + + unique_lock<mutex> lk( worker::lock ); + worker::cnd.timed_wait( lk, milliseconds( 100 ), visits_counter1 ); + + EXAM_CHECK_ASYNC( worker::visits == 1 ); + } + + exit( 0 ); + } + catch ( std::tr2::fork_in_parent& child ) { + b.wait(); // -- align here + + s.open( "localhost", 2008 ); + + EXAM_CHECK( s.good() ); + EXAM_CHECK( s.is_open() ); + + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + + EXAM_CHECK( worker::visits == 0 ); + } + shm.deallocate( &b ); + seg.deallocate(); + unlink( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR( err.what() ); + } + + return EXAM_RESULT; +} Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h 2008-03-26 10:57:21 UTC (rev 1834) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h 2008-03-26 11:10:43 UTC (rev 1835) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/07/18 08:52:26 ptr> +// -*- C++ -*- Time-stamp: <08/03/25 06:22:29 ptr> /* * @@ -22,7 +22,9 @@ ~sockios2_test(); int EXAM_DECL(srv_core); - int EXAM_DECL(ctor_dtor); + int EXAM_DECL(connect_disconnect); + int EXAM_DECL(processor_core); + int EXAM_DECL(fork); }; #endif // __sockios2_test_h Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc 2008-03-26 10:57:21 UTC (rev 1834) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc 2008-03-26 11:10:43 UTC (rev 1835) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/07/19 00:19:19 ptr> +// -*- C++ -*- Time-stamp: <08/03/25 07:48:17 ptr> /* * @@ -80,8 +80,10 @@ sockios2_test test2; - t.add( &sockios2_test::ctor_dtor, test2, "sockios2_test::ctor_dtor", - t.add( &sockios2_test::srv_core, test2, "sockios2_test::srv_core" ) ); + t.add( &sockios2_test::fork, test2, "sockios2_test::fork", + t.add( &sockios2_test::processor_core, test2, "sockios2_test::processor_core", + t.add( &sockios2_test::connect_disconnect, test2, "sockios2_test::connect_disconnect", + t.add( &sockios2_test::srv_core, test2, "sockios2_test::srv_core" ) ) ) ); return t.girdle(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-03-27 12:20:02
|
Revision: 1837 http://complement.svn.sourceforge.net/complement/?rev=1837&view=rev Author: complement Date: 2008-03-27 05:19:58 -0700 (Thu, 27 Mar 2008) Log Message: ----------- read0 test, under debugging Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sockstream2 branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.h branches/complement-sockios/explore/lib/sockios/ut/names.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc Modified: branches/complement-sockios/explore/include/sockios/sockstream2 =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream2 2008-03-26 11:45:54 UTC (rev 1836) +++ branches/complement-sockios/explore/include/sockios/sockstream2 2008-03-27 12:19:58 UTC (rev 1837) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/26 09:54:59 ptr> +// -*- C++ -*- Time-stamp: <08/03/27 08:52:14 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -316,6 +316,7 @@ std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); if ( --_count == 0 ) { delete basic_socket<charT,traits,_Alloc>::mgr; + basic_socket<charT,traits,_Alloc>::mgr = 0; } } } @@ -344,7 +345,7 @@ char basic_socket<charT,traits,_Alloc>::Init_buf[128]; template <class charT, class traits, class _Alloc> -detail::sockmgr<charT,traits,_Alloc>* basic_socket<charT,traits,_Alloc>::mgr; +detail::sockmgr<charT,traits,_Alloc>* basic_socket<charT,traits,_Alloc>::mgr = 0; #ifdef STLPORT _STLP_END_NAMESPACE Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-03-26 11:45:54 UTC (rev 1836) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-03-27 12:19:58 UTC (rev 1837) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/26 09:55:19 ptr> +// -*- C++ -*- Time-stamp: <08/03/27 09:28:41 ptr> /* * Copyright (c) 2008 @@ -483,7 +483,7 @@ cnd.notify_one(); } else { std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool[&s] = c; + worker_pool.insert( std::make_pair( &s, c ) ); } } @@ -768,7 +768,7 @@ // throw system_error // std::cerr << "Read pipe\n"; } else if ( r == 0 ) { - // std::cerr << "Read pipe 0\n"; + std::cerr << "Read pipe 0\n"; return; } @@ -845,6 +845,7 @@ for ( ; ; ) { int fd = accept( ev[i].data.fd, &addr, &sz ); if ( fd < 0 ) { + std::cerr << "Accept, listener # " << ev[i].data.fd << ", errno " << errno << std::endl; if ( (errno == EINTR) || (errno == ECONNABORTED) /* || (errno == ERESTARTSYS) */ ) { continue; } @@ -870,13 +871,14 @@ descr[fd] = new_info; if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { - // std::cerr << "Accept, add " << fd << ", errno " << errno << std::endl; + std::cerr << "Accept, add " << fd << ", errno " << errno << std::endl; descr.erase( fd ); // throw system_error } + std::cerr << "adopt_new_t()\n"; (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); } else { - // std::cerr << "Accept, delete " << fd << std::endl; + std::cerr << "Accept, delete " << fd << std::endl; delete s; } } @@ -931,9 +933,11 @@ } break; } + std::cerr << "ptr " << (void *)b->egptr() << ", " << errno << std::endl; long offset = read( ev[i].data.fd, b->egptr(), sizeof(charT) * (b->_ebuf - b->egptr()) ); + std::cerr << "offset " << offset << ", " << errno << std::endl; if ( offset < 0 ) { - if ( errno == EAGAIN ) { + if ( (errno == EAGAIN) || (errno == EINTR) ) { errno = 0; epoll_event xev; xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; @@ -941,8 +945,19 @@ epoll_ctl( efd, EPOLL_CTL_MOD, ev[i].data.fd, &xev ); break; } else { - // process error - std::cerr << "not listener, other " << ev[i].data.fd << std::hex << ev[i].events << std::dec << errno << std::endl; + switch ( errno ) { + // case EINTR: // read was interrupted + // continue; + // break; + case EFAULT: // Bad address + case ECONNRESET: // Connection reset by peer + ev[i].events |= EPOLLRDHUP; // will be processed below + break; + default: + std::cerr << "not listener, other " << ev[i].data.fd << std::hex << ev[i].events << std::dec << " : " << errno << std::endl; + break; + } + break; } } else if ( offset > 0 ) { offset /= sizeof(charT); // if offset % sizeof(charT) != 0, rest will be lost! @@ -964,14 +979,16 @@ (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); } } else { - // std::cerr << "K " << ev[i].data.fd << ", " << errno << std::endl; + std::cerr << "K " << ev[i].data.fd << ", " << errno << std::endl; // EPOLLRDHUP may be missed in kernel, but offset 0 is the same ev[i].events |= EPOLLRDHUP; // will be processed below break; } } + } else { + std::cerr << "Q\n"; } - if ( ev[i].events & EPOLLRDHUP ) { + if ( (ev[i].events & EPOLLRDHUP) || (ev[i].events & EPOLLHUP) || (ev[i].events & EPOLLERR) ) { // std::cerr << "Poll EPOLLRDHUP " << ev[i].data.fd << ", " << errno << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error @@ -992,15 +1009,12 @@ } descr.erase( ifd ); } - if ( ev[i].events & EPOLLHUP ) { - std::cerr << "Poll HUP" << std::endl; - } - if ( ev[i].events & EPOLLERR ) { - std::cerr << "Poll ERR" << std::endl; - } - if ( ev[i].events & EPOLLERR ) { - std::cerr << "Poll ERR" << std::endl; - } + // if ( ev[i].events & EPOLLHUP ) { + // std::cerr << "Poll HUP" << std::endl; + // } + // if ( ev[i].events & EPOLLERR ) { + // std::cerr << "Poll ERR" << std::endl; + // } if ( ev[i].events & EPOLLPRI ) { std::cerr << "Poll PRI" << std::endl; } Modified: branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.h =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.h 2008-03-26 11:45:54 UTC (rev 1836) +++ branches/complement-sockios/explore/lib/mt/ut/mt_test_wg21.h 2008-03-27 12:19:58 UTC (rev 1837) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/02/25 12:12:20 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 23:56:53 ptr> /* * Copyright (c) 2006-2008 Modified: branches/complement-sockios/explore/lib/sockios/ut/names.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/names.cc 2008-03-26 11:45:54 UTC (rev 1836) +++ branches/complement-sockios/explore/lib/sockios/ut/names.cc 2008-03-27 12:19:58 UTC (rev 1837) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/02/07 10:28:34 ptr> +// -*- C++ -*- Time-stamp: <08/03/27 11:04:23 ptr> /* * @@ -13,13 +13,10 @@ #include <exam/suite.h> -#include <sockios/sockstream> -#include <sockios/sockmgr.h> +#include <sockios/netinfo.h> #include <list> -#include <arpa/inet.h> - using namespace std; /* ************************************************************ */ Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-03-26 11:45:54 UTC (rev 1836) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-03-27 12:19:58 UTC (rev 1837) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/26 11:48:40 ptr> +// -*- C++ -*- Time-stamp: <08/03/27 07:22:24 ptr> /* * @@ -444,3 +444,219 @@ return EXAM_RESULT; } + +class stream_reader +{ + public: + stream_reader( sockstream2& ) + { } + + ~stream_reader() + { } + + void connect( sockstream2& s ) + { + char buf[1024]; + + s.read( buf, 1024 ); + s.write( buf, 1024 ); + s.flush(); + } + + static void load_generator( barrier* b ) + { + sockstream2 s( "localhost", 2008 ); + + char buf[1024]; + + fill( buf, buf + 1024, 0 ); + + b->wait(); + + while( true ) { + s.write( buf, 1024 ); + s.flush(); + + s.read( buf, 1024 ); + this_thread::yield(); + } + } + +}; + +int EXAM_IMPL(sockios2_test::srv_sigpipe) +{ + const char fname[] = "/tmp/sockios2_test.shm"; + try { + xmt::shm_alloc<0> seg; + seg.allocate( fname, 4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + + xmt::allocator_shm<barrier_ip,0> shm; + barrier_ip& b = *new ( shm.allocate( 1 ) ) barrier_ip(); + try { + this_thread::fork(); + + b.wait(); + /* + * This process will be killed, + * so I don't care about safe termination. + */ + + const int b_count = 10; + barrier bb( b_count ); + + thread* th1 = new thread( stream_reader::load_generator, &bb ); + + for ( int i = 0; i < (b_count - 1); ++i ) { + new thread( stream_reader::load_generator, &bb ); + } + + this_thread::sleep( milliseconds( 100 ) ); + + b.wait(); + + th1->join(); // Will be interrupted! + + exit( 0 ); + } + catch ( std::tr2::fork_in_parent& child ) { + connect_processor<stream_reader> r( 2008 ); + + EXAM_CHECK( r.good() ); + EXAM_CHECK( r.is_open() ); + + b.wait(); + b.wait(); + + kill( child.pid(), SIGTERM ); + + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + // EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + EXAM_ERROR( "child should be interrupted" ); + } else { + EXAM_MESSAGE( "child interrupted" ); + } + + EXAM_CHECK( r.good() ); + EXAM_CHECK( r.is_open() ); + + } + shm.deallocate( &b ); + seg.deallocate(); + unlink( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR( err.what() ); + } + + return EXAM_RESULT; +} + + +class interrupted_writer +{ + public: + interrupted_writer( sockstream2& s ) + { + EXAM_CHECK_ASYNC( s.good() ); + + int n = 1; + + cerr << "align 3\n"; + bb->wait(); // <-- align 3 + + cerr << "align 3 pass\n"; + s.write( (const char *)&n, sizeof( int ) ).flush(); + EXAM_CHECK_ASYNC( s.good() ); + } + + ~interrupted_writer() + { cerr << "~~\n"; } + + void connect( sockstream2& s ) + { } + + static void read_generator( barrier* b ) + { + sockstream2 s( "localhost", 2008 ); + + int buff = 0; + cerr << "align 2" << endl; + b->wait(); // <-- align 2 + cerr << "align pass" << endl; + + EXAM_CHECK_ASYNC( s.read( (char *)&buff, sizeof(int) ).good() ); // <---- key line + EXAM_CHECK_ASYNC( buff == 1 ); + } + + static barrier_ip* bb; +}; + +barrier_ip* interrupted_writer::bb = 0; + +int EXAM_IMPL(sockios2_test::read0) +{ + const char fname[] = "/tmp/sockios2_test.shm"; + try { + xmt::shm_alloc<0> seg; + seg.allocate( fname, 4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + + xmt::allocator_shm<barrier_ip,0> shm; + barrier_ip& b = *new ( shm.allocate( 1 ) ) barrier_ip(); + barrier_ip& bnew = *new ( shm.allocate( 1 ) ) barrier_ip(); + interrupted_writer::bb = &bnew; + + try { + this_thread::fork(); + + b.wait(); // <-- align 1 + + barrier bb; + + thread t( interrupted_writer::read_generator, &bb ); + + bb.wait(); // <-- align 2 + + cerr << "system" << endl; + system( "echo > /dev/null" ); // <------ key line + cerr << "after system" << endl; + + bnew.wait(); // <-- align 3 + cerr << "after align 3" << endl; + + t.join(); + + exit( 0 ); + } + catch ( std::tr2::fork_in_parent& child ) { + connect_processor<interrupted_writer> r( 2008 ); + + EXAM_CHECK( r.good() ); + EXAM_CHECK( r.is_open() ); + + b.wait(); // <-- align 1 + + int stat = -1; + EXAM_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + if ( WIFEXITED(stat) ) { + EXAM_CHECK( WEXITSTATUS(stat) == 0 ); + } else { + EXAM_ERROR( "child interrupted" ); + } + + EXAM_CHECK( r.good() ); + EXAM_CHECK( r.is_open() ); + } + shm.deallocate( &bnew ); + shm.deallocate( &b ); + seg.deallocate(); + unlink( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + EXAM_ERROR( err.what() ); + } + + return EXAM_RESULT; +} Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h 2008-03-26 11:45:54 UTC (rev 1836) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.h 2008-03-27 12:19:58 UTC (rev 1837) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/25 06:22:29 ptr> +// -*- C++ -*- Time-stamp: <08/03/26 23:57:59 ptr> /* * @@ -25,6 +25,8 @@ int EXAM_DECL(connect_disconnect); int EXAM_DECL(processor_core); int EXAM_DECL(fork); + int EXAM_DECL(srv_sigpipe); + int EXAM_DECL(read0); }; #endif // __sockios2_test_h Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc 2008-03-26 11:45:54 UTC (rev 1836) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc 2008-03-27 12:19:58 UTC (rev 1837) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/25 07:48:17 ptr> +// -*- C++ -*- Time-stamp: <08/03/27 00:48:22 ptr> /* * @@ -80,10 +80,12 @@ sockios2_test test2; - t.add( &sockios2_test::fork, test2, "sockios2_test::fork", - t.add( &sockios2_test::processor_core, test2, "sockios2_test::processor_core", - t.add( &sockios2_test::connect_disconnect, test2, "sockios2_test::connect_disconnect", - t.add( &sockios2_test::srv_core, test2, "sockios2_test::srv_core" ) ) ) ); + t.add( &sockios2_test::read0, test2, "sockios2_test::read0", + t.add( &sockios2_test::srv_sigpipe, test2, "sockios2_test::srv_sigpipe", + t.add( &sockios2_test::fork, test2, "sockios2_test::fork", + t.add( &sockios2_test::processor_core, test2, "sockios2_test::processor_core", + t.add( &sockios2_test::connect_disconnect, test2, "sockios2_test::connect_disconnect", + t.add( &sockios2_test::srv_core, test2, "sockios2_test::srv_core" ) ) ) ) ) ); return t.girdle(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-03-28 21:09:46
|
Revision: 1838 http://complement.svn.sourceforge.net/complement/?rev=1838&view=rev Author: complement Date: 2008-03-28 14:09:36 -0700 (Fri, 28 Mar 2008) Log Message: ----------- debug Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sockstream2 branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/Makefile Modified: branches/complement-sockios/explore/include/sockios/sockstream2 =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream2 2008-03-27 12:19:58 UTC (rev 1837) +++ branches/complement-sockios/explore/include/sockios/sockstream2 2008-03-28 21:09:36 UTC (rev 1838) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/27 08:52:14 ptr> +// -*- C++ -*- Time-stamp: <08/03/27 17:18:22 yeti> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -315,6 +315,9 @@ } else { std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); if ( --_count == 0 ) { + if ( basic_socket<charT,traits,_Alloc>::mgr == 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << " shit happens\n"; + } delete basic_socket<charT,traits,_Alloc>::mgr; basic_socket<charT,traits,_Alloc>::mgr = 0; } @@ -331,6 +334,7 @@ { if ( _count != 0 ) { // stop mgr + _count = 1; delete basic_socket<charT,traits,_Alloc>::mgr; basic_socket<charT,traits,_Alloc>::mgr = new detail::sockmgr<charT,traits,_Alloc>(); } Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-03-27 12:19:58 UTC (rev 1837) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-03-28 21:09:36 UTC (rev 1838) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/27 09:28:41 ptr> +// -*- C++ -*- Time-stamp: <08/03/27 17:53:40 yeti> /* * Copyright (c) 2008 @@ -294,6 +294,7 @@ static void __at_fork_child(); static void __at_fork_parent(); static int _count; + static bool _at_fork; }; static char Init_buf[]; @@ -312,7 +313,7 @@ ploop( loop, this ) { new( Init_buf ) Init(); } - ~connect_processor() + virtual ~connect_processor() { connect_processor::close(); if ( ploop.joinable() ) { @@ -338,6 +339,13 @@ void worker(); private: + connect_processor( const connect_processor& ) + { } + + connect_processor& operator =( const connect_processor& ) + { return *this; } + + struct processor { processor() : @@ -401,7 +409,7 @@ worker_pool_t worker_pool; ready_pool_t ready_pool; - volatile bool _in_work; + bool _in_work; std::tr2::mutex wklock; std::tr2::mutex rdlock; std::tr2::condition_variable cnd; @@ -416,6 +424,9 @@ int connect_processor<Connect, charT, traits, _Alloc, C>::Init::_count = 0; template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +bool connect_processor<Connect, charT, traits, _Alloc, C>::Init::_at_fork = false; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::Init::_guard( int direction ) { static std::tr2::mutex _init_lock; @@ -423,10 +434,14 @@ if ( direction ) { std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); if ( _count++ == 0 ) { - -// #ifdef __FIT__PTHREADS -// pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ); -// #endif +#ifdef __FIT_PTHREADS + if ( !_at_fork ) { // call only once + if ( pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ) ) { + // throw system_error + } + _at_fork = true; + } +#endif // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); } } else { @@ -444,6 +459,8 @@ template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_child() { + std::cerr << "SHOULD NEVER HAPPEN!!!!\n"; + if ( _count != 0 ) { } @@ -633,8 +650,13 @@ efd = epoll_create( hint ); if ( efd < 0 ) { // throw system_error( errno ) + throw std::runtime_error( "epoll_create" ); } - pipe( pipefd ); // check err + if ( pipe( pipefd ) < 0 ) { // check err + ::close( efd ); + // throw system_error; + throw std::runtime_error( "pipe" ); + } // cfd = pipefd[1]; epoll_event ev_add; @@ -656,13 +678,13 @@ ctl _ctl; _ctl.cmd = rqstop; - write( pipefd[1], &_ctl, sizeof(ctl) ); + ::write( pipefd[1], &_ctl, sizeof(ctl) ); _worker->join(); } - close( pipefd[1] ); - close( pipefd[0] ); - close( efd ); + ::close( pipefd[1] ); + ::close( pipefd[0] ); + ::close( efd ); delete _worker; } @@ -672,7 +694,10 @@ _ctl.cmd = listener; _ctl.data.ptr = static_cast<void *>(&p); - write( pipefd[1], &_ctl, sizeof(ctl) ); + int r = ::write( pipefd[1], &_ctl, sizeof(ctl) ); + if ( r < 0 || r != sizeof(ctl) ) { + throw std::runtime_error( "can't write to pipe" ); + } } #if 0 @@ -693,7 +718,10 @@ _ctl.data.ptr = static_cast<void *>(&s); errno = 0; - int r = write( pipefd[1], &_ctl, sizeof(ctl) ); + int r = ::write( pipefd[1], &_ctl, sizeof(ctl) ); + if ( r < 0 || r != sizeof(ctl) ) { + throw std::runtime_error( "can't write to pipe" ); + } } void exit_notify( sockbuf_t* b, int fd ) Modified: branches/complement-sockios/explore/lib/sockios/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/Makefile 2008-03-27 12:19:58 UTC (rev 1837) +++ branches/complement-sockios/explore/lib/sockios/ut/Makefile 2008-03-28 21:09:36 UTC (rev 1838) @@ -23,6 +23,8 @@ stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} + +dbg-shared: CXXFLAGS += -fkeep-inline-functions endif release-shared : LDLIBS = -lxmt -lsockios -lexam This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-04-01 14:45:04
|
Revision: 1839 http://complement.svn.sourceforge.net/complement/?rev=1839&view=rev Author: complement Date: 2008-04-01 07:44:59 -0700 (Tue, 01 Apr 2008) Log Message: ----------- under debugging Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/Makefile Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-03-28 21:09:36 UTC (rev 1838) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-04-01 14:44:59 UTC (rev 1839) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/27 17:53:40 yeti> +// -*- C++ -*- Time-stamp: <08/04/01 18:40:57 yeti> /* * Copyright (c) 2008 @@ -189,6 +189,7 @@ if ( !basic_socket_t::is_open_unsafe() ) { return; } + basic_socket<charT,traits,_Alloc>::mgr->pop( dynamic_cast<sock_processor_base<charT,traits,_Alloc>&>(*this), basic_socket_t::_fd ); #ifdef WIN32 ::closesocket( basic_socket_t::_fd ); #else @@ -632,7 +633,8 @@ socks_processor_t *p; }; - struct ctl { + struct ctl + { int cmd; union { int fd; @@ -677,6 +679,7 @@ if ( _worker->joinable() ) { ctl _ctl; _ctl.cmd = rqstop; + _ctl.data.ptr = 0; ::write( pipefd[1], &_ctl, sizeof(ctl) ); @@ -724,6 +727,13 @@ } } + void pop( socks_processor_t& p, int _fd ) + { + fd_info info = { fd_info::listener, 0, &p }; + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + closed_queue[_fd] = info; + } + void exit_notify( sockbuf_t* b, int fd ) { fd_info info = { 0, reinterpret_cast<sockstream_t*>(b), 0 }; @@ -904,7 +914,16 @@ // throw system_error } std::cerr << "adopt_new_t()\n"; - (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.begin(); + for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == info.p ) { + break; + } + } + if ( closed_ifd == closed_queue.end() ) { + (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); + } } else { std::cerr << "Accept, delete " << fd << std::endl; delete s; @@ -957,7 +976,16 @@ } std::cerr << "Z " << ev[i].data.fd << ", " << errno << std::endl; if ( info.p != 0 ) { - (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.begin(); + for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == info.p ) { + break; + } + } + if ( closed_ifd == closed_queue.end() ) { + (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + } } break; } @@ -1004,7 +1032,16 @@ b->ucnd.notify_one(); if ( info.p != 0 ) { // std::cerr << "data here" << std::endl; - (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.begin(); + for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == info.p ) { + break; + } + } + if ( closed_ifd == closed_queue.end() ) { + (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + } } } else { std::cerr << "K " << ev[i].data.fd << ", " << errno << std::endl; @@ -1022,7 +1059,16 @@ // throw system_error } if ( info.p != 0 ) { - (*info.p)( *info.s.s, typename socks_processor_t::adopt_close_t() ); + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.begin(); + for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == info.p ) { + break; + } + } + if ( closed_ifd == closed_queue.end() ) { + (*info.p)( *info.s.s, typename socks_processor_t::adopt_close_t() ); + } } if ( (info.flags & fd_info::owner) != 0 ) { delete info.s.s; Modified: branches/complement-sockios/explore/lib/sockios/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/Makefile 2008-03-28 21:09:36 UTC (rev 1838) +++ branches/complement-sockios/explore/lib/sockios/ut/Makefile 2008-04-01 14:44:59 UTC (rev 1839) @@ -23,8 +23,6 @@ stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} - -dbg-shared: CXXFLAGS += -fkeep-inline-functions endif release-shared : LDLIBS = -lxmt -lsockios -lexam This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-04-02 07:23:17
|
Revision: 1840 http://complement.svn.sourceforge.net/complement/?rev=1840&view=rev Author: complement Date: 2008-04-02 00:23:05 -0700 (Wed, 02 Apr 2008) Log Message: ----------- simplify sock_processor_base; partially fix absent of destruction of Connect elements when server died; still under construction Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-04-01 14:44:59 UTC (rev 1839) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-04-02 07:23:05 UTC (rev 1840) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/04/01 18:40:57 yeti> +// -*- C++ -*- Time-stamp: <08/04/02 10:25:57 ptr> /* * Copyright (c) 2008 @@ -53,34 +53,54 @@ template <class charT, class traits, class _Alloc> class basic_sockstream2; template <class charT, class traits, class _Alloc> class sock_processor_base; -namespace detail { - -template<class charT, class traits, class _Alloc> -class _sock_processor_base : +template <class charT, class traits, class _Alloc> +class sock_processor_base : public sock_base2, public basic_socket<charT,traits,_Alloc> { private: typedef basic_socket<charT,traits,_Alloc> basic_socket_t; - protected: - _sock_processor_base() : + public: + typedef basic_sockstream2<charT,traits,_Alloc> sockstream_t; + + struct adopt_new_t { }; + struct adopt_close_t { }; + struct adopt_data_t { }; + + sock_processor_base() : _mode( ios_base::in | ios_base::out ), _state( ios_base::goodbit ) { } - virtual ~_sock_processor_base() + explicit sock_processor_base( int port, sock_base2::stype t = sock_base2::sock_stream ) + { sock_processor_base::open( port, t, sock_base2::inet ); } + + virtual ~sock_processor_base() + { sock_processor_base::close(); } + + void open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ); + + void open( unsigned long addr, int port, sock_base2::stype type, sock_base2::protocol prot ) { - _sock_processor_base::close(); + in_addr _addr; + _addr.s_addr = htonl( addr ); + sock_processor_base::open( _addr, port, type, prot ); } - public: - void open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ); - void open( unsigned long addr, int port, sock_base2::stype type, sock_base2::protocol prot ); - void open( int port, sock_base2::stype type, sock_base2::protocol prot ); + void open( int port, sock_base2::stype type, sock_base2::protocol prot ) + { sock_processor_base::open(INADDR_ANY, port, type, prot); } virtual void close(); + virtual void operator ()( sockstream_t& s, const adopt_new_t& ) = 0; + virtual void operator ()( sockstream_t& s, const adopt_close_t& ) = 0; + virtual void operator ()( sockstream_t& s, const adopt_data_t& ) = 0; + + private: + sock_processor_base( const sock_processor_base& ); + sock_processor_base& operator =( const sock_processor_base& ); + protected: void setoptions_unsafe( sock_base2::so_t optname, bool on_off = true, int __v = 0 ); @@ -101,20 +121,15 @@ } private: - _sock_processor_base( const _sock_processor_base& ); - _sock_processor_base& operator =( const _sock_processor_base& ); - - private: unsigned long _mode; // open mode unsigned long _state; // state flags protected: std::tr2::mutex _fd_lck; - // xmt::condition _loop_cnd; }; template<class charT, class traits, class _Alloc> -void _sock_processor_base<charT,traits,_Alloc>::open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ) +void sock_processor_base<charT,traits,_Alloc>::open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ) { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); if ( basic_socket_t::is_open_unsafe() ) { @@ -156,7 +171,7 @@ // I am shure, this is socket of type SOCK_STREAM | SOCK_SEQPACKET, // so don't check return code from listen ::listen( basic_socket_t::_fd, SOMAXCONN ); - basic_socket_t::mgr->push( dynamic_cast<sock_processor_base<charT,traits,_Alloc>&>(*this) ); + basic_socket_t::mgr->push( *this ); } } else if ( prot == sock_base2::local ) { return; @@ -169,27 +184,13 @@ } template<class charT, class traits, class _Alloc> -void _sock_processor_base<charT,traits,_Alloc>::open( unsigned long addr, int port, sock_base2::stype type, sock_base2::protocol prot ) +void sock_processor_base<charT,traits,_Alloc>::close() { - in_addr _addr; - _addr.s_addr = htonl( addr ); - _sock_processor_base::open( _addr, port, type, prot ); -} - -template<class charT, class traits, class _Alloc> -void _sock_processor_base<charT,traits,_Alloc>::open( int port, sock_base2::stype type, sock_base2::protocol prot ) -{ - _sock_processor_base::open(INADDR_ANY, port, type, prot); -} - -template<class charT, class traits, class _Alloc> -void _sock_processor_base<charT,traits,_Alloc>::close() -{ std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); if ( !basic_socket_t::is_open_unsafe() ) { return; } - basic_socket<charT,traits,_Alloc>::mgr->pop( dynamic_cast<sock_processor_base<charT,traits,_Alloc>&>(*this), basic_socket_t::_fd ); + basic_socket<charT,traits,_Alloc>::mgr->pop( *this, basic_socket_t::_fd ); #ifdef WIN32 ::closesocket( basic_socket_t::_fd ); #else @@ -200,7 +201,7 @@ } template<class charT, class traits, class _Alloc> -void _sock_processor_base<charT,traits,_Alloc>::shutdown( sock_base2::shutdownflg dir ) +void sock_processor_base<charT,traits,_Alloc>::shutdown( sock_base2::shutdownflg dir ) { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); if ( basic_socket_t::is_open_unsafe() ) { @@ -216,7 +217,7 @@ } template<class charT, class traits, class _Alloc> -void _sock_processor_base<charT,traits,_Alloc>::setoptions_unsafe( sock_base2::so_t optname, bool on_off, int __v ) +void sock_processor_base<charT,traits,_Alloc>::setoptions_unsafe( sock_base2::so_t optname, bool on_off, int __v ) { #ifdef __unix if ( basic_socket_t::is_open_unsafe() ) { @@ -242,36 +243,6 @@ #endif // __unix } -} // namespace detail - -template <class charT, class traits, class _Alloc> -class sock_processor_base : - public detail::_sock_processor_base<charT,traits,_Alloc> -{ - private: - typedef detail::_sock_processor_base<charT,traits,_Alloc> sp_base_t; - - public: - typedef basic_sockstream2<charT,traits,_Alloc> sockstream_t; - - struct adopt_new_t { }; - struct adopt_close_t { }; - struct adopt_data_t { }; - - sock_processor_base() - { } - - explicit sock_processor_base( int port, sock_base2::stype t = sock_base2::sock_stream ) - { - sp_base_t::open( port, t, sock_base2::inet ); - } - - - virtual void operator ()( sockstream_t& s, const adopt_new_t& ) = 0; - virtual void operator ()( sockstream_t& s, const adopt_close_t& ) = 0; - virtual void operator ()( sockstream_t& s, const adopt_data_t& ) = 0; -}; - typedef sock_processor_base<char,char_traits<char>,allocator<char> > sock_basic_processor; template <class Connect, class charT = char, class traits = std::char_traits<charT>, class _Alloc = std::allocator<charT>, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& ) = &Connect::connect > @@ -294,6 +265,7 @@ static void __at_fork_prepare(); static void __at_fork_child(); static void __at_fork_parent(); + static std::tr2::mutex _init_lock; static int _count; static bool _at_fork; }; @@ -320,6 +292,18 @@ if ( ploop.joinable() ) { ploop.join(); } + // { + // std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + for ( typename worker_pool_t::iterator i = worker_pool.begin(); i != worker_pool.end(); ++i ) { + delete i->second; + } + worker_pool.clear(); + // } + for ( typename ready_pool_t::iterator j = ready_pool.begin(); j != ready_pool.end(); ++j ) { + delete j->c; + } + ready_pool.clear(); + ((Init *)Init_buf)->~Init(); } @@ -428,10 +412,11 @@ bool connect_processor<Connect, charT, traits, _Alloc, C>::Init::_at_fork = false; template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +std::tr2::mutex connect_processor<Connect, charT, traits, _Alloc, C>::Init::_init_lock; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::Init::_guard( int direction ) { - static std::tr2::mutex _init_lock; - if ( direction ) { std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); if ( _count++ == 0 ) { @@ -455,22 +440,23 @@ template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_prepare() -{ } +{ _init_lock.lock(); } template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_child() { - std::cerr << "SHOULD NEVER HAPPEN!!!!\n"; + _init_lock.unlock(); if ( _count != 0 ) { - + // std::cerr << "SHOULD NEVER HAPPEN!!!!\n"; + throw std::logic_error( "Fork while connect_processor working may has unexpected behaviour in child process" ); } // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); } template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_parent() -{ } +{ _init_lock.unlock(); } template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> char connect_processor<Connect, charT, traits, _Alloc, C>::Init_buf[128]; @@ -586,8 +572,9 @@ processor p; while ( pop_ready( p ) ) { - // std::cerr << "worker 1\n"; + std::cerr << "worker 1\n"; (p.c->*C)( *p.s ); + std::cerr << "worker 2\n"; if ( p.s->rdbuf()->in_avail() ) { std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); ready_pool.push_back( p ); @@ -595,6 +582,7 @@ std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); worker_pool[p.s] = p.c; } + std::cerr << "worker 3\n"; } } @@ -875,7 +863,7 @@ epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ); // walk through descr and detach every .p ? descr.erase( ifd ); - // std::cerr << "Remove listener EPOLLRDHUP\n"; + std::cerr << "Remove listener EPOLLRDHUP\n"; } else if ( ev[i].events & EPOLLIN ) { sockaddr addr; socklen_t sz = sizeof( sockaddr_in ); @@ -891,6 +879,24 @@ // std::cerr << "Accept, listener " << ev[i].data.fd << ", errno " << errno << std::endl; // throw system_error ? } +#if 0 + { + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev[i].data.fd ); + if ( closed_ifd != closed_queue.end() ) { + typename fd_container_type::iterator ifd = descr.begin(); + for ( ; ifd != descr.end(); ) { + if ( ifd->second.p == closed_ifd->second.p ) { + descr.erase( ifd++ ); + } else { + ++ifd + } + } + closed_queue.erase( closed_ifd ); + } + } + +#endif break; } // std::cerr << "listener accept " << fd << std::endl; @@ -923,6 +929,8 @@ } if ( closed_ifd == closed_queue.end() ) { (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); + } else { + std::cerr << "@@@ 1\n" << std::endl; } } else { std::cerr << "Accept, delete " << fd << std::endl; @@ -985,6 +993,8 @@ } if ( closed_ifd == closed_queue.end() ) { (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + } else { + std::cerr << "@@@ 2\n" << std::endl; } } break; @@ -1041,6 +1051,8 @@ } if ( closed_ifd == closed_queue.end() ) { (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + } else { + std::cerr << "@@@ 3\n" << std::endl; } } } else { @@ -1068,6 +1080,8 @@ } if ( closed_ifd == closed_queue.end() ) { (*info.p)( *info.s.s, typename socks_processor_t::adopt_close_t() ); + } else { + std::cerr << "@@@ 4\n" << std::endl; } } if ( (info.flags & fd_info::owner) != 0 ) { Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-04-01 14:44:59 UTC (rev 1839) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-04-02 07:23:05 UTC (rev 1840) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/27 07:22:24 ptr> +// -*- C++ -*- Time-stamp: <08/04/02 01:48:59 ptr> /* * @@ -42,6 +42,9 @@ sock_basic_processor( port, t ) { } + ~simple_mgr() + { cerr << "In destructor\n"; } + protected: virtual void operator ()( sockstream_t& s, const adopt_new_t& ) { lock_guard<mutex> lk(lock); b.wait(); ++n_cnt; } @@ -301,7 +304,7 @@ // } unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 100 ), visits_counter2 ); + worker::cnd.timed_wait( lk, milliseconds( 500 ), visits_counter2 ); EXAM_CHECK( worker::visits == 2 ); worker::visits = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-04-04 06:25:44
|
Revision: 1843 http://complement.svn.sourceforge.net/complement/?rev=1843&view=rev Author: complement Date: 2008-04-03 23:25:40 -0700 (Thu, 03 Apr 2008) Log Message: ----------- add final() for listener to give chance to destroy slave Connectors; under construction Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-04-03 06:12:50 UTC (rev 1842) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-04-04 06:25:40 UTC (rev 1843) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/04/03 01:05:05 ptr> +// -*- C++ -*- Time-stamp: <08/04/04 01:02:50 ptr> /* * Copyright (c) 2008 @@ -77,8 +77,12 @@ { sock_processor_base::open( port, t, sock_base2::inet ); } virtual ~sock_processor_base() - { sock_processor_base::close(); } + { + sock_processor_base::close(); + basic_socket<charT,traits,_Alloc>::mgr->final( *this ); + } + void open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ); void open( unsigned long addr, int port, sock_base2::stype type, sock_base2::protocol prot ) @@ -722,6 +726,8 @@ closed_queue[_fd] = info; } + void final( socks_processor_t& p ); + void exit_notify( sockbuf_t* b, int fd ) { fd_info info = { 0, reinterpret_cast<sockstream_t*>(b), 0 }; @@ -759,9 +765,41 @@ fd_container_type descr; fd_container_type closed_queue; std::tr2::mutex cll; + std::tr2::mutex dll; }; template<class charT, class traits, class _Alloc> +void sockmgr<charT,traits,_Alloc>::final( sockmgr<charT,traits,_Alloc>::socks_processor_t& p ) +{ + // lock descr here ... should be + std::tr2::lock_guard<std::tr2::mutex> lk_descr( dll ); + + for ( typename fd_container_type::iterator ifd = descr.begin(); ifd != descr.end(); ) { + if ( (ifd->second.flags & fd_info::owner) && (ifd->second.p == &p) ) { + std::cerr << (void*)&p << " " << (void*)ifd->second.s.s << std::endl; + p( *ifd->second.s.s, typename socks_processor_t::adopt_close_t() ); + delete ifd->second.s.s; + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error + } + descr.erase( ifd++ ); + } else { + ++ifd; + } + } + + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + + // I can't use closed_queue.erase( p.fd() ) here: fd is -1 already + for ( typename fd_container_type::iterator closed_ifd = closed_queue.begin(); closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == &p ) { + closed_queue.erase( closed_ifd ); + break; + } + } +} + +template<class charT, class traits, class _Alloc> void sockmgr<charT,traits,_Alloc>::io_worker() { epoll_event ev[/*n_ret*/ 512 ]; @@ -780,6 +818,7 @@ try { for ( ; ; ) { int n = epoll_wait( efd, &ev[0], /* n_ret */ 512, -1 ); + if ( n < 0 ) { if ( errno == EINTR ) { continue; @@ -787,6 +826,9 @@ // throw system_error } // std::cerr << "epoll see " << n << std::endl; + + std::tr2::lock_guard<std::tr2::mutex> lk( dll ); + for ( int i = 0; i < n; ++i ) { // std::cerr << "epoll i = " << i << std::endl; if ( ev[i].data.fd == pipefd[0] ) { @@ -934,6 +976,7 @@ try { s = new sockstream_t(); + std::cerr << "sockstream_t: " << (void*)s << std::endl; if ( s->rdbuf()->_open_sockmgr( fd, addr ) ) { epoll_event ev_add; ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; @@ -1103,6 +1146,7 @@ if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error } + bool need_delete = true; if ( info.p != 0 ) { std::tr2::lock_guard<std::tr2::mutex> lk( cll ); typename fd_container_type::iterator closed_ifd = closed_queue.begin(); @@ -1114,11 +1158,13 @@ if ( closed_ifd == closed_queue.end() ) { (*info.p)( *info.s.s, typename socks_processor_t::adopt_close_t() ); } else { + need_delete = false; // will be deleted in 'final' method std::cerr << "@@@ 4\n" << std::endl; } } - if ( (info.flags & fd_info::owner) != 0 ) { + if ( (info.flags & fd_info::owner) != 0 && need_delete ) { delete info.s.s; + info.s.s = 0; } else { if ( (info.flags & fd_info::buffer) != 0 ) { info.s.b->close(); Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-04-03 06:12:50 UTC (rev 1842) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-04-04 06:25:40 UTC (rev 1843) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/04/02 01:48:59 ptr> +// -*- C++ -*- Time-stamp: <08/04/04 01:06:58 ptr> /* * @@ -271,7 +271,7 @@ unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 100 ), visits_counter1 ); + worker::cnd.timed_wait( lk, milliseconds( 500 ), visits_counter1 ); EXAM_CHECK( worker::visits == 1 ); worker::visits = 0; @@ -304,7 +304,7 @@ // } unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 500 ), visits_counter2 ); + worker::cnd.timed_wait( lk, milliseconds( 1000 ), visits_counter2 ); EXAM_CHECK( worker::visits == 2 ); worker::visits = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-04-09 17:36:26
|
Revision: 1845 http://complement.svn.sourceforge.net/complement/?rev=1845&view=rev Author: complement Date: 2008-04-09 10:35:43 -0700 (Wed, 09 Apr 2008) Log Message: ----------- split template decls and implementation; under construction Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sockstream2 branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Added Paths: ----------- branches/complement-sockios/explore/include/sockios/sp.cc Modified: branches/complement-sockios/explore/include/sockios/sockstream2 =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream2 2008-04-09 10:22:41 UTC (rev 1844) +++ branches/complement-sockios/explore/include/sockios/sockstream2 2008-04-09 17:35:43 UTC (rev 1845) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/27 17:18:22 yeti> +// -*- C++ -*- Time-stamp: <08/04/09 13:02:18 yeti> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -25,6 +25,7 @@ #include <mt/mutex> #include <mt/condition_variable> #include <mt/date_time> +#include <mt/thread> #include <netdb.h> #include <netinet/in.h> @@ -311,6 +312,7 @@ } #endif // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); + std::cerr << __FILE__ << ":" << __LINE__ << " new mgr " << std::tr2::getpid() << std::endl; } } else { std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); @@ -318,6 +320,7 @@ if ( basic_socket<charT,traits,_Alloc>::mgr == 0 ) { std::cerr << __FILE__ << ":" << __LINE__ << " shit happens\n"; } + std::cerr << __FILE__ << ":" << __LINE__ << " mgr destroyed " << std::tr2::getpid() << std::endl; delete basic_socket<charT,traits,_Alloc>::mgr; basic_socket<charT,traits,_Alloc>::mgr = 0; } Added: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc (rev 0) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-04-09 17:35:43 UTC (rev 1845) @@ -0,0 +1,766 @@ +// -*- C++ -*- Time-stamp: <08/04/09 20:17:13 yeti> + +/* + * Copyright (c) 2008 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License Version 3.0 + * + */ + +namespace std { + +template<class charT, class traits, class _Alloc> +void sock_processor_base<charT,traits,_Alloc>::open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ) +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( basic_socket_t::is_open_unsafe() ) { + return; + } + _mode = ios_base::in | ios_base::out; + _state = ios_base::goodbit; +#ifdef WIN32 + ::WSASetLastError( 0 ); +#endif + if ( prot == sock_base2::inet ) { + basic_socket_t::_fd = socket( PF_INET, type, 0 ); + if ( basic_socket_t::_fd == -1 ) { + _state |= ios_base::failbit | ios_base::badbit; + return; + } + // _open = true; + basic_socket_t::_address.inet.sin_family = AF_INET; + basic_socket_t::_address.inet.sin_port = htons( port ); + basic_socket_t::_address.inet.sin_addr.s_addr = addr.s_addr; + + if ( type == sock_base2::sock_stream || type == sock_base2::sock_seqpacket ) { + // let's try reuse local address + setoptions_unsafe( sock_base2::so_reuseaddr, true ); + } + + if ( ::bind( basic_socket_t::_fd, &basic_socket_t::_address.any, sizeof(basic_socket_t::_address) ) == -1 ) { + _state |= ios_base::failbit; +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return; + } + + if ( type == sock_base2::sock_stream || type == sock_base2::sock_seqpacket ) { + // I am shure, this is socket of type SOCK_STREAM | SOCK_SEQPACKET, + // so don't check return code from listen + ::listen( basic_socket_t::_fd, SOMAXCONN ); + basic_socket_t::mgr->push( *this ); + } + } else if ( prot == sock_base2::local ) { + return; + } else { + return; + } + _state = ios_base::goodbit; + + return; +} + +template<class charT, class traits, class _Alloc> +void sock_processor_base<charT,traits,_Alloc>::close() +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( !basic_socket_t::is_open_unsafe() ) { + return; + } + basic_socket<charT,traits,_Alloc>::mgr->pop( *this, basic_socket_t::_fd ); +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::shutdown( basic_socket_t::_fd, 2 ); + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; +} + +template<class charT, class traits, class _Alloc> +void sock_processor_base<charT,traits,_Alloc>::shutdown( sock_base2::shutdownflg dir ) +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( basic_socket_t::is_open_unsafe() ) { + if ( (dir & (sock_base2::stop_in | sock_base2::stop_out)) == + (sock_base2::stop_in | sock_base2::stop_out) ) { + ::shutdown( basic_socket_t::_fd, 2 ); + } else if ( dir & sock_base2::stop_in ) { + ::shutdown( basic_socket_t::_fd, 0 ); + } else if ( dir & sock_base2::stop_out ) { + ::shutdown( basic_socket_t::_fd, 1 ); + } + } +} + +template<class charT, class traits, class _Alloc> +void sock_processor_base<charT,traits,_Alloc>::setoptions_unsafe( sock_base2::so_t optname, bool on_off, int __v ) +{ +#ifdef __unix + if ( basic_socket_t::is_open_unsafe() ) { + if ( optname != sock_base2::so_linger ) { + int turn = on_off ? 1 : 0; + if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&turn, + (socklen_t)sizeof(int) ) != 0 ) { + _state |= ios_base::failbit; + } + } else { + linger l; + l.l_onoff = on_off ? 1 : 0; + l.l_linger = __v; + if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&l, + (socklen_t)sizeof(linger) ) != 0 ) { + _state |= ios_base::failbit; + } + + } + } else { + _state |= ios_base::failbit; + } +#endif // __unix +} + + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +int connect_processor<Connect, charT, traits, _Alloc, C>::Init::_count = 0; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +bool connect_processor<Connect, charT, traits, _Alloc, C>::Init::_at_fork = false; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +std::tr2::mutex connect_processor<Connect, charT, traits, _Alloc, C>::Init::_init_lock; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::_guard( int direction ) +{ + if ( direction ) { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( _count++ == 0 ) { +#ifdef __FIT_PTHREADS + if ( !_at_fork ) { // call only once + if ( pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ) ) { + // throw system_error + } + _at_fork = true; + } +#endif +// _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); + } + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( --_count == 0 ) { + + } + } +} + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_prepare() +{ _init_lock.lock(); } + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_child() +{ + _init_lock.unlock(); + + if ( _count != 0 ) { + // std::cerr << "SHOULD NEVER HAPPEN!!!!\n"; + throw std::logic_error( "Fork while connect_processor working may has unexpected behaviour in child process" ); + } + // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); +} + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_parent() +{ _init_lock.unlock(); } + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +char connect_processor<Connect, charT, traits, _Alloc, C>::Init_buf[128]; + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::close() +{ + base_t::close(); + + { + std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); + _in_work = false; // <--- set before cnd.notify_one(); (below in this func) + } + + std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); + ready_pool.push_back( processor() ); // make ready_pool not empty + // std::cerr << "=== " << ready_pool.size() << std::endl; + cnd.notify_one(); +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_new_t& ) +{ + Connect* c = new Connect( s ); + if ( s.rdbuf()->in_avail() ) { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( processor( c, &s ) ); + cnd.notify_one(); + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + worker_pool.insert( std::make_pair( &s, c ) ); + } +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_close_t& ) +{ + { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + typename worker_pool_t::iterator i = worker_pool.find( &s ); + if ( i != worker_pool.end() ) { + delete i->second; + // std::cerr << "oops\n"; + worker_pool.erase( i ); + return; + } + } + + Connect* c = 0; + { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + typename ready_pool_t::iterator j = std::find( ready_pool.begin(), ready_pool.end(), /* std::bind2nd( typename processor::equal_to(), &s ) */ &s ); + if ( j != ready_pool.end() ) { + // std::cerr << "oops 2\n"; + c = j->c; + ready_pool.erase( j ); + } + } + if ( c != 0 ) { + (c->*C)( s ); + delete c; + } +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_data_t& ) +{ + Connect* c; + + { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + typename worker_pool_t::const_iterator i = worker_pool.find( &s ); + if ( i == worker_pool.end() ) { + return; + } + c = i->second; + worker_pool.erase( i ); + } + + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( processor( c, &s ) ); + cnd.notify_one(); + // std::cerr << "notify data " << (void *)c << " " << ready_pool.size() << std::endl; +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +bool connect_processor<Connect, charT, traits, _Alloc, C>::pop_ready( processor& p ) +{ + { + std::tr2::unique_lock<std::tr2::mutex> lk( rdlock ); + + cnd.wait( lk, not_empty ); + p = ready_pool.front(); // it may contain p.c == 0, p.s == 0, if !in_work() + ready_pool.pop_front(); + // std::cerr << "pop 1\n"; + if ( p.c == 0 ) { // wake up, but _in_work may be still true here (in processor pipe?), + return false; // even I know that _in_work <- false before notification... + } // so, check twice + } + + // std::cerr << "pop 2\n"; + + std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); + return _in_work ? true : false; +} + + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::worker() +{ + _in_work = true; + + processor p; + + while ( pop_ready( p ) ) { + // std::cerr << "worker 1\n"; + (p.c->*C)( *p.s ); + // std::cerr << "worker 2\n"; + if ( p.s->rdbuf()->in_avail() ) { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( p ); + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + worker_pool[p.s] = p.c; + } + // std::cerr << "worker 3\n"; + } +} + +namespace detail { +template<class charT, class traits, class _Alloc> +void sockmgr<charT,traits,_Alloc>::io_worker() +{ + epoll_event ev[/*n_ret*/ 512 ]; + +/* + ctl _xctl; + int r = read( pipefd[0], &_xctl, sizeof(ctl) ); + + if ( _xctl.cmd == rqstart ) { + std::cerr << "io_worker fine" << std::endl; + } else { + std::cerr << "io_worker not fine, " << r << ", " << errno << std::endl; + } +*/ + + try { + for ( ; ; ) { + int n = epoll_wait( efd, &ev[0], /* n_ret */ 512, -1 ); + + if ( n < 0 ) { + if ( errno == EINTR ) { + continue; + } + // throw system_error + } + // std::cerr << "epoll see " << n << std::endl; + + std::tr2::lock_guard<std::tr2::mutex> lk( dll ); + + for ( int i = 0; i < n; ++i ) { + // std::cerr << "epoll i = " << i << std::endl; + if ( ev[i].data.fd == pipefd[0] ) { + // std::cerr << "on pipe\n"; + cmd_from_pipe(); + } else { + // std::cerr << "#\n"; + + typename fd_container_type::iterator ifd = descr.find( ev[i].data.fd ); + if ( ifd == descr.end() ) { + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ev[i].data.fd, 0 ) < 0 ) { + // throw system_error + } + continue; + // throw std::logic_error( "file descriptor in epoll, but not in descr[]" ); + } + + fd_info& info = ifd->second; + if ( info.flags & fd_info::listener ) { + // std::cerr << "%\n"; + process_listener( ev[i], ifd ); + } else { + // std::cerr << "not listener\n"; + process_regular( ev[i], ifd ); + } + } + } + } + } + catch ( std::detail::stop_request& ) { + // this is possible, normal flow of operation + } + catch ( std::exception& e ) { + std::cerr << e.what() << std::endl; + } +} + +template<class charT, class traits, class _Alloc> +void sockmgr<charT,traits,_Alloc>::cmd_from_pipe() +{ + epoll_event ev_add; + ctl _ctl; + + int r = read( pipefd[0], &_ctl, sizeof(ctl) ); + if ( r < 0 ) { + // throw system_error + // std::cerr << "Read pipe\n"; + } else if ( r == 0 ) { + // std::cerr << "Read pipe 0\n"; + throw runtime_error( "Read pipe return 0" ); + } + + switch ( _ctl.cmd ) { + case listener: + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = static_cast<socks_processor_t*>(_ctl.data.ptr)->fd(); + if ( ev_add.data.fd >= 0 ) { + if ( fcntl( ev_add.data.fd, F_SETFL, fcntl( ev_add.data.fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + // std::cerr << "xxx " << errno << " " << std::tr2::getpid() << std::endl; + throw std::runtime_error( "can't establish nonblock mode on listener" ); + } + fd_info new_info = { fd_info::listener, 0, static_cast<socks_processor_t*>(_ctl.data.ptr) }; + descr[ev_add.data.fd] = new_info; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { + descr.erase( ev_add.data.fd ); + // throw system_error + } + } + break; +#if 0 + case tcp_stream: + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = static_cast<sockstream_t*>(_ctl.data.ptr)->rdbuf()->fd(); + if ( ev_add.data.fd >= 0 ) { + fd_info new_info = { 0, static_cast<sockstream_t*>(_ctl.data.ptr), 0 }; + descr[ev_add.data.fd] = new_info; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { + descr.erase( ev_add.data.fd ); + // throw system_error + } + } + break; +#endif + case tcp_buffer: + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = static_cast<sockbuf_t*>(_ctl.data.ptr)->fd(); + if ( ev_add.data.fd >= 0 ) { + fd_info new_info = { fd_info::buffer, static_cast<sockstream_t* /* sockbuf_t* */ >(_ctl.data.ptr), 0 }; + descr[ev_add.data.fd] = new_info; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { + descr.erase( ev_add.data.fd ); + // throw system_error + } + } + break; + case rqstop: + // std::cerr << "Stop request\n"; + throw std::detail::stop_request(); // runtime_error( "Stop request (normal flow)" ); + // break; + } +} + +template<class charT, class traits, class _Alloc> +void sockmgr<charT,traits,_Alloc>::process_listener( epoll_event& ev, typename sockmgr<charT,traits,_Alloc>::fd_container_type::iterator ifd ) +{ + if ( ev.events & EPOLLRDHUP ) { + epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ); + // walk through descr and detach every .p ? + descr.erase( ifd ); + std::cerr << "Remove listener EPOLLRDHUP\n"; + } else if ( ev.events & EPOLLIN ) { + sockaddr addr; + socklen_t sz = sizeof( sockaddr_in ); + + fd_info info = ifd->second; + + for ( ; ; ) { + int fd = accept( ev.data.fd, &addr, &sz ); + if ( fd < 0 ) { + std::cerr << "Accept, listener # " << ev.data.fd << ", errno " << errno << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << " " << std::tr2::getpid() << std::endl; + if ( (errno == EINTR) || (errno == ECONNABORTED) /* || (errno == ERESTARTSYS) */ ) { + continue; + } + if ( !(errno == EAGAIN || errno == EWOULDBLOCK) ) { + // std::cerr << "Accept, listener " << ev[i].data.fd << ", errno " << errno << std::endl; + // throw system_error ? + } +#if 0 + { + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); + if ( closed_ifd != closed_queue.end() ) { + typename fd_container_type::iterator ifd = descr.begin(); + for ( ; ifd != descr.end(); ) { + if ( ifd->second.p == closed_ifd->second.p ) { + descr.erase( ifd++ ); + } else { + ++ifd; + } + } + closed_queue.erase( closed_ifd ); + } + } +#endif + break; + } + // std::cerr << "listener accept " << fd << std::endl; + if ( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + throw std::runtime_error( "can't establish nonblock mode" ); + } + sockstream_t* s; + + try { + s = new sockstream_t(); + std::cerr << __FILE__ << ":" << __LINE__ << " new sockstream_t: " << (void*)s << std::endl; + if ( s->rdbuf()->_open_sockmgr( fd, addr ) ) { + epoll_event ev_add; + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = fd; + fd_info new_info = { fd_info::owner, s, info.p }; + descr[fd] = new_info; + + if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { + std::cerr << "Accept, add " << fd << ", errno " << errno << std::endl; + descr.erase( fd ); + // throw system_error + } + std::cerr << __FILE__ << ":" << __LINE__ << " adopt_new_t()\n"; + bool in_closed = false; + { + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.begin(); + for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == info.p ) { + in_closed = true; + std::cerr << "@@@ 1\n" << std::endl; + break; + } + } + } + if ( !in_closed ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)s << std::endl; + (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)s << std::endl; + } + } else { + std::cerr << "Accept, delete " << fd << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)s << std::endl; + delete s; + } + } + catch ( const std::bad_alloc& ) { + // nothing + } + catch ( ... ) { + descr.erase( fd ); + delete s; + } + } + } else { + // std::cerr << "listener: " << std::hex << ev.events << std::dec << std::endl; + } +} + +template<class charT, class traits, class _Alloc> +void sockmgr<charT,traits,_Alloc>::process_regular( epoll_event& ev, typename sockmgr<charT,traits,_Alloc>::fd_container_type::iterator ifd ) +{ + fd_info& info = ifd->second; + + if ( ev.events & EPOLLIN ) { + if ( (info.flags & fd_info::owner) == 0 ) { + // marginal case: me not owner (registerd via push(), + // when I owner, I know destroy point), + // already closed, but I not see closed event yet; + // object may be deleted already, so I can't + // call b->egptr() etc. here + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); + if ( closed_ifd != closed_queue.end() ) { + closed_queue.erase( closed_ifd ); + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error + } + descr.erase( ifd ); + return; + } + } + sockbuf_t* b = (info.flags & fd_info::buffer != 0) ? info.s.b : info.s.s->rdbuf(); + errno = 0; + for ( ; ; ) { + if ( b->_ebuf == b->egptr() ) { + // process extract data from buffer too slow for us! + if ( (info.flags & fd_info::level_triggered) == 0 ) { + epoll_event xev; + xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; + xev.data.fd = ev.data.fd; + info.flags |= fd_info::level_triggered; + if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ) < 0 ) { + std::cerr << "X " << ev.data.fd << ", " << errno << std::endl; + } + } + std::cerr << "Z " << ev.data.fd << ", " << errno << std::endl; + if ( info.p != 0 ) { + bool is_closed = false; + { + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.begin(); + for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == info.p ) { + is_closed = true; + std::cerr << "@@@ 2\n" << std::endl; + break; + } + } + } + if ( !is_closed ) { + (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + } + } + break; + } + // std::cerr << "ptr " << (void *)b->egptr() << ", " << errno << std::endl; + long offset = read( ev.data.fd, b->egptr(), sizeof(charT) * (b->_ebuf - b->egptr()) ); + // std::cerr << "offset " << offset << ", " << errno << std::endl; + if ( offset < 0 ) { + if ( (errno == EAGAIN) || (errno == EINTR) ) { + errno = 0; + epoll_event xev; + xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + xev.data.fd = ev.data.fd; + epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ); + break; + } else { + switch ( errno ) { + // case EINTR: // read was interrupted + // continue; + // break; + case EFAULT: // Bad address + case ECONNRESET: // Connection reset by peer + ev.events |= EPOLLRDHUP; // will be processed below + break; + default: + // std::cerr << "not listener, other " << ev.data.fd << std::hex << ev.events << std::dec << " : " << errno << std::endl; + break; + } + break; + } + } else if ( offset > 0 ) { + offset /= sizeof(charT); // if offset % sizeof(charT) != 0, rest will be lost! + + if ( info.flags & fd_info::level_triggered ) { + epoll_event xev; + xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + xev.data.fd = ev.data.fd; + info.flags &= ~static_cast<unsigned>(fd_info::level_triggered); + if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ) < 0 ) { + std::cerr << "Y " << ev.data.fd << ", " << errno << std::endl; + } + } + std::tr2::lock_guard<std::tr2::mutex> lk( b->ulck ); + b->setg( b->eback(), b->gptr(), b->egptr() + offset ); + b->ucnd.notify_one(); + if ( info.p != 0 ) { + // std::cerr << "data here" << std::endl; + bool is_closed = false; + { + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.begin(); + for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == info.p ) { + is_closed = true; + std::cerr << "@@@ 3\n" << std::endl; + break; + } + } + } + if ( !is_closed ) { + (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + } + } + } else { + std::cerr << "K " << ev.data.fd << ", " << errno << std::endl; + // EPOLLRDHUP may be missed in kernel, but offset 0 is the same + ev.events |= EPOLLRDHUP; // will be processed below + break; + } + } + } else { + std::cerr << "Q\n"; + } + + if ( (ev.events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR) ) != 0 ) { + // std::cerr << "Poll EPOLLRDHUP " << ev.data.fd << ", " << errno << std::endl; + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error + } + bool need_delete = true; + if ( info.p != 0 ) { + { + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.begin(); + for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == info.p ) { + need_delete = false; // will be deleted in 'final' method + std::cerr << "@@@ 4\n" << std::endl; + break; + } + } + } + if ( need_delete ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.s.s << std::endl; + (*info.p)( *info.s.s, typename socks_processor_t::adopt_close_t() ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.s.s << std::endl; + } + } + if ( (info.flags & fd_info::owner) != 0 && need_delete ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.s.s << std::endl; + delete info.s.s; + info.s.s = 0; + } else { + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.s.s << std::endl; + if ( (info.flags & fd_info::buffer) != 0 ) { + info.s.b->close(); + } else { + info.s.s->close(); + } + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + closed_queue.erase( ev.data.fd ); + } + descr.erase( ifd ); + } + // if ( ev.events & EPOLLHUP ) { + // std::cerr << "Poll HUP" << std::endl; + // } + // if ( ev.events & EPOLLERR ) { + // std::cerr << "Poll ERR" << std::endl; + // } + if ( ev.events & EPOLLPRI ) { + std::cerr << "Poll PRI" << std::endl; + } + if ( ev.events & EPOLLRDNORM ) { + std::cerr << "Poll RDNORM" << std::endl; + } + if ( ev.events & EPOLLRDBAND ) { + std::cerr << "Poll RDBAND" << std::endl; + } + if ( ev.events & EPOLLMSG ) { + std::cerr << "Poll MSG" << std::endl; + } +} + +template<class charT, class traits, class _Alloc> +void sockmgr<charT,traits,_Alloc>::final( sockmgr<charT,traits,_Alloc>::socks_processor_t& p ) +{ + std::tr2::lock_guard<std::tr2::mutex> lk_descr( dll ); + + for ( typename fd_container_type::iterator ifd = descr.begin(); ifd != descr.end(); ) { + if ( (ifd->second.flags & fd_info::owner) && (ifd->second.p == &p) ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)&p << " " << (void*)ifd->second.s.s << std::endl; + p( *ifd->second.s.s, typename socks_processor_t::adopt_close_t() ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)&p << " " << (void*)ifd->second.s.s << std::endl; + delete ifd->second.s.s; + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error + } + descr.erase( ifd++ ); + } else { + ++ifd; + } + } + + std::tr2::lock_guard<std::tr2::mutex> lk( cll ); + + // I can't use closed_queue.erase( p.fd() ) here: fd is -1 already + for ( typename fd_container_type::iterator closed_ifd = closed_queue.begin(); closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( closed_ifd->second.p == &p ) { + closed_queue.erase( closed_ifd ); + break; + } + } +} + +} // namespace detail + +} // namespace std Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-04-09 10:22:41 UTC (rev 1844) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-04-09 17:35:43 UTC (rev 1845) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/04/04 01:02:50 ptr> +// -*- C++ -*- Time-stamp: <08/04/09 20:14:14 yeti> /* * Copyright (c) 2008 @@ -80,7 +80,10 @@ { sock_processor_base::close(); - basic_socket<charT,traits,_Alloc>::mgr->final( *this ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)this << " " << std::tr2::getpid() << std::endl; + // Never uncomment next line: + // basic_socket<charT,traits,_Alloc>::mgr->final( *this ); + // this lead to virtual fuction call, that is already pure here. } void open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ); @@ -132,121 +135,6 @@ std::tr2::mutex _fd_lck; }; -template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::open( const in_addr& addr, int port, sock_base2::stype type, sock_base2::protocol prot ) -{ - std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); - if ( basic_socket_t::is_open_unsafe() ) { - return; - } - _mode = ios_base::in | ios_base::out; - _state = ios_base::goodbit; -#ifdef WIN32 - ::WSASetLastError( 0 ); -#endif - if ( prot == sock_base2::inet ) { - basic_socket_t::_fd = socket( PF_INET, type, 0 ); - if ( basic_socket_t::_fd == -1 ) { - _state |= ios_base::failbit | ios_base::badbit; - return; - } - // _open = true; - basic_socket_t::_address.inet.sin_family = AF_INET; - basic_socket_t::_address.inet.sin_port = htons( port ); - basic_socket_t::_address.inet.sin_addr.s_addr = addr.s_addr; - - if ( type == sock_base2::sock_stream || type == sock_base2::sock_seqpacket ) { - // let's try reuse local address - setoptions_unsafe( sock_base2::so_reuseaddr, true ); - } - - if ( ::bind( basic_socket_t::_fd, &basic_socket_t::_address.any, sizeof(basic_socket_t::_address) ) == -1 ) { - _state |= ios_base::failbit; -#ifdef WIN32 - ::closesocket( basic_socket_t::_fd ); -#else - ::close( basic_socket_t::_fd ); -#endif - basic_socket_t::_fd = -1; - return; - } - - if ( type == sock_base2::sock_stream || type == sock_base2::sock_seqpacket ) { - // I am shure, this is socket of type SOCK_STREAM | SOCK_SEQPACKET, - // so don't check return code from listen - ::listen( basic_socket_t::_fd, SOMAXCONN ); - basic_socket_t::mgr->push( *this ); - } - } else if ( prot == sock_base2::local ) { - return; - } else { - return; - } - _state = ios_base::goodbit; - - return; -} - -template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::close() -{ - std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); - if ( !basic_socket_t::is_open_unsafe() ) { - return; - } - basic_socket<charT,traits,_Alloc>::mgr->pop( *this, basic_socket_t::_fd ); -#ifdef WIN32 - ::closesocket( basic_socket_t::_fd ); -#else - ::shutdown( basic_socket_t::_fd, 2 ); - ::close( basic_socket_t::_fd ); -#endif - basic_socket_t::_fd = -1; -} - -template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::shutdown( sock_base2::shutdownflg dir ) -{ - std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); - if ( basic_socket_t::is_open_unsafe() ) { - if ( (dir & (sock_base2::stop_in | sock_base2::stop_out)) == - (sock_base2::stop_in | sock_base2::stop_out) ) { - ::shutdown( basic_socket_t::_fd, 2 ); - } else if ( dir & sock_base2::stop_in ) { - ::shutdown( basic_socket_t::_fd, 0 ); - } else if ( dir & sock_base2::stop_out ) { - ::shutdown( basic_socket_t::_fd, 1 ); - } - } -} - -template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::setoptions_unsafe( sock_base2::so_t optname, bool on_off, int __v ) -{ -#ifdef __unix - if ( basic_socket_t::is_open_unsafe() ) { - if ( optname != sock_base2::so_linger ) { - int turn = on_off ? 1 : 0; - if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&turn, - (socklen_t)sizeof(int) ) != 0 ) { - _state |= ios_base::failbit; - } - } else { - linger l; - l.l_onoff = on_off ? 1 : 0; - l.l_linger = __v; - if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&l, - (socklen_t)sizeof(linger) ) != 0 ) { - _state |= ios_base::failbit; - } - - } - } else { - _state |= ios_base::failbit; - } -#endif // __unix -} - typedef sock_processor_base<char,char_traits<char>,allocator<char> > sock_basic_processor; template <class Connect, class charT = char, class traits = std::char_traits<charT>, class _Alloc = std::allocator<charT>, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& ) = &Connect::connect > @@ -308,6 +196,9 @@ } ready_pool.clear(); + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)this << " " << std::tr2::getpid() << std::endl; + basic_socket<charT,traits,_Alloc>::mgr->final( *this ); + ((Init *)Init_buf)->~Init(); } @@ -409,189 +300,16 @@ friend struct _not_empty; }; -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -int connect_processor<Connect, charT, traits, _Alloc, C>::Init::_count = 0; +namespace detail { -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -bool connect_processor<Connect, charT, traits, _Alloc, C>::Init::_at_fork = false; - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -std::tr2::mutex connect_processor<Connect, charT, traits, _Alloc, C>::Init::_init_lock; - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::Init::_guard( int direction ) +class stop_request : + public std::exception { - if ( direction ) { - std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); - if ( _count++ == 0 ) { -#ifdef __FIT_PTHREADS - if ( !_at_fork ) { // call only once - if ( pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ) ) { - // throw system_error - } - _at_fork = true; - } -#endif -// _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); - } - } else { - std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); - if ( --_count == 0 ) { + public: + virtual const char* what() throw() + { return "sockmgr receive stop reqest"; } +}; - } - } -} - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_prepare() -{ _init_lock.lock(); } - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_child() -{ - _init_lock.unlock(); - - if ( _count != 0 ) { - // std::cerr << "SHOULD NEVER HAPPEN!!!!\n"; - throw std::logic_error( "Fork while connect_processor working may has unexpected behaviour in child process" ); - } - // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); -} - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_parent() -{ _init_lock.unlock(); } - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -char connect_processor<Connect, charT, traits, _Alloc, C>::Init_buf[128]; - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::close() -{ - base_t::close(); - - { - std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); - _in_work = false; // <--- set before cnd.notify_one(); (below in this func) - } - - std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); - ready_pool.push_back( processor() ); // make ready_pool not empty - // std::cerr << "=== " << ready_pool.size() << std::endl; - cnd.notify_one(); -} - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_new_t& ) -{ - Connect* c = new Connect( s ); - if ( s.rdbuf()->in_avail() ) { - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - ready_pool.push_back( processor( c, &s ) ); - cnd.notify_one(); - } else { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool.insert( std::make_pair( &s, c ) ); - } -} - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_close_t& ) -{ - { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - typename worker_pool_t::iterator i = worker_pool.find( &s ); - if ( i != worker_pool.end() ) { - delete i->second; - // std::cerr << "oops\n"; - worker_pool.erase( i ); - return; - } - } - - Connect* c = 0; - { - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - typename ready_pool_t::iterator j = std::find( ready_pool.begin(), ready_pool.end(), /* std::bind2nd( typename processor::equal_to(), &s ) */ &s ); - if ( j != ready_pool.end() ) { - // std::cerr << "oops 2\n"; - c = j->c; - ready_pool.erase( j ); - } - } - if ( c != 0 ) { - (c->*C)( s ); - delete c; - } -} - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockstream_t& s, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_data_t& ) -{ - Connect* c; - - { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - typename worker_pool_t::const_iterator i = worker_pool.find( &s ); - if ( i == worker_pool.end() ) { - return; - } - c = i->second; - worker_pool.erase( i ); - } - - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - ready_pool.push_back( processor( c, &s ) ); - cnd.notify_one(); - // std::cerr << "notify data " << (void *)c << " " << ready_pool.size() << std::endl; -} - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -bool connect_processor<Connect, charT, traits, _Alloc, C>::pop_ready( processor& p ) -{ - { - std::tr2::unique_lock<std::tr2::mutex> lk( rdlock ); - - cnd.wait( lk, not_empty ); - p = ready_pool.front(); // it may contain p.c == 0, p.s == 0, if !in_work() - ready_pool.pop_front(); - // std::cerr << "pop 1\n"; - if ( p.c == 0 ) { // wake up, but _in_work may be still true here (in processor pipe?), - return false; // even I know that _in_work <- false before notification... - } // so, check twice - } - - // std::cerr << "pop 2\n"; - - std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); - return _in_work ? true : false; -} - - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::worker() -{ - _in_work = true; - - processor p; - - while ( pop_ready( p ) ) { - std::cerr << "worker 1\n"; - (p.c->*C)( *p.s ); - std::cerr << "worker 2\n"; - if ( p.s->rdbuf()->in_avail() ) { - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - ready_pool.push_back( p ); - } else { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool[p.s] = p.c; - } - std::cerr << "worker 3\n"; - } -} - -namespace detail { - template<class charT, class traits, class _Alloc> class sockmgr { @@ -724,6 +442,7 @@ fd_info info = { fd_info::listener, 0, &p }; std::tr2::lock_guard<std::tr2::mutex> lk( cll ); closed_queue[_fd] = info; + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)&p << " " << std::tr2::getpid() << std::endl; } void final( socks_processor_t& p ); @@ -733,6 +452,7 @@ fd_info info = { 0, reinterpret_cast<sockstream_t*>(b), 0 }; std::tr2::lock_guard<std::tr2::mutex> lk( cll ); closed_queue[fd] = info; + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)b << " " << std::tr2::getpid() << std::endl; } private: @@ -768,434 +488,6 @@ std::tr2::mutex dll; }; -template<class charT, class traits, class _Alloc> -void sockmgr<charT,traits,_Alloc>::final( sockmgr<charT,traits,_Alloc>::socks_processor_t& p ) -{ - // lock descr here ... should be - std::tr2::lock_guard<std::tr2::mutex> lk_descr( dll ); - - for ( typename fd_container_type::iterator ifd = descr.begin(); ifd != descr.end(); ) { - if ( (ifd->second.flags & fd_info::owner) && (ifd->second.p == &p) ) { - std::cerr << (void*)&p << " " << (void*)ifd->second.s.s << std::endl; - p( *ifd->second.s.s, typename socks_processor_t::adopt_close_t() ); - delete ifd->second.s.s; - if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { - // throw system_error - } - descr.erase( ifd++ ); - } else { - ++ifd; - } - } - - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - - // I can't use closed_queue.erase( p.fd() ) here: fd is -1 already - for ( typename fd_container_type::iterator closed_ifd = closed_queue.begin(); closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == &p ) { - closed_queue.erase( closed_ifd ); - break; - } - } -} - -template<class charT, class traits, class _Alloc> -void sockmgr<charT,traits,_Alloc>::io_worker() -{ - epoll_event ev[/*n_ret*/ 512 ]; - -/* - ctl _xctl; - int r = read( pipefd[0], &_xctl, sizeof(ctl) ); - - if ( _xctl.cmd == rqstart ) { - std::cerr << "io_worker fine" << std::endl; - } else { - std::cerr << "io_worker not fine, " << r << ", " << errno << std::endl; - } -*/ - - try { - for ( ; ; ) { - int n = epoll_wait( efd, &ev[0], /* n_ret */ 512, -1 ); - - if ( n < 0 ) { - if ( errno == EINTR ) { - continue; - } - // throw system_error - } - // std::cerr << "epoll see " << n << std::endl; - - std::tr2::lock_guard<std::tr2::mutex> lk( dll ); - - for ( int i = 0; i < n; ++i ) { - // std::cerr << "epoll i = " << i << std::endl; - if ( ev[i].data.fd == pipefd[0] ) { - // std::cerr << "on pipe\n"; - cmd_from_pipe(); - } else { - // std::cerr << "#\n"; - - typename fd_container_type::iterator ifd = descr.find( ev[i].data.fd ); - if ( ifd == descr.end() ) { - throw std::logic_error( "file descriptor in epoll, but not in descr[]" ); - } - - fd_info& info = ifd->second; - if ( info.flags & fd_info::listener ) { - // std::cerr << "%\n"; - process_listener( ev[i], ifd ); - } else { - // std::cerr << "not listener\n"; - process_regular( ev[i], ifd ); - } - } - } - } - } - catch ( std::exception& e ) { - std::cerr << e.what() << std::endl; - } -} - -template<class charT, class traits, class _Alloc> -void sockmgr<charT,traits,_Alloc>::cmd_from_pipe() -{ - epoll_event ev_add; - ctl _ctl; - - int r = read( pipefd[0], &_ctl, sizeof(ctl) ); - if ( r < 0 ) { - // throw system_error - // std::cerr << "Read pipe\n"; - } else if ( r == 0 ) { - // std::cerr << "Read pipe 0\n"; - throw runtime_error( "Read pipe return 0" ); - } - - switch ( _ctl.cmd ) { - case listener: - ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - ev_add.data.fd = static_cast<socks_processor_t*>(_ctl.data.ptr)->fd(); - if ( ev_add.data.fd >= 0 ) { - if ( fcntl( ev_add.data.fd, F_SETFL, fcntl( ev_add.data.fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { - // std::cerr << "xxx " << errno << " " << std::tr2::getpid() << std::endl; - throw std::runtime_error( "can't establish nonblock mode on listener" ); - } - fd_info new_info = { fd_info::listener, 0, static_cast<socks_processor_t*>(_ctl.data.ptr) }; - descr[ev_add.data.fd] = new_info; - if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { - descr.erase( ev_add.data.fd ); - // throw system_error - } - } - break; -#if 0 - case tcp_stream: - ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - ev_add.data.fd = static_cast<sockstream_t*>(_ctl.data.ptr)->rdbuf()->fd(); - if ( ev_add.data.fd >= 0 ) { - fd_info new_info = { 0, static_cast<sockstream_t*>(_ctl.data.ptr), 0 }; - descr[ev_add.data.fd] = new_info; - if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { - descr.erase( ev_add.data.fd ); - // throw system_error - } - } - break; -#endif - case tcp_buffer: - ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - ev_add.data.fd = static_cast<sockbuf_t*>(_ctl.data.ptr)->fd(); - if ( ev_add.data.fd >= 0 ) { - fd_info new_info = { fd_info::buffer, static_cast<sockstream_t* /* sockbuf_t* */ >(_ctl.data.ptr), 0 }; - descr[ev_add.data.fd] = new_info; - if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { - descr.erase( ev_add.data.fd ); - // throw system_error - } - } - break; - case rqstop: - // std::cerr << "Stop request\n"; - throw runtime_error( "Stop request (normal flow)" ); - break; - } -} - -template<class charT, class traits, class _Alloc> -void sockmgr<charT,traits,_Alloc>::process_listener( epoll_event& ev, typename sockmgr<charT,traits,_Alloc>::fd_container_type::iterator ifd ) -{ - if ( ev.events & EPOLLRDHUP ) { - epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ); - // walk through descr and detach every .p ? - descr.erase( ifd ); - std::cerr << "Remove listener EPOLLRDHUP\n"; - } else if ( ev.events & EPOLLIN ) { - sockaddr addr; - socklen_t sz = sizeof( sockaddr_in ); - - fd_info& info = ifd->second; - - for ( ; ; ) { - int fd = accept( ev.data.fd, &addr, &sz ); - if ( fd < 0 ) { - std::cerr << "Accept, listener # " << ev.data.fd << ", errno " << errno << std::endl; - if ( (errno == EINTR) || (errno == ECONNABORTED) /* || (errno == ERESTARTSYS) */ ) { - continue; - } - if ( !(errno == EAGAIN || errno == EWOULDBLOCK) ) { - // std::cerr << "Accept, listener " << ev[i].data.fd << ", errno " << errno << std::endl; - // throw system_error ? - } -#if 0 - { - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); - if ( closed_ifd != closed_queue.end() ) { - typename fd_container_type::iterator ifd = descr.begin(); - for ( ; ifd != descr.end(); ) { - if ( ifd->second.p == closed_ifd->second.p ) { - descr.erase( ifd++ ); - } else { - ++ifd; - } - } - closed_queue.erase( closed_ifd ); - } - } -#endif - break; - } - // std::cerr << "listener accept " << fd << std::endl; - if ( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { - throw std::runtime_error( "can't establish nonblock mode" ); - } - sockstream_t* s; - - try { - s = new sockstream_t(); - std::cerr << "sockstream_t: " << (void*)s << std::endl; - if ( s->rdbuf()->_open_sockmgr( fd, addr ) ) { - epoll_event ev_add; - ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - ev_add.data.fd = fd; - fd_info new_info = { fd_info::owner, s, info.p }; - descr[fd] = new_info; - - if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { - std::cerr << "Accept, add " << fd << ", errno " << errno << std::endl; - descr.erase( fd ); - // throw system_error - } - std::cerr << "adopt_new_t()\n"; - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.begin(); - for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == info.p ) { - break; - } - } - if ( closed_ifd == closed_queue.end() ) { - (*info.p)( *s, typename socks_processor_t::adopt_new_t() ); - } else { - std::cerr << "@@@ 1\n" << std::endl; - } - } else { - std::cerr << "Accept, delete " << fd << std::endl; - delete s; - } - } - catch ( const std::bad_alloc& ) { - // nothing - } - catch ( ... ) { - descr.erase( fd ); - delete s; - } - } - } else { - // std::cerr << "listener: " << std::hex << ev.events << std::dec << std::endl; - } -} - -template<class charT, class traits, class _Alloc> -void sockmgr<charT,traits,_Alloc>::process_regular( epoll_event& ev, typename sockmgr<charT,traits,_Alloc>::fd_container_type::iterator ifd ) -{ - fd_info& info = ifd->second; - - if ( ev.events & EPOLLIN ) { - if ( (info.flags & fd_info::owner) == 0 ) { - // marginal case: me not owner (registerd via push(), - // when I owner, I know destroy point), - // already closed, but I not see closed event yet; - // object may be deleted already, so I can't - // call b->egptr() etc. here - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); - if ( closed_ifd != closed_queue.end() ) { - closed_queue.erase( closed_ifd ); - if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { - // throw system_error - } - descr.erase( ifd ); - return; - } - } - sockbuf_t* b = (info.flags & fd_info::buffer != 0) ? info.s.b : info.s.s->rdbuf(); - errno = 0; - for ( ; ; ) { - if ( b->_ebuf == b->egptr() ) { - // process extract data from buffer too slow for us! - if ( (info.flags & fd_info::level_triggered) == 0 ) { - epoll_event xev; - xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; - xev.data.fd = ev.data.fd; - info.flags |= fd_info::level_triggered; - if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ) < 0 ) { - std::cerr << "X " << ev.data.fd << ", " << errno << std::endl; - } - } - std::cerr << "Z " << ev.data.fd << ", " << errno << std::endl; - if ( info.p != 0 ) { - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.begin(); - for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == info.p ) { - break; - } - } - if ( closed_ifd == closed_queue.end() ) { - (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); - } else { - std::cerr << "@@@ 2\n" << std::endl; - } - } - break; - } - std::cerr << "ptr " << (void *)b->egptr() << ", " << errno << std::endl; - long offset = read( ev.data.fd, b->egptr(), sizeof(charT) * (b->_ebuf - b->egptr()) ); - std::cerr << "offset " << offset << ", " << errno << std::endl; - if ( offset < 0 ) { - if ( (errno == EAGAIN) || (errno == EINTR) ) { - errno = 0; - epoll_event xev; - xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - xev.data.fd = ev.data.fd; - epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ); - break; - } else { - switch ( errno ) { - // case EINTR: // read was interrupted - // continue; - // break; - case EFAULT: // Bad address - case ECONNRESET: // Connection reset by peer - ev.events |= EPOLLRDHUP; // will be processed below - break; - default: - std::cerr << "not listener, other " << ev.data.fd << std::hex << ev.events << std::dec << " : " << errno << std::endl; - break; - } - break; - } - } else if ( offset > 0 ) { - offset /= sizeof(charT); // if offset % sizeof(charT) != 0, rest will be lost! - - if ( info.flags & fd_info::level_triggered ) { - epoll_event xev; - xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - xev.data.fd = ev.data.fd; - info.flags &= ~static_cast<unsigned>(fd_info::level_triggered); - if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ) < 0 ) { - std::cerr << "Y " << ev.data.fd << ", " << errno << std::endl; - } - } - std::tr2::lock_guard<std::tr2::mutex> lk( b->ulck ); - b->setg( b->eback(), b->gptr(), b->egptr() + offset ); - b->ucnd.notify_one(); - if ( info.p != 0 ) { - // std::cerr << "data here" << std::endl; - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.begin(); - for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == info.p ) { - break; - } - } - if ( closed_ifd == closed_queue.end() ) { - (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); - } else { - std::cerr << "@@@ 3\n" << std::endl; - } - } - } else { - std::cerr << "K " << ev.data.fd << ", " << errno << std::endl; - // EPOLLRDHUP may be missed in kernel, but offset 0 is the same - ev.events |= EPOLLRDHUP; // will be processed below - break; - } - } - } else { - std::cerr << "Q\n"; - } - - if ( (ev.events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR) ) != 0 ) { - // std::cerr << "Poll EPOLLRDHUP " << ev.data.fd << ", " << errno << std::endl; - if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { - // throw system_error - } - bool need_delete = true; - if ( info.p != 0 ) { - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.begin(); - for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == info.p ) { - break; - } - } - if ( closed_ifd == closed_queue.end() ) { - (*info.p)( *info.s.s, typename socks_processor_t::adopt_close_t() ); - } else { - need_delete = false; // will be deleted in 'final' method - std::cerr << "@@@ 4\n" << std::endl; - } - } - if ( (info.flags & fd_info::owner) != 0 && need_delete ) { - delete info.s.s; - info.s.s = 0; - } else { - if ( (info.flags & fd_info::buffer) != 0 ) { - info.s.b->close(); - } else { - info.s.s->close(); - } - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - closed_queue.erase( ev.data.fd ); - } - descr.erase( ifd ); - } - // if ( ev.events & EPOLLHUP ) { - // std::cerr << "Poll HUP" << std::endl; - // } - // if ( ev.events & EPOLLERR ) { - // std::cerr << "Poll ERR" << std::endl; - // } - if ( ev.events & EPOLLPRI ) { - std::cerr << "Poll PRI" << std::endl; - } - if ( ev.events & EPOLLRDNORM ) { - std::cerr << "Poll RDNORM" << std::endl; - } - if ( ev.events & EPOLLRDBAND ) { - std::cerr << "Poll RDBAND" << std::endl; - } - if ( ev.events & EPOLLMSG ) { - std::cerr << "Poll MSG" << std::endl; - } ... [truncated message content] |
From: <oke...@us...> - 2008-06-03 13:20:05
|
Revision: 1884 http://complement.svn.sourceforge.net/complement/?rev=1884&view=rev Author: okechina Date: 2008-06-03 06:19:42 -0700 (Tue, 03 Jun 2008) Log Message: ----------- Changes made for successful project compilation Modified Paths: -------------- branches/complement-sockios/explore/include/mt/mutex branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/mt/date_time.cc Modified: branches/complement-sockios/explore/include/mt/mutex =================================================================== --- branches/complement-sockios/explore/include/mt/mutex 2008-05-26 09:20:46 UTC (rev 1883) +++ branches/complement-sockios/explore/include/mt/mutex 2008-06-03 13:19:42 UTC (rev 1884) @@ -379,7 +379,7 @@ { if ( --_count == 0 ) { # ifdef __FIT_PTHREADS - _id = __STATIC_CAST(pthread_t,-1); + _id = static_cast<pthread_t>(-1); pthread_spin_unlock( &this->_M_lock ); # endif } Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-05-26 09:20:46 UTC (rev 1883) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-03 13:19:42 UTC (rev 1884) @@ -241,7 +241,8 @@ } } if ( c != 0 ) { - (c->*C)( s ); +//using unknown variable s +// (c->*C)( s ); delete c; } } @@ -501,7 +502,9 @@ epoll_event ev_add; ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; ev_add.data.fd = fd; - fd_info new_info = { fd_info::owner, s, info.p }; +//undeclared s with some flags +// fd_info new_info = { fd_info::owner, s, info.p }; + fd_info new_info = { fd_info::owner, 0, info.p }; descr[fd] = new_info; if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-05-26 09:20:46 UTC (rev 1883) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-06-03 13:19:42 UTC (rev 1884) @@ -110,13 +110,13 @@ protected: void setoptions_unsafe( sock_base2::so_t optname, bool on_off = true, int __v = 0 ); - sockstream_t* create_stream( int fd ) +/* sockstream_t* create_stream( int fd ) { typename base_t::sockstream_t* s = new typename base_t::sockstream_t(); s->rdbuf()->_open_sockmgr( fd, addr ); return s; } - +*/ public: bool is_open() const { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); return basic_socket_t::is_open_unsafe(); } Modified: branches/complement-sockios/explore/lib/mt/date_time.cc =================================================================== --- branches/complement-sockios/explore/lib/mt/date_time.cc 2008-05-26 09:20:46 UTC (rev 1883) +++ branches/complement-sockios/explore/lib/mt/date_time.cc 2008-06-03 13:19:42 UTC (rev 1884) @@ -14,6 +14,7 @@ #include <mt/date_time> #include <ctime> +#include <sys/time.h> namespace std { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <oke...@us...> - 2008-06-04 13:54:00
|
Revision: 1885 http://complement.svn.sourceforge.net/complement/?rev=1885&view=rev Author: okechina Date: 2008-06-04 06:53:54 -0700 (Wed, 04 Jun 2008) Log Message: ----------- Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-03 13:19:42 UTC (rev 1884) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-04 13:53:54 UTC (rev 1885) @@ -502,7 +502,7 @@ epoll_event ev_add; ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; ev_add.data.fd = fd; -//undeclared s with some flags +//undeclared s // fd_info new_info = { fd_info::owner, s, info.p }; fd_info new_info = { fd_info::owner, 0, info.p }; descr[fd] = new_info; @@ -734,7 +734,7 @@ for ( typename fd_container_type::iterator ifd = descr.begin(); ifd != descr.end(); ) { if ( (ifd->second.flags & fd_info::owner) && (ifd->second.p == &p) ) { std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)&p << " " << (void*)ifd->second.s.s << std::endl; - p( *ifd->second.s.s, typename socks_processor_t::adopt_close_t() ); + p( /* *ifd->second.s.s */ /* *ifd->second.s.s.rdbuf()->fd() */, typename socks_processor_t::adopt_close_t() ); std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)&p << " " << (void*)ifd->second.s.s << std::endl; delete ifd->second.s.s; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-06-03 13:19:42 UTC (rev 1884) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-06-04 13:53:54 UTC (rev 1885) @@ -110,13 +110,13 @@ protected: void setoptions_unsafe( sock_base2::so_t optname, bool on_off = true, int __v = 0 ); -/* sockstream_t* create_stream( int fd ) + sockstream_t* create_stream( int fd ) { - typename base_t::sockstream_t* s = new typename base_t::sockstream_t(); - s->rdbuf()->_open_sockmgr( fd, addr ); + sockstream_t* s = new sockstream_t(); + // s->rdbuf()->_open_sockmgr( fd, addr ); return s; } -*/ + public: bool is_open() const { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); return basic_socket_t::is_open_unsafe(); } @@ -193,7 +193,9 @@ // { // std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); for ( typename worker_pool_t::iterator i = worker_pool.begin(); i != worker_pool.end(); ++i ) { - delete i->second; + // delete i->second; + delete i->second.s; + delete i->second.c; } worker_pool.clear(); // } Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-03 13:19:42 UTC (rev 1884) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-04 13:53:54 UTC (rev 1885) @@ -46,11 +46,11 @@ { /* cerr << "In destructor\n"; */ } protected: - virtual void operator ()( sockstream_t& s, const adopt_new_t& ) + virtual void operator ()( int, const adopt_new_t& ) { lock_guard<mutex> lk(lock); b.wait(); ++n_cnt; } - virtual void operator ()( sockstream_t& s, const adopt_close_t& ) + virtual void operator ()( int, const adopt_close_t& ) { lock_guard<mutex> lk(lock); b.wait(); ++c_cnt; } - virtual void operator ()( sockstream_t& s, const adopt_data_t& ) + virtual void operator ()( int, const adopt_data_t& ) { lock_guard<mutex> lk(lock); ++d_cnt; } public: @@ -80,17 +80,17 @@ { } protected: - virtual void operator ()( sockstream_t& s, const adopt_new_t& ) + virtual void operator ()( int, const adopt_new_t& ) { lock_guard<mutex> lk(lock); b.wait(); ++n_cnt; } - virtual void operator ()( sockstream_t& s, const adopt_close_t& ) + virtual void operator ()( int, const adopt_close_t& ) { lock_guard<mutex> lk(lock); b.wait(); ++c_cnt; } - virtual void operator ()( sockstream_t& s, const adopt_data_t& ) + virtual void operator ()( int, const adopt_data_t& ) { lock_guard<mutex> lk(lock); b.wait(); ++d_cnt; string str; - getline( s, str ); + // getline( s, str ); // map fd -> s EXAM_CHECK_ASYNC( str == "Hello" ); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-05 08:57:46
|
Revision: 1886 http://complement.svn.sourceforge.net/complement/?rev=1886&view=rev Author: complement Date: 2008-06-05 01:57:35 -0700 (Thu, 05 Jun 2008) Log Message: ----------- fix compilation; shouldn't work indeed, review required Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sockstream2 branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/sockstream2 =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream2 2008-06-04 13:53:54 UTC (rev 1885) +++ branches/complement-sockios/explore/include/sockios/sockstream2 2008-06-05 08:57:35 UTC (rev 1886) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/04/09 13:02:18 yeti> +// -*- C++ -*- Time-stamp: <08/06/05 12:53:21 yeti> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -190,6 +190,9 @@ template <class charT, class traits, class _Alloc> class sockmgr; } // namespace detail +template <class charT, class traits, class _Alloc> +class sock_processor_base; + template<class charT, class traits, class _Alloc> class basic_socket { @@ -617,6 +620,7 @@ std::tr2::condition_variable ucnd; friend class detail::sockmgr<charT,traits,_Alloc>; + friend class sock_processor_base<charT,traits,_Alloc>; }; template <class charT, class traits, class _Alloc> @@ -768,7 +772,7 @@ typedef basic_sockbuf2<char,char_traits<char>,allocator<char> > sockbuf2; // typedef basic_sockbuf2<wchar_t,char_traits<wchar_t>,allocator<wchar_t> > wsockbuf; -typedef basic_sockstream2<char,char_traits<char>,allocator<char> > sockstream2; +typedef basic_sockstream2<char,std::char_traits<char>,std::allocator<char> > sockstream2; // typedef basic_sockstream<wchar_t,char_traits<wchar_t>,allocator<wchar_t> > wsockstream; #ifdef STLPORT Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-04 13:53:54 UTC (rev 1885) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-05 08:57:35 UTC (rev 1886) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/04/11 21:52:28 yeti> +// -*- C++ -*- Time-stamp: <08/06/05 12:55:59 yeti> /* * Copyright (c) 2008 @@ -199,19 +199,19 @@ } template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream2<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( int fd, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_new_t& ) +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( int fd, const sockaddr& addr ) { - typename base_t::sockstream_t* s = base_t::create_stream( fd ); + typename base_t::sockstream_t* s = base_t::create_stream( fd, addr ); - Connect* c = new Connect( s ); // bad point! I can't read from s in ctor indeed! + Connect* c = new Connect( *s ); // bad point! I can't read from s in ctor indeed! - if ( s.rdbuf()->in_avail() ) { + if ( s->rdbuf()->in_avail() ) { std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - ready_pool.push_back( processor( c, &s ) ); + ready_pool.push_back( processor( c, s ) ); cnd.notify_one(); } else { std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool.insert( std::make_pair( &s, c ) ); + worker_pool.insert( std::make_pair( fd, processor( c, s ) ) ); } } @@ -306,7 +306,7 @@ ready_pool.push_back( p ); } else { std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool[p.s] = p.c; + worker_pool[p.s->rdbuf()->fd()] = p; } // std::cerr << "worker 3\n"; } @@ -497,7 +497,7 @@ try { std::cerr << __FILE__ << ":" << __LINE__ << " new sockstream_t" << std::endl; - (*info.p)( fd, typename socks_processor_t::adopt_new_t() ); + (*info.p)( fd, addr ); epoll_event ev_add; ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; @@ -591,7 +591,7 @@ } } if ( !is_closed ) { - (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + (*info.p)( ev.data.fd, typename socks_processor_t::adopt_data_t() ); } } break; @@ -652,7 +652,7 @@ } } if ( !is_closed ) { - (*info.p)( *info.s.s, typename socks_processor_t::adopt_data_t() ); + (*info.p)( ev.data.fd, typename socks_processor_t::adopt_data_t() ); } } } else { @@ -686,13 +686,13 @@ } if ( need_delete ) { std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.s.s << std::endl; - (*info.p)( *info.s.s, typename socks_processor_t::adopt_close_t() ); + (*info.p)( ifd->first, typename socks_processor_t::adopt_close_t() ); std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.s.s << std::endl; } } if ( (info.flags & fd_info::owner) != 0 && need_delete ) { std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.s.s << std::endl; - delete info.s.s; + delete info.s.s; // Ahtung! info.s.s = 0; } else { std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.s.s << std::endl; @@ -734,7 +734,7 @@ for ( typename fd_container_type::iterator ifd = descr.begin(); ifd != descr.end(); ) { if ( (ifd->second.flags & fd_info::owner) && (ifd->second.p == &p) ) { std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)&p << " " << (void*)ifd->second.s.s << std::endl; - p( /* *ifd->second.s.s */ /* *ifd->second.s.s.rdbuf()->fd() */, typename socks_processor_t::adopt_close_t() ); + p( ifd->first, typename socks_processor_t::adopt_close_t() ); std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)&p << " " << (void*)ifd->second.s.s << std::endl; delete ifd->second.s.s; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-06-04 13:53:54 UTC (rev 1885) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-06-05 08:57:35 UTC (rev 1886) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/04/11 22:14:39 yeti> +// -*- C++ -*- Time-stamp: <08/06/05 12:38:28 yeti> /* * Copyright (c) 2008 @@ -100,7 +100,7 @@ virtual void close(); - virtual void operator ()( int fd, const adopt_new_t& ) = 0; + virtual void operator ()( int fd, const sockaddr& ) = 0; virtual void operator ()( int fd, const adopt_close_t& ) = 0; virtual void operator ()( int fd, const adopt_data_t& ) = 0; @@ -110,10 +110,10 @@ protected: void setoptions_unsafe( sock_base2::so_t optname, bool on_off = true, int __v = 0 ); - sockstream_t* create_stream( int fd ) + sockstream_t* create_stream( int fd, const sockaddr& addr ) { sockstream_t* s = new sockstream_t(); - // s->rdbuf()->_open_sockmgr( fd, addr ); + s->rdbuf()->_open_sockmgr( fd, addr ); return s; } @@ -216,7 +216,7 @@ { if ( ploop.joinable() ) { ploop.join(); } } private: - virtual void operator ()( int fd, const typename base_t::adopt_new_t& ); + virtual void operator ()( int fd, const sockaddr& ); virtual void operator ()( int fd, const typename base_t::adopt_close_t& ); virtual void operator ()( int fd, const typename base_t::adopt_data_t& ); Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-04 13:53:54 UTC (rev 1885) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-05 08:57:35 UTC (rev 1886) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/04/09 21:18:52 yeti> +// -*- C++ -*- Time-stamp: <08/06/05 12:37:58 yeti> /* * @@ -46,7 +46,7 @@ { /* cerr << "In destructor\n"; */ } protected: - virtual void operator ()( int, const adopt_new_t& ) + virtual void operator ()( int, const sockaddr& ) { lock_guard<mutex> lk(lock); b.wait(); ++n_cnt; } virtual void operator ()( int, const adopt_close_t& ) { lock_guard<mutex> lk(lock); b.wait(); ++c_cnt; } @@ -80,7 +80,7 @@ { } protected: - virtual void operator ()( int, const adopt_new_t& ) + virtual void operator ()( int, const sockaddr& ) { lock_guard<mutex> lk(lock); b.wait(); ++n_cnt; } virtual void operator ()( int, const adopt_close_t& ) { lock_guard<mutex> lk(lock); b.wait(); ++c_cnt; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-09 18:32:08
|
Revision: 1892 http://complement.svn.sourceforge.net/complement/?rev=1892&view=rev Author: complement Date: 2008-06-09 11:31:16 -0700 (Mon, 09 Jun 2008) Log Message: ----------- sockstream2 family renamed to sockstream; basic_sockbuf become proxy, real implementation is basic_sockbuf_aux and should be controlled from sockmgr; just compile, not really work Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/Makefile.inc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc branches/complement-sockios/explore/lib/sockios/ut/sockios_test.cc branches/complement-sockios/explore/lib/sockios/ut/sockios_test.h branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc Added Paths: ----------- branches/complement-sockios/explore/include/sockios/sockstream branches/complement-sockios/explore/include/sockios/sockstream.cc Removed Paths: ------------- branches/complement-sockios/explore/include/sockios/sockstream branches/complement-sockios/explore/include/sockios/sockstream.cc branches/complement-sockios/explore/include/sockios/sockstream2 branches/complement-sockios/explore/include/sockios/sockstream2.cc Deleted: branches/complement-sockios/explore/include/sockios/sockstream =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream 2008-06-07 17:06:27 UTC (rev 1891) +++ branches/complement-sockios/explore/include/sockios/sockstream 2008-06-09 18:31:16 UTC (rev 1892) @@ -1,623 +0,0 @@ -// -*- C++ -*- Time-stamp: <07/09/06 23:42:19 ptr> - -/* - * Copyright (c) 1997-1999, 2002, 2003, 2005-2007 - * Petr Ovtchenkov - * - * Portion Copyright (c) 1999-2001 - * Parallel Graphics Ltd. - * - * Licensed under the Academic Free License version 3.0 - * - */ - -#ifndef __SOCKSTREAM__ -#define __SOCKSTREAM__ - -#ifndef __config_feature_h -#include <config/feature.h> -#endif - -#if !defined(__sun) && !defined(_WIN32) // i.e. __linux and __hpux -#include <sys/poll.h> // pollfd -#endif - -#ifndef __XMT_H -#include <mt/xmt.h> -#endif - -#include <netdb.h> -#include <netinet/in.h> - -#include <iosfwd> -#include <ios> -#include <streambuf> -#include <iostream> -#include <string> -#include <stdexcept> - -#ifdef WIN32 -# include <winsock2.h> -#else // WIN32 -# include <unistd.h> -# include <sys/types.h> -# if defined(__hpux) && !defined(_INCLUDE_XOPEN_SOURCE_EXTENDED) -# define _INCLUDE_XOPEN_SOURCE_EXTENDED -# endif -# include <sys/socket.h> -# if !defined(__UCLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -# include <stropts.h> -# endif -# ifdef __sun -# include <sys/conf.h> -# endif -# include <netinet/in.h> -# include <arpa/inet.h> -# include <netdb.h> -# ifdef __hpux -// # ifndef socklen_t // HP-UX 10.01 -// typedef int socklen_t; -// # endif -# endif -# include <cerrno> -#endif // !WIN32 - -#include <sockios/netinfo.h> - -#ifdef STLPORT -_STLP_BEGIN_NAMESPACE -#else -namespace std { -#endif - -class sock_base -{ - public: - typedef unsigned long shutdownflg; -#ifdef __unix - typedef int socket_type; -#endif -#ifdef WIN32 - typedef SOCKET socket_type; -#endif - - enum stype { - sock_stream = SOCK_STREAM, // stream socket - sock_dgram = SOCK_DGRAM, // datagram socket - sock_raw = SOCK_RAW, // raw-protocol interface - sock_rdm = SOCK_RDM, // reliably-delivered message - sock_seqpacket = SOCK_SEQPACKET // sequenced packet stream - }; - - enum protocol { - local, // local to host (pipes, portals) - inet // internetwork: UDP, TCP, etc. - }; - - // Option flags per-socket. - enum so_t { - so_debug = SO_DEBUG, // turn on debugging info recording -#ifndef __linux - so_acceptconn = SO_ACCEPTCONN, // socket has had listen() -#endif - so_reuseaddr = SO_REUSEADDR, // allow local address reuse - so_keepalive = SO_KEEPALIVE, // keep connections alive - so_dontroute = SO_DONTROUTE, // just use interface addresses - so_broadcast = SO_BROADCAST, // permit sending of broadcast msgs -#ifndef __linux - so_useloopback = SO_USELOOPBACK, // bypass hardware when possible -#endif - so_linger = SO_LINGER, // linger on close if data present - so_oobinline = SO_OOBINLINE, // leave received OOB data in line - // Additional options, not kept in so_options. - so_sndbuf = SO_SNDBUF, // send buffer size - so_rcvbuf = SO_RCVBUF, // receive buffer size - so_sndlowat = SO_SNDLOWAT, // send low-water mark - so_rcvlowat = SO_RCVLOWAT, // receive low-water mark - so_sndtimeo = SO_SNDTIMEO, // send timeout - so_rcvtimeo = SO_RCVTIMEO, // receive timeout - so_error = SO_ERROR, // get error status and clear - so_type = SO_TYPE // get socket type -#ifdef __sun // indeed HP-UX 11.00 also has it, but 10.01 not - , - so_prototype = SO_PROTOTYPE // get/set protocol type -#endif - }; - - // Level number for (get/set)sockopt() to apply to socket itself. -// enum _level { -// sol_socket = SOL_SOCKET -// }; - - enum shutdownflags { - stop_in = 0x1, - stop_out = 0x2 - }; - -#ifdef WIN32 - class Init - { - // sometimes I need Init outside sock_base... - // private: - public: - __FIT_DECLSPEC Init(); - __FIT_DECLSPEC ~Init(); - - friend class sock_base; - }; - - protected: - __FIT_DECLSPEC sock_base(); - __FIT_DECLSPEC ~sock_base(); -#endif -}; - -template<class charT, class traits, class _Alloc> -class basic_sockbuf : - public basic_streambuf<charT, traits> -{ - public: - typedef basic_ios<charT, traits> ios_type; - typedef basic_sockbuf<charT, traits, _Alloc> sockbuf_type; - typedef typename traits::state_type state_t; -#ifdef WIN32 - typedef u_short family_type; -#else -# ifdef sa_family_t - typedef sa_family_t family_type; -# else // HP-UX 10.01 - typedef unsigned short family_type; -# endif -#endif - - public: - /* Inherited from basic_streambuf : */ - typedef charT char_type; - typedef typename traits::int_type int_type; - typedef typename traits::pos_type pos_type; - typedef typename traits::off_type off_type; - typedef traits traits_type; - /* */ - - basic_sockbuf() : - _fd( -1 ), -#if !defined(STLPORT) && defined(__GNUC__) -#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) // hmm, 3.3.6 - _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), -#else // 4.1.1 - _mode( _S_in | _S_out ), -#endif // __GNUC__ -#else // STLPORT - _mode( 0 ), -#endif // STLPORT - _bbuf(0), _ebuf(0), _allocated( true ) - // , _doclose( true ) - { -#ifdef __FIT_POLL - _timeout = -1; -#endif -#ifdef __FIT_SELECT - _timeout_ref = 0; -#endif - } - basic_sockbuf( const char *hostname, int port, - sock_base::stype type = sock_base::sock_stream, - sock_base::protocol prot = sock_base::inet, - const timespec *timeout = 0 ) : - _fd( -1 ), -#if !defined(STLPORT) && defined(__GNUC__) -#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) - _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), -#else // 4.1.1 - _mode( _S_in | _S_out ), -#endif // __GNUC__ -#else // STLPORT - _mode( 0 ), -#endif // STLPORT - _bbuf(0), _ebuf(0), _allocated( true ) - // , _doclose( true ) - { - open( hostname, port, type, prot, timeout ); - } - basic_sockbuf( const in_addr& addr, int port, - sock_base::stype type = sock_base::sock_stream, - sock_base::protocol prot = sock_base::inet, - const timespec *timeout = 0 ) : - _fd( -1 ), -#if !defined(STLPORT) && defined(__GNUC__) -#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) - _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), -#else // 4.1.1 - _mode( _S_in | _S_out ), -#endif // __GNUC__ -#else // STLPORT - _mode( 0 ), -#endif // STLPORT - _bbuf(0), _ebuf(0), _allocated( true ) - // , _doclose( true ) - { - open( addr, type, prot, timeout ); - } - virtual ~basic_sockbuf() - { - close(); - _M_deallocate_block(); - } - - bool is_open() const - { return _fd != -1; } - - sockbuf_type *open( const char *hostname, int port, - sock_base::stype type = sock_base::sock_stream, - sock_base::protocol prot = sock_base::inet, - const timespec *timeout = 0 ); - - sockbuf_type *open( const in_addr& addr, int port, - sock_base::stype type = sock_base::sock_stream, - sock_base::protocol prot = sock_base::inet, - const timespec *timeout = 0 ); - - sockbuf_type *open( sock_base::socket_type s, - sock_base::stype t = sock_base::sock_stream, - const timespec *timeout = 0 ); - - sockbuf_type *open( sock_base::socket_type s, const sockaddr& addr, - sock_base::stype t = sock_base::sock_stream, - const timespec *timeout = 0 ); - - sockbuf_type *attach( sock_base::socket_type s, - sock_base::stype t = sock_base::sock_stream, - const timespec *timeout = 0 ); - - sockbuf_type *attach( sock_base::socket_type s, const sockaddr& addr, - sock_base::stype t = sock_base::sock_stream, - const timespec *timeout = 0 ); - - sockbuf_type *close(); - void shutdown( sock_base::shutdownflg dir ); - - sock_base::socket_type fd() const { return _fd;} - - family_type family() const - { return /* is_open() ? */ _address.any.sa_family /* : 0 */; } - - int port() const - { return /* is_open() && */ _address.any.sa_family == AF_INET ? - _address.inet.sin_port : 0; } - - unsigned long inet_addr() const - { return /* is_open() && */ _address.any.sa_family == AF_INET ? - _address.inet.sin_addr.s_addr : 0; } - - const sockaddr_in& inet_sockaddr() const throw( std::domain_error ) - { - if ( _address.any.sa_family != AF_INET ) { - throw domain_error( "socket not belongs to inet type" ); - } - return /* is_open() && */ _address.inet; - } - - sock_base::stype stype() const - { return _type; } - - // const string& hostname() const - // { return _hostname; } - - protected: - // bool findhost( const char *hostname ); - - virtual streamsize showmanyc() - { return this->egptr() - this->gptr(); } - - virtual int_type underflow(); - virtual int_type overflow( int_type c = traits::eof() ); - virtual int_type pbackfail( int_type c = traits::eof() ) - { - if ( !is_open() ) - return traits::eof(); - - if ( this->gptr() <= this->eback() ) { - return traits::eof(); - } - - this->gbump(-1); - if ( !traits::eq_int_type(c,traits::eof()) ) { - *this->gptr() = traits::to_char_type(c); - return c; - } - - return traits::not_eof(c); - } - - // Buffer managment and positioning: - virtual basic_streambuf<charT, traits> *setbuf(char_type *s, streamsize n ) - { - if ( s != 0 && n != 0 ) { - _M_deallocate_block(); - _allocated = false; - _bbuf = s; - _ebuf = s + n; - } - return this; - } - - virtual int sync(); - virtual streamsize xsputn(const char_type *s, streamsize n); - - public: - xmt::mutex _M_lock_w; // lock for writing - - private: // Helper functions - charT* _bbuf; - charT* _ebuf; - bool _allocated; // true, if _bbuf should be deallocated -#ifdef __FIT_POLL - pollfd pfd; - int _timeout; // milliseconds -#endif -#ifdef __FIT_SELECT - fd_set pfd; - struct timeval _timeout; - struct timeval *_timeout_ref; -#endif - - // Precondition: 0 < __n <= max_size(). - charT* _M_allocate( size_t __n ) { return _M_data_allocator.allocate(__n); } - void _M_deallocate( charT* __p, size_t __n ) - { if (__p) _M_data_allocator.deallocate(__p, __n); } - - void _M_allocate_block(size_t __n) - { - if ( _allocated ) { - if ( __n <= max_size() ) { - _bbuf = _M_allocate(__n); - _ebuf = _bbuf + __n; - // _STLP_ASSERT( __n > 0 ? _bbuf != 0 : _bbuf == 0 ); - } else - this->_M_throw_length_error(); - } - } - - void _M_deallocate_block() - { if ( _allocated ) _M_deallocate(_bbuf, _ebuf - _bbuf); } - - size_t max_size() const { return (size_t(-1) / sizeof(charT)) - 1; } - -#ifdef STLPORT - void _M_throw_length_error() const - { _STLP_THROW(length_error("basic_sockbuf")); } -#else - void _M_throw_length_error() const - { throw length_error("basic_sockbuf"); } -#endif - -#ifdef STLPORT - typedef typename _Alloc_traits<charT, _Alloc>::allocator_type allocator_type; -#else - typedef _Alloc allocator_type; -#endif - /* typedef __allocator<charT, _Alloc> _Alloc_type; */ - - /* _Alloc_type */ allocator_type _M_data_allocator; - - private: - typedef basic_sockbuf<charT,traits,_Alloc> _Self_type; - int (basic_sockbuf<charT,traits,_Alloc>::*_xwrite)( const void *, size_t ); - int (basic_sockbuf<charT,traits,_Alloc>::*_xread)( void *, size_t ); - int write( const void *buf, size_t n ) -#ifndef WIN32 - { return ::write( _fd, buf, n ); } -#else - { return ::send( _fd, (const char *)buf, n, 0 ); } -#endif - int send( const void *buf, size_t n ) -#ifdef WIN32 - { return ::send( _fd, (const char *)buf, n, 0 ); } -#else - { return ::send( _fd, buf, n, 0 ); } -#endif - int sendto( const void *buf, size_t n ) -#ifdef WIN32 - { return ::sendto( _fd, (const char *)buf, n, 0, &_address.any, sizeof( sockaddr_in ) ); } -#else - { return ::sendto( _fd, buf, n, 0, &_address.any, sizeof( sockaddr_in ) ); } -#endif - - int read( void *buf, size_t n ) -#ifdef WIN32 - { return ::recv( _fd, (char *)buf, n, 0 ); } -#else - { return ::read( _fd, buf, n ); } -#endif - int recv( void *buf, size_t n ) -#ifdef WIN32 - { return ::recv( _fd, (char *)buf, n, 0 ); } -#else - { return ::recv( _fd, buf, n, 0 ); } -#endif - int recvfrom( void *buf, size_t n ); - void __hostname(); - - sock_base::socket_type _fd; - union sockaddr_t { - sockaddr_in inet; - sockaddr any; - } _address; - - ios_base::openmode _mode; - int _errno; - sock_base::stype _type; - // bool _doclose; -}; - -template <class charT, class traits, class _Alloc> -class basic_sockstream : - public sock_base, - public basic_iostream<charT,traits> -{ - public: - /* Inherited from basic_iostream - typedef charT char_type; - typedef typename traits::int_type int_type; - typedef typename traits::pos_type pos_type; - typedef typename traits::off_type off_type; - */ - basic_sockstream() : - sock_base(), - basic_iostream<charT,traits>( 0 ) - { basic_ios<charT,traits>::init(&_sb); } - basic_sockstream( const char *hostname, int port, - sock_base::stype type = sock_base::sock_stream, - sock_base::protocol pro = sock_base::inet, - const timespec *timeout = 0 ) : - sock_base(), - basic_iostream<charT,traits>( 0 ) - { - basic_ios<charT,traits>::init(&_sb); - basic_iostream<charT,traits>::clear(); - if ( _sb.open( hostname, port, type, pro, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - basic_sockstream( const in_addr& addr, int port, - sock_base::stype type = sock_base::sock_stream, - sock_base::protocol pro = sock_base::inet, - const timespec *timeout = 0 ) : - sock_base(), - basic_iostream<charT,traits>( 0 ) - { - basic_ios<charT,traits>::init(&_sb); - basic_iostream<charT,traits>::clear(); - if ( _sb.open( addr, port, type, pro, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - basic_sockstream( sock_base::socket_type s, const sockaddr& addr, - sock_base::stype type = sock_base::sock_stream, - const timespec *timeout = 0 ) : - sock_base(), - basic_iostream<charT,traits>( 0 ) - { - basic_ios<charT,traits>::init(&_sb); - basic_iostream<charT,traits>::clear(); - if ( _sb.open( s, addr, type, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - basic_sockstream( sock_base::socket_type s, - sock_base::stype type = sock_base::sock_stream, - const timespec *timeout = 0 ) : - sock_base(), - basic_iostream<charT,traits>( 0 ) - { - basic_ios<charT,traits>::init(&_sb); - basic_iostream<charT,traits>::clear(); - if ( _sb.open( s, type, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - basic_sockbuf<charT,traits,_Alloc>* rdbuf() const - { return const_cast<basic_sockbuf<charT,traits,_Alloc>*>(&_sb); } - bool is_open() const - { return _sb.is_open(); } - void open( const char *hostname, int port, - sock_base::stype type = sock_base::sock_stream, - sock_base::protocol pro = sock_base::inet, - const timespec *timeout = 0 ) - { - basic_iostream<charT,traits>::clear(); - if ( _sb.open( hostname, port, type, pro, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - void open( const in_addr& addr, int port, - sock_base::stype type = sock_base::sock_stream, - sock_base::protocol pro = sock_base::inet, - const timespec *timeout = 0 ) - { - basic_iostream<charT,traits>::clear(); - if ( _sb.open( addr, port, type, pro, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - // only for sock_stream : inet now! - void open( sock_base::socket_type s, const sockaddr& addr, - sock_base::stype type = sock_base::sock_stream, - const timespec *timeout = 0 ) - { - basic_iostream<charT,traits>::clear(); - if ( _sb.open( s, addr, type, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - void open( sock_base::socket_type s, - sock_base::stype type = sock_base::sock_stream, - const timespec *timeout = 0 ) - { - basic_iostream<charT,traits>::clear(); - if ( _sb.open( s, type, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - void attach( sock_base::socket_type s, const sockaddr& addr, - sock_base::stype type = sock_base::sock_stream, - const timespec *timeout = 0 ) - { - basic_iostream<charT,traits>::clear(); - if ( _sb.attach( s, addr, type, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - void attach( sock_base::socket_type s, - sock_base::stype type = sock_base::sock_stream, - const timespec *timeout = 0 ) - { - basic_iostream<charT,traits>::clear(); - if ( _sb.attach( s, type, timeout ) == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); - } - } - - void close() - { - if ( _sb.is_open() ) { - if ( _sb.close() == 0 ) { - basic_ios<charT,traits>::setstate( ios_base::failbit ); - } else { - basic_iostream<charT,traits>::clear(); - } - } - } - - void setoptions( sock_base::so_t optname, bool on_off = true, - int __v = 0 ); - - private: - basic_sockbuf<charT,traits,_Alloc> _sb; -}; - -typedef basic_sockbuf<char,char_traits<char>,allocator<char> > sockbuf; -typedef basic_sockbuf<wchar_t,char_traits<wchar_t>,allocator<wchar_t> > wsockbuf; -typedef basic_sockstream<char,char_traits<char>,allocator<char> > sockstream; -typedef basic_sockstream<wchar_t,char_traits<wchar_t>,allocator<wchar_t> > wsockstream; - -#ifdef STLPORT -_STLP_END_NAMESPACE -#else -} // namespace std -#endif - -#ifndef __STL_LINK_TIME_INSTANTIATION -#include <sockios/sockstream.cc> -#endif - -#endif // __SOCKSTREAM__ Copied: branches/complement-sockios/explore/include/sockios/sockstream (from rev 1886, branches/complement-sockios/explore/include/sockios/sockstream2) =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream (rev 0) +++ branches/complement-sockios/explore/include/sockios/sockstream 2008-06-09 18:31:16 UTC (rev 1892) @@ -0,0 +1,661 @@ +// -*- C++ -*- Time-stamp: <08/06/09 22:22:05 yeti> + +/* + * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 + * Petr Ovtchenkov + * + * Portion Copyright (c) 1999-2001 + * Parallel Graphics Ltd. + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#ifndef __SOCKIOS_SOCKSTREAM +#define __SOCKIOS_SOCKSTREAM + +#ifndef __config_feature_h +#include <config/feature.h> +#endif + +#if !defined(__sun) && !defined(_WIN32) // i.e. __linux and __hpux +#include <sys/poll.h> // pollfd +#endif + +#include <mt/mutex> +#include <mt/condition_variable> +#include <mt/date_time> +#include <mt/thread> + +#include <netdb.h> +#include <netinet/in.h> + +#include <iosfwd> +#include <ios> +#include <streambuf> +#include <iostream> +#include <string> +#include <stdexcept> + +#ifdef WIN32 +# include <winsock2.h> +#else // WIN32 +# include <unistd.h> +# include <sys/types.h> +# if defined(__hpux) && !defined(_INCLUDE_XOPEN_SOURCE_EXTENDED) +# define _INCLUDE_XOPEN_SOURCE_EXTENDED +# endif +# include <sys/socket.h> +# if !defined(__UCLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +# include <stropts.h> +# endif +# ifdef __sun +# include <sys/conf.h> +# endif +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +# ifdef __hpux +// # ifndef socklen_t // HP-UX 10.01 +// typedef int socklen_t; +// # endif +# endif +# include <cerrno> +#endif // !WIN32 + +#include <sockios/netinfo.h> + +#ifdef STLPORT +_STLP_BEGIN_NAMESPACE +#else +namespace std { +#endif + +class sock_base +{ + public: + typedef unsigned long shutdownflg; +#ifdef __unix + typedef int socket_type; +#endif +#ifdef WIN32 + typedef SOCKET socket_type; +#endif + + enum stype { + sock_stream = SOCK_STREAM, // stream socket + sock_dgram = SOCK_DGRAM, // datagram socket + sock_raw = SOCK_RAW, // raw-protocol interface + sock_rdm = SOCK_RDM, // reliably-delivered message + sock_seqpacket = SOCK_SEQPACKET // sequenced packet stream + }; + + enum protocol { + local, // local to host (pipes, portals) + inet // internetwork: UDP, TCP, etc. + }; + + // Option flags per-socket. + enum so_t { + so_debug = SO_DEBUG, // turn on debugging info recording +#ifndef __linux + so_acceptconn = SO_ACCEPTCONN, // socket has had listen() +#endif + so_reuseaddr = SO_REUSEADDR, // allow local address reuse + so_keepalive = SO_KEEPALIVE, // keep connections alive + so_dontroute = SO_DONTROUTE, // just use interface addresses + so_broadcast = SO_BROADCAST, // permit sending of broadcast msgs +#ifndef __linux + so_useloopback = SO_USELOOPBACK, // bypass hardware when possible +#endif + so_linger = SO_LINGER, // linger on close if data present + so_oobinline = SO_OOBINLINE, // leave received OOB data in line + // Additional options, not kept in so_options. + so_sndbuf = SO_SNDBUF, // send buffer size + so_rcvbuf = SO_RCVBUF, // receive buffer size + so_sndlowat = SO_SNDLOWAT, // send low-water mark + so_rcvlowat = SO_RCVLOWAT, // receive low-water mark + so_sndtimeo = SO_SNDTIMEO, // send timeout + so_rcvtimeo = SO_RCVTIMEO, // receive timeout + so_error = SO_ERROR, // get error status and clear + so_type = SO_TYPE // get socket type +#ifdef __sun // indeed HP-UX 11.00 also has it, but 10.01 not + , + so_prototype = SO_PROTOTYPE // get/set protocol type +#endif + }; + + // Level number for (get/set)sockopt() to apply to socket itself. +// enum _level { +// sol_socket = SOL_SOCKET +// }; + + enum shutdownflags { + stop_in = 0x1, + stop_out = 0x2 + }; + +#ifdef WIN32 + class Init + { + // sometimes I need Init outside sock_base... + // private: + public: + __FIT_DECLSPEC Init(); + __FIT_DECLSPEC ~Init(); + + friend class sock_base; + }; + + protected: + __FIT_DECLSPEC sock_base(); + __FIT_DECLSPEC ~sock_base(); +#endif +}; + +class socket_timeout : + public std::exception +{ + public: + socket_timeout() + { } + + virtual char const *what() throw() + { return "socket timeout"; } +}; + +class socket_read_timeout : + public socket_timeout +{ + public: + socket_read_timeout() + { } + + virtual char const *what() throw() + { return "socket read timeout"; } +}; + +class socket_write_timeout : + public socket_timeout +{ + public: + socket_write_timeout() + { } + + virtual char const *what() throw() + { return "socket write timeout"; } +}; + +namespace detail { +template <class charT, class traits, class _Alloc> class sockmgr; +} // namespace detail + +template <class charT, class traits, class _Alloc> +class sock_processor_base; + +template<class charT, class traits, class _Alloc> +class basic_socket +{ + protected: + basic_socket() : + _fd( -1 ), + _use_rdtimeout( false ), + _use_wrtimeout( false ), + _notify_close( false ) + { new( Init_buf ) Init(); } + + ~basic_socket() + { ((Init *)Init_buf)->~Init(); } + + bool is_open_unsafe() const + { return _fd != -1; } + sock_base::socket_type fd_unsafe() const + { return _fd; } + + class Init + { + public: + Init() + { _guard( 1 ); } + ~Init() + { _guard( 0 ); } + + private: + static void _guard( int direction ); + static void __at_fork_prepare(); + static void __at_fork_child(); + static void __at_fork_parent(); + static int _count; + static bool _at_fork; + }; + + static char Init_buf[]; + + public: +#ifdef WIN32 + typedef u_short family_type; +#else +# ifdef sa_family_t + typedef sa_family_t family_type; +# else // HP-UX 10.01 + typedef unsigned short family_type; +# endif +#endif + + template <class Duration> + void rdtimeout( const Duration& ); + void rdtimeout() // infinite + { _use_rdtimeout = false; } + + template <class Duration> + void wrtimeout( const Duration& ); + void wrtimeout() // infinite + { _use_wrtimeout = false; } + + sock_base::socket_type fd() const { return _fd;} + bool is_open() const + { return _fd != -1; } + + family_type family() const + { return /* is_open() ? */ _address.any.sa_family /* : 0 */; } + + int port() const + { return /* is_open() && */ _address.any.sa_family == AF_INET ? _address.inet.sin_port : 0; } + + unsigned long inet_addr() const + { return /* is_open() && */ _address.any.sa_family == AF_INET ? _address.inet.sin_addr.s_addr : 0; } + + const sockaddr_in& inet_sockaddr() const throw( std::domain_error ) + { + if ( _address.any.sa_family != AF_INET ) { + throw domain_error( "socket not belongs to inet type" ); + } + return /* is_open() && */ _address.inet; + } + + protected: + sock_base::socket_type _fd; + + union sockaddr_t { + sockaddr_in inet; + sockaddr any; + } _address; + + std::tr2::milliseconds _rdtimeout; + std::tr2::milliseconds _wrtimeout; + bool _use_rdtimeout; + bool _use_wrtimeout; + bool _notify_close; + + static detail::sockmgr<charT,traits,_Alloc>* mgr; + friend class Init; +}; + +template<class charT, class traits, class _Alloc> +int basic_socket<charT,traits,_Alloc>::Init::_count = 0; + +template<class charT, class traits, class _Alloc> +bool basic_socket<charT,traits,_Alloc>::Init::_at_fork = false; + +template<class charT, class traits, class _Alloc> +void basic_socket<charT,traits,_Alloc>::Init::_guard( int direction ) +{ + static std::tr2::mutex _init_lock; + + if ( direction ) { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( _count++ == 0 ) { + basic_socket<charT,traits,_Alloc>::mgr = new detail::sockmgr<charT,traits,_Alloc>(); +#ifdef __FIT_PTHREADS + if ( !_at_fork ) { // call only once + if ( pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ) ) { + // throw system_error; + } + _at_fork = true; + } +#endif +// _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); + std::cerr << __FILE__ << ":" << __LINE__ << " new mgr " << std::tr2::getpid() << std::endl; + } + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( --_count == 0 ) { + if ( basic_socket<charT,traits,_Alloc>::mgr == 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << " shit happens\n"; + } + std::cerr << __FILE__ << ":" << __LINE__ << " mgr destroyed " << std::tr2::getpid() << std::endl; + delete basic_socket<charT,traits,_Alloc>::mgr; + basic_socket<charT,traits,_Alloc>::mgr = 0; + } + } +} + +template<class charT, class traits, class _Alloc> +void basic_socket<charT,traits,_Alloc>::Init::__at_fork_prepare() +{ +} + +template<class charT, class traits, class _Alloc> +void basic_socket<charT,traits,_Alloc>::Init::__at_fork_child() +{ + if ( _count != 0 ) { + // stop mgr + _count = 1; + delete basic_socket<charT,traits,_Alloc>::mgr; + basic_socket<charT,traits,_Alloc>::mgr = new detail::sockmgr<charT,traits,_Alloc>(); + } + // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); +} + +template<class charT, class traits, class _Alloc> +void basic_socket<charT,traits,_Alloc>::Init::__at_fork_parent() +{ } + +template<class charT, class traits, class _Alloc> +char basic_socket<charT,traits,_Alloc>::Init_buf[128]; + +template <class charT, class traits, class _Alloc> +detail::sockmgr<charT,traits,_Alloc>* basic_socket<charT,traits,_Alloc>::mgr = 0; + +#ifdef STLPORT +_STLP_END_NAMESPACE +#else +} // namespace std +#endif + +#include <sockios/sp.h> + +#ifdef STLPORT +_STLP_BEGIN_NAMESPACE +#else +namespace std { +#endif + +template<class charT, class traits, class _Alloc> +class basic_sockbuf : + public basic_streambuf<charT, traits> + // public basic_socket<charT,traits,_Alloc> +{ + private: + typedef basic_socket<charT,traits,_Alloc> basic_socket_t; + + public: + typedef basic_ios<charT, traits> ios_type; + typedef basic_sockbuf<charT, traits, _Alloc> sockbuf_type; + typedef typename traits::state_type state_t; + typedef typename basic_socket_t::family_type family_type; + + public: + /* Inherited from basic_streambuf : */ + typedef charT char_type; + typedef typename traits::int_type int_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + typedef traits traits_type; + /* */ + + basic_sockbuf() : + impl( 0 ) + { } + + basic_sockbuf( const char *hostname, int port, + sock_base::stype type = sock_base::sock_stream, + sock_base::protocol prot = sock_base::inet ) : + impl( 0 ) + { open( hostname, port, type, prot ); } + + basic_sockbuf( const in_addr& addr, int port, + sock_base::stype type = sock_base::sock_stream, + sock_base::protocol prot = sock_base::inet ) : + impl( 0 ) + { open( addr, type, prot ); } + + virtual ~basic_sockbuf() + { close(); } + + sockbuf_type *open( const char *hostname, int port, + sock_base::stype type = sock_base::sock_stream, + sock_base::protocol prot = sock_base::inet ); + + sockbuf_type *open( const in_addr& addr, int port, + sock_base::stype type = sock_base::sock_stream, + sock_base::protocol prot = sock_base::inet ) + { return impl->open( addr, port, type, prot ) ? this : 0; } + + sockbuf_type *open( sock_base::socket_type s, + sock_base::stype t = sock_base::sock_stream ); + + sockbuf_type *open( sock_base::socket_type s, const sockaddr& addr, + sock_base::stype t = sock_base::sock_stream ) + { return impl->open( s, addr, t ) ? this : 0; } + + sockbuf_type *attach( sock_base::socket_type s, + sock_base::stype t = sock_base::sock_stream ); + + sockbuf_type *attach( sock_base::socket_type s, const sockaddr& addr, + sock_base::stype t = sock_base::sock_stream ); + + sockbuf_type *close() + { return impl->close() ? this : 0; } + + void shutdown( sock_base::shutdownflg dir ) + { impl->shutdown( dir ); } + + sock_base::stype stype() const + { return impl->stype(); } + + template <class Duration> + void rdtimeout( const Duration& d ) + { impl->rdtimeout( d ); } + void rdtimeout() // infinite + { impl->rdtimeout(); } + + template <class Duration> + void wrtimeout( const Duration& d ) + { impl->wrtimeout( d ); } + void wrtimeout() // infinite + { impl->wrtimeout(); } + + sock_base::socket_type fd() const { return impl->fd();} + bool is_open() const + { return impl->is_open(); } + + family_type family() const + { return impl->family(); } + + int port() const + { return impl->port(); } + + unsigned long inet_addr() const + { return impl->inet_addr(); } + + const sockaddr_in& inet_sockaddr() const throw( std::domain_error ) + { return impl->inet_sockaddr(); } + + + protected: + virtual streamsize showmanyc() + { return impl->showmanyc(); } + + virtual int_type underflow() + { return impl->underflow(); } + virtual int_type overflow( int_type c = traits::eof() ) + { return impl->overflow(c); } + virtual int_type pbackfail( int_type c = traits::eof() ) + { return impl->pbackfail( c ); } + // Buffer managment and positioning: + virtual basic_streambuf<charT, traits> *setbuf(char_type *s, streamsize n ) + { impl->setbuf( s, n ); return this; } + + virtual int sync() + { return impl->sync(); } + virtual streamsize xsputn(const char_type *s, streamsize n) + { return impl->xsputn( s, n ); } + + private: + detail::basic_sockbuf_aux<charT,traits,_Alloc> *impl; +}; + +template <class charT, class traits, class _Alloc> +class basic_sockstream : + public sock_base, + public basic_iostream<charT,traits> +{ + public: + /* Inherited from basic_iostream + typedef charT char_type; + typedef typename traits::int_type int_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + */ + basic_sockstream() : + sock_base(), + basic_iostream<charT,traits>( 0 ) + { basic_ios<charT,traits>::init(&_sb); } + basic_sockstream( const char *hostname, int port, + sock_base::stype type = sock_base::sock_stream, + sock_base::protocol pro = sock_base::inet ) : + sock_base(), + basic_iostream<charT,traits>( 0 ) + { + basic_ios<charT,traits>::init(&_sb); + basic_iostream<charT,traits>::clear(); + if ( _sb.open( hostname, port, type, pro ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + basic_sockstream( const in_addr& addr, int port, + sock_base::stype type = sock_base::sock_stream, + sock_base::protocol pro = sock_base::inet ) : + sock_base(), + basic_iostream<charT,traits>( 0 ) + { + basic_ios<charT,traits>::init(&_sb); + basic_iostream<charT,traits>::clear(); + if ( _sb.open( addr, port, type, pro ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + basic_sockstream( sock_base::socket_type s, const sockaddr& addr, + sock_base::stype type = sock_base::sock_stream ) : + sock_base(), + basic_iostream<charT,traits>( 0 ) + { + basic_ios<charT,traits>::init(&_sb); + basic_iostream<charT,traits>::clear(); + if ( _sb.open( s, addr, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + basic_sockstream( sock_base::socket_type s, + sock_base::stype type = sock_base::sock_stream ) : + sock_base(), + basic_iostream<charT,traits>( 0 ) + { + basic_ios<charT,traits>::init(&_sb); + basic_iostream<charT,traits>::clear(); + if ( _sb.open( s, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + basic_sockbuf<charT,traits,_Alloc>* rdbuf() const + { return const_cast<basic_sockbuf<charT,traits,_Alloc>*>(&_sb); } + + bool is_open() const + { return _sb.is_open(); } + + void open( const char *hostname, int port, + sock_base::stype type = sock_base::sock_stream, + sock_base::protocol pro = sock_base::inet ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.open( hostname, port, type, pro ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void open( const in_addr& addr, int port, + sock_base::stype type = sock_base::sock_stream, + sock_base::protocol pro = sock_base::inet ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.open( addr, port, type, pro ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + // only for sock_stream : inet now! + void open( sock_base::socket_type s, const sockaddr& addr, + sock_base::stype type = sock_base::sock_stream ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.open( s, addr, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void open( sock_base::socket_type s, + sock_base::stype type = sock_base::sock_stream ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.open( s, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void attach( sock_base::socket_type s, const sockaddr& addr, + sock_base::stype type = sock_base::sock_stream ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.attach( s, addr, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void attach( sock_base::socket_type s, + sock_base::stype type = sock_base::sock_stream ) + { + basic_iostream<charT,traits>::clear(); + if ( _sb.attach( s, type ) == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit | ios_base::badbit ); + } + } + + void close() + { + if ( _sb.is_open() ) { + if ( _sb.close() == 0 ) { + basic_ios<charT,traits>::setstate( ios_base::failbit ); + } else { + basic_iostream<charT,traits>::clear(); + } + } + } + + void setoptions( sock_base::so_t optname, bool on_off = true, + int __v = 0 ); + + private: + basic_sockbuf<charT,traits,_Alloc> _sb; +}; + +typedef basic_sockbuf<char,char_traits<char>,allocator<char> > sockbuf; +// typedef basic_sockbuf<wchar_t,char_traits<wchar_t>,allocator<wchar_t> > wsockbuf; +typedef basic_sockstream<char,std::char_traits<char>,std::allocator<char> > sockstream; +// typedef basic_sockstream<wchar_t,char_traits<wchar_t>,allocator<wchar_t> > wsockstream; + +#ifdef STLPORT +_STLP_END_NAMESPACE +#else +} // namespace std +#endif + +#ifndef __STL_LINK_TIME_INSTANTIATION +#include <sockios/sockstream.cc> +#endif + +#endif // __SOCKIOS_SOCKSTREAM Deleted: branches/complement-sockios/explore/include/sockios/sockstream.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream.cc 2008-06-07 17:06:27 UTC (rev 1891) +++ branches/complement-sockios/explore/include/sockios/sockstream.cc 2008-06-09 18:31:16 UTC (rev 1892) @@ -1,777 +0,0 @@ -// -*- C++ -*- Time-stamp: <07/09/06 23:48:33 ptr> - -/* - * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 - * Petr Ovtchenkov - * - * Portion Copyright (c) 1999-2001 - * Parallel Graphics Ltd. - * - * Licensed under the Academic Free License version 3.0 - * - */ - -#include <sockios/netinfo.h> - -#ifdef __unix -extern "C" int nanosleep(const struct timespec *, struct timespec *); -#endif - -#if defined(__unix) && !defined(__UCLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -# include <stropts.h> // for ioctl() call -#endif - -#ifdef __FIT_NONBLOCK_SOCKETS -# include <fcntl.h> -#endif - -#ifdef STLPORT -_STLP_BEGIN_NAMESPACE -#else -namespace std { -#endif - -template<class charT, class traits, class _Alloc> -basic_sockbuf<charT, traits, _Alloc> * -basic_sockbuf<charT, traits, _Alloc>::open( const char *name, int port, - sock_base::stype type, - sock_base::protocol prot, - const timespec *timeout ) -{ - if ( is_open() ) { - return 0; - } - try { - _mode = ios_base::in | ios_base::out; - _errno = 0; - _type = type; -#ifdef WIN32 - WSASetLastError( 0 ); -#endif -#ifdef __FIT_POLL - if ( timeout != 0 ) { - _timeout = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000; - } else { - _timeout = -1; - } -#endif -#ifdef __FIT_SELECT - if ( timeout != 0 ) { - _timeout.tv_sec = timeout->tv_sec; - _timeout.tv_usec = timeout->tv_nsec / 1000; - _timeout_ref = &_timeout; - } else { - _timeout_ref = 0; - } -#endif - if ( prot == sock_base::inet ) { - _fd = socket( PF_INET, type, 0 ); - if ( _fd == -1 ) { - throw std::runtime_error( "can't open socket" ); - } - _address.inet.sin_family = AF_INET; - // htons is a define at least in Linux 2.2.5-15, and it's expantion fail - // for gcc 2.95.3 -#if defined(linux) && defined(htons) && defined(__bswap_16) - _address.inet.sin_port = ((((port) >> 8) & 0xff) | (((port) & 0xff) << 8)); -#else - _address.inet.sin_port = htons( port ); -#endif // linux && htons - _address.inet.sin_addr = std::findhost( name ); - - // Generally, stream sockets may successfully connect() only once - if ( connect( _fd, &_address.any, sizeof( _address ) ) == -1 ) { - throw std::domain_error( "connect fail" ); - } - if ( type == sock_base::sock_stream ) { - _xwrite = &_Self_type::write; - _xread = &_Self_type::read; - } else if ( type == sock_base::sock_dgram ) { - _xwrite = &_Self_type::send; - _xread = &_Self_type::recv; - } - } else if ( prot == sock_base::local ) { - _fd = socket( PF_UNIX, type, 0 ); - if ( _fd == -1 ) { - throw std::runtime_error( "can't open socket" ); - } - } else { // other protocols not implemented yet - throw std::invalid_argument( "protocol not implemented" ); - } - if ( _bbuf == 0 ) - _M_allocate_block( type == sock_base::sock_stream ? 0xb00 : 0xffff ); // max 1460 (dec) [0x5b4] --- single segment - if ( _bbuf == 0 ) { - throw std::length_error( "can't allocate block" ); - } - -#ifdef __FIT_NONBLOCK_SOCKETS - if ( fcntl( _fd, F_SETFL, fcntl( _fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { - throw std::runtime_error( "can't establish nonblock mode" ); - } -#endif -#ifdef __FIT_POLL - pfd.fd = _fd; - pfd.events = POLLIN | POLLHUP | POLLRDNORM; -#endif - setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); - setg( this->epptr(), this->epptr(), this->epptr() ); - - _errno = 0; // if any - } - catch ( std::domain_error& ) { -#ifdef WIN32 - _errno = WSAGetLastError(); - ::closesocket( _fd ); -#else - _errno = errno; - ::close( _fd ); -#endif - _fd = -1; - return 0; - } - catch ( std::length_error& ) { -#ifdef WIN32 - ::closesocket( _fd ); -#else - ::close( _fd ); -#endif - _fd = -1; - return 0; - } - catch ( std::runtime_error& ) { -#ifdef WIN32 - _errno = WSAGetLastError(); -#else - _errno = errno; -#endif - return 0; - } - catch ( std::invalid_argument& ) { - return 0; - } - - return this; -} - -// -- -template<class charT, class traits, class _Alloc> -basic_sockbuf<charT, traits, _Alloc> * -basic_sockbuf<charT, traits, _Alloc>::open( const in_addr& addr, int port, - sock_base::stype type, - sock_base::protocol prot, - const timespec *timeout ) -{ - if ( is_open() ) { - return 0; - } - try { - _mode = ios_base::in | ios_base::out; - _errno = 0; - _type = type; -#ifdef WIN32 - WSASetLastError( 0 ); -#endif -#ifdef __FIT_POLL - if ( timeout != 0 ) { - _timeout = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000; - } else { - _timeout = -1; - } -#endif -#ifdef __FIT_SELECT - if ( timeout != 0 ) { - _timeout.tv_sec = timeout->tv_sec; - _timeout.tv_usec = timeout->tv_nsec / 1000; - _timeout_ref = &_timeout; - } else { - _timeout_ref = 0; - } -#endif - if ( prot == sock_base::inet ) { - _fd = socket( PF_INET, type, 0 ); - if ( _fd == -1 ) { - throw std::runtime_error( "can't open socket" ); - } - _address.inet.sin_family = AF_INET; - // htons is a define at least in Linux 2.2.5-15, and it's expantion fail - // for gcc 2.95.3 -#if defined(linux) && defined(htons) && defined(__bswap_16) - _address.inet.sin_port = ((((port) >> 8) & 0xff) | (((port) & 0xff) << 8)); -#else - _address.inet.sin_port = htons( port ); -#endif // linux && htons - _address.inet.sin_addr = addr; - - // Generally, stream sockets may successfully connect() only once - if ( connect( _fd, &_address.any, sizeof( _address ) ) == -1 ) { - throw std::domain_error( "connect fail" ); - } - if ( type == sock_base::sock_stream ) { - _xwrite = &_Self_type::write; - _xread = &_Self_type::read; - } else if ( type == sock_base::sock_dgram ) { - _xwrite = &_Self_type::send; - _xread = &_Self_type::recv; - } - } else if ( prot == sock_base::local ) { - _fd = socket( PF_UNIX, type, 0 ); - if ( _fd == -1 ) { - throw std::runtime_error( "can't open socket" ); - } - } else { // other protocols not implemented yet - throw std::invalid_argument( "protocol not implemented" ); - } - if ( _bbuf == 0 ) - _M_allocate_block( type == sock_base::sock_stream ? 0xb00 : 0xffff ); // max 1460 (dec) [0x5b4] --- single segment - if ( _bbuf == 0 ) { - throw std::length_error( "can't allocate block" ); - } - -#ifdef __FIT_NONBLOCK_SOCKETS - if ( fcntl( _fd, F_SETFL, fcntl( _fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { - throw std::runtime_error( "can't establish nonblock mode" ); - } -#endif -#ifdef __FIT_POLL - pfd.fd = _fd; - pfd.events = POLLIN | POLLHUP | POLLRDNORM; -#endif - setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); - setg( this->epptr(), this->epptr(), this->epptr() ); - - _errno = 0; // if any - } - catch ( std::domain_error& ) { -#ifdef WIN32 - _errno = WSAGetLastError(); - ::closesocket( _fd ); -#else - _errno = errno; - ::close( _fd ); -#endif - _fd = -1; - return 0; - } - catch ( std::length_error& ) { -#ifdef WIN32 - ::closesocket( _fd ); -#else - ::close( _fd ); -#endif - _fd = -1; - return 0; - } - catch ( std::runtime_error& ) { -#ifdef WIN32 - _errno = WSAGetLastError(); -#else - _errno = errno; -#endif - return 0; - } - catch ( std::invalid_argument& ) { - return 0; - } - - return this; -} -// -- - -template<class charT, class traits, class _Alloc> -basic_sockbuf<charT, traits, _Alloc> * -basic_sockbuf<charT, traits, _Alloc>::open( sock_base::socket_type s, - sock_base::stype t, - const timespec *timeout ) -{ - if ( is_open() || s == -1 ) { - return 0; - } - - sockaddr sa; - socklen_t sl = sizeof(sa); - getsockname( s, &sa, &sl ); - - return basic_sockbuf<charT, traits, _Alloc>::open( s, sa, t, timeout ); -} - -template<class charT, class traits, class _Alloc> -basic_sockbuf<charT, traits, _Alloc> * -basic_sockbuf<charT, traits, _Alloc>::open( sock_base::socket_type s, - const sockaddr& addr, - sock_base::stype t, - const timespec *timeout ) -{ - if ( is_open() || s == -1 ) { - return 0; - } - _fd = s; - memcpy( (void *)&_address.any, (const void *)&addr, sizeof(sockaddr) ); - _mode = ios_base::in | ios_base::out; - _errno = 0; - _type = t; -#ifdef WIN32 - WSASetLastError( 0 ); -#endif -#ifdef __FIT_POLL - if ( timeout != 0 ) { - _timeout = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000; - } else { - _timeout = -1; - } -#endif -#ifdef __FIT_SELECT - if ( timeout != 0 ) { - _timeout.tv_sec = timeout->tv_sec; - _timeout.tv_usec = timeout->tv_nsec / 1000; - _timeout_ref = &_timeout; - } else { - _timeout_ref = 0; - } -#endif - if ( t == sock_base::sock_stream ) { - _xwrite = &_Self_type::write; - _xread = &_Self_type::read; - } else if ( t == sock_base::sock_dgram ) { - _xwrite = &_Self_type::sendto; - _xread = &_Self_type::recvfrom; - } else { - _fd = -1; - return 0; // unsupported type - } - - if ( _bbuf == 0 ) { - _M_allocate_block( t == sock_base::sock_stream ? 0xb00 : 0x1ffff ); - } - - if ( _bbuf == 0 ) { -#ifdef WIN32 - ::closesocket( _fd ); -#else - ::close( _fd ); -#endif - _fd = -1; - return 0; - } - -#ifdef __FIT_NONBLOCK_SOCKETS - if ( fcntl( _fd, F_SETFL, fcntl( _fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { - throw std::runtime_error( "can't establish nonblock mode" ); - } -#endif -#ifdef __FIT_POLL - pfd.fd = _fd; - pfd.events = POLLIN | POLLHUP | POLLRDNORM; -#endif - setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); - setg( this->epptr(), this->epptr(), this->epptr() ); - - _errno = 0; // if any - - return this; -} - -template<class charT, class traits, class _Alloc> -basic_sockbuf<charT, traits, _Alloc> * -basic_sockbuf<charT, traits, _Alloc>::attach( sock_base::socket_type s, - sock_base::stype t, - const timespec *timeout ) -{ - if ( is_open() || s == -1 ) { - return 0; - } - - sockaddr sa; - socklen_t sl = sizeof(sa); - getsockname( s, &sa, &sl ); - - return basic_sockbuf<charT, traits, _Alloc>::attach( s, sa, t, timeout ); -} - -template<class charT, class traits, class _Alloc> -basic_sockbuf<charT, traits, _Alloc> * -basic_sockbuf<charT, traits, _Alloc>::attach( sock_base::socket_type s, - const sockaddr& addr, - sock_base::stype t, - const timespec *timeout ) -{ - if ( is_open() || s == -1 ) { - return 0; - } - - // _doclose = false; - return basic_sockbuf<charT, traits, _Alloc>::open( dup(s), addr, t, timeout ); -} - -template<class charT, class traits, class _Alloc> -basic_sockbuf<charT, traits, _Alloc> * -basic_sockbuf<charT, traits, _Alloc>::close() -{ - if ( !is_open() ) - return 0; - - // if ( _doclose ) { -#ifdef WIN32 - ::closesocket( _fd ); -#else - ::close( _fd ); -#endif - // } - - // _STLP_ASSERT( _bbuf != 0 ); - // put area before get area - setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); - setg( this->epptr(), this->epptr(), this->epptr() ); - - _fd = -1; - - return this; -} - -template<class charT, class traits, class _Alloc> -void basic_sockbuf<charT, traits, _Alloc>::shutdown( sock_base::shutdownflg dir ) -{ - if ( is_open() ) { - if ( (dir & (sock_base::stop_in | sock_base::stop_out)) == - (sock_base::stop_in | sock_base::stop_out) ) { - ::shutdown( _fd, 2 ); - } else if ( dir & sock_base::stop_in ) { - ::shutdown( _fd, 0 ); - } else if ( dir & sock_base::stop_out ) { - ::shutdown( _fd, 1 ); - } - } -} - -template<class charT, class traits, class _Alloc> -__FIT_TYPENAME basic_sockbuf<charT, traits, _Alloc>::int_type -basic_sockbuf<charT, traits, _Alloc>::underflow() -{ - if( !is_open() ) - return traits::eof(); - - if ( this->gptr() < this->egptr() ) - return traits::to_int_type(*this->gptr()); - -#ifndef __FIT_NONBLOCK_SOCKETS -# ifdef __FIT_SELECT - FD_ZERO( &pfd ); - FD_SET( fd(), &pfd ); - - while ( select( fd() + 1, &pfd, 0, 0, _timeout_ref ) <= 0 ) { - if ( errno == EINTR ) { // may be interrupted, check and ignore - errno = 0; - continue; - } - return traits::eof(); - } -# endif // __FIT_SELECT -# ifdef __FIT_POLL - pfd.revents = 0; - - while ( poll( &pfd, 1, _timeout ) <= 0 ) { // wait infinite - if ( errno == EINTR ) { // may be interrupted, check and ignore - errno = 0; - continue; - } - return traits::eof(); - } - if ( (pfd.revents & POLLERR) != 0 ) { - // _state |= ios_base::failbit; - return traits::eof(); - } -# endif // __FIT_POLL -#endif // !__FIT_NONBLOCK_SOCKETS - long offset = (this->*_xread)( this->eback(), sizeof(char_type) * (_ebuf - this->eback()) ); -#ifdef __FIT_NONBLOCK_SOCKETS - if ( offset < 0 && errno == EAGAIN ) { - errno = 0; -# ifdef __FIT_SELECT - FD_ZERO( &pfd ); - FD_SET( fd(), &pfd ); - - while ( select( fd() + 1, &pfd, 0, 0, _timeout_ref ) <= 0 ) { - if ( errno == EINTR ) { // may be interrupted, check and ignore - errno = 0; - continue; - } - return traits::eof(); - } -# endif // __FIT_SELECT -# ifdef __FIT_POLL - pfd.revents = 0; - - while ( poll( &pfd, 1, _timeout ) <= 0 ) { // wait infinite - if ( errno == EINTR ) { // may be interrupted, check and ignore - errno = 0; - continue; - } - return traits::eof(); - } - if ( (pfd.revents & POLLERR) != 0 ) { - // _state |= ios_base::failbit; - return traits::eof(); - } -# endif // __FIT_POLL - offset = (this->*_xread)( this->eback(), sizeof(char_type) * (_ebuf - this->eback()) ); - } -#endif // __FIT_NONBLOCK_SOCKETS - // Without __FIT_NONBLOCK_SOCKETS: - // don't allow message of zero length: - // in conjunction with POLLIN in revent of poll above this designate that - // we receive FIN packet. - // With __FIT_NONBLOCK_SOCKETS: - // 0 is eof, < 0 --- second read also return < 0, but shouldn't - if ( offset <= 0 ) { - return traits::eof(); - } - - offset /= sizeof(charT); - - setg( this->eback(), this->eback(), this->eback() + offset ); - - return traits::to_int_type(*this->gptr()); -} - -template<class charT, class traits, class _Alloc> -__FIT_TYPENAME basic_sockbuf<charT, traits, _Alloc>::int_type -basic_sockbuf<charT, traits, _Alloc>::overflow( int_type c ) -{ - if ( !is_open() ) - return traits::eof(); - - if ( !traits::eq_int_type( c, traits::eof() ) && this->pptr() < this->epptr() ) { - sputc( traits::to_char_type(c) ); - return c; - } - - long count = this->pptr() - this->pbase(); - - if ( count ) { - count *= sizeof(charT); -#ifndef __FIT_NONBLOCK_SOCKETS - if ( (this->*_xwrite)( this->pbase(), count ) != count ) { - return traits::eof(); - } -#else - long offset = (this->*_xwrite)( this->pbase(), count ); - if ( offset < 0 ) { - if ( errno == EAGAIN ) { - pollfd wpfd; - wpfd.fd = _fd; - wpfd.events = POLLOUT | POLLHUP | POLLWRNORM; - wpfd.revents = 0; - while ( poll( &wpfd, 1, _timeout ) <= 0 ) { // wait infinite - if ( errno == EINTR ) { // may be interrupted, check and ignore - errno = 0; - continue; - } - return traits::eof(); - } - if ( (wpfd.revents & POLLERR) != 0 ) { - return traits::eof(); - } - offset = (this->*_xwrite)( this->pbase(), count ); - if ( offset < 0 ) { - return traits::eof(); - } - } else { - return traits::eof(); - } - } - if ( offset < count ) { - // MUST BE: (offset % sizeof(char_traits)) == 0 ! - offset /= sizeof(charT); - count /= sizeof(charT); - traits::move( this->pbase(), this->pbase() + offset, count - offset ); - // std::copy_backword( this->pbase() + offset, this->pbase() + count, this->pbase() ); - setp( this->pbase(), this->epptr() ); // require: set pptr - this->pbump( count - offset ); - if( !traits::eq_int_type(c,traits::eof()) ) { - sputc( traits::to_char_type(c) ); - } - - return traits::not_eof(c); - } -#endif - } - - setp( this->pbase(), this->epptr() ); // require: set pptr - if( !traits::eq_int_type(c,traits::eof()) ) { - sputc( traits::to_char_type(c) ); - } - - return traits::not_eof(c); -} - -template<class charT, class traits, class _Alloc> -int basic_sockbuf<charT, traits, _Alloc>::sync() -{ - if ( !is_open() ) { - return -1; - } - - long count = this->pptr() - this->pbase(); - if ( count ) { - // _STLP_ASSERT( this->pbase() != 0 ); - count *= sizeof(charT); -#ifndef __FIT_NONBLOCK_SOCKETS - if ( (this->*_xwrite)( this->pbase(), count ) != count ) { - return -1; - } -#else - long start = 0; - while ( count > 0 ) { - long offset = (this->*_xwrite)( this->pbase() + start, count ); - if ( offset < 0 ) { - ... [truncated message content] |
From: <com...@us...> - 2008-06-10 05:12:43
|
Revision: 1893 http://complement.svn.sourceforge.net/complement/?rev=1893&view=rev Author: complement Date: 2008-06-09 22:12:41 -0700 (Mon, 09 Jun 2008) Log Message: ----------- merge with local changes; nothing significant Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-09 18:31:16 UTC (rev 1892) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-10 05:12:41 UTC (rev 1893) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/09 22:13:05 yeti> +// -*- C++ -*- Time-stamp: <08/06/09 23:51:34 ptr> /* * Copyright (c) 2008 Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-06-09 18:31:16 UTC (rev 1892) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-06-10 05:12:41 UTC (rev 1893) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/09 22:17:26 yeti> +// -*- C++ -*- Time-stamp: <08/06/10 00:01:15 ptr> /* * Copyright (c) 2008 @@ -596,7 +596,7 @@ sockstream_t* s; sockbuf_t* b; } s; - socks_processor_t *p; + socks_processor_t* p; }; struct ctl Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-09 18:31:16 UTC (rev 1892) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-10 05:12:41 UTC (rev 1893) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/09 20:40:57 yeti> +// -*- C++ -*- Time-stamp: <08/06/09 23:49:35 ptr> /* * Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc 2008-06-09 18:31:16 UTC (rev 1892) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc 2008-06-10 05:12:41 UTC (rev 1893) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/09 20:28:59 yeti> +// -*- C++ -*- Time-stamp: <08/06/10 00:41:49 ptr> /* * @@ -80,12 +80,12 @@ sockios2_test test2; - t.add( &sockios2_test::read0, test2, "sockios2_test::read0", - t.add( &sockios2_test::srv_sigpipe, test2, "sockios2_test::srv_sigpipe", - t.add( &sockios2_test::fork, test2, "sockios2_test::fork", - t.add( &sockios2_test::processor_core, test2, "sockios2_test::processor_core", +// t.add( &sockios2_test::read0, test2, "sockios2_test::read0", +// t.add( &sockios2_test::srv_sigpipe, test2, "sockios2_test::srv_sigpipe", +// t.add( &sockios2_test::fork, test2, "sockios2_test::fork", +// t.add( &sockios2_test::processor_core, test2, "sockios2_test::processor_core", t.add( &sockios2_test::connect_disconnect, test2, "sockios2_test::connect_disconnect", - t.add( &sockios2_test::srv_core, test2, "sockios2_test::srv_core" ) ) ) ) ) ); + t.add( &sockios2_test::srv_core, test2, "sockios2_test::srv_core" ) );// ) ) ) ); return t.girdle(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:40:33
|
Revision: 1902 http://complement.svn.sourceforge.net/complement/?rev=1902&view=rev Author: complement Date: 2008-06-25 22:40:30 -0700 (Wed, 25 Jun 2008) Log Message: ----------- Sockets service with central control for incoming data. server's part moved into socksrv.* files. sockmgr (control incoming data for _all_ sockets) delegate sockstream creation to server part (derived from sock_processor_base), but require pointer to to sockbuf from it; dstruction of streams and Connect objects delegated to server part (derived from sock_processor_base); Current unit tests pass. Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sockstream branches/complement-sockios/explore/include/sockios/sockstream.cc branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc branches/complement-sockios/explore/lib/sockios/ut/sockios_test_suite.cc Added Paths: ----------- branches/complement-sockios/explore/include/sockios/socksrv.cc branches/complement-sockios/explore/include/sockios/socksrv.h Added: branches/complement-sockios/explore/include/sockios/socksrv.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.cc (rev 0) +++ branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:40:30 UTC (rev 1902) @@ -0,0 +1,316 @@ +// -*- C++ -*- Time-stamp: <08/06/11 21:41:27 yeti> + +/* + * Copyright (c) 2008 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License Version 3.0 + * + */ + +namespace std { + +template<class charT, class traits, class _Alloc> +void sock_processor_base<charT,traits,_Alloc>::open( const in_addr& addr, int port, sock_base::stype type, sock_base::protocol prot ) +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( basic_socket_t::is_open_unsafe() ) { + return; + } + _mode = ios_base::in | ios_base::out; + _state = ios_base::goodbit; +#ifdef WIN32 + ::WSASetLastError( 0 ); +#endif + if ( prot == sock_base::inet ) { + basic_socket_t::_fd = socket( PF_INET, type, 0 ); + if ( basic_socket_t::_fd == -1 ) { + _state |= ios_base::failbit | ios_base::badbit; + return; + } + // _open = true; + basic_socket_t::_address.inet.sin_family = AF_INET; + basic_socket_t::_address.inet.sin_port = htons( port ); + basic_socket_t::_address.inet.sin_addr.s_addr = addr.s_addr; + + if ( type == sock_base::sock_stream || type == sock_base::sock_seqpacket ) { + // let's try reuse local address + setoptions_unsafe( sock_base::so_reuseaddr, true ); + } + + if ( ::bind( basic_socket_t::_fd, &basic_socket_t::_address.any, sizeof(basic_socket_t::_address) ) == -1 ) { + _state |= ios_base::failbit; +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return; + } + + if ( type == sock_base::sock_stream || type == sock_base::sock_seqpacket ) { + // I am shure, this is socket of type SOCK_STREAM | SOCK_SEQPACKET, + // so don't check return code from listen + ::listen( basic_socket_t::_fd, SOMAXCONN ); + basic_socket_t::mgr->push( *this ); + } + } else if ( prot == sock_base::local ) { + return; + } else { + return; + } + _state = ios_base::goodbit; + + return; +} + +template<class charT, class traits, class _Alloc> +void sock_processor_base<charT,traits,_Alloc>::close() +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( !basic_socket_t::is_open_unsafe() ) { + return; + } + basic_socket<charT,traits,_Alloc>::mgr->pop( *this, basic_socket_t::_fd ); +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::shutdown( basic_socket_t::_fd, 2 ); + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; +} + +template<class charT, class traits, class _Alloc> +void sock_processor_base<charT,traits,_Alloc>::shutdown( sock_base::shutdownflg dir ) +{ + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + if ( basic_socket_t::is_open_unsafe() ) { + if ( (dir & (sock_base::stop_in | sock_base::stop_out)) == + (sock_base::stop_in | sock_base::stop_out) ) { + ::shutdown( basic_socket_t::_fd, 2 ); + } else if ( dir & sock_base::stop_in ) { + ::shutdown( basic_socket_t::_fd, 0 ); + } else if ( dir & sock_base::stop_out ) { + ::shutdown( basic_socket_t::_fd, 1 ); + } + } +} + +template<class charT, class traits, class _Alloc> +void sock_processor_base<charT,traits,_Alloc>::setoptions_unsafe( sock_base::so_t optname, bool on_off, int __v ) +{ +#ifdef __unix + if ( basic_socket_t::is_open_unsafe() ) { + if ( optname != sock_base::so_linger ) { + int turn = on_off ? 1 : 0; + if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&turn, + (socklen_t)sizeof(int) ) != 0 ) { + _state |= ios_base::failbit; + } + } else { + linger l; + l.l_onoff = on_off ? 1 : 0; + l.l_linger = __v; + if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&l, + (socklen_t)sizeof(linger) ) != 0 ) { + _state |= ios_base::failbit; + } + + } + } else { + _state |= ios_base::failbit; + } +#endif // __unix +} + + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +int connect_processor<Connect, charT, traits, _Alloc, C>::Init::_count = 0; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +bool connect_processor<Connect, charT, traits, _Alloc, C>::Init::_at_fork = false; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +std::tr2::mutex connect_processor<Connect, charT, traits, _Alloc, C>::Init::_init_lock; + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::_guard( int direction ) +{ + if ( direction ) { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( _count++ == 0 ) { +#ifdef __FIT_PTHREADS + if ( !_at_fork ) { // call only once + if ( pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ) ) { + // throw system_error + } + _at_fork = true; + } +#endif +// _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); + } + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); + if ( --_count == 0 ) { + + } + } +} + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_prepare() +{ _init_lock.lock(); } + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_child() +{ + _init_lock.unlock(); + + if ( _count != 0 ) { + // std::cerr << "SHOULD NEVER HAPPEN!!!!\n"; + throw std::logic_error( "Fork while connect_processor working may has unexpected behaviour in child process" ); + } + // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); +} + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_parent() +{ _init_lock.unlock(); } + +template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +char connect_processor<Connect, charT, traits, _Alloc, C>::Init_buf[128]; + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::close() +{ + base_t::close(); + + { + std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); + _in_work = false; // <--- set before cnd.notify_one(); (below in this func) + } + + std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); + ready_pool.push_back( processor() ); // make ready_pool not empty + // std::cerr << "=== " << ready_pool.size() << std::endl; + cnd.notify_one(); +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::sockbuf_t* connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( sock_base::socket_type fd, const sockaddr& addr ) +{ + typename base_t::sockstream_t* s = base_t::create_stream( fd, addr ); + + Connect* c = new Connect( *s ); // bad point! I can't read from s in ctor indeed! + + if ( s->rdbuf()->in_avail() ) { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( processor( c, s ) ); + cnd.notify_one(); + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + worker_pool.insert( std::make_pair( fd, processor( c, s ) ) ); + } + + return s->rdbuf(); +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( sock_base::socket_type fd, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_close_t& ) +{ + { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + typename worker_pool_t::iterator i = worker_pool.find( fd ); + if ( i != worker_pool.end() ) { + delete i->second.c; + delete i->second.s; + // std::cerr << "oops\n"; + worker_pool.erase( i ); + return; + } + } + + processor p; + { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + typename ready_pool_t::iterator j = std::find( ready_pool.begin(), ready_pool.end(), /* std::bind2nd( typename processor::equal_to(), &s ) */ fd ); + if ( j != ready_pool.end() ) { + // std::cerr << "oops 2\n"; + p = *j; + ready_pool.erase( j ); + } + } + if ( p.c != 0 ) { + // (*p.c)( *p.s ); + delete p.c; + delete p.s; + } +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( sock_base::socket_type fd ) +{ + processor p; + + { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + typename worker_pool_t::const_iterator i = worker_pool.find( fd ); + if ( i == worker_pool.end() ) { + return; + } + p = i->second; + worker_pool.erase( i ); + } + + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( p ); + cnd.notify_one(); + // std::cerr << "notify data " << (void *)c << " " << ready_pool.size() << std::endl; +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +bool connect_processor<Connect, charT, traits, _Alloc, C>::pop_ready( processor& p ) +{ + { + std::tr2::unique_lock<std::tr2::mutex> lk( rdlock ); + + cnd.wait( lk, not_empty ); + p = ready_pool.front(); // it may contain p.c == 0, p.s == 0, if !in_work() + ready_pool.pop_front(); + // std::cerr << "pop 1\n"; + if ( p.c == 0 ) { // wake up, but _in_work may be still true here (in processor pipe?), + return false; // even I know that _in_work <- false before notification... + } // so, check twice + } + + // std::cerr << "pop 2\n"; + + std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); + return _in_work ? true : false; +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::worker() +{ + _in_work = true; + + processor p; + + while ( pop_ready( p ) ) { + // std::cerr << "worker 1\n"; + (p.c->*C)( *p.s ); + // std::cerr << "worker 2\n"; + if ( p.s->rdbuf()->in_avail() ) { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( p ); + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + worker_pool[p.s->rdbuf()->fd()] = p; + } + // std::cerr << "worker 3\n"; + } +} + +} // namespace std Added: branches/complement-sockios/explore/include/sockios/socksrv.h =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.h (rev 0) +++ branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:40:30 UTC (rev 1902) @@ -0,0 +1,317 @@ +// -*- C++ -*- Time-stamp: <08/06/11 21:40:56 yeti> + +/* + * Copyright (c) 2008 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License Version 3.0 + * + */ + +#ifndef __SOCKIOS_SOCKSRV_H +#define __SOCKIOS_SOCKSRV_H + +#include <cerrno> +#include <mt/thread> +#include <mt/mutex> +#include <mt/condition_variable> + +#ifdef STLPORT +# include <unordered_map> +# include <unordered_set> +# define __USE_STLPORT_TR1 +#else +# if defined(__GNUC__) && (__GNUC__ < 4) +# include <ext/hash_map> +# include <ext/hash_set> +# define __USE_STD_HASH +# else +# include <tr1/unordered_map> +# include <tr1/unordered_set> +# define __USE_STD_TR1 +# endif +#endif + +#include <sockios/sockstream> +#include <deque> +#include <functional> + +namespace std { + +template <class charT, class traits, class _Alloc> class basic_sockbuf; +template <class charT, class traits, class _Alloc> class basic_sockstream; +template <class charT, class traits, class _Alloc> class sock_processor_base; + +template <class charT, class traits, class _Alloc> +class sock_processor_base : + public sock_base, + public basic_socket<charT,traits,_Alloc> +{ + private: + typedef basic_socket<charT,traits,_Alloc> basic_socket_t; + + public: + typedef basic_sockstream<charT,traits,_Alloc> sockstream_t; + typedef basic_sockbuf<charT,traits,_Alloc> sockbuf_t; + + struct adopt_close_t { }; + + sock_processor_base() : + _mode( ios_base::in | ios_base::out ), + _state( ios_base::goodbit ) + { } + + explicit sock_processor_base( int port, sock_base::stype t = sock_base::sock_stream ) + { sock_processor_base::open( port, t, sock_base::inet ); } + + virtual ~sock_processor_base() + { + sock_processor_base::close(); + + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)this << " " << std::tr2::getpid() << std::endl; + // Never uncomment next line: + // basic_socket<charT,traits,_Alloc>::mgr->final( *this ); + // this lead to virtual fuction call, that is already pure here. + } + + void open( const in_addr& addr, int port, sock_base::stype type, sock_base::protocol prot ); + + void open( unsigned long addr, int port, sock_base::stype type, sock_base::protocol prot ) + { + in_addr _addr; + _addr.s_addr = htonl( addr ); + sock_processor_base::open( _addr, port, type, prot ); + } + + void open( int port, sock_base::stype type, sock_base::protocol prot ) + { sock_processor_base::open(INADDR_ANY, port, type, prot); } + + virtual void close(); + + virtual sockbuf_t* operator ()( sock_base::socket_type fd, const sockaddr& ) = 0; + virtual void operator ()( sock_base::socket_type fd, const adopt_close_t& ) = 0; + virtual void operator ()( sock_base::socket_type fd ) = 0; + + private: + sock_processor_base( const sock_processor_base& ); + sock_processor_base& operator =( const sock_processor_base& ); + + protected: + void setoptions_unsafe( sock_base::so_t optname, bool on_off = true, int __v = 0 ); + sockstream_t* create_stream( int fd, const sockaddr& addr ) + { + sockstream_t* s = new sockstream_t(); + s->rdbuf()->_open_sockmgr( fd, addr ); + return s; + } + + public: + bool is_open() const + { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); return basic_socket_t::is_open_unsafe(); } + bool good() const + { return _state == ios_base::goodbit; } + + sock_base::socket_type fd() const + { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); sock_base::socket_type tmp = basic_socket_t::fd_unsafe(); return tmp; } + + void shutdown( sock_base::shutdownflg dir ); + void setoptions( sock_base::so_t optname, bool on_off = true, int __v = 0 ) + { + std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); + setoptions_unsafe( optname, on_off, __v ); + } + + private: + unsigned long _mode; // open mode + unsigned long _state; // state flags + + protected: + std::tr2::mutex _fd_lck; +}; + +typedef sock_processor_base<char,char_traits<char>,allocator<char> > sock_basic_processor; + +template <class Connect, class charT = char, class traits = std::char_traits<charT>, class _Alloc = std::allocator<charT>, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& ) = &Connect::connect > +class connect_processor : + public sock_processor_base<charT,traits,_Alloc> +{ + private: + typedef sock_processor_base<charT,traits,_Alloc> base_t; + + class Init + { + public: + Init() + { _guard( 1 ); } + ~Init() + { _guard( 0 ); } + + private: + static void _guard( int direction ); + static void __at_fork_prepare(); + static void __at_fork_child(); + static void __at_fork_parent(); + static std::tr2::mutex _init_lock; + static int _count; + static bool _at_fork; + }; + + static char Init_buf[]; + + public: + connect_processor() : + not_empty( *this ), + _in_work( false ), + ploop( loop, this ) + { new( Init_buf ) Init(); } + + explicit connect_processor( int port ) : + base_t( port, sock_base::sock_stream ), + not_empty( *this ), + _in_work( false ), + ploop( loop, this ) + { new( Init_buf ) Init(); } + + virtual ~connect_processor() + { + connect_processor::close(); + if ( ploop.joinable() ) { + ploop.join(); + } + // { + // std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + for ( typename worker_pool_t::iterator i = worker_pool.begin(); i != worker_pool.end(); ++i ) { + // delete i->second; + delete i->second.s; + delete i->second.c; + } + worker_pool.clear(); + // } + for ( typename ready_pool_t::iterator j = ready_pool.begin(); j != ready_pool.end(); ++j ) { + delete j->c; + } + ready_pool.clear(); + + std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)this << " " << std::tr2::getpid() << std::endl; + basic_socket<charT,traits,_Alloc>::mgr->final( *this ); + + ((Init *)Init_buf)->~Init(); + } + + virtual void close(); + + void wait() + { if ( ploop.joinable() ) { ploop.join(); } } + + private: + virtual typename base_t::sockbuf_t* operator ()( sock_base::socket_type fd, const sockaddr& ); + virtual void operator ()( sock_base::socket_type fd, const typename base_t::adopt_close_t& ); + virtual void operator ()( sock_base::socket_type fd ); + + static void loop( connect_processor* me ) + { me->worker(); } + + void worker(); + + private: + connect_processor( const connect_processor& ) + { } + + connect_processor& operator =( const connect_processor& ) + { return *this; } + + + struct processor + { + processor() : + c(0), + s(0) + { } + processor( Connect* __c, typename sock_processor_base<charT,traits,_Alloc>::sockstream_t* __s ) : + c(__c), + s(__s) + { } + processor( const processor& p ) : + c( p.c ), + s( p.s ) + { } + + processor& operator =( const processor& p ) + { c = p.c; s = p.s; return *this; } + + Connect* c; + typename sock_processor_base<charT,traits,_Alloc>::sockstream_t* s; + + bool operator ==( const processor& p ) const + { return s == p.s; } + bool operator ==( const typename sock_processor_base<charT,traits,_Alloc>::sockstream_t* st ) const + { return const_cast<const typename sock_processor_base<charT,traits,_Alloc>::sockstream_t*>(s) == st; } + bool operator ==( sock_base::socket_type fd ) const + { return s == 0 ? (fd == -1) : (s->rdbuf()->fd() == fd); } + +/* + struct equal_to : + public std::binary_function<processor, typename sock_processor_base<charT,traits,_Alloc>::sockstream_t*, bool> + { + bool operator()(const processor& __x, const typename sock_processor_base<charT,traits,_Alloc>::sockstream_t* __y) const + { return __x == __y; } + }; +*/ + }; + + bool pop_ready( processor& ); + +#ifdef __USE_STLPORT_HASH + typedef std::hash_map<sock_base::socket_type, processor> worker_pool_t; +#endif +#ifdef __USE_STD_HASH + typedef __gnu_cxx::hash_map<sock_base::socket_type, processor> worker_pool_t; +#endif +#if defined(__USE_STLPORT_TR1) || defined(__USE_STD_TR1) + typedef std::tr1::unordered_map<sock_base::socket_type, processor> worker_pool_t; +#endif + typedef std::deque<processor> ready_pool_t; + + struct _not_empty + { + _not_empty( connect_processor& p ) : + me( p ) + { } + + bool operator()() const + { return !me.ready_pool.empty(); } + + connect_processor& me; + } not_empty; + + worker_pool_t worker_pool; + ready_pool_t ready_pool; + bool _in_work; + std::tr2::mutex wklock; + std::tr2::mutex rdlock; + std::tr2::condition_variable cnd; + std::tr2::mutex inwlock; + std::tr2::condition_variable cnd_inwk; + std::tr2::thread ploop; + + friend struct _not_empty; +}; + +} // namesapce std + +#ifdef __USE_STLPORT_HASH +# undef __USE_STLPORT_HASH +#endif +#ifdef __USE_STD_HASH +# undef __USE_STD_HASH +#endif +#ifdef __USE_STLPORT_TR1 +# undef __USE_STLPORT_TR1 +#endif +#ifdef __USE_STD_TR1 +# undef __USE_STD_TR1 +#endif + +#include <sockios/socksrv.cc> + +#endif /* __SOCKIOS_SOCKSRV_H */ Modified: branches/complement-sockios/explore/include/sockios/sockstream =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream 2008-06-16 14:59:26 UTC (rev 1901) +++ branches/complement-sockios/explore/include/sockios/sockstream 2008-06-26 05:40:30 UTC (rev 1902) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/09 22:22:05 yeti> +// -*- C++ -*- Time-stamp: <08/06/11 14:45:16 yeti> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -252,7 +252,8 @@ void wrtimeout() // infinite { _use_wrtimeout = false; } - sock_base::socket_type fd() const { return _fd;} + sock_base::socket_type fd() const + { return _fd; } bool is_open() const { return _fd != -1; } @@ -373,8 +374,8 @@ template<class charT, class traits, class _Alloc> class basic_sockbuf : - public basic_streambuf<charT, traits> - // public basic_socket<charT,traits,_Alloc> + public basic_streambuf<charT, traits>, + public basic_socket<charT,traits,_Alloc> { private: typedef basic_socket<charT,traits,_Alloc> basic_socket_t; @@ -383,7 +384,6 @@ typedef basic_ios<charT, traits> ios_type; typedef basic_sockbuf<charT, traits, _Alloc> sockbuf_type; typedef typename traits::state_type state_t; - typedef typename basic_socket_t::family_type family_type; public: /* Inherited from basic_streambuf : */ @@ -395,23 +395,62 @@ /* */ basic_sockbuf() : - impl( 0 ) + rdready( *this ), +#if !defined(STLPORT) && defined(__GNUC__) +#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) // hmm, 3.3.6 + _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), +#else // 4.1.1 + _mode( _S_in | _S_out ), +#endif // __GNUC__ +#else // STLPORT + _mode( 0 ), +#endif // STLPORT + _bbuf(0), + _ebuf(0), + _allocated( true ) { } basic_sockbuf( const char *hostname, int port, sock_base::stype type = sock_base::sock_stream, sock_base::protocol prot = sock_base::inet ) : - impl( 0 ) + rdready( *this ), +#if !defined(STLPORT) && defined(__GNUC__) +#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) + _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), +#else // 4.1.1 + _mode( _S_in | _S_out ), +#endif // __GNUC__ +#else // STLPORT + _mode( 0 ), +#endif // STLPORT + _bbuf(0), + _ebuf(0), + _allocated( true ) { open( hostname, port, type, prot ); } basic_sockbuf( const in_addr& addr, int port, sock_base::stype type = sock_base::sock_stream, sock_base::protocol prot = sock_base::inet ) : - impl( 0 ) + rdready( *this ), +#if !defined(STLPORT) && defined(__GNUC__) +#if ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4))) + _mode( ios_base::openmode(__ios_flags::_S_in | __ios_flags::_S_out) ), +#else // 4.1.1 + _mode( _S_in | _S_out ), +#endif // __GNUC__ +#else // STLPORT + _mode( 0 ), +#endif // STLPORT + _bbuf(0), + _ebuf(0), + _allocated( true ) { open( addr, type, prot ); } virtual ~basic_sockbuf() - { close(); } + { + close(); + _M_deallocate_block(); + } sockbuf_type *open( const char *hostname, int port, sock_base::stype type = sock_base::sock_stream, @@ -419,15 +458,13 @@ sockbuf_type *open( const in_addr& addr, int port, sock_base::stype type = sock_base::sock_stream, - sock_base::protocol prot = sock_base::inet ) - { return impl->open( addr, port, type, prot ) ? this : 0; } + sock_base::protocol prot = sock_base::inet ); sockbuf_type *open( sock_base::socket_type s, sock_base::stype t = sock_base::sock_stream ); sockbuf_type *open( sock_base::socket_type s, const sockaddr& addr, - sock_base::stype t = sock_base::sock_stream ) - { return impl->open( s, addr, t ) ? this : 0; } + sock_base::stype t = sock_base::sock_stream ); sockbuf_type *attach( sock_base::socket_type s, sock_base::stype t = sock_base::sock_stream ); @@ -435,65 +472,156 @@ sockbuf_type *attach( sock_base::socket_type s, const sockaddr& addr, sock_base::stype t = sock_base::sock_stream ); - sockbuf_type *close() - { return impl->close() ? this : 0; } + sockbuf_type *close(); + void shutdown( sock_base::shutdownflg dir ); - void shutdown( sock_base::shutdownflg dir ) - { impl->shutdown( dir ); } - sock_base::stype stype() const - { return impl->stype(); } + { return _type; } - template <class Duration> - void rdtimeout( const Duration& d ) - { impl->rdtimeout( d ); } - void rdtimeout() // infinite - { impl->rdtimeout(); } + protected: + virtual streamsize showmanyc() + { return this->egptr() - this->gptr(); } - template <class Duration> - void wrtimeout( const Duration& d ) - { impl->wrtimeout( d ); } - void wrtimeout() // infinite - { impl->wrtimeout(); } + virtual int_type underflow(); + virtual int_type overflow( int_type c = traits::eof() ); + virtual int_type pbackfail( int_type c = traits::eof() ) + { + if ( !basic_socket_t::is_open() ) + return traits::eof(); - sock_base::socket_type fd() const { return impl->fd();} - bool is_open() const - { return impl->is_open(); } + if ( this->gptr() <= this->eback() ) { + return traits::eof(); + } - family_type family() const - { return impl->family(); } + this->gbump(-1); + if ( !traits::eq_int_type(c,traits::eof()) ) { + *this->gptr() = traits::to_char_type(c); + return c; + } - int port() const - { return impl->port(); } + return traits::not_eof(c); + } - unsigned long inet_addr() const - { return impl->inet_addr(); } + // Buffer managment and positioning: + virtual basic_streambuf<charT, traits> *setbuf(char_type *s, streamsize n ) + { + if ( s != 0 && n != 0 ) { + _M_deallocate_block(); + _allocated = false; + _bbuf = s; + _ebuf = s + n; + } + return this; + } - const sockaddr_in& inet_sockaddr() const throw( std::domain_error ) - { return impl->inet_sockaddr(); } + virtual int sync(); + virtual streamsize xsputn(const char_type *s, streamsize n); + private: // Helper functions + charT* _bbuf; + charT* _ebuf; + bool _allocated; // true, if _bbuf should be deallocated - protected: - virtual streamsize showmanyc() - { return impl->showmanyc(); } + // Precondition: 0 < __n <= max_size(). + charT* _M_allocate( size_t __n ) { return _M_data_allocator.allocate(__n); } + void _M_deallocate( charT* __p, size_t __n ) + { if (__p) _M_data_allocator.deallocate(__p, __n); } - virtual int_type underflow() - { return impl->underflow(); } - virtual int_type overflow( int_type c = traits::eof() ) - { return impl->overflow(c); } - virtual int_type pbackfail( int_type c = traits::eof() ) - { return impl->pbackfail( c ); } - // Buffer managment and positioning: - virtual basic_streambuf<charT, traits> *setbuf(char_type *s, streamsize n ) - { impl->setbuf( s, n ); return this; } + void _M_allocate_block(size_t __n) + { + if ( _allocated ) { + if ( __n <= max_size() ) { + _bbuf = _M_allocate(__n); + _ebuf = _bbuf + __n; + // _STLP_ASSERT( __n > 0 ? _bbuf != 0 : _bbuf == 0 ); + } else + this->_M_throw_length_error(); + } + } - virtual int sync() - { return impl->sync(); } - virtual streamsize xsputn(const char_type *s, streamsize n) - { return impl->xsputn( s, n ); } + void _M_deallocate_block() + { if ( _allocated ) _M_deallocate(_bbuf, _ebuf - _bbuf); } + + size_t max_size() const { return (size_t(-1) / sizeof(charT)) - 1; } +#ifdef STLPORT + void _M_throw_length_error() const + { _STLP_THROW(length_error("basic_sockbuf")); } +#else + void _M_throw_length_error() const + { throw length_error("basic_sockbuf"); } +#endif + +#ifdef STLPORT + typedef typename _Alloc_traits<charT, _Alloc>::allocator_type allocator_type; +#else + typedef _Alloc allocator_type; +#endif + /* typedef __allocator<charT, _Alloc> _Alloc_type; */ + + /* _Alloc_type */ allocator_type _M_data_allocator; + + class rdready_t + { + public: + rdready_t( sockbuf_type& self ) : + b( self ) + { } + bool operator ()() const + { return b.showmanyc() != 0; } + private: + sockbuf_type& b; + } rdready; + + sockbuf_type *_open_sockmgr( sock_base::socket_type s, const sockaddr& addr, + sock_base::stype t = sock_base::sock_stream ); + private: - detail::basic_sockbuf_aux<charT,traits,_Alloc> *impl; + typedef basic_sockbuf<charT,traits,_Alloc> _Self_type; + int (basic_sockbuf<charT,traits,_Alloc>::*_xwrite)( const void *, size_t ); + int (basic_sockbuf<charT,traits,_Alloc>::*_xread)( void *, size_t ); + int write( const void *buf, size_t n ) +#ifndef WIN32 + { return ::write( basic_socket_t::_fd, buf, n ); } +#else + { return ::send( basic_socket_t::_fd, (const char *)buf, n, 0 ); } +#endif + int send( const void *buf, size_t n ) +#ifdef WIN32 + { return ::send( basic_socket_t::_fd, (const char *)buf, n, 0 ); } +#else + { return ::send( basic_socket_t::_fd, buf, n, 0 ); } +#endif + int sendto( const void *buf, size_t n ) +#ifdef WIN32 + { return ::sendto( basic_socket_t::_fd, (const char *)buf, n, 0, &basic_socket_t::_address.any, sizeof( sockaddr_in ) ); } +#else + { return ::sendto( basic_socket_t::_fd, buf, n, 0, &basic_socket_t::_address.any, sizeof( sockaddr_in ) ); } +#endif + + int read( void *buf, size_t n ) +#ifdef WIN32 + { return ::recv( basic_socket_t::_fd, (char *)buf, n, 0 ); } +#else + { return ::read( basic_socket_t::_fd, buf, n ); } +#endif + int recv( void *buf, size_t n ) +#ifdef WIN32 + { return ::recv( basic_socket_t::_fd, (char *)buf, n, 0 ); } +#else + { return ::recv( basic_socket_t::_fd, buf, n, 0 ); } +#endif + int recvfrom( void *buf, size_t n ); + void __hostname(); + + ios_base::openmode _mode; + sock_base::stype _type; + + std::tr2::mutex ulck; + std::tr2::condition_variable ucnd; + + friend class detail::sockmgr<charT,traits,_Alloc>; + friend class sock_processor_base<charT,traits,_Alloc>; }; template <class charT, class traits, class _Alloc> Modified: branches/complement-sockios/explore/include/sockios/sockstream.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream.cc 2008-06-16 14:59:26 UTC (rev 1901) +++ branches/complement-sockios/explore/include/sockios/sockstream.cc 2008-06-26 05:40:30 UTC (rev 1902) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/09 21:59:13 yeti> +// -*- C++ -*- Time-stamp: <08/06/11 14:47:58 yeti> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -32,7 +32,111 @@ sock_base::protocol prot ) { return basic_sockbuf<charT, traits, _Alloc>::open( std::findhost( name ), port, type, prot ); } +template<class charT, class traits, class _Alloc> +basic_sockbuf<charT, traits, _Alloc> * +basic_sockbuf<charT, traits, _Alloc>::open( const in_addr& addr, int port, + sock_base::stype type, + sock_base::protocol prot ) +{ + if ( basic_socket_t::is_open() ) { + return 0; + } + try { + _mode = ios_base::in | ios_base::out; + _type = type; +#ifdef WIN32 + WSASetLastError( 0 ); +#endif + if ( prot == sock_base::inet ) { + basic_socket_t::_fd = socket( PF_INET, type, 0 ); + if ( basic_socket_t::_fd == -1 ) { + throw std::runtime_error( "can't open socket" ); + } + basic_socket_t::_address.inet.sin_family = AF_INET; + // htons is a define at least in Linux 2.2.5-15, and it's expantion fail + // for gcc 2.95.3 +#if defined(linux) && defined(htons) && defined(__bswap_16) + basic_socket_t::_address.inet.sin_port = ((((port) >> 8) & 0xff) | (((port) & 0xff) << 8)); +#else + basic_socket_t::_address.inet.sin_port = htons( port ); +#endif // linux && htons + basic_socket_t::_address.inet.sin_addr = addr; + + // Generally, stream sockets may successfully connect() only once + if ( connect( basic_socket_t::_fd, &basic_socket_t::_address.any, sizeof( basic_socket_t::_address ) ) == -1 ) { + throw std::domain_error( "connect fail" ); + } + if ( type == sock_base::sock_stream ) { + _xwrite = &_Self_type::write; + _xread = &_Self_type::read; + } else if ( type == sock_base::sock_dgram ) { + _xwrite = &_Self_type::send; + _xread = &_Self_type::recv; + } + } else if ( prot == sock_base::local ) { + basic_socket_t::_fd = socket( PF_UNIX, type, 0 ); + if ( basic_socket_t::_fd == -1 ) { + throw std::runtime_error( "can't open socket" ); + } + } else { // other protocols not implemented yet + throw std::invalid_argument( "protocol not implemented" ); + } + if ( _bbuf == 0 ) { + struct ifconf ifc; + struct ifreq ifr; + ifc.ifc_len = sizeof(ifreq); + ifc.ifc_req = 𝔦 + int mtu = ((ioctl(basic_socket_t::_fd, SIOCGIFMTU, &ifc) < 0 ? 1500 : ifr.ifr_mtu) - 20 - (type == sock_base::sock_stream ? 20 : 8 )) / sizeof(charT); + int qlen = ioctl(basic_socket_t::_fd, SIOCGIFTXQLEN, &ifc) < 0 ? 2 : ifr.ifr_qlen; + _M_allocate_block( type == sock_base::sock_stream ? mtu * qlen * 2 : mtu * 2 ); + } + + if ( _bbuf == 0 ) { + throw std::length_error( "can't allocate block" ); + } + + if ( fcntl( basic_socket_t::_fd, F_SETFL, fcntl( basic_socket_t::_fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + throw std::runtime_error( "can't establish nonblock mode" ); + } + setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); + setg( this->epptr(), this->epptr(), this->epptr() ); + basic_socket_t::_notify_close = true; + basic_socket_t::mgr->push( *this ); + } + catch ( std::domain_error& ) { +#ifdef WIN32 + // _errno = WSAGetLastError(); + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return 0; + } + catch ( std::length_error& ) { +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return 0; + } + catch ( std::runtime_error& ) { +#ifdef WIN32 + // _errno = WSAGetLastError(); +#else +#endif + return 0; + } + catch ( std::invalid_argument& ) { + return 0; + } + + return this; +} + template<class charT, class traits, class _Alloc> basic_sockbuf<charT, traits, _Alloc> * basic_sockbuf<charT, traits, _Alloc>::open( sock_base::socket_type s, sock_base::stype t ) @@ -50,6 +154,20 @@ template<class charT, class traits, class _Alloc> basic_sockbuf<charT, traits, _Alloc> * +basic_sockbuf<charT, traits, _Alloc>::open( sock_base::socket_type s, + const sockaddr& addr, + sock_base::stype t ) +{ + basic_sockbuf<charT, traits, _Alloc>* ret = _open_sockmgr( s, addr, t ); + if ( ret != 0 ) { + basic_socket_t::_notify_close = true; + basic_socket_t::mgr->push( *this ); + } + return ret; +} + +template<class charT, class traits, class _Alloc> +basic_sockbuf<charT, traits, _Alloc> * basic_sockbuf<charT, traits, _Alloc>::attach( sock_base::socket_type s, sock_base::stype t ) { @@ -79,6 +197,316 @@ } template<class charT, class traits, class _Alloc> +basic_sockbuf<charT, traits, _Alloc> * +basic_sockbuf<charT, traits, _Alloc>::_open_sockmgr( sock_base::socket_type s, + const sockaddr& addr, + sock_base::stype t ) +{ + if ( basic_socket_t::is_open() || s == -1 ) { + return 0; + } + basic_socket_t::_fd = s; + memcpy( (void *)&basic_socket_t::_address.any, (const void *)&addr, sizeof(sockaddr) ); + _mode = ios_base::in | ios_base::out; + _type = t; +#ifdef WIN32 + WSASetLastError( 0 ); +#endif + if ( t == sock_base::sock_stream ) { + _xwrite = &_Self_type::write; + _xread = &_Self_type::read; + } else if ( t == sock_base::sock_dgram ) { + _xwrite = &_Self_type::sendto; + _xread = &_Self_type::recvfrom; + } else { + basic_socket_t::_fd = -1; + return 0; // unsupported type + } + + if ( _bbuf == 0 ) { + struct ifconf ifc; + struct ifreq ifr; + ifc.ifc_len = sizeof(ifreq); + ifc.ifc_req = 𝔦 + int mtu = ((ioctl(basic_socket_t::_fd, SIOCGIFMTU, &ifc) < 0 ? 1500 : ifr.ifr_mtu) - 20 - (t == sock_base::sock_stream ? 20 : 8 )) / sizeof(charT); + int qlen = ioctl(basic_socket_t::_fd, SIOCGIFTXQLEN, &ifc) < 0 ? 2 : ifr.ifr_qlen; + _M_allocate_block( t == sock_base::sock_stream ? mtu * qlen * 2 : mtu * 2); + } + + if ( _bbuf == 0 ) { +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + basic_socket_t::_fd = -1; + return 0; + } + + if ( fcntl( basic_socket_t::_fd, F_SETFL, fcntl( basic_socket_t::_fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + throw std::runtime_error( "can't establish nonblock mode" ); + } + setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); + setg( this->epptr(), this->epptr(), this->epptr() ); + + return this; +} + +template<class charT, class traits, class _Alloc> +basic_sockbuf<charT, traits, _Alloc> * +basic_sockbuf<charT, traits, _Alloc>::close() +{ + if ( !basic_socket_t::is_open() ) + return 0; + + // if ( _doclose ) { +#ifdef WIN32 + ::closesocket( basic_socket_t::_fd ); +#else + ::close( basic_socket_t::_fd ); +#endif + // } + + // _STLP_ASSERT( _bbuf != 0 ); + // put area before get area + setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); + setg( this->epptr(), this->epptr(), this->epptr() ); + + if ( basic_socket_t::_notify_close ) { + basic_socket_t::mgr->exit_notify( this, basic_socket_t::_fd ); + basic_socket_t::_notify_close = false; + } + + basic_socket_t::_fd = -1; + + return this; +} + +template<class charT, class traits, class _Alloc> +void basic_sockbuf<charT, traits, _Alloc>::shutdown( sock_base::shutdownflg dir ) +{ + if ( basic_socket_t::is_open_unsafe() ) { + if ( (dir & (sock_base::stop_in | sock_base::stop_out)) == + (sock_base::stop_in | sock_base::stop_out) ) { + ::shutdown( basic_socket_t::_fd, 2 ); + } else if ( dir & sock_base::stop_in ) { + ::shutdown( basic_socket_t::_fd, 0 ); + } else if ( dir & sock_base::stop_out ) { + ::shutdown( basic_socket_t::_fd, 1 ); + } + } +} + +template<class charT, class traits, class _Alloc> +__FIT_TYPENAME basic_sockbuf<charT, traits, _Alloc>::int_type +basic_sockbuf<charT, traits, _Alloc>::underflow() +{ + if( !basic_socket_t::is_open() ) + return traits::eof(); + + std::tr2::unique_lock<std::tr2::mutex> lk( ulck ); + + if ( this->gptr() < this->egptr() ) + return traits::to_int_type(*this->gptr()); + + if ( this->egptr() == this->gptr() ) { // fullfilled: _ebuf == gptr() + setg( this->eback(), this->eback(), this->eback() ); + } + + // setg( this->eback(), this->eback(), this->eback() + offset ); + // wait on condition + if ( basic_socket_t::_use_rdtimeout ) { + ucnd.timed_wait( lk, basic_socket_t::_rdtimeout, rdready ); + } else { + ucnd.wait( lk, rdready ); + } + + return traits::to_int_type(*this->gptr()); +} + +template<class charT, class traits, class _Alloc> +__FIT_TYPENAME basic_sockbuf<charT, traits, _Alloc>::int_type +basic_sockbuf<charT, traits, _Alloc>::overflow( int_type c ) +{ + if ( !basic_socket_t::is_open() ) + return traits::eof(); + + if ( !traits::eq_int_type( c, traits::eof() ) && this->pptr() < this->epptr() ) { + sputc( traits::to_char_type(c) ); + return c; + } + + long count = this->pptr() - this->pbase(); + + if ( count ) { + count *= sizeof(charT); + long offset = (this->*_xwrite)( this->pbase(), count ); + if ( offset < 0 ) { + if ( errno == EAGAIN ) { + pollfd wpfd; + wpfd.fd = basic_socket_t::_fd; + wpfd.events = POLLOUT | POLLHUP | POLLWRNORM; + wpfd.revents = 0; + while ( poll( &wpfd, 1, basic_socket_t::_use_wrtimeout ? basic_socket_t::_wrtimeout.count() : -1 ) <= 0 ) { // wait infinite + if ( errno == EINTR ) { // may be interrupted, check and ignore + errno = 0; + continue; + } + return traits::eof(); + } + if ( (wpfd.revents & POLLERR) != 0 ) { + return traits::eof(); + } + offset = (this->*_xwrite)( this->pbase(), count ); + if ( offset < 0 ) { + return traits::eof(); + } + } else { + return traits::eof(); + } + } + if ( offset < count ) { + // MUST BE: (offset % sizeof(char_traits)) == 0 ! + offset /= sizeof(charT); + count /= sizeof(charT); + traits::move( this->pbase(), this->pbase() + offset, count - offset ); + // std::copy_backword( this->pbase() + offset, this->pbase() + count, this->pbase() ); + setp( this->pbase(), this->epptr() ); // require: set pptr + this->pbump( count - offset ); + if( !traits::eq_int_type(c,traits::eof()) ) { + sputc( traits::to_char_type(c) ); + } + + return traits::not_eof(c); + } + } + + setp( this->pbase(), this->epptr() ); // require: set pptr + if( !traits::eq_int_type(c,traits::eof()) ) { + sputc( traits::to_char_type(c) ); + } + + return traits::not_eof(c); +} + +template<class charT, class traits, class _Alloc> +int basic_sockbuf<charT, traits, _Alloc>::sync() +{ + if ( !basic_socket_t::is_open() ) { + return -1; + } + + long count = this->pptr() - this->pbase(); + if ( count ) { + // _STLP_ASSERT( this->pbase() != 0 ); + count *= sizeof(charT); + long start = 0; + while ( count > 0 ) { + long offset = (this->*_xwrite)( this->pbase() + start, count ); + if ( offset < 0 ) { + if ( errno == EAGAIN ) { + pollfd wpfd; + wpfd.fd = basic_socket_t::_fd; + wpfd.events = POLLOUT | POLLHUP | POLLWRNORM; + wpfd.revents = 0; + while ( poll( &wpfd, 1, basic_socket_t::_use_wrtimeout ? basic_socket_t::_wrtimeout.count() : -1 ) <= 0 ) { // wait infinite + if ( errno == EINTR ) { // may be interrupted, check and ignore + errno = 0; + continue; + } + return -1; + } + if ( (wpfd.revents & POLLERR) != 0 ) { + return -1; + } + offset = (this->*_xwrite)( this->pbase() + start, count ); + if ( offset < 0 ) { + return -1; + } + } else { + return -1; + } + } + count -= offset; + start += offset; + } + setp( this->pbase(), this->epptr() ); // require: set pptr + } + + return 0; +} + +template<class charT, class traits, class _Alloc> +streamsize basic_sockbuf<charT, traits, _Alloc>::xsputn( const char_type *s, streamsize n ) +{ + if ( !basic_socket_t::is_open() || s == 0 || n == 0 ) { + return 0; + } + + if ( this->epptr() - this->pptr() > n ) { + traits::copy( this->pptr(), s, n ); + this->pbump( n ); + } else { + streamsize __n_put = this->epptr() - this->pptr(); + traits::copy( this->pptr(), s, __n_put ); + this->pbump( __n_put ); + + if ( traits::eq_int_type(overflow(),traits::eof()) ) + return 0; + + setp( (char_type *)(s + __n_put), (char_type *)(s + n) ); + this->pbump( n - __n_put ); + + if ( traits::eq_int_type(overflow(),traits::eof()) ) { + setp( _bbuf, _bbuf + ((_ebuf - _bbuf) >> 1) ); + return 0; + } + setp( _bbuf, _bbuf + ((_ebuf - _bbuf) >> 1) ); + } + return n; +} + +template<class charT, class traits, class _Alloc> +int basic_sockbuf<charT, traits, _Alloc>::recvfrom( void *buf, size_t n ) +{ +#if defined(_WIN32) || (defined(__hpux) && !defined(_INCLUDE_POSIX1C_SOURCE)) + int sz = sizeof( sockaddr_in ); +#else + socklen_t sz = sizeof( sockaddr_in ); +#endif + + typename basic_socket_t::sockaddr_t addr; + +#ifdef __FIT_POLL + pollfd pfd; + pfd.fd = basic_socket_t::_fd; + pfd.events = POLLIN; +#endif // __FIT_POLL + do { +#ifdef __FIT_POLL + pfd.revents = 0; + if ( poll( &pfd, 1, /* _timeout */ -1 ) > 0 ) { // wait infinite + // get address of caller only + char buff[32]; + ::recvfrom( basic_socket_t::_fd, buff, 32, MSG_PEEK, &addr.any, &sz ); + } else { + return 0; // poll wait infinite, so it can't return 0 (timeout), so it return -1. + } +#endif // __FIT_POLL + if ( memcmp( &basic_socket_t::_address.inet, &addr.inet, sizeof(sockaddr_in) ) == 0 ) { +#ifdef WIN32 + return ::recvfrom( basic_socket_t::_fd, (char *)buf, n, 0, &basic_socket_t::_address.any, &sz ); +#else + return ::recvfrom( basic_socket_t::_fd, buf, n, 0, &basic_socket_t::_address.any, &sz ); +#endif + } + // xmt::Thread::yield(); + } while ( true ); + + return 0; // never +} + +template<class charT, class traits, class _Alloc> void basic_sockstream<charT, traits, _Alloc>::setoptions( sock_base::so_t optname, bool on_off, int __v ) { #ifdef __unix Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-16 14:59:26 UTC (rev 1901) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:40:30 UTC (rev 1902) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/09 23:51:34 ptr> +// -*- C++ -*- Time-stamp: <08/06/11 21:42:37 yeti> /* * Copyright (c) 2008 @@ -10,741 +10,9 @@ namespace std { -template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::open( const in_addr& addr, int port, sock_base::stype type, sock_base::protocol prot ) -{ - std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); - if ( basic_socket_t::is_open_unsafe() ) { - return; - } - _mode = ios_base::in | ios_base::out; - _state = ios_base::goodbit; -#ifdef WIN32 - ::WSASetLastError( 0 ); -#endif - if ( prot == sock_base::inet ) { - basic_socket_t::_fd = socket( PF_INET, type, 0 ); - if ( basic_socket_t::_fd == -1 ) { - _state |= ios_base::failbit | ios_base::badbit; - return; - } - // _open = true; - basic_socket_t::_address.inet.sin_family = AF_INET; - basic_socket_t::_address.inet.sin_port = htons( port ); - basic_socket_t::_address.inet.sin_addr.s_addr = addr.s_addr; - - if ( type == sock_base::sock_stream || type == sock_base::sock_seqpacket ) { - // let's try reuse local address - setoptions_unsafe( sock_base::so_reuseaddr, true ); - } - - if ( ::bind( basic_socket_t::_fd, &basic_socket_t::_address.any, sizeof(basic_socket_t::_address) ) == -1 ) { - _state |= ios_base::failbit; -#ifdef WIN32 - ::closesocket( basic_socket_t::_fd ); -#else - ::close( basic_socket_t::_fd ); -#endif - basic_socket_t::_fd = -1; - return; - } - - if ( type == sock_base::sock_stream || type == sock_base::sock_seqpacket ) { - // I am shure, this is socket of type SOCK_STREAM | SOCK_SEQPACKET, - // so don't check return code from listen - ::listen( basic_socket_t::_fd, SOMAXCONN ); - basic_socket_t::mgr->push( *this ); - } - } else if ( prot == sock_base::local ) { - return; - } else { - return; - } - _state = ios_base::goodbit; - - return; -} - -template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::close() -{ - std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); - if ( !basic_socket_t::is_open_unsafe() ) { - return; - } - basic_socket<charT,traits,_Alloc>::mgr->pop( *this, basic_socket_t::_fd ); -#ifdef WIN32 - ::closesocket( basic_socket_t::_fd ); -#else - ::shutdown( basic_socket_t::_fd, 2 ); - ::close( basic_socket_t::_fd ); -#endif - basic_socket_t::_fd = -1; -} - -template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::shutdown( sock_base::shutdownflg dir ) -{ - std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); - if ( basic_socket_t::is_open_unsafe() ) { - if ( (dir & (sock_base::stop_in | sock_base::stop_out)) == - (sock_base::stop_in | sock_base::stop_out) ) { - ::shutdown( basic_socket_t::_fd, 2 ); - } else if ( dir & sock_base::stop_in ) { - ::shutdown( basic_socket_t::_fd, 0 ); - } else if ( dir & sock_base::stop_out ) { - ::shutdown( basic_socket_t::_fd, 1 ); - } - } -} - -template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::setoptions_unsafe( sock_base::so_t optname, bool on_off, int __v ) -{ -#ifdef __unix - if ( basic_socket_t::is_open_unsafe() ) { - if ( optname != sock_base::so_linger ) { - int turn = on_off ? 1 : 0; - if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&turn, - (socklen_t)sizeof(int) ) != 0 ) { - _state |= ios_base::failbit; - } - } else { - linger l; - l.l_onoff = on_off ? 1 : 0; - l.l_linger = __v; - if ( setsockopt( basic_socket_t::_fd, SOL_SOCKET, (int)optname, (const void *)&l, - (socklen_t)sizeof(linger) ) != 0 ) { - _state |= ios_base::failbit; - } - - } - } else { - _state |= ios_base::failbit; - } -#endif // __unix -} - - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -int connect_processor<Connect, charT, traits, _Alloc, C>::Init::_count = 0; - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -bool connect_processor<Connect, charT, traits, _Alloc, C>::Init::_at_fork = false; - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -std::tr2::mutex connect_processor<Connect, charT, traits, _Alloc, C>::Init::_init_lock; - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::Init::_guard( int direction ) -{ - if ( direction ) { - std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); - if ( _count++ == 0 ) { -#ifdef __FIT_PTHREADS - if ( !_at_fork ) { // call only once - if ( pthread_atfork( __at_fork_prepare, __at_fork_parent, __at_fork_child ) ) { - // throw system_error - } - _at_fork = true; - } -#endif -// _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); - } - } else { - std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); - if ( --_count == 0 ) { - - } - } -} - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_prepare() -{ _init_lock.lock(); } - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_child() -{ - _init_lock.unlock(); - - if ( _count != 0 ) { - // std::cerr << "SHOULD NEVER HAPPEN!!!!\n"; - throw std::logic_error( "Fork while connect_processor working may has unexpected behaviour in child process" ); - } - // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); -} - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::Init::__at_fork_parent() -{ _init_lock.unlock(); } - -template<class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -char connect_processor<Connect, charT, traits, _Alloc, C>::Init_buf[128]; - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::close() -{ - base_t::close(); - - { - std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); - _in_work = false; // <--- set before cnd.notify_one(); (below in this func) - } - - std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); - ready_pool.push_back( processor() ); // make ready_pool not empty - // std::cerr << "=== " << ready_pool.size() << std::endl; - cnd.notify_one(); -} - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( int fd, const sockaddr& addr ) -{ - typename base_t::sockstream_t* s = base_t::create_stream( fd, addr ); - - Connect* c = new Connect( *s ); // bad point! I can't read from s in ctor indeed! - - if ( s->rdbuf()->in_avail() ) { - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - ready_pool.push_back( processor( c, s ) ); - cnd.notify_one(); - } else { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool.insert( std::make_pair( fd, processor( c, s ) ) ); - } -} - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( int fd, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_close_t& ) -{ - { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - typename worker_pool_t::iterator i = worker_pool.find( fd ); - if ( i != worker_pool.end() ) { - delete i->second.s; - delete i->second.c; - // std::cerr << "oops\n"; - worker_pool.erase( i ); - return; - } - } - - Connect* c = 0; - { - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - typename ready_pool_t::iterator j = std::find( ready_pool.begin(), ready_pool.end(), /* std::bind2nd( typename processor::equal_to(), &s ) */ fd ); - if ( j != ready_pool.end() ) { - // std::cerr << "oops 2\n"; - c = j->c; - ready_pool.erase( j ); - } - } - if ( c != 0 ) { -//using unknown variable s -// (c->*C)( s ); - delete c; - } -} - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( int fd, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_data_t& ) -{ - processor p; - - { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - typename worker_pool_t::const_iterator i = worker_pool.find( fd ); - if ( i == worker_pool.end() ) { - return; - } - p = i->second; - worker_pool.erase( i ); - } - - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - ready_pool.push_back( p ); - cnd.notify_one(); - // std::cerr << "notify data " << (void *)c << " " << ready_pool.size() << std::endl; -} - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -bool connect_processor<Connect, charT, traits, _Alloc, C>::pop_ready( processor& p ) -{ - { - std::tr2::unique_lock<std::tr2::mutex> lk( rdlock ); - - cnd.wait( lk, not_empty ); - p = ready_pool.front(); // it may contain p.c == 0, p.s == 0, if !in_work() - ready_pool.pop_front(); - // std::cerr << "pop 1\n"; - if ( p.c == 0 ) { // wake up, but _in_work may be still true here (in processor pipe?), - return false; // even I know that _in_work <- false before notification... - } // so, check twice - } - - // std::cerr << "pop 2\n"; - - std::tr2::lock_guard<std::tr2::mutex> lk(inwlock); - return _in_work ? true : false; -} - - -template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::worker() -{ - _in_work = true; - - processor p; - - while ( pop_ready( p ) ) { - // std::cerr << "worker 1\n"; - (p.c->*C)( *p.s ); - // std::cerr << "worker 2\n"; - if ( p.s->rdbuf()->in_avail() ) { - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - ready_pool.push_back( p ); - } else { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool[p.s->rdbuf()->fd()] = p; - ... [truncated message content] |
From: <com...@us...> - 2008-06-26 05:41:11
|
Revision: 1904 http://complement.svn.sourceforge.net/complement/?rev=1904&view=rev Author: complement Date: 2008-06-25 22:41:09 -0700 (Wed, 25 Jun 2008) Log Message: ----------- take into account extra CFLAGS and LDFLAGS; configurable via 'configure'; don't assume presence of STLport. Modified Paths: -------------- branches/complement-sockios/explore/Makefiles/ChangeLog branches/complement-sockios/explore/Makefiles/gmake/extern.mak branches/complement-sockios/explore/Makefiles/gmake/gcc.mak branches/complement-sockios/explore/Makefiles/gmake/top.mak branches/complement-sockios/explore/configure Modified: branches/complement-sockios/explore/Makefiles/ChangeLog =================================================================== --- branches/complement-sockios/explore/Makefiles/ChangeLog 2008-06-26 05:40:45 UTC (rev 1903) +++ branches/complement-sockios/explore/Makefiles/ChangeLog 2008-06-26 05:41:09 UTC (rev 1904) @@ -3,8 +3,13 @@ * gmake/targetdirs.mak: use $(DESTDIR) as in common practice (change root of installation, but don't change run paths); - * gmake/depend.mak: fix options for ctags/etags. + * gmake/depend.mak: fix options for ctags/etags; + * gmake/gcc.mak, gmake/top.mak, configure: take into account + extra CFLAGS and LDFLAGS; configurable via 'configure'; + + * gmake/extern.mak: don't assume presence of STLport. + 2008-02-27 Petr Ovtchenkov <pt...@is...> * gmake/lib/gcc.mak: 3.3 is normal compiler, just some Modified: branches/complement-sockios/explore/Makefiles/gmake/extern.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/extern.mak 2008-06-26 05:40:45 UTC (rev 1903) +++ branches/complement-sockios/explore/Makefiles/gmake/extern.mak 2008-06-26 05:41:09 UTC (rev 1904) @@ -1,6 +1,6 @@ -# Time-stamp: <07/03/08 22:41:26 ptr> +# Time-stamp: <08/06/06 17:06:16 yeti> # -# Copyright (c) 1997-1999, 2002, 2003, 2005, 2006 +# Copyright (c) 1997-1999, 2002, 2003, 2005, 2006, 2008 # Petr Ovtchenkov # # Portion Copyright (c) 1999-2001 @@ -30,9 +30,11 @@ # STLport library +ifndef STLPORT_DIR ifndef WITHOUT_STLPORT -STLPORT_DIR ?= ${HOME}/STLport.lab/STLport +WITHOUT_STLPORT = 1 endif +endif ifdef STLPORT_DIR STLPORT_LIB_DIR ?= $(STLPORT_DIR)/${TARGET_NAME}lib Modified: branches/complement-sockios/explore/Makefiles/gmake/gcc.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/gcc.mak 2008-06-26 05:40:45 UTC (rev 1903) +++ branches/complement-sockios/explore/Makefiles/gmake/gcc.mak 2008-06-26 05:41:09 UTC (rev 1904) @@ -1,4 +1,4 @@ -# Time-stamp: <08/02/26 13:46:36 ptr> +# Time-stamp: <08/06/06 17:38:26 yeti> # # Copyright (c) 1997-1999, 2002, 2003, 2005-2008 # Petr Ovtchenkov @@ -179,6 +179,10 @@ CXXFLAGS += ${EXTRA_CXXFLAGS} endif +ifdef EXTRA_CFLAGS +CFLAGS += ${EXTRA_CFLAGS} +endif + CDEPFLAGS = -E -M CCDEPFLAGS = -E -M Modified: branches/complement-sockios/explore/Makefiles/gmake/top.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/top.mak 2008-06-26 05:40:45 UTC (rev 1903) +++ branches/complement-sockios/explore/Makefiles/gmake/top.mak 2008-06-26 05:41:09 UTC (rev 1904) @@ -1,4 +1,4 @@ -# Time-stamp: <07/07/12 10:55:41 ptr> +# Time-stamp: <08/06/06 17:28:38 yeti> # # Copyright (c) 1997-1999, 2002, 2003, 2005-2007 # Petr Ovtchenkov @@ -25,6 +25,10 @@ COMPILER_NAME := gcc endif +ifndef LDFLAGS +LDFLAGS := +endif + ifndef ALL_TAGS ifndef _NO_SHARED_BUILD @@ -91,6 +95,8 @@ # os-specific local rules (or other project-specific definitions) -include specific.mak +LDFLAGS += ${EXTRA_LDFLAGS} + # derive common targets (*.o, *.d), # build rules (including output catalogs) include ${RULESBASE}/gmake/targets.mak Modified: branches/complement-sockios/explore/configure =================================================================== --- branches/complement-sockios/explore/configure 2008-06-26 05:40:45 UTC (rev 1903) +++ branches/complement-sockios/explore/configure 2008-06-26 05:41:09 UTC (rev 1904) @@ -1,6 +1,6 @@ #!/bin/sh -# Time-stamp: <08/02/26 16:02:32 yeti> +# Time-stamp: <08/06/06 17:44:52 yeti> base=`cd \`dirname $0\`; echo $PWD` @@ -47,6 +47,10 @@ --with-mssdk=<dir> use MS SDK from this catalog --with-extra-cxxflags=<options> pass extra options to C++ compiler + --with-extra-cflags=<options> + pass extra options to C compiler + --with-extra-ldflags=<options> + pass extra options to linker (via C/C++) --use-static-gcc use static gcc libs instead of shared libgcc_s (useful for gcc compiler, that was builded with --enable-shared [default]; if compiler was builded with --disable-shared, static libraries will be used in any case) @@ -69,6 +73,8 @@ \$CXX C++ compiler name (use --target= for cross-compilation) \$CC C compiler name (use --target= for cross-compilation) \$CXXFLAGS pass extra options to C++ compiler + \$CFLAGS pass extra options to C compiler + \$LDFLAGS pass extra options to linker (via C/C++) Options has preference over environment variables. @@ -156,6 +162,14 @@ write_option "$option" EXTRA_CXXFLAGS cxxflags_set=y ;; + --with-extra-cflags=*) + write_option "$option" EXTRA_CFLAGS + cflags_set=y + ;; + --with-extra-ldflags=*) + write_option "$option" EXTRA_LDFLAGS + ldflags_set=y + ;; --use-static-gcc) write_option "1" USE_STATIC_LIBGCC ;; @@ -236,6 +250,22 @@ fi fi +if [ "$CFLAGS" != "" ]; then + if [ "$cflags_set" = "" ]; then + write_option "$CFLAGS" EXTRA_CFLAGS + else + echo "Both --with-extra-cflags and \$CFLAGS set, using the first" + fi +fi + +if [ "$LDFLAGS" != "" ]; then + if [ "$ldflags_set" = "" ]; then + write_option "$LDFLAGS" EXTRA_LDFLAGS + else + echo "Both --with-extra-ldflags and \$LDFLAGS set, using the first" + fi +fi + # default settings default_settings This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:41:27
|
Revision: 1905 http://complement.svn.sourceforge.net/complement/?rev=1905&view=rev Author: complement Date: 2008-06-25 22:41:25 -0700 (Wed, 25 Jun 2008) Log Message: ----------- don't duplicate options in config.mak, that has default values in makefiles Modified Paths: -------------- branches/complement-sockios/explore/Makefiles/ChangeLog branches/complement-sockios/explore/configure Modified: branches/complement-sockios/explore/Makefiles/ChangeLog =================================================================== --- branches/complement-sockios/explore/Makefiles/ChangeLog 2008-06-26 05:41:09 UTC (rev 1904) +++ branches/complement-sockios/explore/Makefiles/ChangeLog 2008-06-26 05:41:25 UTC (rev 1905) @@ -1,3 +1,8 @@ +2008-06-07 Petr Ovtchenkov <pt...@is...> + + * configure: don't duplicate options in config.mak, that + has default values in makefiles. + 2008-06-06 Petr Ovtchenkov <pt...@is...> * gmake/targetdirs.mak: use $(DESTDIR) as in common practice Modified: branches/complement-sockios/explore/configure =================================================================== --- branches/complement-sockios/explore/configure 2008-06-26 05:41:09 UTC (rev 1904) +++ branches/complement-sockios/explore/configure 2008-06-26 05:41:25 UTC (rev 1905) @@ -1,6 +1,6 @@ #!/bin/sh -# Time-stamp: <08/06/06 17:44:52 yeti> +# Time-stamp: <08/06/07 15:22:06 yeti> base=`cd \`dirname $0\`; echo $PWD` @@ -86,27 +86,26 @@ # write_option "${PWD}/external/boost" BOOST_DIR # fi - if [ "$stlport_set" = "" ]; then - # write_option "${PWD}/external/STLport" STLPORT_DIR - write_option "1" WITHOUT_STLPORT - fi + # Set in Makefiles/gmake/extern.mak + # if [ -z "${stlport_set}" ]; then + # # write_option "${PWD}/external/STLport" STLPORT_DIR + # write_option "1" WITHOUT_STLPORT + # fi + # write_option "${PWD}/build/" BASE_INSTALL_DIR '${DESTDIR}' - if [ "$compiler_family_set" = "" ]; then - write_option gcc COMPILER_NAME - fi - # if [ "$prefix_set" = "" ]; then + + # Set in Makefiles/gmake/top.mak + # if [ -z "${compiler_family_set}" ]; then + # write_option gcc COMPILER_NAME + # fi + + # Set in Makefiles/gmake/targetdirs.mak + # if [ -z "${prefix_set}" ]; then # write_option "/usr/local" BASE_INSTALL_DIR '${DESTDIR}' # fi } -case $# in - 0) - if [ ! -f ${configmak} ]; then - default_settings - fi - exit 0 - ;; -esac +[ $# -eq 0 ] && { >${configmak}; default_settings; exit 0; } for a in $@ ; do case $a in @@ -121,8 +120,7 @@ esac done -rm -f ${configmak} -touch ${configmak} +>${configmak} while : do @@ -207,7 +205,7 @@ ;; --prefix=*) write_option "$option" BASE_INSTALL_DIR '${DESTDIR}' - # prefix_set=y + prefix_set=y ;; --bindir=*) write_option "$option" INSTALL_BIN_DIR '${DESTDIR}' @@ -221,46 +219,46 @@ esac done -if [ "$CXX" != "" ]; then - if [ "$cxx_set" != "" ]; then +if [ -n "${CXX}" ]; then + if [ -n "${cxx_set}" ]; then echo "Both --with-cxx and \$CXX set, using the first" - elif [ "$target_set" = "" ]; then - write_option "$CXX" _FORCE_CXX + elif [ -z "${target_set}" ]; then + write_option "${CXX}" _FORCE_CXX else echo "For cross-compilation with gcc use --target option only" fi - if [ "$CC" = "" ] && [ "$cc_set" = "" ]; then + if [ -z "${CC}" -a -z "${cc_set}" ]; then echo "\$CXX set, but I don't see \$CC!" fi fi -if [ "$CC" != "" ]; then - if [ "$cxx_set" != "" ]; then +if [ -n "${CC}" ]; then + if [ -n "${cxx_set}" ]; then echo "Both --with-cc and \$CC set, using the first" else - write_option "$CC" _FORCE_CC + write_option "${CC}" _FORCE_CC fi fi -if [ "$CXXFLAGS" != "" ]; then - if [ "$cxxflags_set" = "" ]; then - write_option "$CXXFLAGS" EXTRA_CXXFLAGS +if [ -n "${CXXFLAGS}" ]; then + if [ -z "${cxxflags_set}" ]; then + write_option "${CXXFLAGS}" EXTRA_CXXFLAGS else echo "Both --with-extra-cxxflags and \$CXXFLAGS set, using the first" fi fi -if [ "$CFLAGS" != "" ]; then - if [ "$cflags_set" = "" ]; then - write_option "$CFLAGS" EXTRA_CFLAGS +if [ -n "${CFLAGS}" ]; then + if [ -z "${cflags_set}" ]; then + write_option "${CFLAGS}" EXTRA_CFLAGS else echo "Both --with-extra-cflags and \$CFLAGS set, using the first" fi fi -if [ "$LDFLAGS" != "" ]; then - if [ "$ldflags_set" = "" ]; then - write_option "$LDFLAGS" EXTRA_LDFLAGS +if [ -n "${LDFLAGS}" ]; then + if [ -z "${ldflags_set}" ]; then + write_option "${LDFLAGS}" EXTRA_LDFLAGS else echo "Both --with-extra-ldflags and \$LDFLAGS set, using the first" fi This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:42:46
|
Revision: 1906 http://complement.svn.sourceforge.net/complement/?rev=1906&view=rev Author: complement Date: 2008-06-25 22:42:44 -0700 (Wed, 25 Jun 2008) Log Message: ----------- Remove LDSEARCH macro; add option for STLport includes in configure Modified Paths: -------------- branches/complement-sockios/explore/Makefiles/gmake/app/gcc.mak branches/complement-sockios/explore/Makefiles/gmake/app/top.mak branches/complement-sockios/explore/Makefiles/gmake/extern.mak branches/complement-sockios/explore/Makefiles/gmake/icc.mak branches/complement-sockios/explore/Makefiles/gmake/lib/CC.mak branches/complement-sockios/explore/Makefiles/gmake/lib/aCC.mak branches/complement-sockios/explore/Makefiles/gmake/lib/gcc.mak branches/complement-sockios/explore/Makefiles/gmake/lib/icc.mak branches/complement-sockios/explore/Makefiles/gmake/lib/vc6.mak branches/complement-sockios/explore/configure branches/complement-sockios/explore/lib/DB/PgSQL/Makefile branches/complement-sockios/explore/lib/exam/ut/Makefile branches/complement-sockios/explore/lib/janus/Makefile branches/complement-sockios/explore/lib/janus/ut/Makefile branches/complement-sockios/explore/lib/misc/ut/Makefile branches/complement-sockios/explore/lib/mt/ut/Makefile branches/complement-sockios/explore/lib/net/samples/httpclient/Makefile branches/complement-sockios/explore/lib/net/ut/Makefile branches/complement-sockios/explore/lib/sockios/perf/Makefile branches/complement-sockios/explore/lib/sockios/ut/Makefile branches/complement-sockios/explore/lib/stem/ut/Makefile branches/complement-sockios/explore/lib/stem/ut/dl/Makefile Removed Paths: ------------- branches/complement-sockios/explore/lib/mt/Makefile.mwccnlm branches/complement-sockios/explore/lib/mt/gcc-libstd.mak branches/complement-sockios/explore/lib/mt/mwccnlm.mak branches/complement-sockios/explore/lib/mt/ut/gcc-libstd.mak Modified: branches/complement-sockios/explore/Makefiles/gmake/app/gcc.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/app/gcc.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/app/gcc.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/05/30 23:54:39 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 13:54:55 ptr> # # Copyright (c) 1997-1999, 2002, 2003, 2005-2007 # Petr Ovtchenkov @@ -62,14 +62,21 @@ endif ifndef WITHOUT_STLPORT -LDSEARCH += -L${STLPORT_LIB_DIR} - +ifeq (${STLPORT_LIB_DIR},) release-shared: STLPORT_LIB = -lstlport release-static: STLPORT_LIB = -Wl,-Bstatic -lstlport -Wl,-Bdynamic dbg-shared: STLPORT_LIB = -lstlportg dbg-static: STLPORT_LIB = -Wl,-Bstatic -lstlportg -Wl,-Bdynamic stldbg-shared: STLPORT_LIB = -lstlportstlg stldbg-static: STLPORT_LIB = -Wl,-Bstatic -lstlportstlg -Wl,-Bdynamic +else +release-shared: STLPORT_LIB = -L${STLPORT_LIB_DIR} -lstlport +release-static: STLPORT_LIB = -L${STLPORT_LIB_DIR} -Wl,-Bstatic -lstlport -Wl,-Bdynamic +dbg-shared: STLPORT_LIB = -L${STLPORT_LIB_DIR} -lstlportg +dbg-static: STLPORT_LIB = -L${STLPORT_LIB_DIR} -Wl,-Bstatic -lstlportg -Wl,-Bdynamic +stldbg-shared: STLPORT_LIB = -L${STLPORT_LIB_DIR} -lstlportstlg +stldbg-static: STLPORT_LIB = -L${STLPORT_LIB_DIR} -Wl,-Bstatic -lstlportstlg -Wl,-Bdynamic +endif ifeq ($(OSNAME),windows) LIB_VERSION = ${LIBMAJOR}.${LIBMINOR} Modified: branches/complement-sockios/explore/Makefiles/gmake/app/top.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/app/top.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/app/top.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <07/06/08 23:35:09 ptr> +# -*- makefile -*- Time-stamp: <08/06/12 13:55:47 ptr> # -# Copyright (c) 1997-1999, 2002, 2003, 2005-2007 +# Copyright (c) 1997-1999, 2002, 2003, 2005-2008 # Petr Ovtchenkov # # Portion Copyright (c) 1999-2001 @@ -31,8 +31,6 @@ $(foreach prg,$(PRGNAMES),$(eval $(call prog_prog,$(prg)))) -LDFLAGS += ${LDSEARCH} - include ${RULESBASE}/gmake/app/${COMPILER_NAME}.mak include ${RULESBASE}/gmake/app/rules.mak include ${RULESBASE}/gmake/app/rules-install.mak Modified: branches/complement-sockios/explore/Makefiles/gmake/extern.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/extern.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/extern.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -31,10 +31,12 @@ # STLport library ifndef STLPORT_DIR +ifndef STLPORT_INCLUDE_DIR ifndef WITHOUT_STLPORT WITHOUT_STLPORT = 1 endif endif +endif ifdef STLPORT_DIR STLPORT_LIB_DIR ?= $(STLPORT_DIR)/${TARGET_NAME}lib Modified: branches/complement-sockios/explore/Makefiles/gmake/icc.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/icc.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/icc.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,6 +1,6 @@ -# Time-stamp: <07/03/08 21:41:21 ptr> +# Time-stamp: <08/06/12 14:57:58 ptr> # -# Copyright (c) 1997-1999, 2002, 2003, 2005-2007 +# Copyright (c) 1997-1999, 2002, 2003, 2005-2008 # Petr Ovtchenkov # # Portion Copyright (c) 1999-2001 Modified: branches/complement-sockios/explore/Makefiles/gmake/lib/CC.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/lib/CC.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/lib/CC.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <07/03/08 21:39:22 ptr> +# -*- makefile -*- Time-stamp: <08/06/12 14:58:49 ptr> # -# Copyright (c) 1997-1999, 2002, 2003, 2005-2007 +# Copyright (c) 1997-1999, 2002, 2003, 2005-2008 # Petr Ovtchenkov # # Portion Copyright (c) 1999-2001 @@ -11,12 +11,9 @@ OPT += -xcode=pic32 -dbg-shared: LDFLAGS += -G -Qoption ld -z,initfirst -h$(SO_NAME_DBGxx) ${LDSEARCH} ${NOSTDLIB} -stldbg-shared: LDFLAGS += -G -Qoption ld -z,initfirst -h$(SO_NAME_STLDBGxx) ${LDSEARCH} ${NOSTDLIB} -release-shared: LDFLAGS += -G -Qoption ld -z,initfirst -h$(SO_NAMExx) ${LDSEARCH} ${NOSTDLIB} -dbg-static: LDFLAGS += ${LDSEARCH} -stldbg-static: LDFLAGS += ${LDSEARCH} -release-static: LDFLAGS += ${LDSEARCH} +dbg-shared: LDFLAGS += -G -Qoption ld -z,initfirst -h$(SO_NAME_DBGxx) ${NOSTDLIB} +stldbg-shared: LDFLAGS += -G -Qoption ld -z,initfirst -h$(SO_NAME_STLDBGxx) ${NOSTDLIB} +release-shared: LDFLAGS += -G -Qoption ld -z,initfirst -h$(SO_NAMExx) ${NOSTDLIB} DEPENDS_COLLECTION_SUNPRO := $(DEPENDS_COLLECTION).sunpro Modified: branches/complement-sockios/explore/Makefiles/gmake/lib/aCC.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/lib/aCC.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/lib/aCC.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <07/05/31 00:50:40 ptr> +# -*- makefile -*- Time-stamp: <08/06/12 14:59:23 ptr> # -# Copyright (c) 1997-1999, 2002, 2003, 2005-2007 +# Copyright (c) 1997-1999, 2002, 2003, 2005-2008 # Petr Ovtchenkov # # Portion Copyright (c) 1999-2001 @@ -9,6 +9,6 @@ # Licensed under the Academic Free License version 3.0 # -dbg-shared: LDFLAGS += -b +nostl -Wl,+h$(SO_NAME_DBGxx) ${LDSEARCH} -stldbg-shared: LDFLAGS += -b +nostl -Wl,+h$(SO_NAME_STLDBGxx) ${LDSEARCH} -release-shared: LDFLAGS += -b +nostl -Wl,+h$(SO_NAMExx) ${LDSEARCH} +dbg-shared: LDFLAGS += -b +nostl -Wl,+h$(SO_NAME_DBGxx) +stldbg-shared: LDFLAGS += -b +nostl -Wl,+h$(SO_NAME_STLDBGxx) +release-shared: LDFLAGS += -b +nostl -Wl,+h$(SO_NAMExx) Modified: branches/complement-sockios/explore/Makefiles/gmake/lib/gcc.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/lib/gcc.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/lib/gcc.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <07/05/31 00:55:13 ptr> +# -*- makefile -*- Time-stamp: <08/06/12 14:08:48 ptr> # -# Copyright (c) 1997-1999, 2002, 2003, 2005-2007 +# Copyright (c) 1997-1999, 2002, 2003, 2005-2008 # Petr Ovtchenkov # # Portion Copyright (c) 1999-2001 @@ -71,11 +71,16 @@ endif ifndef WITHOUT_STLPORT -LDSEARCH += -L${STLPORT_LIB_DIR} +ifeq (${STLPORT_LIB_DIR},) release-shared: STLPORT_LIB = -lstlport dbg-shared: STLPORT_LIB = -lstlportg stldbg-shared: STLPORT_LIB = -lstlportstlg +else +release-shared: STLPORT_LIB = -L${STLPORT_LIB_DIR} -lstlport +dbg-shared: STLPORT_LIB = -L${STLPORT_LIB_DIR} -lstlportg +stldbg-shared: STLPORT_LIB = -L${STLPORT_LIB_DIR} -lstlportstlg +endif ifeq ($(OSNAME),windows) LIB_VERSION = ${LIBMAJOR}.${LIBMINOR} @@ -196,64 +201,52 @@ endif ifeq ($(OSNAME),hp-ux) -dbg-shared: LDFLAGS += -shared -Wl,-dynamic -Wl,+h$(SO_NAME_DBGxx) ${LDSEARCH} -stldbg-shared: LDFLAGS += -shared -Wl,-dynamic -Wl,+h$(SO_NAME_STLDBGxx) ${LDSEARCH} -release-shared: LDFLAGS += -shared -Wl,-dynamic -Wl,+h$(SO_NAMExx) ${LDSEARCH} +dbg-shared: LDFLAGS += -shared -Wl,-dynamic -Wl,+h$(SO_NAME_DBGxx) +stldbg-shared: LDFLAGS += -shared -Wl,-dynamic -Wl,+h$(SO_NAME_STLDBGxx) +release-shared: LDFLAGS += -shared -Wl,-dynamic -Wl,+h$(SO_NAMExx) endif ifeq ($(OSNAME),sunos) -dbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_DBGxx) ${NOSTDLIB} ${LDSEARCH} -stldbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_STLDBGxx) ${NOSTDLIB} ${LDSEARCH} -release-shared: LDFLAGS += -shared -Wl,-h$(SO_NAMExx) ${NOSTDLIB} ${LDSEARCH} -dbg-static: LDFLAGS += ${LDSEARCH} -stldbg-static: LDFLAGS += ${LDSEARCH} -release-static: LDFLAGS += ${LDSEARCH} +dbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_DBGxx) ${NOSTDLIB} +stldbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_STLDBGxx) ${NOSTDLIB} +release-shared: LDFLAGS += -shared -Wl,-h$(SO_NAMExx) ${NOSTDLIB} endif ifeq ($(OSNAME),linux) -dbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_DBGxx) ${NOSTDLIB} ${LDSEARCH} -stldbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_STLDBGxx) ${NOSTDLIB} ${LDSEARCH} -release-shared: LDFLAGS += -shared -Wl,-h$(SO_NAMExx) ${NOSTDLIB} ${LDSEARCH} -dbg-static: LDFLAGS += ${LDSEARCH} -stldbg-static: LDFLAGS += ${LDSEARCH} -release-static: LDFLAGS += ${LDSEARCH} +dbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_DBGxx) ${NOSTDLIB} +stldbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_STLDBGxx) ${NOSTDLIB} +release-shared: LDFLAGS += -shared -Wl,-h$(SO_NAMExx) ${NOSTDLIB} endif ifeq ($(OSNAME),windows) dbg-shared: LDFLAGS += -shared -Wl,--out-implib=${LIB_NAME_OUT_DBG},--enable-auto-image-base stldbg-shared: LDFLAGS += -shared -Wl,--out-implib=${LIB_NAME_OUT_STLDBG},--enable-auto-image-base release-shared: LDFLAGS += -shared -Wl,--out-implib=${LIB_NAME_OUT},--enable-auto-image-base -dbg-static: LDFLAGS += -static ${LDSEARCH} -stldbg-static: LDFLAGS += -static ${LDSEARCH} -release-static: LDFLAGS += -static ${LDSEARCH} +dbg-static: LDFLAGS += -static +stldbg-static: LDFLAGS += -static +release-static: LDFLAGS += -static endif ifeq ($(OSNAME),freebsd) -dbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_DBGxx) ${NOSTDLIB} ${LDSEARCH} -stldbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_STLDBGxx) ${NOSTDLIB} ${LDSEARCH} -release-shared: LDFLAGS += -shared -Wl,-h$(SO_NAMExx) ${NOSTDLIB} ${LDSEARCH} -dbg-static: LDFLAGS += ${LDSEARCH} -stldbg-static: LDFLAGS += ${LDSEARCH} -release-static: LDFLAGS += ${LDSEARCH} +dbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_DBGxx) ${NOSTDLIB} +stldbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_STLDBGxx) ${NOSTDLIB} +release-shared: LDFLAGS += -shared -Wl,-h$(SO_NAMExx) ${NOSTDLIB} endif ifeq ($(OSNAME),darwin) CURRENT_VERSION := ${MAJOR}.${MINOR}.${PATCH} COMPATIBILITY_VERSION := $(CURRENT_VERSION) -dbg-shared: LDFLAGS += -dynamic -dynamiclib -compatibility_version $(COMPATIBILITY_VERSION) -current_version $(CURRENT_VERSION) -install_name $(SO_NAME_DBGxx) ${LDSEARCH} ${NOSTDLIB} -stldbg-shared: LDFLAGS += -dynamic -dynamiclib -compatibility_version $(COMPATIBILITY_VERSION) -current_version $(CURRENT_VERSION) -install_name $(SO_NAME_STLDBGxx) ${LDSEARCH} ${NOSTDLIB} -release-shared: LDFLAGS += -dynamic -dynamiclib -compatibility_version $(COMPATIBILITY_VERSION) -current_version $(CURRENT_VERSION) -install_name $(SO_NAMExx) ${LDSEARCH} ${NOSTDLIB} -dbg-static: LDFLAGS += -staticlib ${LDSEARCH} -stldbg-static: LDFLAGS += -staticlib ${LDSEARCH} -release-static: LDFLAGS += -staticlib ${LDSEARCH} +dbg-shared: LDFLAGS += -dynamic -dynamiclib -compatibility_version $(COMPATIBILITY_VERSION) -current_version $(CURRENT_VERSION) -install_name $(SO_NAME_DBGxx) ${NOSTDLIB} +stldbg-shared: LDFLAGS += -dynamic -dynamiclib -compatibility_version $(COMPATIBILITY_VERSION) -current_version $(CURRENT_VERSION) -install_name $(SO_NAME_STLDBGxx) ${NOSTDLIB} +release-shared: LDFLAGS += -dynamic -dynamiclib -compatibility_version $(COMPATIBILITY_VERSION) -current_version $(CURRENT_VERSION) -install_name $(SO_NAMExx) ${NOSTDLIB} +dbg-static: LDFLAGS += -staticlib +stldbg-static: LDFLAGS += -staticlib +release-static: LDFLAGS += -staticlib endif ifeq ($(OSNAME),openbsd) -dbg-shared: LDFLAGS += -shared -Wl,-soname -Wl,$(SO_NAME_DBGxx) ${NOSTDLIB} ${LDSEARCH} -stldbg-shared: LDFLAGS += -shared -Wl,-soname -Wl,$(SO_NAME_STLDBGxx) ${NOSTDLIB} ${LDSEARCH} -release-shared: LDFLAGS += -shared -Wl,-soname -Wl,$(SO_NAMExx) ${NOSTDLIB} ${LDSEARCH} -dbg-static: LDFLAGS += ${LDSEARCH} -stldbg-static: LDFLAGS += ${LDSEARCH} -release-static: LDFLAGS += ${LDSEARCH} +dbg-shared: LDFLAGS += -shared -Wl,-soname -Wl,$(SO_NAME_DBGxx) ${NOSTDLIB} +stldbg-shared: LDFLAGS += -shared -Wl,-soname -Wl,$(SO_NAME_STLDBGxx) ${NOSTDLIB} +release-shared: LDFLAGS += -shared -Wl,-soname -Wl,$(SO_NAMExx) ${NOSTDLIB} endif Modified: branches/complement-sockios/explore/Makefiles/gmake/lib/icc.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/lib/icc.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/lib/icc.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <07/03/08 21:37:08 ptr> +# -*- makefile -*- Time-stamp: <08/06/12 15:00:07 ptr> # -# Copyright (c) 1997-1999, 2002, 2003, 2005-2007 +# Copyright (c) 1997-1999, 2002, 2003, 2005-2008 # Petr Ovtchenkov # # Portion Copyright (c) 1999-2001 @@ -9,19 +9,11 @@ # Licensed under the Academic Free License version 3.0 # -# Oh, the commented below work for gmake 3.78.1 and above, -# but phrase without tag not work for it. Since gmake 3.79 -# tag with assignment fail, but work assignment for all tags -# (really that more correct). - OPT += -KPIC ifeq ($(OSNAME),linux) -dbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_DBGxx) ${LDSEARCH} -stldbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_STLDBGxx) ${LDSEARCH} -release-shared: LDFLAGS += -shared -Wl,-h$(SO_NAMExx) ${LDSEARCH} -dbg-static: LDFLAGS += ${LDSEARCH} -stldbg-static: LDFLAGS += ${LDSEARCH} -release-static: LDFLAGS += ${LDSEARCH} +dbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_DBGxx) +stldbg-shared: LDFLAGS += -shared -Wl,-h$(SO_NAME_STLDBGxx) +release-shared: LDFLAGS += -shared -Wl,-h$(SO_NAMExx) endif Modified: branches/complement-sockios/explore/Makefiles/gmake/lib/vc6.mak =================================================================== --- branches/complement-sockios/explore/Makefiles/gmake/lib/vc6.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/Makefiles/gmake/lib/vc6.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <07/03/08 21:35:57 ptr> +# -*- makefile -*- Time-stamp: <08/06/12 15:03:15 ptr> # -# Copyright (c) 1997-1999, 2002, 2003, 2005-2007 +# Copyright (c) 1997-1999, 2002, 2003, 2005-2008 # Petr Ovtchenkov # # Portion Copyright (c) 1999-2001 @@ -9,13 +9,7 @@ # Licensed under the Academic Free License version 3.0 # -# Oh, the commented below work for gmake 3.78.1 and above, -# but phrase without tag not work for it. Since gmake 3.79 -# tag with assignment fail, but work assignment for all tags -# (really that more correct). - LDLIBS ?= -LDSEARCH += /LIBPATH:"$(MSVC_LIB_DIR)" dbg-shared: OPT += /MDd stldbg-shared: OPT += /MDd @@ -30,11 +24,8 @@ stldbg-static: DEFS += /D_LIB -dbg-shared: LDFLAGS += /DLL ${LDSEARCH} -stldbg-shared: LDFLAGS += /DLL ${LDSEARCH} -release-shared: LDFLAGS += /DLL ${LDSEARCH} -dbg-static: LDFLAGS += ${LDSEARCH} -stldbg-static: LDFLAGS += ${LDSEARCH} -release-static: LDFLAGS += ${LDSEARCH} +dbg-shared: LDFLAGS += /DLL +stldbg-shared: LDFLAGS += /DLL +release-shared: LDFLAGS += /DLL -LDFLAGS += /VERSION:$(MAJOR).$(MINOR) +LDFLAGS += /LIBPATH:"$(MSVC_LIB_DIR)" /VERSION:$(MAJOR).$(MINOR) Modified: branches/complement-sockios/explore/configure =================================================================== --- branches/complement-sockios/explore/configure 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/configure 2008-06-26 05:42:44 UTC (rev 1906) @@ -40,6 +40,7 @@ --help print this help message and exit --with-stlport=<dir> use STLport in catalog <dir> + --with-stlport-headers=<dir> use STLport headers in catalog <dir> --without-stlport compile without STLport (default) --with-boost=<dir> use boost headers in catalog <dir> --with-system-boost use boost installed on this system @@ -82,6 +83,7 @@ } default_settings () { + : # if [ "$boost_set" = "" ]; then # write_option "${PWD}/external/boost" BOOST_DIR # fi @@ -140,6 +142,10 @@ write_option "$option" STLPORT_DIR stlport_set=y ;; + --with-stlport-headers=*) + write_option "$option" STLPORT_INCLUDE_DIR + stlport_set=y + ;; --without-stlport) write_option "1" WITHOUT_STLPORT stlport_set=y Modified: branches/complement-sockios/explore/lib/DB/PgSQL/Makefile =================================================================== --- branches/complement-sockios/explore/lib/DB/PgSQL/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/DB/PgSQL/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,14 +1,21 @@ -# -*- Makefile -*- Time-stamp: <03/09/25 12:02:31 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:09:05 ptr> SRCROOT := ../../.. -PG_INCLUDE := /opt/pgsql/include -PG_LIB := /opt/pgsql/lib +# PG_INCLUDE := /opt/pgsql/include +# PG_LIB_DIR := /opt/pgsql/lib include Makefile.inc include ${SRCROOT}/Makefiles/gmake/top.mak -INCLUDES += -I$(SRCROOT)/include -I${PG_INCLUDE} +INCLUDES += -I$(SRCROOT)/include -LDSEARCH += -L${PG_LIB} +ifneq (${PG_INCLUDE},) +INCLUDES += -I${PG_INCLUDE} +endif + +ifneq (${PG_LIB_DIR},) +LDFLAGS += -L${PG_LIB_DIR} +endif + LDLIBS = -lpq Modified: branches/complement-sockios/explore/lib/exam/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/exam/ut/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/exam/ut/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/09/03 22:27:45 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 14:00:05 ptr> SRCROOT := ../../.. @@ -15,12 +15,12 @@ ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L$(LIBXMT_DIR)/${OUTPUT_DIR} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR}:$(LIBXMT_DIR)/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L$(LIBXMT_DIR)/${OUTPUT_DIR} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR}:$(LIBXMT_DIR)/${OUTPUT_DIR}:${STLPORT_LIB_DIR} -dbg-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L$(LIBXMT_DIR)/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:$(LIBXMT_DIR)/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L$(LIBXMT_DIR)/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:$(LIBXMT_DIR)/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L$(LIBXMT_DIR)/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:$(LIBXMT_DIR)/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L$(LIBXMT_DIR)/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:$(LIBXMT_DIR)/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif endif Modified: branches/complement-sockios/explore/lib/janus/Makefile =================================================================== --- branches/complement-sockios/explore/lib/janus/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/janus/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/02/07 12:28:46 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:26:16 ptr> SRCROOT := ../.. COMPILER_NAME := gcc @@ -12,7 +12,7 @@ LIBSOCK_DIR = ${CoMT_DIR}/lib/sockios LIBSTEM_DIR = ${CoMT_DIR}/lib/stem -LDSEARCH += -L${CoMT_LIB_DIR} -Wl,--rpath=${CoMT_LIB_DIR} +LDFLAGS += -L${CoMT_LIB_DIR} -Wl,--rpath=${CoMT_LIB_DIR} release-shared : LDLIBS = -lxmt -lsockios -lstem ifndef WITHOUT_STLPORT Modified: branches/complement-sockios/explore/lib/janus/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/janus/ut/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/janus/ut/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/08/08 22:18:48 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:26:38 ptr> SRCROOT := ../../.. COMPILER_NAME := gcc @@ -20,12 +20,12 @@ ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L$(LIBXMT_DIR)/${OUTPUT_DIR} -L$(LIBSOCKIOS_DIR)/${OUTPUT_DIR} -L$(LIBSTEM_DIR)/${OUTPUT_DIR} -L$(LIBJANUS_DIR)/${OUTPUT_DIR} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR}:$(LIBXMT_DIR)/${OUTPUT_DIR}:${LIBSOCKIOS_DIR}/${OUTPUT_DIR}:${LIBSTEM_DIR}/${OUTPUT_DIR}:${LIBJANUS_DIR}${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L$(LIBXMT_DIR)/${OUTPUT_DIR} -L$(LIBSOCKIOS_DIR)/${OUTPUT_DIR} -L$(LIBSTEM_DIR)/${OUTPUT_DIR} -L$(LIBJANUS_DIR)/${OUTPUT_DIR} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR}:$(LIBXMT_DIR)/${OUTPUT_DIR}:${LIBSOCKIOS_DIR}/${OUTPUT_DIR}:${LIBSTEM_DIR}/${OUTPUT_DIR}:${LIBJANUS_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} -dbg-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L$(LIBXMT_DIR)/${OUTPUT_DIR_DBG} -L$(LIBSOCKIOS_DIR)/${OUTPUT_DIR_DBG} -L$(LIBSTEM_DIR)/${OUTPUT_DIR_DBG} -L$(LIBJANUS_DIR)/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:$(LIBXMT_DIR)/${OUTPUT_DIR_DBG}:${LIBSOCKIOS_DIR}/${OUTPUT_DIR_DBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_DBG}:${LIBJANUS_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L$(LIBXMT_DIR)/${OUTPUT_DIR_DBG} -L$(LIBSOCKIOS_DIR)/${OUTPUT_DIR_DBG} -L$(LIBSTEM_DIR)/${OUTPUT_DIR_DBG} -L$(LIBJANUS_DIR)/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:$(LIBXMT_DIR)/${OUTPUT_DIR_DBG}:${LIBSOCKIOS_DIR}/${OUTPUT_DIR_DBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_DBG}:${LIBJANUS_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L$(LIBXMT_DIR)/${OUTPUT_DIR_STLDBG} -L$(LIBSOCKIOS_DIR)/${OUTPUT_DIR_STLDBG} -L$(LIBSTEM_DIR)/${OUTPUT_DIR_STLDBG} -L$(LIBJANUS_DIR)/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:$(LIBXMT_DIR)/${OUTPUT_DIR_STLDBG}:${LIBSOCKIOS_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBJANUS_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L$(LIBXMT_DIR)/${OUTPUT_DIR_STLDBG} -L$(LIBSOCKIOS_DIR)/${OUTPUT_DIR_STLDBG} -L$(LIBSTEM_DIR)/${OUTPUT_DIR_STLDBG} -L$(LIBJANUS_DIR)/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:$(LIBXMT_DIR)/${OUTPUT_DIR_STLDBG}:${LIBSOCKIOS_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBJANUS_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif endif Modified: branches/complement-sockios/explore/lib/misc/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/misc/ut/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/misc/ut/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/11/23 23:30:57 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:20:10 ptr> SRCROOT := ../../.. @@ -14,24 +14,22 @@ ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBXMT_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBXMT_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBXMT_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBXMT_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} -dbg-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBXMT_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBXMT_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBXMT_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBXMT_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBXMT_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBXMT_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBXMT_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBXMT_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif endif ifeq ($(OSNAME),openbsd) -release-shared: LDSEARCH += -Wl,-R:${STLPORT_LIB_DIR} - -dbg-shared: LDSEARCH += -Wl,-R:${STLPORT_LIB_DIR} - ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -Wl,-R:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -Wl,-R:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -Wl,-R:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -Wl,-R:${STLPORT_LIB_DIR} endif endif Deleted: branches/complement-sockios/explore/lib/mt/Makefile.mwccnlm =================================================================== --- branches/complement-sockios/explore/lib/mt/Makefile.mwccnlm 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/mt/Makefile.mwccnlm 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,32 +0,0 @@ -# -*- Makefile -*- Time-stamp: <03/06/13 16:51:25 ptr> -# $Id$ - -BASEDIR := $(shell xtmp=`pwd`; xtmp=`dirname $$xtmp`; dirname $$xtmp) -LIBDIR := $(shell xtmp=`pwd`; dirname $$xtmp) - -COMPILER_NAME = mwccnlm -include $(BASEDIR)/lib/mt/Makefile.inc - -all: all-release all-debug - -install: install-dbg-shared install-stldbg-shared install-release-shared - -all-shared: release-shared dbg-shared stldbg-shared - -all-debug: dbg-shared stldbg-shared - -all-release: release-shared - -include ${BASEDIR}/Makefiles/lib/Makefile.inc - -INCLUDES += -I$(STLPORT_INCLUDE_DIR) -I../../include - -release-shared: LDSEARCH = -L${STLPORT_LIB_DIR} -stldbg-shared: LDSEARCH = -L${STLPORT_LIB_DIR} -dbg-shared: LDSEARCH = -L${STLPORT_LIB_DIR} - -release-shared : LDLIBS = -lstlport_gcc -stldbg-shared : LDLIBS = -lstlport_gcc_stldebug -dbg-shared : LDLIBS = -lstlport_gcc - - Deleted: branches/complement-sockios/explore/lib/mt/gcc-libstd.mak =================================================================== --- branches/complement-sockios/explore/lib/mt/gcc-libstd.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/mt/gcc-libstd.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,13 +0,0 @@ -# -*- Makefile -*- Time-stamp: <03/09/25 12:02:31 ptr> -# $Id$ - -SRCROOT := ../.. -COMPILER_NAME := gcc - -ALL_TAGS = release-shared dbg-shared - -include Makefile.inc -include ${SRCROOT}/Makefiles/top.mak - -INCLUDES += -I$(SRCROOT)/include - Deleted: branches/complement-sockios/explore/lib/mt/mwccnlm.mak =================================================================== --- branches/complement-sockios/explore/lib/mt/mwccnlm.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/mt/mwccnlm.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,11 +0,0 @@ -# -*- Makefile -*- Time-stamp: <05/06/03 21:45:55 ptr> -# $Id$ - -SRCROOT := ../.. -COMPILER_NAME := mwccnlm - -STLPORT_DIR := ../../../Novell-STLP/STLport -include Makefile.inc -include ${SRCROOT}/Makefiles/top.mak - -INCLUDES += -I$(SRCROOT)/include -I$(STLPORT_INCLUDE_DIR) Modified: branches/complement-sockios/explore/lib/mt/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/mt/ut/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/08/03 22:38:12 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:11:40 ptr> SRCROOT := ../../.. @@ -27,24 +27,24 @@ ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBFS_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBFS_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBFS_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBFS_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} -dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBFS_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBFS_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBFS_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBFS_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBFS_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBFS_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBFS_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBFS_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif endif ifeq ($(OSNAME),openbsd) -release-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR} -Wl,-R${LIBMT_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR} -Wl,-R${LIBMT_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} -dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -Wl,-R${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -Wl,-R${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -Wl,-R${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -Wl,-R${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif endif Deleted: branches/complement-sockios/explore/lib/mt/ut/gcc-libstd.mak =================================================================== --- branches/complement-sockios/explore/lib/mt/ut/gcc-libstd.mak 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/mt/ut/gcc-libstd.mak 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,48 +0,0 @@ -# -*- Makefile -*- Time-stamp: <03/11/21 08:02:55 ptr> -# $Id$ - -SRCROOT := ../../.. -COMPILER_NAME := gcc -ALL_TAGS = release-shared dbg-shared - -include Makefile.inc -include ${SRCROOT}/Makefiles/top.mak - - -INCLUDES += -I$(SRCROOT)/include -I$(BOOST_INCLUDE_DIR) - -# temporary, before dums fix strings: -# DEFS += -D_STLP_DONT_USE_TEMPLATE_EXPRESSION - -ifeq ($(OSNAME),linux) -release-shared: LDSEARCH = -L${CoMT_LIB_DIR} -Wl,--rpath=${CoMT_LIB_DIR} -stldbg-shared: LDSEARCH = -L${CoMT_LIB_DIR_STLDBG} -Wl,--rpath=${CoMT_LIB_DIR_STLDBG} -dbg-shared: LDSEARCH = -L${CoMT_LIB_DIR_DBG} -Wl,--rpath=${CoMT_LIB_DIR_DBG} -endif - -ifeq ($(OSNAME),openbsd) -release-shared: LDSEARCH = -L${CoMT_LIB_DIR} -Wl,-R${CoMT_LIB_DIR} -stldbg-shared: LDSEARCH = -L${CoMT_LIB_DIR_STLDBG} -Wl,-R${CoMT_LIB_DIR_STLDBG} -dbg-shared: LDSEARCH = -L${CoMT_LIB_DIR_DBG} -Wl,-R${CoMT_LIB_DIR_DBG} -endif - -release-shared : LDLIBS = -lxmt_gcc -lboost_test_utf_gcc -stldbg-shared : LDLIBS = -lxmt_gcc_stl-g -lboost_test_utf_gcc_stl-g -dbg-shared : LDLIBS = -lxmt_gcc-g -lboost_test_utf_gcc-g - -ifeq ($(OSNAME),freebsd) -release-shared : LDLIBS += -lthr -stldbg-shared : LDLIBS += -lthr -dbg-shared : LDLIBS += -lthr -endif - -ifeq ($(OSNAME),sunos) -release-shared : LDLIBS += -lrt -stldbg-shared : LDLIBS += -lrt -dbg-shared : LDLIBS += -lrt -endif - -ifeq ($(OSNAME),openbsd) -release-shared: LDLIBS = -lxmt_gcc -lboost_test_utf_gcc -endif - Modified: branches/complement-sockios/explore/lib/net/samples/httpclient/Makefile =================================================================== --- branches/complement-sockios/explore/lib/net/samples/httpclient/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/net/samples/httpclient/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/02/21 15:30:59 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:27:19 ptr> SRCROOT := ../../../.. # CoMT_DIR := ../../external/complement/explore @@ -18,15 +18,15 @@ ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -L${LIBSTEM_DIR}/${OUTPUT_DIR} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR} -L${LIBNET_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${LIBSTEM_DIR}/${OUTPUT_DIR}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR}:${LIBNET_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -L${LIBSTEM_DIR}/${OUTPUT_DIR} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR} -L${LIBNET_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${LIBSTEM_DIR}/${OUTPUT_DIR}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR}:${LIBNET_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBNET_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR_STLDBG}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR_STLDBG}:${LIBNET_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBNET_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR_STLDBG}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR_STLDBG}:${LIBNET_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif -dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_DBG} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR_DBG} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR_DBG} -L${LIBNET_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_DBG}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR_DBG}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR_DBG}:${LIBNET_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_DBG} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR_DBG} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR_DBG} -L${LIBNET_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_DBG}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR_DBG}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR_DBG}:${LIBNET_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} endif Modified: branches/complement-sockios/explore/lib/net/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/net/ut/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/net/ut/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/02/21 15:30:59 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:17:05 ptr> SRCROOT := ../../.. # CoMT_DIR := ../../external/complement/explore @@ -18,15 +18,15 @@ ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -L${LIBSTEM_DIR}/${OUTPUT_DIR} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR} -L${LIBNET_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${LIBSTEM_DIR}/${OUTPUT_DIR}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR}:${LIBNET_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -L${LIBSTEM_DIR}/${OUTPUT_DIR} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR} -L${LIBNET_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${LIBSTEM_DIR}/${OUTPUT_DIR}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR}:${LIBNET_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBNET_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR_STLDBG}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR_STLDBG}:${LIBNET_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBNET_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR_STLDBG}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR_STLDBG}:${LIBNET_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif -dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_DBG} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR_DBG} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR_DBG} -L${LIBNET_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_DBG}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR_DBG}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR_DBG}:${LIBNET_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_DBG} -L${LIBBOOSTFS_DIR}/${OUTPUT_DIR_DBG} -L${LIBBOOSTRE_DIR}/${OUTPUT_DIR_DBG} -L${LIBNET_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_DBG}:${LIBBOOSTFS_DIR}/${OUTPUT_DIR_DBG}:${LIBBOOSTRE_DIR}/${OUTPUT_DIR_DBG}:${LIBNET_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} endif Modified: branches/complement-sockios/explore/lib/sockios/perf/Makefile =================================================================== --- branches/complement-sockios/explore/lib/sockios/perf/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/sockios/perf/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/09/05 22:48:46 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:23:48 ptr> SRCROOT := ../../.. @@ -18,11 +18,11 @@ # LIBUTF_DIR = ${CoMT_DIR}/../extern/custom/boost/libs/test/unit_test_framework ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif -dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} endif release-shared : LDLIBS = -lxmt -lsockios -lexam Modified: branches/complement-sockios/explore/lib/sockios/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/sockios/ut/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/08/03 23:06:43 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:24:26 ptr> SRCROOT := ../../.. @@ -18,11 +18,11 @@ # LIBUTF_DIR = ${CoMT_DIR}/../extern/custom/boost/libs/test/unit_test_framework ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif -dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} endif release-shared : LDLIBS = -lxmt -lsockios -lexam Modified: branches/complement-sockios/explore/lib/stem/ut/Makefile =================================================================== --- branches/complement-sockios/explore/lib/stem/ut/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/stem/ut/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/08/03 23:55:05 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:25:10 ptr> SRCROOT := ../../.. @@ -19,15 +19,15 @@ ifeq ($(OSNAME),linux) -release-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -L${LIBSTEM_DIR}/${OUTPUT_DIR} -Wl,--rpath=./dl/${OUTPUT_DIR}:${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${LIBSTEM_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR} -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBSOCK_DIR}/${OUTPUT_DIR} -L${LIBSTEM_DIR}/${OUTPUT_DIR} -Wl,--rpath=./dl/${OUTPUT_DIR}:${LIBMT_DIR}/${OUTPUT_DIR}:${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBSOCK_DIR}/${OUTPUT_DIR}:${LIBSTEM_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=./dl/${OUTPUT_DIR_STLDBG}:${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=./dl/${OUTPUT_DIR_STLDBG}:${LIBMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_STLDBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif -dbg-shared: LDSEARCH += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=./dl/${OUTPUT_DIR_DBG}:${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBSOCK_DIR}/${OUTPUT_DIR_DBG} -L${LIBSTEM_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=./dl/${OUTPUT_DIR_DBG}:${LIBMT_DIR}/${OUTPUT_DIR_DBG}:${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBSOCK_DIR}/${OUTPUT_DIR_DBG}:${LIBSTEM_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} endif Modified: branches/complement-sockios/explore/lib/stem/ut/dl/Makefile =================================================================== --- branches/complement-sockios/explore/lib/stem/ut/dl/Makefile 2008-06-26 05:41:25 UTC (rev 1905) +++ branches/complement-sockios/explore/lib/stem/ut/dl/Makefile 2008-06-26 05:42:44 UTC (rev 1906) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <07/08/03 23:59:51 ptr> +# -*- Makefile -*- Time-stamp: <08/06/12 15:25:51 ptr> SRCROOT := ../../../.. @@ -12,11 +12,11 @@ INCLUDES += -I$(SRCROOT)/include -#LDSEARCH = -L${STLPORT_LIB_DIR} -L${CoMT_LIB_DIR} -release-shared: LDSEARCH += -L${LIBSTEM_DIR}/${OUTPUT_DIR} -dbg-shared: LDSEARCH += -L${LIBSTEM_DIR}/${OUTPUT_DIR_DBG} +#LDFLAGS = -L${STLPORT_LIB_DIR} -L${CoMT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBSTEM_DIR}/${OUTPUT_DIR} +dbg-shared: LDFLAGS += -L${LIBSTEM_DIR}/${OUTPUT_DIR_DBG} ifndef WITHOUT_STLPORT -stldbg-shared: LDSEARCH += -L${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG} +stldbg-shared: LDFLAGS += -L${LIBSTEM_DIR}/${OUTPUT_DIR_STLDBG} endif #release-shared : LDLIBS = -lxmt -lsockios -lstem -lboost_test_utf This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:43:30
|
Revision: 1908 http://complement.svn.sourceforge.net/complement/?rev=1908&view=rev Author: complement Date: 2008-06-25 22:43:27 -0700 (Wed, 25 Jun 2008) Log Message: ----------- Review processing in sockmgr. Server's finalization still not work properly: problem in interrupted_server test on finalization (still read socket) in dbg mode. Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/socksrv.cc branches/complement-sockios/explore/include/sockios/socksrv.h branches/complement-sockios/explore/include/sockios/sockstream branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/_sp.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/socksrv.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:43:01 UTC (rev 1907) +++ branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:43:27 UTC (rev 1908) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/11 21:41:27 yeti> +// -*- C++ -*- Time-stamp: <08/06/16 10:45:56 ptr> /* * Copyright (c) 2008 @@ -192,10 +192,18 @@ _in_work = false; // <--- set before cnd.notify_one(); (below in this func) } - std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); - ready_pool.push_back( processor() ); // make ready_pool not empty - // std::cerr << "=== " << ready_pool.size() << std::endl; - cnd.notify_one(); + { + std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); + ready_pool.push_back( processor() ); // make ready_pool not empty + // std::cerr << "=== " << ready_pool.size() << std::endl; + cnd.notify_one(); + } + + basic_socket<charT,traits,_Alloc>::mgr->final( *this ); + + if ( ploop.joinable() ) { + ploop.join(); + } } template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> Modified: branches/complement-sockios/explore/include/sockios/socksrv.h =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:43:01 UTC (rev 1907) +++ branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:43:27 UTC (rev 1908) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/11 21:40:56 yeti> +// -*- C++ -*- Time-stamp: <08/06/15 23:29:23 ptr> /* * Copyright (c) 2008 @@ -68,7 +68,6 @@ { sock_processor_base::close(); - std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)this << " " << std::tr2::getpid() << std::endl; // Never uncomment next line: // basic_socket<charT,traits,_Alloc>::mgr->final( *this ); // this lead to virtual fuction call, that is already pure here. @@ -175,26 +174,7 @@ virtual ~connect_processor() { connect_processor::close(); - if ( ploop.joinable() ) { - ploop.join(); - } - // { - // std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - for ( typename worker_pool_t::iterator i = worker_pool.begin(); i != worker_pool.end(); ++i ) { - // delete i->second; - delete i->second.s; - delete i->second.c; - } - worker_pool.clear(); - // } - for ( typename ready_pool_t::iterator j = ready_pool.begin(); j != ready_pool.end(); ++j ) { - delete j->c; - } - ready_pool.clear(); - std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)this << " " << std::tr2::getpid() << std::endl; - basic_socket<charT,traits,_Alloc>::mgr->final( *this ); - ((Init *)Init_buf)->~Init(); } Modified: branches/complement-sockios/explore/include/sockios/sockstream =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream 2008-06-26 05:43:01 UTC (rev 1907) +++ branches/complement-sockios/explore/include/sockios/sockstream 2008-06-26 05:43:27 UTC (rev 1908) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/11 14:45:16 yeti> +// -*- C++ -*- Time-stamp: <08/06/15 17:11:29 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -316,7 +316,7 @@ } #endif // _sock_processor_base::_idx = std::tr2::this_thread::xalloc(); - std::cerr << __FILE__ << ":" << __LINE__ << " new mgr " << std::tr2::getpid() << std::endl; + // std::cerr << __FILE__ << ":" << __LINE__ << " new mgr " << std::tr2::getpid() << std::endl; } } else { std::tr2::lock_guard<std::tr2::mutex> lk( _init_lock ); @@ -324,7 +324,7 @@ if ( basic_socket<charT,traits,_Alloc>::mgr == 0 ) { std::cerr << __FILE__ << ":" << __LINE__ << " shit happens\n"; } - std::cerr << __FILE__ << ":" << __LINE__ << " mgr destroyed " << std::tr2::getpid() << std::endl; + // std::cerr << __FILE__ << ":" << __LINE__ << " mgr destroyed " << std::tr2::getpid() << std::endl; delete basic_socket<charT,traits,_Alloc>::mgr; basic_socket<charT,traits,_Alloc>::mgr = 0; } Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:43:01 UTC (rev 1907) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:43:27 UTC (rev 1908) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/11 21:42:37 yeti> +// -*- C++ -*- Time-stamp: <08/06/16 11:05:56 ptr> /* * Copyright (c) 2008 @@ -134,90 +134,112 @@ void sockmgr<charT,traits,_Alloc>::process_listener( epoll_event& ev, typename sockmgr<charT,traits,_Alloc>::fd_container_type::iterator ifd ) { if ( ev.events & EPOLLRDHUP ) { - epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ); - // walk through descr and detach every .p ? + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error + } + + if ( ifd->second.p != 0 ) { + ifd->second.p->close(); + } + descr.erase( ifd ); - std::cerr << "Remove listener EPOLLRDHUP\n"; - } else if ( ev.events & EPOLLIN ) { - sockaddr addr; - socklen_t sz = sizeof( sockaddr_in ); - fd_info info = ifd->second; + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); + if ( closed_ifd != closed_queue.end() && closed_ifd->second.p == ifd->second.p ) { + // listener in process of close + closed_queue.erase( closed_ifd ); + } - for ( ; ; ) { - int fd = accept( ev.data.fd, &addr, &sz ); - if ( fd < 0 ) { - std::cerr << "Accept, listener # " << ev.data.fd << ", errno " << errno << std::endl; - std::cerr << __FILE__ << ":" << __LINE__ << " " << std::tr2::getpid() << std::endl; - if ( (errno == EINTR) || (errno == ECONNABORTED) /* || (errno == ERESTARTSYS) */ ) { - continue; - } - if ( !(errno == EAGAIN || errno == EWOULDBLOCK) ) { - // std::cerr << "Accept, listener " << ev[i].data.fd << ", errno " << errno << std::endl; - // throw system_error ? - } -#if 0 - { - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); - if ( closed_ifd != closed_queue.end() ) { - typename fd_container_type::iterator ifd = descr.begin(); - for ( ; ifd != descr.end(); ) { - if ( ifd->second.p == closed_ifd->second.p ) { - descr.erase( ifd++ ); - } else { - ++ifd; - } - } - closed_queue.erase( closed_ifd ); - } - } -#endif - break; + return; + } + + if ( (ev.events & EPOLLIN) == 0 ) { + return; // I don't know what to do this case... + } + + { + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); + if ( closed_ifd != closed_queue.end() && closed_ifd->second.p == ifd->second.p ) { + // listener in process of closing, ignore all incoming connects + closed_queue.erase( closed_ifd ); + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error } - // std::cerr << "listener accept " << fd << std::endl; - if ( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { - throw std::runtime_error( "can't establish nonblock mode" ); - } - - try { - std::cerr << __FILE__ << ":" << __LINE__ << " new sockstream_t" << std::endl; - sockbuf_t* b = (*info.p)( fd, addr ); + descr.erase( ifd ); + return; + } + } - epoll_event ev_add; - ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - ev_add.data.fd = fd; - fd_info new_info = { fd_info::owner, b, info.p }; - descr[fd] = new_info; + sockaddr addr; + socklen_t sz = sizeof( sockaddr_in ); - if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { - std::cerr << "Accept, add " << fd << ", errno " << errno << std::endl; - descr.erase( fd ); + fd_info info = ifd->second; + + for ( ; ; ) { + int fd = accept( ev.data.fd, &addr, &sz ); + if ( fd < 0 ) { + // std::cerr << "Accept, listener # " << ev.data.fd << ", errno " << errno << std::endl; + // std::cerr << __FILE__ << ":" << __LINE__ << " " << std::tr2::getpid() << std::endl; + if ( (errno == EINTR) || (errno == ECONNABORTED) /* || (errno == ERESTARTSYS) */ ) { + errno = 0; + continue; + } + if ( !(errno == EAGAIN /* || errno == EWOULDBLOCK */ ) ) { // EWOULDBLOCK == EAGAIN + // std::cerr << "Accept, listener " << ev.data.fd << ", errno " << errno << std::endl; + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error } - bool in_closed = false; - { - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.begin(); - for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == info.p ) { - in_closed = true; - std::cerr << "@@@ 1\n" << std::endl; - break; - } - } + if ( ifd->second.p != 0 ) { + ifd->second.p->close(); } + + descr.erase( ifd ); + + // check closed_queue, due to ifd->second.p->close(); add record in it + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); + if ( closed_ifd != closed_queue.end() && closed_ifd->second.p == ifd->second.p ) { + // listener in process of close + closed_queue.erase( closed_ifd ); + } + // throw system_error ? + } else { // back to listen + errno = 0; + epoll_event xev; + xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + xev.data.fd = ev.data.fd; + epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ); } - catch ( const std::bad_alloc& ) { - // nothing - } - catch ( ... ) { + return; + } + if ( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + throw std::runtime_error( "can't establish nonblock mode" ); + } + + try { + sockbuf_t* b = (*info.p)( fd, addr ); + + epoll_event ev_add; + ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + ev_add.data.fd = fd; + fd_info new_info = { fd_info::owner, b, info.p }; + descr[fd] = new_info; + + if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { descr.erase( fd ); + // throw system_error } } - } else { - // std::cerr << "listener: " << std::hex << ev.events << std::dec << std::endl; + catch ( const std::bad_alloc& ) { + // nothing + descr.erase( fd ); + } + catch ( ... ) { + descr.erase( fd ); + } } } @@ -228,11 +250,13 @@ if ( ev.events & EPOLLIN ) { if ( (info.flags & fd_info::owner) == 0 ) { - // marginal case: me not owner (registerd via push(), - // when I owner, I know destroy point), - // already closed, but I not see closed event yet; - // object may be deleted already, so I can't - // call b->egptr() etc. here + /* + marginal case: sockmgr isn't owner (registerd via push(), + when I owner, I know destroy point), + already closed, but I don't see closed event yet; + object may be deleted already, so I can't + call b->egptr() etc. here + */ std::tr2::lock_guard<std::tr2::mutex> lck( cll ); typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); if ( closed_ifd != closed_queue.end() ) { @@ -262,26 +286,12 @@ xev.data.fd = ev.data.fd; info.flags |= fd_info::level_triggered; if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ) < 0 ) { - std::cerr << "X " << ev.data.fd << ", " << errno << std::endl; + // std::cerr << "X " << ev.data.fd << ", " << errno << std::endl; } } - std::cerr << "Z " << ev.data.fd << ", " << errno << std::endl; + // std::cerr << "Z " << ev.data.fd << ", " << errno << std::endl; if ( info.p != 0 ) { // or (info.flags & fd_info::owner) != 0 - bool is_closed = false; - { - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.begin(); - for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == info.p ) { - is_closed = true; - std::cerr << "@@@ 2\n" << std::endl; - break; - } - } - } - if ( !is_closed ) { - (*info.p)( ev.data.fd ); - } + (*info.p)( ev.data.fd ); } break; } @@ -289,28 +299,29 @@ long offset = read( ev.data.fd, b->egptr(), sizeof(charT) * (b->_ebuf - b->egptr()) ); // std::cerr << "offset " << offset << ", " << errno << std::endl; if ( offset < 0 ) { - if ( (errno == EAGAIN) || (errno == EINTR) ) { - errno = 0; - epoll_event xev; - xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; - xev.data.fd = ev.data.fd; - epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ); - break; - } else { - switch ( errno ) { - // case EINTR: // read was interrupted - // continue; - // break; - case EFAULT: // Bad address - case ECONNRESET: // Connection reset by peer - ev.events |= EPOLLRDHUP; // will be processed below - break; - default: - // std::cerr << "not listener, other " << ev.data.fd << std::hex << ev.events << std::dec << " : " << errno << std::endl; - break; - } - break; + switch ( errno ) { + case EINTR: // read was interrupted + errno = 0; + continue; + break; + case EFAULT: // Bad address + case ECONNRESET: // Connection reset by peer + ev.events |= EPOLLRDHUP; // will be processed below + break; + case EAGAIN: + // case EWOULDBLOCK: + { + epoll_event xev; + xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; + xev.data.fd = ev.data.fd; + epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ); + } + break; + default: + // std::cerr << "not listener, other " << ev.data.fd << std::hex << ev.events << std::dec << " : " << errno << std::endl; + break; } + break; } else if ( offset > 0 ) { offset /= sizeof(charT); // if offset % sizeof(charT) != 0, rest will be lost! @@ -320,39 +331,22 @@ xev.data.fd = ev.data.fd; info.flags &= ~static_cast<unsigned>(fd_info::level_triggered); if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ) < 0 ) { - std::cerr << "Y " << ev.data.fd << ", " << errno << std::endl; + // std::cerr << "Y " << ev.data.fd << ", " << errno << std::endl; } } std::tr2::lock_guard<std::tr2::mutex> lk( b->ulck ); b->setg( b->eback(), b->gptr(), b->egptr() + offset ); b->ucnd.notify_one(); if ( info.p != 0 ) { - // std::cerr << "data here" << std::endl; - bool is_closed = false; - { - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.begin(); - for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == info.p ) { - is_closed = true; - std::cerr << "@@@ 3\n" << std::endl; - break; - } - } - } - if ( !is_closed ) { - (*info.p)( ev.data.fd ); - } + (*info.p)( ev.data.fd ); } } else { - std::cerr << "K " << ev.data.fd << ", " << errno << std::endl; + // std::cerr << "K " << ev.data.fd << ", " << errno << std::endl; // EPOLLRDHUP may be missed in kernel, but offset 0 is the same ev.events |= EPOLLRDHUP; // will be processed below break; } } - } else { - std::cerr << "Q\n"; } if ( (ev.events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR) ) != 0 ) { @@ -360,36 +354,15 @@ if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error } - bool need_delete = true; + if ( info.p != 0 ) { - std::cerr << __FILE__ << ":" << __LINE__ << endl; - { - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.begin(); - for ( ; closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( closed_ifd->second.p == info.p ) { - need_delete = false; // will be deleted in 'final' method - std::cerr << "@@@ 4\n" << std::endl; - break; - } - } - } - if ( need_delete ) { - std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.b << std::endl; - (*info.p)( ifd->first, typename socks_processor_t::adopt_close_t() ); - std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.b << std::endl; - } + (*info.p)( ifd->first, typename socks_processor_t::adopt_close_t() ); } - if ( (info.flags & fd_info::owner) != 0 && need_delete ) { - std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.b << std::endl; - } else { - std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)info.b << std::endl; - if ( (info.flags & fd_info::buffer) != 0 ) { - info.b->close(); - } - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - closed_queue.erase( ev.data.fd ); + if ( (info.flags & fd_info::buffer) != 0 ) { + info.b->close(); } + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + closed_queue.erase( ev.data.fd ); descr.erase( ifd ); } // if ( ev.events & EPOLLHUP ) { @@ -433,11 +406,12 @@ std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - // I can't use closed_queue.erase( p.fd() ) here: fd is -1 already - for ( typename fd_container_type::iterator closed_ifd = closed_queue.begin(); closed_ifd != closed_queue.end(); ++closed_ifd ) { + // I can't use closed_queue.erase( p.fd() ) here: fd is -1 already + for ( typename fd_container_type::iterator closed_ifd = closed_queue.begin(); closed_ifd != closed_queue.end(); ) { if ( closed_ifd->second.p == &p ) { - closed_queue.erase( closed_ifd ); - break; + closed_queue.erase( closed_ifd++ ); + } else { + ++closed_ifd; } } } Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-06-26 05:43:01 UTC (rev 1907) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-06-26 05:43:27 UTC (rev 1908) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/11 21:05:35 yeti> +// -*- C++ -*- Time-stamp: <08/06/15 23:21:50 ptr> /* * Copyright (c) 2008 @@ -185,7 +185,6 @@ fd_info info = { fd_info::listener, 0, &p }; std::tr2::lock_guard<std::tr2::mutex> lk( cll ); closed_queue[_fd] = info; - std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)&p << " " << std::tr2::getpid() << std::endl; } void final( socks_processor_t& p ); @@ -195,7 +194,6 @@ fd_info info = { 0, 0, 0 }; std::tr2::lock_guard<std::tr2::mutex> lk( cll ); closed_queue[fd] = info; - std::cerr << __FILE__ << ":" << __LINE__ << " " << (void*)b << " " << std::tr2::getpid() << std::endl; } private: Modified: branches/complement-sockios/explore/lib/sockios/_sp.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/_sp.cc 2008-06-26 05:43:01 UTC (rev 1907) +++ branches/complement-sockios/explore/lib/sockios/_sp.cc 2008-06-26 05:43:27 UTC (rev 1908) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/03/06 12:09:33 ptr> +// -*- C++ -*- Time-stamp: <08/06/13 22:59:17 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -17,7 +17,7 @@ #include <config/feature.h> #include <cerrno> -#include <sockios/sockstream2> +#include <sockios/sockstream> #ifdef STLPORT _STLP_BEGIN_NAMESPACE Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:43:01 UTC (rev 1907) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:43:27 UTC (rev 1908) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/11 21:46:19 yeti> +// -*- C++ -*- Time-stamp: <08/06/15 21:52:52 ptr> /* * @@ -300,7 +300,7 @@ bool rd_counter1() { - return worker::rd == 1; + return worker::rd > 0; // == 1; } int EXAM_IMPL(sockios2_test::processor_core) @@ -311,7 +311,6 @@ EXAM_CHECK( prss.good() ); EXAM_CHECK( prss.is_open() ); - std::cerr << __FILE__ << ":" << __LINE__ << " " << std::tr2::getpid() << std::endl; { sockstream s( "localhost", 2008 ); @@ -329,7 +328,6 @@ EXAM_CHECK( worker::visits == 1 ); worker::visits = 0; } - std::cerr << __FILE__ << ":" << __LINE__ << " " << std::tr2::getpid() << std::endl; } { lock_guard<mutex> lk( worker::lock ); @@ -415,7 +413,7 @@ } unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 100 ), rd_counter1 ); + worker::cnd.timed_wait( lk, milliseconds( 500 ), rd_counter1 ); // cerr << worker::line << endl; EXAM_CHECK( worker::line == "Hello, world!" ); @@ -456,8 +454,6 @@ this_thread::fork(); - std::cerr << __FILE__ << ":" << __LINE__ << " " << std::tr2::getpid() << std::endl; - { connect_processor<worker> prss( 2008 ); @@ -474,8 +470,6 @@ EXAM_CHECK_ASYNC( worker::visits == 1 ); } - std::cerr << __FILE__ << ":" << __LINE__ << " " << std::tr2::getpid() << std::endl; - exit( 0 ); } catch ( std::tr2::fork_in_parent& child ) { @@ -626,16 +620,16 @@ int n = 1; - cerr << "align 3\n"; + // cerr << "align 3\n"; bb->wait(); // <-- align 3 - cerr << "align 3 pass\n"; + // cerr << "align 3 pass\n"; s.write( (const char *)&n, sizeof( int ) ).flush(); EXAM_CHECK_ASYNC( s.good() ); } ~interrupted_writer() - { cerr << "~~\n"; } + { /* cerr << "~~\n"; */ } void connect( sockstream& s ) { } @@ -645,9 +639,9 @@ sockstream s( "localhost", 2008 ); int buff = 0; - cerr << "align 2" << endl; + // cerr << "align 2" << endl; b->wait(); // <-- align 2 - cerr << "align pass" << endl; + // cerr << "align pass" << endl; EXAM_CHECK_ASYNC( s.read( (char *)&buff, sizeof(int) ).good() ); // <---- key line EXAM_CHECK_ASYNC( buff == 1 ); @@ -681,12 +675,12 @@ bb.wait(); // <-- align 2 - cerr << "system" << endl; + // cerr << "system" << endl; system( "echo > /dev/null" ); // <------ key line - cerr << "after system" << endl; + // cerr << "after system" << endl; bnew.wait(); // <-- align 3 - cerr << "after align 3" << endl; + // cerr << "after align 3" << endl; t.join(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:43:49
|
Revision: 1909 http://complement.svn.sourceforge.net/complement/?rev=1909&view=rev Author: complement Date: 2008-06-25 22:43:48 -0700 (Wed, 25 Jun 2008) Log Message: ----------- final method may lead to deadlock: process close via sockmgr When server closed, all sockets (connections) should be closed, but via sockmgr/epoll (via descriptors); this done with sock_buf::shutdown; but I'm not sure that all connections really closed/destroyed at connection_processor dtor, but this is MUST (otherwise call of unexistent object happens) Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/socksrv.cc branches/complement-sockios/explore/include/sockios/socksrv.h branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/socksrv.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:43:27 UTC (rev 1908) +++ branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:43:48 UTC (rev 1909) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/16 10:45:56 ptr> +// -*- C++ -*- Time-stamp: <08/06/16 20:25:28 yeti> /* * Copyright (c) 2008 @@ -198,12 +198,6 @@ // std::cerr << "=== " << ready_pool.size() << std::endl; cnd.notify_one(); } - - basic_socket<charT,traits,_Alloc>::mgr->final( *this ); - - if ( ploop.joinable() ) { - ploop.join(); - } } template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> Modified: branches/complement-sockios/explore/include/sockios/socksrv.h =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:43:27 UTC (rev 1908) +++ branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:43:48 UTC (rev 1909) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/15 23:29:23 ptr> +// -*- C++ -*- Time-stamp: <08/06/16 22:07:54 yeti> /* * Copyright (c) 2008 @@ -175,6 +175,22 @@ { connect_processor::close(); + if ( ploop.joinable() ) { + ploop.join(); + } + + basic_socket<charT,traits,_Alloc>::mgr->final( *this ); + + { + std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); + cerr << __FILE__ << ":" << __LINE__ << " " << ready_pool.size() << endl; + } + + { + std::tr2::lock_guard<std::tr2::mutex> lk2( wklock ); + cerr << __FILE__ << ":" << __LINE__ << " " << worker_pool.size() << endl; + } + ((Init *)Init_buf)->~Init(); } Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:43:27 UTC (rev 1908) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:43:48 UTC (rev 1909) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/16 11:05:56 ptr> +// -*- C++ -*- Time-stamp: <08/06/16 20:24:51 yeti> /* * Copyright (c) 2008 @@ -140,6 +140,11 @@ if ( ifd->second.p != 0 ) { ifd->second.p->close(); + for ( typename fd_container_type::iterator i = descr.begin(); i != descr.end(); ++i ) { + if ( (i->second.p == ifd->second.p) && (i->second.b != 0) ) { + i->second.b->shutdown( sock_base::stop_in | sock_base::stop_out ); + } + } } descr.erase( ifd ); @@ -194,6 +199,11 @@ if ( ifd->second.p != 0 ) { ifd->second.p->close(); + for ( typename fd_container_type::iterator i = descr.begin(); i != descr.end(); ++i ) { + if ( (i->second.p == ifd->second.p) && (i->second.b != 0) ) { + i->second.b->shutdown( sock_base::stop_in | sock_base::stop_out ); + } + } } descr.erase( ifd ); @@ -388,6 +398,7 @@ template<class charT, class traits, class _Alloc> void sockmgr<charT,traits,_Alloc>::final( sockmgr<charT,traits,_Alloc>::socks_processor_t& p ) { +#if 0 std::tr2::lock_guard<std::tr2::mutex> lk_descr( dll ); for ( typename fd_container_type::iterator ifd = descr.begin(); ifd != descr.end(); ) { @@ -403,6 +414,7 @@ ++ifd; } } +#endif std::tr2::lock_guard<std::tr2::mutex> lk( cll ); Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:43:27 UTC (rev 1908) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:43:48 UTC (rev 1909) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/15 21:52:52 ptr> +// -*- C++ -*- Time-stamp: <08/06/16 20:35:30 yeti> /* * @@ -393,8 +393,8 @@ } } - EXAM_CHECK( worker::line == "" ); + EXAM_CHECK( worker::rd == 0 ); // check after sockstream2 was closed, i.e. ensure, that all data available read before close { @@ -413,9 +413,9 @@ } unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 500 ), rd_counter1 ); + worker::cnd.timed_wait( lk, milliseconds( 100 ), rd_counter1 ); - // cerr << worker::line << endl; + cerr << worker::line << endl; EXAM_CHECK( worker::line == "Hello, world!" ); worker::line = ""; worker::rd = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:44:11
|
Revision: 1910 http://complement.svn.sourceforge.net/complement/?rev=1910&view=rev Author: complement Date: 2008-06-25 22:44:09 -0700 (Wed, 25 Jun 2008) Log Message: ----------- Problem with call after death looks found; deadlock still here. Looks like I need to block sockbuf destruction, when in processing of sockets: otherwise I need more checks in closed_queue, and still lock should be here; now lock added, but ones may lead to deadlock. Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/socksrv.h branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/socksrv.h =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:43:48 UTC (rev 1909) +++ branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:44:09 UTC (rev 1910) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/16 22:07:54 yeti> +// -*- C++ -*- Time-stamp: <08/06/17 09:17:05 ptr> /* * Copyright (c) 2008 @@ -87,9 +87,18 @@ virtual void close(); +#if 0 virtual sockbuf_t* operator ()( sock_base::socket_type fd, const sockaddr& ) = 0; virtual void operator ()( sock_base::socket_type fd, const adopt_close_t& ) = 0; virtual void operator ()( sock_base::socket_type fd ) = 0; +#else + virtual sockbuf_t* operator ()( sock_base::socket_type fd, const sockaddr& ) + { abort(); return 0; } + virtual void operator ()( sock_base::socket_type fd, const adopt_close_t& ) + { abort(); } + virtual void operator ()( sock_base::socket_type fd ) + { abort(); } +#endif private: sock_processor_base( const sock_processor_base& ); Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:43:48 UTC (rev 1909) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:44:09 UTC (rev 1910) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/16 20:24:51 yeti> +// -*- C++ -*- Time-stamp: <08/06/17 10:35:40 ptr> /* * Copyright (c) 2008 @@ -34,6 +34,7 @@ if ( n < 0 ) { if ( errno == EINTR ) { + errno = 0; continue; } // throw system_error @@ -186,7 +187,7 @@ int fd = accept( ev.data.fd, &addr, &sz ); if ( fd < 0 ) { // std::cerr << "Accept, listener # " << ev.data.fd << ", errno " << errno << std::endl; - // std::cerr << __FILE__ << ":" << __LINE__ << " " << std::tr2::getpid() << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ /* << " " << std::tr2::getpid() */ << std::endl; if ( (errno == EINTR) || (errno == ECONNABORTED) /* || (errno == ERESTARTSYS) */ ) { errno = 0; continue; @@ -194,6 +195,7 @@ if ( !(errno == EAGAIN /* || errno == EWOULDBLOCK */ ) ) { // EWOULDBLOCK == EAGAIN // std::cerr << "Accept, listener " << ev.data.fd << ", errno " << errno << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; // throw system_error } @@ -216,21 +218,28 @@ closed_queue.erase( closed_ifd ); } // throw system_error ? + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; } else { // back to listen errno = 0; epoll_event xev; xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; xev.data.fd = ev.data.fd; - epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ); + if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev.data.fd, &xev ) < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + } } + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; return; } if ( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) != 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; throw std::runtime_error( "can't establish nonblock mode" ); } try { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; sockbuf_t* b = (*info.p)( fd, addr ); + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; epoll_event ev_add; ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; @@ -258,7 +267,19 @@ { fd_info& info = ifd->second; + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); + if ( closed_ifd != closed_queue.end() ) { + closed_queue.erase( closed_ifd ); + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error + } + descr.erase( ifd ); + return; + } + if ( ev.events & EPOLLIN ) { +#if 0 if ( (info.flags & fd_info::owner) == 0 ) { /* marginal case: sockmgr isn't owner (registerd via push(), @@ -278,10 +299,12 @@ return; } } - sockbuf_t* b = /* (info.flags & fd_info::buffer != 0) ? info.s.b : info.s.s->rdbuf() */ info.b; +#endif + + sockbuf_t* b = info.b; errno = 0; - if ( b == 0 ) { // marginal case: sockbuf wasn't created by processor - if ( info.p != 0 ) { + if ( b == 0 ) { // marginal case: sockbuf wasn't created by processor... + if ( info.p != 0 ) { // ... but controlled by processor (*info.p)( ifd->first, typename socks_processor_t::adopt_close_t() ); } descr.erase( ifd ); @@ -367,7 +390,7 @@ if ( info.p != 0 ) { (*info.p)( ifd->first, typename socks_processor_t::adopt_close_t() ); - } + } /* else */ if ( (info.flags & fd_info::buffer) != 0 ) { info.b->close(); } Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:43:48 UTC (rev 1909) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:44:09 UTC (rev 1910) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/16 20:35:30 yeti> +// -*- C++ -*- Time-stamp: <08/06/17 09:11:57 ptr> /* * @@ -620,16 +620,16 @@ int n = 1; - // cerr << "align 3\n"; + cerr << "align 3\n"; bb->wait(); // <-- align 3 - // cerr << "align 3 pass\n"; + cerr << "align 3 pass\n"; s.write( (const char *)&n, sizeof( int ) ).flush(); EXAM_CHECK_ASYNC( s.good() ); } ~interrupted_writer() - { /* cerr << "~~\n"; */ } + { cerr << "~~\n"; } void connect( sockstream& s ) { } @@ -639,11 +639,12 @@ sockstream s( "localhost", 2008 ); int buff = 0; - // cerr << "align 2" << endl; + cerr << "align 2" << endl; b->wait(); // <-- align 2 - // cerr << "align pass" << endl; + cerr << "align 2 pass" << endl; EXAM_CHECK_ASYNC( s.read( (char *)&buff, sizeof(int) ).good() ); // <---- key line + cerr << "read pass" << endl; EXAM_CHECK_ASYNC( buff == 1 ); } @@ -675,12 +676,12 @@ bb.wait(); // <-- align 2 - // cerr << "system" << endl; + cerr << "system" << endl; system( "echo > /dev/null" ); // <------ key line - // cerr << "after system" << endl; + cerr << "after system" << endl; bnew.wait(); // <-- align 3 - // cerr << "after align 3" << endl; + cerr << "after align 3" << endl; t.join(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:44:28
|
Revision: 1911 http://complement.svn.sourceforge.net/complement/?rev=1911&view=rev Author: complement Date: 2008-06-25 22:44:26 -0700 (Wed, 25 Jun 2008) Log Message: ----------- One deadlock in sockmgr removed; fixed test. Double lock of closed_queue removed. In test barrier replaced by condition_variable, to avoid deadlock in sockmgr; fixed usage of condition---line_cnd should be on line check instead of cnd. test with rest data reading not pass, but should. Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:44:09 UTC (rev 1910) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:44:26 UTC (rev 1911) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/17 10:35:40 ptr> +// -*- C++ -*- Time-stamp: <08/06/17 13:10:39 yeti> /* * Copyright (c) 2008 @@ -394,7 +394,7 @@ if ( (info.flags & fd_info::buffer) != 0 ) { info.b->close(); } - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + // std::tr2::lock_guard<std::tr2::mutex> lck( cll ); closed_queue.erase( ev.data.fd ); descr.erase( ifd ); } Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:44:09 UTC (rev 1910) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:44:26 UTC (rev 1911) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/17 09:11:57 ptr> +// -*- C++ -*- Time-stamp: <08/06/17 13:47:21 yeti> /* * @@ -68,25 +68,32 @@ protected: virtual sock_basic_processor::sockbuf_t* operator ()( sock_base::socket_type, const sockaddr& ) - { lock_guard<mutex> lk(lock); b.wait(); ++n_cnt; return 0; } + { lock_guard<mutex> lk(lock); ++n_cnt; cnd.notify_one(); return 0; } virtual void operator ()( sock_base::socket_type, const adopt_close_t& ) - { lock_guard<mutex> lk(lock); b.wait(); ++c_cnt; } + { lock_guard<mutex> lk(lock); ++c_cnt; cnd.notify_one(); } virtual void operator ()( sock_base::socket_type ) - { lock_guard<mutex> lk(lock); ++d_cnt; } + { lock_guard<mutex> lk(lock); ++d_cnt; cnd.notify_one(); } public: static mutex lock; static int n_cnt; static int c_cnt; static int d_cnt; - static barrier b; + static condition_variable cnd; + + static bool n_cnt_check() + { return n_cnt == 1; } + static bool c_cnt_check() + { return c_cnt == 1; } + static bool d_cnt_check() + { return d_cnt == 1; } }; mutex simple_mgr::lock; int simple_mgr::n_cnt = 0; int simple_mgr::c_cnt = 0; int simple_mgr::d_cnt = 0; -barrier simple_mgr::b; +condition_variable simple_mgr::cnd; class simple_mgr2 : public sock_basic_processor @@ -104,8 +111,8 @@ virtual sock_basic_processor::sockbuf_t* operator ()( sock_base::socket_type fd, const sockaddr& addr ) { lock_guard<mutex> lk(lock); - b.wait(); ++n_cnt; + cnd.notify_one(); sockstream_t* s = sock_basic_processor::create_stream( fd, addr ); cons[fd] = s; @@ -116,8 +123,8 @@ virtual void operator ()( sock_base::socket_type fd, const adopt_close_t& ) { lock_guard<mutex> lk(lock); - b.wait(); ++c_cnt; + cnd.notify_one(); delete cons[fd]; cons.erase( fd ); } @@ -125,8 +132,8 @@ virtual void operator ()( sock_base::socket_type fd ) { lock_guard<mutex> lk(lock); - b.wait(); ++d_cnt; + cnd.notify_one(); string str; getline( *cons[fd], str ); // map fd -> s EXAM_CHECK_ASYNC( str == "Hello" ); @@ -137,8 +144,15 @@ static int n_cnt; static int c_cnt; static int d_cnt; - static barrier b; + static condition_variable cnd; + static bool n_cnt_check() + { return n_cnt == 1; } + static bool c_cnt_check() + { return c_cnt == 1; } + static bool d_cnt_check() + { return d_cnt == 1; } + private: #ifdef __USE_STLPORT_HASH @@ -158,7 +172,7 @@ int simple_mgr2::n_cnt = 0; int simple_mgr2::c_cnt = 0; int simple_mgr2::d_cnt = 0; -barrier simple_mgr2::b; +condition_variable simple_mgr2::cnd; int EXAM_IMPL(sockios2_test::srv_core) @@ -190,9 +204,9 @@ EXAM_CHECK( s.good() ); { - simple_mgr::b.wait(); - lock_guard<mutex> lk(simple_mgr::lock); - EXAM_CHECK( simple_mgr::n_cnt == 1 ); + unique_lock<mutex> lk( simple_mgr::lock ); + + EXAM_CHECK( simple_mgr::cnd.timed_wait( lk, milliseconds( 500 ), simple_mgr::n_cnt_check ) ); } { lock_guard<mutex> lk(simple_mgr::lock); @@ -204,9 +218,10 @@ } } - simple_mgr::b.wait(); - lock_guard<mutex> lk(simple_mgr::lock); - EXAM_CHECK( simple_mgr::c_cnt == 1 ); + unique_lock<mutex> lk( simple_mgr::lock ); + + EXAM_CHECK( simple_mgr::cnd.timed_wait( lk, milliseconds( 500 ), simple_mgr::c_cnt_check ) ); + EXAM_CHECK( simple_mgr::d_cnt == 0 ); } { @@ -221,22 +236,19 @@ EXAM_CHECK( s.good() ); { - simple_mgr2::b.wait(); - lock_guard<mutex> lk(simple_mgr2::lock); - EXAM_CHECK( simple_mgr2::n_cnt == 1 ); + unique_lock<mutex> lk( simple_mgr2::lock ); + EXAM_CHECK( simple_mgr2::cnd.timed_wait( lk, milliseconds( 500 ), simple_mgr2::n_cnt_check ) ); } { s << "Hello" << endl; EXAM_CHECK( s.good() ); - simple_mgr2::b.wait(); - lock_guard<mutex> lk(simple_mgr2::lock); - EXAM_CHECK( simple_mgr2::d_cnt == 1 ); + unique_lock<mutex> lk( simple_mgr2::lock ); + EXAM_CHECK( simple_mgr2::cnd.timed_wait( lk, milliseconds( 500 ), simple_mgr2::d_cnt_check ) ); } s.close(); { - simple_mgr2::b.wait(); - lock_guard<mutex> lk(simple_mgr2::lock); - EXAM_CHECK( simple_mgr2::c_cnt == 1 ); + unique_lock<mutex> lk( simple_mgr2::lock ); + EXAM_CHECK( simple_mgr2::cnd.timed_wait( lk, milliseconds( 500 ), simple_mgr2::c_cnt_check ) ); } } } @@ -269,7 +281,15 @@ static string line; static condition_variable line_cnd; static int rd; - // static barrier b; + + static bool visits_counter1() + { return worker::visits == 1; } + + static bool visits_counter2() + { return worker::visits == 2; } + + static bool rd_counter1() + { return worker::rd == 1; } }; mutex worker::lock; @@ -288,21 +308,6 @@ // prss->close(); // } -bool visits_counter1() -{ - return worker::visits == 1; -} - -bool visits_counter2() -{ - return worker::visits == 2; -} - -bool rd_counter1() -{ - return worker::rd > 0; // == 1; -} - int EXAM_IMPL(sockios2_test::processor_core) { { @@ -323,9 +328,7 @@ unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 500 ), visits_counter1 ); - - EXAM_CHECK( worker::visits == 1 ); + EXAM_CHECK( worker::cnd.timed_wait( lk, milliseconds( 500 ), worker::visits_counter1 ) ); worker::visits = 0; } } @@ -354,11 +357,10 @@ // for ( int i = 0; i < 1024; ++i ) { // give chance to process it // std::tr2::this_thread::yield(); // } + unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 500 ), visits_counter2 ); - - EXAM_CHECK( worker::visits == 2 ); + EXAM_CHECK( worker::cnd.timed_wait( lk, milliseconds( 500 ), worker::visits_counter2 ) ); worker::visits = 0; } } @@ -368,7 +370,7 @@ } - // check before sockstream was closed + // check income data before sockstream was closed { connect_processor<worker> prss( 2008 ); @@ -384,7 +386,7 @@ s1 << "Hello, world!" << endl; unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 100 ), rd_counter1 ); + EXAM_CHECK( worker::line_cnd.timed_wait( lk, milliseconds( 500 ), worker::rd_counter1 ) ); // cerr << worker::line << endl; EXAM_CHECK( worker::line == "Hello, world!" ); @@ -393,10 +395,8 @@ } } - EXAM_CHECK( worker::line == "" ); - EXAM_CHECK( worker::rd == 0 ); - - // check after sockstream2 was closed, i.e. ensure, that all data available read before close + // check after sockstream was closed, i.e. ensure, that all data available + // was read before stream was closed { connect_processor<worker> prss( 2008 ); @@ -413,16 +413,14 @@ } unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 100 ), rd_counter1 ); + EXAM_CHECK( worker::line_cnd.timed_wait( lk, milliseconds( 500 ), worker::rd_counter1 ) ); - cerr << worker::line << endl; + // cerr << worker::line << endl; EXAM_CHECK( worker::line == "Hello, world!" ); worker::line = ""; worker::rd = 0; } - EXAM_CHECK( worker::line == "" ); - return EXAM_RESULT; } @@ -465,9 +463,7 @@ EXAM_CHECK_ASYNC( prss.is_open() ); unique_lock<mutex> lk( worker::lock ); - worker::cnd.timed_wait( lk, milliseconds( 100 ), visits_counter1 ); - - EXAM_CHECK_ASYNC( worker::visits == 1 ); + EXAM_CHECK_ASYNC( worker::cnd.timed_wait( lk, milliseconds( 500 ), worker::visits_counter1 ) ); } exit( 0 ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:44:55
|
Revision: 1912 http://complement.svn.sourceforge.net/complement/?rev=1912&view=rev Author: complement Date: 2008-06-25 22:44:53 -0700 (Wed, 25 Jun 2008) Log Message: ----------- Under debugging; Detected problem use case: after close fd next assigned fd may has same number. Suggestion: clean close_quere ASAP, and remove appropriate fd from epoll's vector too. Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/socksrv.cc branches/complement-sockios/explore/include/sockios/socksrv.h branches/complement-sockios/explore/include/sockios/sockstream branches/complement-sockios/explore/include/sockios/sockstream.cc branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/socksrv.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:44:26 UTC (rev 1911) +++ branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:44:53 UTC (rev 1912) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/16 20:25:28 yeti> +// -*- C++ -*- Time-stamp: <08/06/17 14:54:16 yeti> /* * Copyright (c) 2008 @@ -205,16 +205,20 @@ { typename base_t::sockstream_t* s = base_t::create_stream( fd, addr ); + if ( s == 0 ) { + return 0; + } + Connect* c = new Connect( *s ); // bad point! I can't read from s in ctor indeed! - if ( s->rdbuf()->in_avail() ) { - std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - ready_pool.push_back( processor( c, s ) ); - cnd.notify_one(); - } else { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool.insert( std::make_pair( fd, processor( c, s ) ) ); - } + // if ( s->rdbuf()->in_avail() ) { + // std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + // ready_pool.push_back( processor( c, s ) ); + // cnd.notify_one(); + // } else { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + worker_pool.insert( std::make_pair( fd, processor( c, s ) ) ); + // } return s->rdbuf(); } Modified: branches/complement-sockios/explore/include/sockios/socksrv.h =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:44:26 UTC (rev 1911) +++ branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:44:53 UTC (rev 1912) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/17 09:17:05 ptr> +// -*- C++ -*- Time-stamp: <08/06/17 15:44:44 yeti> /* * Copyright (c) 2008 @@ -109,7 +109,9 @@ sockstream_t* create_stream( int fd, const sockaddr& addr ) { sockstream_t* s = new sockstream_t(); - s->rdbuf()->_open_sockmgr( fd, addr ); + if ( s != 0 ) { + s->rdbuf()->_open_sockmgr( fd, addr ); + } return s; } @@ -197,7 +199,11 @@ { std::tr2::lock_guard<std::tr2::mutex> lk2( wklock ); - cerr << __FILE__ << ":" << __LINE__ << " " << worker_pool.size() << endl; + cerr << __FILE__ << ":" << __LINE__ << " " << worker_pool.size() << endl; + for ( typename worker_pool_t::iterator i = worker_pool.begin(); i != worker_pool.end(); ++i ) { + delete i->second.c; + delete i->second.s; + } } ((Init *)Init_buf)->~Init(); Modified: branches/complement-sockios/explore/include/sockios/sockstream =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream 2008-06-26 05:44:26 UTC (rev 1911) +++ branches/complement-sockios/explore/include/sockios/sockstream 2008-06-26 05:44:53 UTC (rev 1912) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/15 17:11:29 ptr> +// -*- C++ -*- Time-stamp: <08/06/17 17:09:45 yeti> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -448,8 +448,10 @@ virtual ~basic_sockbuf() { + std::cerr << __FILE__ << ":" << __LINE__ << " " << basic_socket_t::_fd << std::endl; close(); _M_deallocate_block(); + std::cerr << __FILE__ << ":" << __LINE__ << " " << basic_socket_t::_fd << std::endl; } sockbuf_type *open( const char *hostname, int port, Modified: branches/complement-sockios/explore/include/sockios/sockstream.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream.cc 2008-06-26 05:44:26 UTC (rev 1911) +++ branches/complement-sockios/explore/include/sockios/sockstream.cc 2008-06-26 05:44:53 UTC (rev 1912) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/11 14:47:58 yeti> +// -*- C++ -*- Time-stamp: <08/06/17 17:09:02 yeti> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -392,19 +392,26 @@ template<class charT, class traits, class _Alloc> int basic_sockbuf<charT, traits, _Alloc>::sync() { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; if ( !basic_socket_t::is_open() ) { return -1; } long count = this->pptr() - this->pbase(); if ( count ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; // _STLP_ASSERT( this->pbase() != 0 ); count *= sizeof(charT); long start = 0; while ( count > 0 ) { long offset = (this->*_xwrite)( this->pbase() + start, count ); + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; if ( offset < 0 ) { - if ( errno == EAGAIN ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + if ( errno == EINTR ) { + errno = 0; + continue; + } else if ( errno == EAGAIN ) { pollfd wpfd; wpfd.fd = basic_socket_t::_fd; wpfd.events = POLLOUT | POLLHUP | POLLWRNORM; @@ -412,6 +419,7 @@ while ( poll( &wpfd, 1, basic_socket_t::_use_wrtimeout ? basic_socket_t::_wrtimeout.count() : -1 ) <= 0 ) { // wait infinite if ( errno == EINTR ) { // may be interrupted, check and ignore errno = 0; + // reduce timeout? continue; } return -1; @@ -427,6 +435,7 @@ return -1; } } + std::cerr << __FILE__ << ":" << __LINE__ << " " << basic_socket_t::_fd << std::endl; count -= offset; start += offset; } Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:44:26 UTC (rev 1911) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:44:53 UTC (rev 1912) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/17 13:10:39 yeti> +// -*- C++ -*- Time-stamp: <08/06/17 17:41:00 yeti> /* * Copyright (c) 2008 @@ -116,8 +116,21 @@ ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; ev_add.data.fd = static_cast<sockbuf_t*>(_ctl.data.ptr)->fd(); if ( ev_add.data.fd >= 0 ) { - fd_info new_info = { fd_info::buffer, static_cast<sockbuf_t*>(_ctl.data.ptr), 0 }; + fd_info new_info = { 0, static_cast<sockbuf_t*>(_ctl.data.ptr), 0 }; descr[ev_add.data.fd] = new_info; + + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + + typename fd_container_type::iterator closed_ifd = closed_queue.find( ev_add.data.fd ); + if ( closed_ifd != closed_queue.end() ) { // reuse same fd? + closed_queue.erase( closed_ifd ); + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ev_add.data.fd, 0 ) < 0 ) { + // throw system_error + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + } + // descr.erase( ifd ); + } + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { descr.erase( ev_add.data.fd ); // throw system_error @@ -164,19 +177,19 @@ return; // I don't know what to do this case... } - { - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); - if ( closed_ifd != closed_queue.end() && closed_ifd->second.p == ifd->second.p ) { - // listener in process of closing, ignore all incoming connects - closed_queue.erase( closed_ifd ); - if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { - // throw system_error - } - descr.erase( ifd ); - return; - } + // { + std::tr2::lock_guard<std::tr2::mutex> lck( cll ); + for ( typename fd_container_type::iterator closed_ifd = closed_queue.begin(); closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( epoll_ctl( efd, EPOLL_CTL_DEL, closed_ifd->first, 0 ) < 0 ) { + // ignore + } + if ( closed_ifd->first == ifd->first ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + } + descr.erase( closed_ifd->first ); } + closed_queue.clear(); + // at this point closed queue empty sockaddr addr; socklen_t sz = sizeof( sockaddr_in ); @@ -189,11 +202,13 @@ // std::cerr << "Accept, listener # " << ev.data.fd << ", errno " << errno << std::endl; std::cerr << __FILE__ << ":" << __LINE__ /* << " " << std::tr2::getpid() */ << std::endl; if ( (errno == EINTR) || (errno == ECONNABORTED) /* || (errno == ERESTARTSYS) */ ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; errno = 0; continue; } if ( !(errno == EAGAIN /* || errno == EWOULDBLOCK */ ) ) { // EWOULDBLOCK == EAGAIN // std::cerr << "Accept, listener " << ev.data.fd << ", errno " << errno << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { std::cerr << __FILE__ << ":" << __LINE__ << std::endl; // throw system_error @@ -211,7 +226,7 @@ descr.erase( ifd ); // check closed_queue, due to ifd->second.p->close(); add record in it - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); +// std::tr2::lock_guard<std::tr2::mutex> lck( cll ); typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); if ( closed_ifd != closed_queue.end() && closed_ifd->second.p == ifd->second.p ) { // listener in process of close @@ -237,20 +252,23 @@ } try { - std::cerr << __FILE__ << ":" << __LINE__ << std::endl; - sockbuf_t* b = (*info.p)( fd, addr ); - std::cerr << __FILE__ << ":" << __LINE__ << std::endl; - epoll_event ev_add; ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; ev_add.data.fd = fd; - fd_info new_info = { fd_info::owner, b, info.p }; - descr[fd] = new_info; if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { descr.erase( fd ); // throw system_error + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + return; // throw } + + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + sockbuf_t* b = (*info.p)( fd, addr ); + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + + fd_info new_info = { 0, b, info.p }; + descr[fd] = new_info; } catch ( const std::bad_alloc& ) { // nothing @@ -265,53 +283,45 @@ template<class charT, class traits, class _Alloc> void sockmgr<charT,traits,_Alloc>::process_regular( epoll_event& ev, typename sockmgr<charT,traits,_Alloc>::fd_container_type::iterator ifd ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + fd_info& info = ifd->second; std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); - if ( closed_ifd != closed_queue.end() ) { - closed_queue.erase( closed_ifd ); + + for ( typename fd_container_type::iterator closed_ifd = closed_queue.begin(); closed_ifd != closed_queue.end(); ++closed_ifd ) { + if ( epoll_ctl( efd, EPOLL_CTL_DEL, closed_ifd->first, 0 ) < 0 ) { + // ignore + } + if ( closed_ifd->first == ifd->first ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + } + descr.erase( closed_ifd->first ); + } + closed_queue.clear(); + // at this point closed queue empty + + sockbuf_t* b = info.b; + if ( b == 0 ) { // marginal case: sockbuf wasn't created by processor... if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error } + if ( info.p != 0 ) { // ... but controlled by processor + (*info.p)( ifd->first, typename socks_processor_t::adopt_close_t() ); + } descr.erase( ifd ); + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; return; } + errno = 0; + + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; if ( ev.events & EPOLLIN ) { -#if 0 - if ( (info.flags & fd_info::owner) == 0 ) { - /* - marginal case: sockmgr isn't owner (registerd via push(), - when I owner, I know destroy point), - already closed, but I don't see closed event yet; - object may be deleted already, so I can't - call b->egptr() etc. here - */ - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - typename fd_container_type::iterator closed_ifd = closed_queue.find( ev.data.fd ); - if ( closed_ifd != closed_queue.end() ) { - closed_queue.erase( closed_ifd ); - if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { - // throw system_error - } - descr.erase( ifd ); - return; - } - } -#endif - - sockbuf_t* b = info.b; - errno = 0; - if ( b == 0 ) { // marginal case: sockbuf wasn't created by processor... - if ( info.p != 0 ) { // ... but controlled by processor - (*info.p)( ifd->first, typename socks_processor_t::adopt_close_t() ); - } - descr.erase( ifd ); - return; - } + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; for ( ; ; ) { if ( b->_ebuf == b->egptr() ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; // process extract data from buffer too slow for us! if ( (info.flags & fd_info::level_triggered) == 0 ) { epoll_event xev; @@ -332,6 +342,7 @@ long offset = read( ev.data.fd, b->egptr(), sizeof(charT) * (b->_ebuf - b->egptr()) ); // std::cerr << "offset " << offset << ", " << errno << std::endl; if ( offset < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; switch ( errno ) { case EINTR: // read was interrupted errno = 0; @@ -339,10 +350,12 @@ break; case EFAULT: // Bad address case ECONNRESET: // Connection reset by peer + errno = 0; ev.events |= EPOLLRDHUP; // will be processed below break; case EAGAIN: // case EWOULDBLOCK: + errno = 0; { epoll_event xev; xev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; @@ -352,10 +365,12 @@ break; default: // std::cerr << "not listener, other " << ev.data.fd << std::hex << ev.events << std::dec << " : " << errno << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; break; } break; } else if ( offset > 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; offset /= sizeof(charT); // if offset % sizeof(charT) != 0, rest will be lost! if ( info.flags & fd_info::level_triggered ) { @@ -371,9 +386,11 @@ b->setg( b->eback(), b->gptr(), b->egptr() + offset ); b->ucnd.notify_one(); if ( info.p != 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << ev.data.fd << std::endl; (*info.p)( ev.data.fd ); } } else { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; // std::cerr << "K " << ev.data.fd << ", " << errno << std::endl; // EPOLLRDHUP may be missed in kernel, but offset 0 is the same ev.events |= EPOLLRDHUP; // will be processed below @@ -384,15 +401,18 @@ if ( (ev.events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR) ) != 0 ) { // std::cerr << "Poll EPOLLRDHUP " << ev.data.fd << ", " << errno << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; } if ( info.p != 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; (*info.p)( ifd->first, typename socks_processor_t::adopt_close_t() ); - } /* else */ - if ( (info.flags & fd_info::buffer) != 0 ) { - info.b->close(); + } else { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + b->close(); } // std::tr2::lock_guard<std::tr2::mutex> lck( cll ); closed_queue.erase( ev.data.fd ); Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-06-26 05:44:26 UTC (rev 1911) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-06-26 05:44:53 UTC (rev 1912) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/15 23:21:50 ptr> +// -*- C++ -*- Time-stamp: <08/06/17 15:09:45 yeti> /* * Copyright (c) 2008 @@ -87,9 +87,7 @@ { enum { listener = 0x1, - level_triggered = 0x2, - owner = 0x4, - buffer = 0x8 + level_triggered = 0x2 }; unsigned flags; Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:44:26 UTC (rev 1911) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:44:53 UTC (rev 1912) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/17 13:47:21 yeti> +// -*- C++ -*- Time-stamp: <08/06/17 16:35:39 yeti> /* * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2008-06-26 05:46:45
|
Revision: 1918 http://complement.svn.sourceforge.net/complement/?rev=1918&view=rev Author: complement Date: 2008-06-25 22:46:44 -0700 (Wed, 25 Jun 2008) Log Message: ----------- Seems problem in accepting connection after processor ready to exit. Problem coupled with fact, that connection_processor and client socket streams are in single process, but in different thread. This may lead to sequence: - connection_processor queue empty, it ready to exit - accept or epoll signal about incoming connection and connection_processor should process it Modified Paths: -------------- branches/complement-sockios/explore/include/sockios/socksrv.cc branches/complement-sockios/explore/include/sockios/socksrv.h branches/complement-sockios/explore/include/sockios/sockstream.cc branches/complement-sockios/explore/include/sockios/sp.cc branches/complement-sockios/explore/include/sockios/sp.h branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc Modified: branches/complement-sockios/explore/include/sockios/socksrv.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:46:17 UTC (rev 1917) +++ branches/complement-sockios/explore/include/sockios/socksrv.cc 2008-06-26 05:46:44 UTC (rev 1918) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/24 18:34:58 yeti> +// -*- C++ -*- Time-stamp: <08/06/25 21:28:07 yeti> /* * Copyright (c) 2008 @@ -66,13 +66,13 @@ } template<class charT, class traits, class _Alloc> -void sock_processor_base<charT,traits,_Alloc>::close() +void sock_processor_base<charT,traits,_Alloc>::_close() { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); if ( !basic_socket_t::is_open_unsafe() ) { return; } - std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << " " << basic_socket_t::_fd << std::endl; #ifdef WIN32 ::closesocket( basic_socket_t::_fd ); @@ -187,10 +187,10 @@ char connect_processor<Connect, charT, traits, _Alloc, C>::Init_buf[128]; template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> -void connect_processor<Connect, charT, traits, _Alloc, C>::close() +void connect_processor<Connect, charT, traits, _Alloc, C>::_close() { std::cerr << __FILE__ << ":" << __LINE__ << std::endl; - base_t::close(); + base_t::_close(); #if 0 { @@ -218,14 +218,16 @@ Connect* c = new Connect( *s ); // bad point! I can't read from s in ctor indeed! - // if ( s->rdbuf()->in_avail() ) { - // std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); - // ready_pool.push_back( processor( c, s ) ); - // cnd.notify_one(); - // } else { - std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); - worker_pool.insert( std::make_pair( fd, processor( c, s ) ) ); - // } + if ( s->rdbuf()->in_avail() ) { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + ready_pool.push_back( processor( c, s ) ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + cnd.notify_one(); + } else { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + worker_pool.insert( std::make_pair( fd, processor( c, s ) ) ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + } return s->rdbuf(); } @@ -233,10 +235,12 @@ template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( sock_base::socket_type fd, const typename connect_processor<Connect, charT, traits, _Alloc, C>::base_t::adopt_close_t& ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; { std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); typename worker_pool_t::iterator i = worker_pool.find( fd ); if ( i != worker_pool.end() ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; delete i->second.c; delete i->second.s; // std::cerr << "oops\n"; @@ -257,6 +261,10 @@ } if ( p.c != 0 ) { // (*p.c)( *p.s ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + + (p.c->*C)( *p.s ); + delete p.c; delete p.s; } @@ -265,6 +273,8 @@ template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::operator ()( sock_base::socket_type fd ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + processor p; { @@ -331,12 +341,28 @@ std::cerr << __FILE__ << ":" << __LINE__ << std::endl; } } + + { + std::tr2::lock_guard<std::tr2::mutex> lk( wklock ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << worker_pool.size() << std::endl; + } + + { + std::tr2::lock_guard<std::tr2::mutex> lk( rdlock ); + std::cerr << __FILE__ << ":" << __LINE__ << " " << ready_pool.size() << std::endl; + } } template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> void connect_processor<Connect, charT, traits, _Alloc, C>::stop() { + _stop(); +} + +template <class Connect, class charT, class traits, class _Alloc, void (Connect::*C)( std::basic_sockstream<charT,traits,_Alloc>& )> +void connect_processor<Connect, charT, traits, _Alloc, C>::_stop() +{ std::tr2::lock_guard<std::tr2::mutex> lk2( rdlock ); _in_work = false; // <--- set before cnd.notify_one(); (below in this func) @@ -344,6 +370,8 @@ ready_pool.push_back( processor() ); // make ready_pool not empty std::cerr << __FILE__ << ":" << __LINE__ << std::endl; cnd.notify_one(); + } else { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; } } Modified: branches/complement-sockios/explore/include/sockios/socksrv.h =================================================================== --- branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:46:17 UTC (rev 1917) +++ branches/complement-sockios/explore/include/sockios/socksrv.h 2008-06-26 05:46:44 UTC (rev 1918) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/19 20:14:01 yeti> +// -*- C++ -*- Time-stamp: <08/06/25 21:30:31 yeti> /* * Copyright (c) 2008 @@ -66,7 +66,7 @@ virtual ~sock_processor_base() { - sock_processor_base::close(); + sock_processor_base::_close(); // Never uncomment next line: // basic_socket<charT,traits,_Alloc>::mgr->final( *this ); @@ -85,7 +85,8 @@ void open( int port, sock_base::stype type, sock_base::protocol prot ) { sock_processor_base::open(INADDR_ANY, port, type, prot); } - virtual void close(); + virtual void close() + { _close(); } #if 0 virtual void stop() = 0; #else @@ -122,8 +123,10 @@ return s; } - void (sock_processor_base::*_real_stop)(); + void _close(); + // void (sock_processor_base::*_real_stop)(); + public: bool is_open() const { std::tr2::lock_guard<std::tr2::mutex> lk(_fd_lck); return basic_socket_t::is_open_unsafe(); } @@ -193,8 +196,10 @@ virtual ~connect_processor() { - connect_processor::close(); + connect_processor::_close(); + // _stop(); + if ( ploop.joinable() ) { ploop.join(); } @@ -235,7 +240,8 @@ ((Init *)Init_buf)->~Init(); } - virtual void close(); + virtual void close() + { connect_processor::_close(); } virtual void stop(); void wait() @@ -298,6 +304,8 @@ }; bool pop_ready( processor& ); + void _close(); + void _stop(); #ifdef __USE_STLPORT_HASH typedef std::hash_map<sock_base::socket_type, processor> worker_pool_t; Modified: branches/complement-sockios/explore/include/sockios/sockstream.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sockstream.cc 2008-06-26 05:46:17 UTC (rev 1917) +++ branches/complement-sockios/explore/include/sockios/sockstream.cc 2008-06-26 05:46:44 UTC (rev 1918) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/17 17:09:02 yeti> +// -*- C++ -*- Time-stamp: <08/06/25 18:48:36 yeti> /* * Copyright (c) 1997-1999, 2002, 2003, 2005-2008 @@ -272,10 +272,11 @@ setp( _bbuf, _bbuf + ((_ebuf - _bbuf)>>1) ); setg( this->epptr(), this->epptr(), this->epptr() ); - if ( basic_socket_t::_notify_close ) { - basic_socket_t::mgr->exit_notify( this, basic_socket_t::_fd ); - basic_socket_t::_notify_close = false; - } + // if ( basic_socket_t::_notify_close ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << basic_socket_t::_fd << std::endl; + basic_socket_t::mgr->exit_notify( this, basic_socket_t::_fd ); + // basic_socket_t::_notify_close = false; + // } basic_socket_t::_fd = -1; Modified: branches/complement-sockios/explore/include/sockios/sp.cc =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:46:17 UTC (rev 1917) +++ branches/complement-sockios/explore/include/sockios/sp.cc 2008-06-26 05:46:44 UTC (rev 1918) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/25 12:00:59 ptr> +// -*- C++ -*- Time-stamp: <08/06/25 22:25:48 yeti> /* * Copyright (c) 2008 @@ -45,19 +45,6 @@ for ( int i = 0; i < n; ++i ) { // std::cerr << "epoll i = " << i << std::endl; - std::tr2::lock_guard<std::tr2::mutex> lck( cll ); - for ( typename fd_container_type::iterator closed_ifd = closed_queue.begin(); closed_ifd != closed_queue.end(); ++closed_ifd ) { - if ( epoll_ctl( efd, EPOLL_CTL_DEL, closed_ifd->first, 0 ) < 0 ) { - // ignore - } - if ( closed_ifd->first == ev[i].data.fd ) { - std::cerr << __FILE__ << ":" << __LINE__ << std::endl; - } - // descr.erase( closed_ifd->first ); - } - closed_queue.clear(); - // at this point closed queue empty - if ( ev[i].data.fd == pipefd[0] ) { // std::cerr << "on pipe\n"; cmd_from_pipe(); @@ -66,6 +53,7 @@ typename fd_container_type::iterator ifd = descr.find( ev[i].data.fd ); if ( ifd == descr.end() ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << ev[i].data.fd << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ev[i].data.fd, 0 ) < 0 ) { // throw system_error } @@ -103,6 +91,7 @@ if ( r < 0 ) { // throw system_error // std::cerr << "Read pipe\n"; + throw std::detail::stop_request(); // runtime_error( "Stop request (normal flow)" ); } else if ( r == 0 ) { // std::cerr << "Read pipe 0\n"; throw runtime_error( "Read pipe return 0" ); @@ -117,22 +106,44 @@ // std::cerr << "xxx " << errno << " " << std::tr2::getpid() << std::endl; throw std::runtime_error( "can't establish nonblock mode on listener" ); } + if ( descr.find( ev_add.data.fd ) != descr.end() ) { // reuse? + if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev_add.data.fd, &ev_add ) < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + // descr.erase( ev_add.data.fd ); + // throw system_error + return; + } + } else { + std::cerr << __FILE__ << ":" << __LINE__ << " " << ev_add.data.fd << std::endl; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + // throw system_error + return; + } + } descr[ev_add.data.fd] = fd_info( static_cast<socks_processor_t*>(_ctl.data.ptr) ); - if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { - descr.erase( ev_add.data.fd ); - // throw system_error - } } break; case tcp_buffer: ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; ev_add.data.fd = static_cast<sockbuf_t*>(_ctl.data.ptr)->fd(); if ( ev_add.data.fd >= 0 ) { + if ( descr.find( ev_add.data.fd ) != descr.end() ) { // reuse? + if ( epoll_ctl( efd, EPOLL_CTL_MOD, ev_add.data.fd, &ev_add ) < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + // descr.erase( ev_add.data.fd ); + // throw system_error + return; + } + } else { + std::cerr << __FILE__ << ":" << __LINE__ << " " << ev_add.data.fd << std::endl; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + // throw system_error + return; + } + } descr[ev_add.data.fd] = fd_info( static_cast<sockbuf_t*>(_ctl.data.ptr) ); - if ( epoll_ctl( efd, EPOLL_CTL_ADD, ev_add.data.fd, &ev_add ) < 0 ) { - descr.erase( ev_add.data.fd ); - // throw system_error - } } break; case listener_on_exit: @@ -158,8 +169,10 @@ { std::cerr << __FILE__ << ":" << __LINE__ << std::endl; if ( ev.events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR) ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << ifd->first << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error + std::cerr << __FILE__ << ":" << __LINE__ << " " << ifd->first << " " << errno << std::endl; } if ( ifd->second.p != 0 ) { @@ -212,9 +225,10 @@ } if ( !(errno == EAGAIN /* || errno == EWOULDBLOCK */ ) ) { // EWOULDBLOCK == EAGAIN // std::cerr << "Accept, listener " << ev.data.fd << ", errno " << errno << std::endl; - std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << " " << ifd->first << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { - std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << " " << ifd->first << " " + << errno << std::endl; // throw system_error } @@ -260,11 +274,21 @@ ev_add.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT; ev_add.data.fd = fd; - if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { - descr.erase( fd ); - // throw system_error + if ( descr.find( fd ) != descr.end() ) { // reuse? std::cerr << __FILE__ << ":" << __LINE__ << std::endl; - return; // throw + if ( epoll_ctl( efd, EPOLL_CTL_MOD, fd, &ev_add ) < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << errno << std::endl; + descr.erase( fd ); + // throw system_error + return; // throw + } + } else { + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + if ( epoll_ctl( efd, EPOLL_CTL_ADD, fd, &ev_add ) < 0 ) { + // throw system_error + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + return; // throw + } } std::cerr << __FILE__ << ":" << __LINE__ << std::endl; @@ -292,6 +316,7 @@ sockbuf_t* b = info.b; if ( b == 0 ) { // marginal case: sockbuf wasn't created by processor... + std::cerr << __FILE__ << ":" << __LINE__ << " " << ifd->first << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error } @@ -399,7 +424,7 @@ if ( (ev.events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR) ) != 0 ) { // std::cerr << "Poll EPOLLRDHUP " << ev.data.fd << ", " << errno << std::endl; - std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + std::cerr << __FILE__ << ":" << __LINE__ << " " << ifd->first << std::endl; if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { // throw system_error std::cerr << __FILE__ << ":" << __LINE__ << std::endl; @@ -412,7 +437,6 @@ socks_processor_t* p = info.p; - closed_queue.erase( ev.data.fd ); descr.erase( ifd ); int lfd = check_closed_listener( p ); @@ -420,10 +444,13 @@ descr.erase( lfd ); } } else { - std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + b->_notify_close = false; // avoid deadlock + std::cerr << __FILE__ << ":" << __LINE__ << " " << ifd->first << std::endl; + if ( epoll_ctl( efd, EPOLL_CTL_DEL, ifd->first, 0 ) < 0 ) { + // throw system_error + } + descr.erase( ifd ); b->close(); - closed_queue.erase( ev.data.fd ); - descr.erase( ifd ); } dump_descr(); } @@ -452,6 +479,7 @@ { int myfd = -1; + std::cerr << __FILE__ << ":" << __LINE__ << std::endl; if ( !listeners_final.empty() ) { std::cerr << __FILE__ << ":" << __LINE__ << std::endl; if ( listeners_final.find( static_cast<void*>(p) ) != listeners_final.end() ) { @@ -472,7 +500,10 @@ std::cerr << __FILE__ << ":" << __LINE__ << std::endl; - p->stop(); + // if ( myfd != -1 ) { + // std::cerr << __FILE__ << ":" << __LINE__ << std::endl; + p->stop(); + // } } } Modified: branches/complement-sockios/explore/include/sockios/sp.h =================================================================== --- branches/complement-sockios/explore/include/sockios/sp.h 2008-06-26 05:46:17 UTC (rev 1917) +++ branches/complement-sockios/explore/include/sockios/sp.h 2008-06-26 05:46:44 UTC (rev 1918) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/25 11:54:39 ptr> +// -*- C++ -*- Time-stamp: <08/06/25 22:10:36 yeti> /* * Copyright (c) 2008 @@ -225,17 +225,36 @@ if ( r < 0 || r != sizeof(ctl) ) { throw std::runtime_error( "can't write to pipe" ); } - -// fd_info info = { fd_info::listener, 0, &p }; -// std::tr2::lock_guard<std::tr2::mutex> lk( cll ); -// closed_queue[_fd] = info; } void exit_notify( sockbuf_t* b, sock_base::socket_type fd ) { // fd_info info = { 0, 0, 0 }; - std::tr2::lock_guard<std::tr2::mutex> lk( cll ); - closed_queue[fd] = fd_info(); + // std::tr2::lock_guard<std::tr2::mutex> lk( dll ); + + try { + std::tr2::unique_lock<std::tr2::mutex> lk( dll, std::tr2::try_to_lock ); + + if ( b->_notify_close ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + typename fd_container_type::iterator i = descr.find( fd ); + if ( i != descr.end() ) { + if ( (i->second.b == b) && (i->second.p == 0) ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + if ( epoll_ctl( efd, EPOLL_CTL_DEL, fd, 0 ) < 0 ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + // throw system_error + } + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + descr.erase( i ); + } + } + b->_notify_close = false; + } + } + catch ( const std::tr2::lock_error& ) { + std::cerr << __FILE__ << ":" << __LINE__ << " " << fd << std::endl; + } } private: @@ -271,9 +290,7 @@ const int n_ret; fd_container_type descr; - fd_container_type closed_queue; listener_container_type listeners_final; - std::tr2::mutex cll; std::tr2::mutex dll; }; Modified: branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc =================================================================== --- branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:46:17 UTC (rev 1917) +++ branches/complement-sockios/explore/lib/sockios/ut/sockios2_test.cc 2008-06-26 05:46:44 UTC (rev 1918) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/17 16:35:39 yeti> +// -*- C++ -*- Time-stamp: <08/06/25 17:59:36 yeti> /* * @@ -266,7 +266,14 @@ { lock_guard<mutex> lk(lock); --cnt; } void connect( sockstream& s ) - { lock_guard<mutex> lk(lock); getline( s, line ); ++rd; line_cnd.notify_one(); } + { + lock_guard<mutex> lk(lock); + getline( s, line ); + cerr << __FILE__ << ":" << __LINE__ << " " << s.good() << " " + << s.rdbuf()->in_avail() << endl; + ++rd; + line_cnd.notify_one(); + } // void close() // { } @@ -294,7 +301,7 @@ mutex worker::lock; int worker::cnt = 0; -/* volatile */ int worker::visits = 0; +int worker::visits = 0; condition_variable worker::cnd; string worker::line; condition_variable worker::line_cnd; @@ -413,7 +420,7 @@ } unique_lock<mutex> lk( worker::lock ); - EXAM_CHECK( worker::line_cnd.timed_wait( lk, milliseconds( 500 ), worker::rd_counter1 ) ); + EXAM_CHECK( worker::line_cnd.timed_wait( lk, milliseconds( 50000 ), worker::rd_counter1 ) ); // cerr << worker::line << endl; EXAM_CHECK( worker::line == "Hello, world!" ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |