Thread: [complement-svn] SF.net SVN: complement: [1293] trunk/explore
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2006-10-05 06:49:48
|
Revision: 1293 http://svn.sourceforge.net/complement/?rev=1293&view=rev Author: complement Date: 2006-10-04 23:49:32 -0700 (Wed, 04 Oct 2006) Log Message: ----------- recover from working copy after disk crash---master CVS was lost or corrupted Added Paths: ----------- trunk/explore/include/misc/dir_utils.h trunk/explore/include/misc/node.h trunk/explore/lib/misc/args.cc trunk/explore/lib/sockios/ChangeLog trunk/explore/lib/sockios/Makefile.inc Added: trunk/explore/include/misc/dir_utils.h =================================================================== --- trunk/explore/include/misc/dir_utils.h (rev 0) +++ trunk/explore/include/misc/dir_utils.h 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,43 @@ +// -*- C++ -*- Time-stamp: <01/03/19 16:32:47 ptr> + +/* + * + * Copyright (c) 1997 + * Petr Ovchenkov + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + */ + +#ifndef __dir_utils_h + +#ifdef __unix +# ifdef __HP_aCC +#pragma VERSIONID "$SunId$" +# else +#pragma ident "$SunId$" +# endif +#endif + +#ifndef __config_feature_h +#include <config/feature.h> +#endif + +#include <string> + +#ifndef _UNISTD_H +#include <unistd.h> +#endif + +std::string mkunique_dir( const std::string& base, const std::string& prefix ); + +inline void rm_dir( const std::string& d ) { ::rmdir( d.c_str() ); } +void rm_dir_all( const std::string& d ); + +#endif // __dir_utils_h Added: trunk/explore/include/misc/node.h =================================================================== --- trunk/explore/include/misc/node.h (rev 0) +++ trunk/explore/include/misc/node.h 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,621 @@ +// -*- C++ -*- Time-stamp: <03/11/16 21:49:19 ptr> + +/* + * Copyright (c) 1999 + * Petr Ovchenkov + * + * Copyright (c) 1999-2001 + * ParallelGraphics Ltd. + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + */ + +#ifndef __node_h +#define __node_h + +#ifdef __unix +# ifdef __HP_aCC +#pragma VERSIONID "@(#)$Id: node.h,v 1.20 2005/03/31 10:22:26 ptr Exp $" +# else +#pragma ident "@(#)$Id: node.h,v 1.20 2005/03/31 10:22:26 ptr Exp $" +# endif +#endif + +#ifndef __config_feature_h +#include <config/feature.h> +#endif + +#include <list> +#include <string> +#include <map> + +#ifndef __XMT_H +#include <mt/xmt.h> +#endif + +#include <iostream> +#include <stdexcept> + +namespace Helios { + +class __node_base +{ + public: + typedef unsigned key_type; + typedef std::list<unsigned> grp_container_type; + + enum { + u_mask = 00700, + g_mask = 00070, + o_mask = 00007, + c_bit = 01000, // catalog bit + r_mask = 00444, + w_mask = 00222, + x_mask = 00111, + rw_mask = 00666 + }; + + __node_base() : + prot( 0 ), + refcount( 0 ), + uid( static_cast<unsigned>(-1) ), + gid( static_cast<unsigned>(-1) ) + { } + + __node_base( unsigned _uid, unsigned _gid, unsigned _prot ) : + prot( _prot ), + refcount( 0 ), + uid( _uid ), + gid( _gid ) + { } + + unsigned addref() + { return (unsigned)(++refcount); } + unsigned rmref() + { return (unsigned)(--refcount); } + void protection( unsigned _prot ) + { + prot &= ~0777; + prot |= _prot & 0777; + } + unsigned protection() const + { return (unsigned)( prot & 0777 ); } + bool is_catalog() const + { return (prot & c_bit) != 0; } + + bool can_read( unsigned __u, unsigned __g ) const + { return _can( __u, __g, r_mask ); } + bool can_write( unsigned __u, unsigned __g ) const + { return _can( __u, __g, w_mask ); } + bool can_exec( unsigned __u, unsigned __g ) const + { return _can( __u, __g, x_mask ); } + + bool can_read( unsigned __u, unsigned __g, + grp_container_type::const_iterator __first, + grp_container_type::const_iterator __last ) const + { return _can( __u, __g, r_mask, __first, __last ); } + bool can_write( unsigned __u, unsigned __g, + grp_container_type::const_iterator __first, + grp_container_type::const_iterator __last ) const + { return _can( __u, __g, w_mask, __first, __last ); } + bool can_exec( unsigned __u, unsigned __g, + grp_container_type::const_iterator __first, + grp_container_type::const_iterator __last ) const + { return _can( __u, __g, x_mask, __first, __last ); } + + unsigned short prot; + unsigned short refcount; + unsigned uid; + unsigned gid; + + private: + bool _can( unsigned __u, unsigned __g, unsigned mask ) const + { return (prot & ( __u == uid ? u_mask : __g == gid ? g_mask : o_mask) & mask) != 0; } + bool _can( unsigned __u, unsigned __g, unsigned mask, + grp_container_type::const_iterator __first, + grp_container_type::const_iterator __last ) const + { + if ( (prot & ( __u == uid ? u_mask : __g == gid ? g_mask : o_mask) & mask) != 0 ) + return true; + + if ( (prot & g_mask & mask) != 0 ) { // any group permissions + while ( __first != __last ) { + if ( gid == *__first++ ) { // user is group member + return true; + } + } + } + return false; + } +}; + +class __node_base_catalog : + public __node_base +{ + public: + typedef std::pair<key_type,std::string> catalog_entry; +// typedef __STD::list<catalog_entry, __STL_DEFAULT_ALLOCATOR(catalog_entry) > catalog_type; + typedef std::list<catalog_entry > catalog_type; + typedef catalog_type::iterator iterator; + typedef catalog_type::const_iterator const_iterator; + + __node_base_catalog() : + __node_base() + { prot |= c_bit; } + + __node_base_catalog( unsigned _uid, unsigned _gid, unsigned _prot ) : + __node_base( _uid, _gid, _prot ) + { prot |= c_bit; } + + iterator begin() + { return catalog.begin(); } + iterator end() + { return catalog.end(); } + const_iterator begin() const + { return catalog.begin(); } + const_iterator end() const + { return catalog.end(); } + + iterator erase( iterator __x ) + { return catalog.erase( __x ); } + iterator erase( key_type __k ) + { + iterator i = entry( __k ); + if ( i != catalog.end() ) { + return catalog.erase( i ); + } + return i; + } + void push( key_type inode, const std::string& name ) + { catalog.push_back(catalog_entry(inode,name)); } + iterator insert( iterator i, key_type inode, const std::string& name ) + { return catalog.insert( i, catalog_entry(inode,name)); } + key_type inode( const std::string& name ) + { + iterator i = entry( name ); + return i != catalog.end() ? (*i).first : static_cast<key_type>(-1); + } + iterator entry( const std::string& name ) + { + iterator i = catalog.begin(); + while ( i != catalog.end() && (*i).second != name ) { + ++i; + } + return i; + } + iterator entry( key_type k ) + { + iterator i = catalog.begin(); + while ( i != catalog.end() && (*i).first != k ) { + ++i; + } + return i; + } + + catalog_type::size_type size() const + { return catalog.size(); } + + protected: + catalog_type catalog; +}; + +template <class T> +class __node_base_t : + public __node_base +{ + public: + typedef T value_type; + typedef value_type& reference; + + __node_base_t() : + __node_base() + { } + + __node_base_t( unsigned _uid, unsigned _gid, unsigned _prot ) : + __node_base( _uid, _gid, _prot ) + { } + + reference value() + { return data; } + + T data; +}; + +typedef __node_base_t<std::string> node_string; +typedef __node_base_t<void *> node_void_ptr; + +class __nodes_heap_base +{ + public: + typedef __node_base::key_type key_type; + + __nodes_heap_base() : + _low( 0 ), + _high( 0x7fffffff ), + _id( _low ) + { } + + __nodes_heap_base( key_type __low, key_type __high ) : + _low( __low ), + _high( __high ), + _id( _low ) + { } + + bool is_avail( key_type __id ) const + { return heap.find( __id ) != heap.end(); } + + protected: +// typedef __STD::map<key_type,void *,__STD::less<key_type>, +// __STL_DEFAULT_ALLOCATOR(void *) > heap_type; + + typedef std::map<key_type,void *,std::less<key_type> > heap_type; + void *& value( key_type __id ) + { + // _STLP_ASSERT( heap.find( __id ) != heap.end() ); + return heap[__id]; + } + key_type create_unique(); + const __impl::MutexSDS& oplock() const + { return _op_lock; } + + const key_type _low; + const key_type _high; + + key_type _id; + heap_type heap; + __impl::Mutex _lock; + __impl::MutexSDS _op_lock; + static const std::string dot; + static const std::string dotdot; +}; + +template <class Node> class nodes_heap_cursor; + +template <class Node> +class nodes_heap : + public __nodes_heap_base +{ + public: + typedef typename Node::reference reference; + typedef __node_base_catalog Catalog; + typedef nodes_heap_cursor<Node> cursor_type; + + nodes_heap() : + __nodes_heap_base() + { create_root( 0755 ); } + + nodes_heap( unsigned prot ) : + __nodes_heap_base() + { create_root( prot ); } + + nodes_heap( key_type __low, key_type __high, unsigned prot = 0755 ) : + __nodes_heap_base( __low, __high ) + { create_root( prot ); } + + heap_type::size_type size() + { return heap.size(); } + + reference operator[]( key_type __id ) + { + // __node_base *tmp = reinterpret_cast<__node_base *> + // if this is catalog, result undefined + return reinterpret_cast<Node *>(heap[__id])->value(); + } + + cursor_type cursor( unsigned uid, unsigned gid, unsigned prot_mask = 0 ) + { return cursor_type( this, uid, gid, prot_mask ); } + + key_type create_node( unsigned uid, unsigned gid, unsigned prot ); + key_type create_catalog( unsigned uid, unsigned gid, unsigned prot ); + void destroy( key_type __id ); + + private: + key_type create_root( unsigned ); + + friend class nodes_heap_cursor<Node>; +}; + +class entry_error : +// #ifdef __GNUC__ +// public __STD_QUALIFIER runtime_error +// #else + public std::runtime_error +// #endif +{ + public: + entry_error(const std::string& __arg) : runtime_error(__arg) {} +}; + + +template <class Node> +class nodes_heap_cursor +{ + public: + typedef Helios::__node_base::key_type key_type; + typedef __node_base_catalog Catalog; + typedef Catalog::iterator iterator; + typedef Catalog::const_iterator const_iterator; + typedef typename Node::value_type value_type; + typedef typename Node::reference reference; + + nodes_heap_cursor() : + _heap( 0 ), + catalog( 0 ), + _uid( -1 ), + _gid( -1 ), + _defprot( 0 ) + { } + nodes_heap_cursor( const nodes_heap_cursor<Node>& cursor ) : + _heap( cursor._heap ), + _uid( cursor._uid ), + _gid( cursor._gid ), + _defprot( cursor._defprot ), + _grp( cursor._grp ) + { + catalog = cursor.catalog; + catalog->addref(); // that's locking indeed + } + ~nodes_heap_cursor() + { + if ( catalog != 0 ) catalog->rmref(); + } + + void close() + { + _grp.clear(); + if ( catalog != 0 ) { + catalog->rmref(); + catalog = 0; + } + } + + const __impl::MutexSDS& oplocker() + { + if ( _heap == 0 ) { + throw std::domain_error( "nodes_heap_cursor" ); + } + return _heap->oplock(); + } + + bool operator ==( const nodes_heap_cursor<Node>& cursor ) + { return _heap == cursor._heap && catalog == cursor.catalog; } + bool operator !=( const nodes_heap_cursor<Node>& cursor ) + { return _heap != cursor._heap || catalog != cursor.catalog; } + + void cr_uid( unsigned __uid ) + { _uid = __uid; } + void cr_gid( unsigned __gid ) + { _gid = __gid; } + void cr_own( unsigned __uid, unsigned __gid ) + { _uid = __uid; _gid = __gid; } + void add_grp( unsigned __gid ) + { _grp.push_back( __gid ); } + + iterator begin() + { return catalog->begin(); } + iterator end() + { return catalog->end(); } + const_iterator begin() const + { return catalog->begin(); } + const_iterator end() const + { return catalog->end(); } + + bool is_catalog( const_iterator i ) const + { + // __stl_assert( i != catalog->end() ); + //_STLP_ASSERT( (*i).first != -1 ); + //_STLP_ASSERT( _heap->value((*i).first) != 0 ); + return reinterpret_cast<__node_base *>(_heap->value((*i).first))->is_catalog(); + } + unsigned uid() const + { return _uid; } + unsigned gid() const + { return _gid; } + unsigned uid( const_iterator i ) const + { return reinterpret_cast<__node_base *>(_heap->value((*i).first))->uid; } + unsigned gid( const_iterator i ) const + { return reinterpret_cast<__node_base *>(_heap->value((*i).first))->gid; } + unsigned uid( key_type k ) const + { return uid( catalog->entry( k ) ); } + unsigned gid( key_type k ) const + { return gid( catalog->entry( k ) ); } + unsigned uid( const std::string& name ) const + { return uid( catalog->entry( name ) ); } + unsigned gid( const std::string& name ) const + { return gid( catalog->entry( name ) ); } + void uid( iterator i, unsigned __uid ) + { + if ( _uid == 0 || _gid == 0 ) { + reinterpret_cast<__node_base *>(_heap->value((*i).first))->uid = __uid; + } + } + void gid( iterator i, unsigned __gid ) + { + if ( _uid == 0 || _gid == 0 ) { + reinterpret_cast<__node_base *>(_heap->value((*i).first))->gid = __gid; + } else if ( reinterpret_cast<__node_base *>(_heap->value((*i).first))->uid == _uid ) { +#ifndef __GNUC__ +#if !defined(__HP_aCC) || (__HP_aCC > 1) + typename __node_base::grp_container_type::iterator g = _grp.begin(); +#else + __node_base::grp_container_type::iterator g = _grp.begin(); +#endif +#else +// typename Helios::__node_base::grp_container_type::iterator g = _grp.begin(); + typename std::list<unsigned>::iterator g = _grp.begin(); +#endif + while ( g != _grp.end() ) { + if ( __gid == *g++ ) { + reinterpret_cast<__node_base *>(_heap->value((*i).first))->gid = __gid; + break; + } + } + } + } + void uid( key_type k, unsigned __uid ) + { uid( catalog->entry( k ), __uid ); } + void gid( key_type k, unsigned __gid ) + { gid( catalog->entry( k ), __gid ); } + void uid( const std::string& name, unsigned __uid ) + { uid( catalog->entry( name ), __uid ); } + void gid( const std::string& name, unsigned __gid ) + { gid( catalog->entry( name ), __gid ); } + bool can_read() const + { + return reinterpret_cast<__node_base *>(_heap->value(dot()))->can_read( _uid, _gid, _grp.begin(), _grp.end() ); + } + bool can_write() const + { + return reinterpret_cast<__node_base *>(_heap->value(dot()))->can_write( _uid, _gid, _grp.begin(), _grp.end() ); + } + bool can_exec() const + { + return reinterpret_cast<__node_base *>(_heap->value(dot()))->can_exec( _uid, _gid, _grp.begin(), _grp.end() ); + } + reference operator [] ( iterator i ) + { + if ( is_catalog(i) ) throw entry_error( "catalog" ); + return reinterpret_cast<Node *>(_heap->value((*i).first))->value(); + } + reference operator [] ( const std::string& name ) + { + iterator i = catalog->entry( name ); + if ( i == catalog->end() ) throw entry_error( "no entry" ); + if ( is_catalog(i) ) throw entry_error( "catalog" ); + return reinterpret_cast<Node *>(_heap->value((*i).first))->value(); + } + iterator entry( const std::string& name ) + { return catalog->entry( name ); } + iterator entry( key_type k ) + { return catalog->entry( k ); } + // key_type inode( const std::string& name ) + // { return catalog->inode( name ); } + + iterator create( const std::string& name, unsigned prot ) + { + if ( can_write() ) { + catalog->push( _heap->create_node( _uid, _gid, prot ), name ); + return --catalog->end(); + } + return catalog->end(); + } + iterator create( const std::string& name ) + { return create( name, _defprot ); } + iterator insert( iterator i, const std::string& name, unsigned prot ) + { + if ( can_write() ) { + return catalog->insert( i, _heap->create_node( _uid, _gid, prot ), name ); + } + return catalog->end(); + } + iterator insert( iterator i, const std::string& name ) + { return insert( i, name, _defprot ); } + + // if default protection has read bit, for catalog should be set exec bit + iterator create_catalog( const std::string& name ) + { return create_catalog( name, _defprot | + ((_defprot & __node_base::r_mask) >> 2 ) ); } + iterator create_catalog( const std::string& name, unsigned prot ); + iterator insert_catalog( iterator i, const std::string& name ) + { return insert_catalog( i, name, _defprot | + ((_defprot & __node_base::r_mask) >> 2 ) ); } + iterator insert_catalog( iterator i, const std::string& name, unsigned prot ); + + void erase( const std::string& name ) + { erase( catalog->entry( name ) ); } + void erase( iterator i ); + void erase( key_type k ) + { erase( catalog->entry( k ) ); } + + void cd( key_type k ); + void cd( iterator i ); + void cd( const std::string& name ) + { cd( catalog->entry(name) ); } + void cd_dotdot() + { cd( ++begin() ); } + + iterator mv( iterator i, nodes_heap_cursor<Node>& cursor ); + iterator mv( iterator i, nodes_heap_cursor<Node>& cursor, const std::string& name ); + iterator mv( key_type k, nodes_heap_cursor<Node>& cursor ); + iterator mv( key_type k, nodes_heap_cursor<Node>& cursor, iterator i ); + iterator ln( iterator i ); + iterator ln( key_type k, nodes_heap_cursor<Node>& cursor ); + + unsigned protection( iterator i ) + { return reinterpret_cast<__node_base *>(_heap->value((*i).first))->protection(); } + unsigned protection( key_type k ) + { return protection( catalog->entry( k ) ); } + unsigned protection( const std::string& name ) + { return protection( catalog->entry( name ) ); } + void protection( iterator i, unsigned p ) + { + if ( reinterpret_cast<__node_base *>(_heap->value((*i).first))->uid == _uid || _uid == 0 ) { + reinterpret_cast<__node_base *>(_heap->value((*i).first))->protection( p ); + } + } + void protection( key_type k, unsigned p ) + { protection( catalog->entry( k ), p ); } + void protection( const std::string& name, unsigned p ) + { protection( catalog->entry( name ), p ); } + + key_type dot() const + { return (*catalog->begin()).first; } + key_type dotdot() const + { return (*++catalog->begin()).first; } + + protected: + // prot_mask here is mask for clear protection bits from 0666 + // I never set default exec bit. It's set for catalogs if default + // protection has read bit (see above, create_catalog) + + nodes_heap_cursor( nodes_heap<Node>& __heap, unsigned uid, unsigned gid, unsigned prot_mask ) : + _heap( &__heap ), + _uid( uid ), + _gid( gid ), + _defprot( ~prot_mask & __node_base::rw_mask ) // clear exec bits + { + catalog = reinterpret_cast<Catalog *>(_heap->value(0)); + catalog->addref(); + } + nodes_heap_cursor( nodes_heap<Node> *__heap, unsigned uid, unsigned gid, unsigned prot_mask ) : + _heap( __heap ), + _uid( uid ), + _gid( gid ), + _defprot( ~prot_mask & __node_base::rw_mask ) // clear exec bits + { + catalog = reinterpret_cast<Catalog *>(_heap->value(0)); + catalog->addref(); + } + + bool erase_catalog( __node_base& node ); + + Catalog *catalog; + nodes_heap<Node> *_heap; + unsigned _uid; + unsigned _gid; + unsigned _defprot; +#if defined(__HP_aCC) && (__HP_aCC == 1) + __node_base::grp_container_type _grp; +#else + typename __node_base::grp_container_type _grp; +#endif + + friend class nodes_heap<Node>; +}; + +typedef nodes_heap<node_string> stringtree; + +} // namespace Helios + +#ifndef __STL_LINK_TIME_INSTANTIATION +# include <misc/node.cc> +#endif + +#endif // __node.h Added: trunk/explore/lib/misc/args.cc =================================================================== --- trunk/explore/lib/misc/args.cc (rev 0) +++ trunk/explore/lib/misc/args.cc 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,372 @@ +// -*- C++ -*- Time-stamp: <04/05/21 17:47:51 ptr> + +/* + * + * Copyright (c) 1997-1998, 2001, 2006 + * Petr Ovtchenkov + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + */ + +#include <config/feature.h> +#include <ostream> +#include <iomanip> +#include <sstream> +#include <string> +#include <functional> +#include "misc/args.h" + +using namespace std; + +ArgsParser::ArgsParser( int argc, char * const *argv ) +{ + int i = 1; + + while ( i < argc ) { + arg.push_back( argv[i] ); + ++i; + } +} + +ArgsParser::ArgsParser( const string& in ) +{ + stringstream s( in ); + string tmp; + + while ( s.good() ) { + s >> tmp; + if ( tmp.length() != 0 && tmp[0] == '"' ) { +// s.unsetf( ios_base::skipws ); + getline( s, tmp, '"' ); + } + arg.push_back( tmp ); + } +} + +ArgsParser::ArgsParser( istream& in ) +{ + string tmp; + + while ( in.good() ) { + in >> tmp; + if ( tmp.length() != 0 && tmp[0] == '"' ) { +// s.unsetf( ios_base::skipws ); + getline( in, tmp, '"' ); + } + arg.push_back( tmp ); + } +} + +ArgsParser::ArgsParser() +{ +} + +void ArgsParser::parse( int argc, char * const *argv ) +{ + _pname = argv[0]; + + int i = 1; + + while ( i < argc ) { + arg.push_back( argv[i] ); + ++i; + } +} + +void ArgsParser::copyright( const char *s ) +{ + _copyright = s; +} + +void ArgsParser::brief( const char *s ) +{ + _announce = s; +} + +void ArgsParser::print_help( ostream& s ) +{ + s << "This is " << _pname << ", " << _announce << "\n" + << _copyright << "\n\n" + << "Usage: \n"; +} + +string ArgsParser::get_next( const string& op ) +{ + container_type::iterator i = find( arg.begin(), arg.end(), op ); + + if ( i != arg.end() ) { + ++i; + if ( i != arg.end() ) { + return *i; + } + } + + return ""; +} + +string ArgsParser::get( int n ) +{ + iterator i; + if ( n >= 0 ) { + i = arg.begin(); + int j = 0; + + while ( i != arg.end() && j < n ) { + ++i; + ++j; + } + } else { + i = --arg.end(); + int j = -1; + + while ( i != arg.end() && j > n ) { + --i; + --j; + } + } + + return i != arg.end() ? (*i) : string(""); +} + +bool ArgsParser::is_option_X( const string& op ) +{ + container_type::iterator i = arg.begin(); + while ( i != arg.end() ) { + if ( (*i).length() > 0 && (*i)[0] == '-' && + (*i).find( op ) != string::npos ) { + return true; + } + ++i; + } + return false; +} + +Option<std::string>::Option( const char *n, const std::string& v, const char *h ) +{ + _nm = n; + _v = v; + if ( h != 0 ) { + _hlp = h; + } +} + +Option<char *>::Option( const char *n, const char *v, const char *h ) +{ + _nm = n; + _v = v; + if ( h != 0 ) { + _hlp = h; + } +} + +void Argv::parse( int argc, char * const *argv ) +{ + _pname = argv[0]; + + int i = 1; + opt_container_type::iterator a; + string argvI; + string argvII; + string::size_type p; + + while ( i < argc ) { + if ( _stop_opt == argv[i] || (strlen( argv[i] ) > 0 && argv[i][0] != '-') ) { + // ++i; + break; + } + + argvI = argv[i]; + + if ( (p = argvI.find( '=' ) ) != string::npos ) { + argvII = argvI.substr( p + 1 ); + argvI.erase( p ); + } else { + argvII.clear(); + } + + // find '=' in argvI + // strip after '=' + // after '=' is a value; search in options the string before '=' + a = std::find_if( opt.begin(), opt.end(), bind2nd( eqs, /* argv[i] */ argvI ) ); + if ( a == opt.end() ) { + string err( "unknown option: " ); + err += argv[i]; + throw std::invalid_argument( err ); + } + if ( (*a)->type() != typeid(bool) ) { +// if ( ++i < argc ) { + (*a)->read( argvII ); + (*a)->is_set = true; +// } else { +// string err( "option " ); +// err += argv[i-1]; +// err += " require value"; +// throw std::invalid_argument( err ); +// } + } else { + (*a)->read( "1" ); + (*a)->is_set = true; + } + ++i; + } + while ( i < argc ) { + arg.push_back( argv[i] ); + ++i; + } +} + +const std::string& Argv::operator[]( int i ) const +{ + if ( i < 0 || i >= arg.size() ) { + throw std::range_error( "out of range" ); + } + return arg[i]; +} + +void Argv::stop_option( const char *s ) +{ + _stop_opt = s; +} + +void Argv::copyright( const char *s ) +{ + _copyright = s; +} + +void Argv::brief( const char *s ) +{ + _announce = s; +} + +void Argv::args( const char *s ) +{ + _args = s; +} + +void Argv::print_help( ostream& s ) +{ + s << "This is " << _pname << ", " << _announce << "\n\n" + << _copyright << "\n\n" + << "Usage:\n" << " " << _pname << "\n\n" + << "Options:\n"; + string tmp; + for ( opt_container_type::iterator i = opt.begin(); i != opt.end(); ++i ) { + tmp = (*i)->_nm; + if ( (*i)->type() == typeid(std::string) ) { + tmp += "=<string>"; + } else if ( (*i)->type() == typeid(int) ) { + tmp += "=<int>"; + } else if ( (*i)->type() == typeid(unsigned) ) { + tmp += "=<uint>"; + } + s << " " << setw(24) << setfill( ' ' ) << setiosflags( ios_base::left ) + << tmp << (*i)->_hlp << "\n"; + } + s << "\n"; +} + +bool Argv::is( const char *nm ) const +{ + return (*find( nm ))->is_set; +} + +Argv::opt_container_type::iterator Argv::find( const char *nm ) +{ + opt_container_type::iterator i = std::find_if( opt.begin(), opt.end(), bind2nd( eq, nm ) ); + if ( i == opt.end() ) { + std::string err( "unknown option " ); + err += nm; + throw std::invalid_argument( err ); + } + return i; +} + +Argv::opt_container_type::const_iterator Argv::find( const char *nm ) const +{ + opt_container_type::const_iterator i = std::find_if( opt.begin(), opt.end(), bind2nd( eq, nm ) ); + if ( i == opt.end() ) { + std::string err( "unknown option " ); + err += nm; + throw std::invalid_argument( err ); + } + return i; +} + +IniParser::IniParser( istream& cfg ) +{ + string tmp; + string::size_type p; + + while ( cfg.good() ) { + tmp.clear(); + getline( cfg, tmp ); + p = tmp.find( '#' ); + if ( p != string::npos ) { + tmp.erase( p ); + } + if ( tmp.length() > 0 ) { + p = tmp.find( ':' ); + if ( p != string::npos ) { + string name = tmp.substr( 0, p ); + ++p; + string value = tmp.substr( p, tmp.size() - p ); + + p = name.find_first_not_of( " \t" ); + if ( p != string::npos ) { + if ( p > 0 ) { + name.erase( 0, p ); + } + p = name.find_last_not_of( " \t" ); + if ( p != string::npos ) { + ++p; + name.erase( p, name.length() - p ); + } + p = value.find_first_not_of( " \t" ); + if ( p != string::npos ) { + if ( p > 0 ) { + value.erase( 0, p ); + } + p = value.find_last_not_of( " \t" ); + if ( p != string::npos ) { + ++p; + value.erase( p, value.length() - p ); + } + pars.push_back( par( name, value ) ); + } + } + } + } + } +} + +string IniParser::value( const string& key, const string& def ) +{ + container_type::iterator i = find( pars.begin(), pars.end(), par( key, "" ) ); + + return i != pars.end()? (*i).value : def; +} + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500) + +// #pragma weak __1cDstdMbasic_string4Ccn0ALchar_traits4Cc__n0AJallocator4Cc___Rfind_first_not_of6kMpkcII_I_ +// #pragma weak unsigned std::string::find_first_not_of( const char *, unsigned, unsigned ) + +// void __Bug1() +// { +// const char *_ch = 0; +// std::basic_string<char,std::char_traits<char>,std::allocator<char> > _str; +// _str.find( _ch, 0, 0 ); +// _str.find_first_not_of( (const char *)0, 0U, 0U ); +// } +// unsigned _xxx = _str.find_first_not_of( (const char *)0, 0U, 0U ); + +// #pragma weak __Bug1 + +#endif Added: trunk/explore/lib/sockios/ChangeLog =================================================================== --- trunk/explore/lib/sockios/ChangeLog (rev 0) +++ trunk/explore/lib/sockios/ChangeLog 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,456 @@ +2006-09-25 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: introduce configuration parameters + for connection processing---limit of threads, time interval + to detect 'busy' thread, time interval to observe processing + threads, time interval to detect 'idle' thread + [ready for termination]. Implemented concurrent + connections processing by minimal number of threads with + guarantee that blocking in processing of some connections + don't lead to stop other connections processing [but + within number of limit of processsing threads; the marginal + case may be one thread per connect; adjust number + of processing threads, if needed]. If number of + processing threads unlimited [i.e. too big], too many + threads created under heavy load, and resources + used ineffective. + +2006-09-22 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: use concurrent threads pool; + special thread [observer] control threads creation; + connection processing thread can detect that no more + work and go away. + +2006-09-21 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: revision of sockmgr_stream_MP; + pass ready for read sockets to processing thread via + FIFO queue; don't listen sockets that in the processing; + avoid situation when same connection processed in + the different threads in the same time. + Note, that udp processing is broken now. + + * libsockios: Version 1.9.0 + +2006-09-20 Petr Ovtchenkov <pt...@is...> + + * libsockios: Version 1.8.1 + +2006-09-18 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: use vector as container for pollfd structures, + instead of raw array; move processed socket to the end of pollfd sequence, + to avoid usurp processing by older connections. + +2006-08-21 Petr Ovtchenkov <pt...@is...> + + * sockmgr.cc: the same as 2006-08-18 for poll/select on server side. + +2006-08-18 Petr Ovtchenkov <pt...@is...> + + * sockstream.cc: poll and select can be interrupted by signal not associated + with data on socket [SIGCHLD, for example]; in this case ones return some + negative value and set errno to EINTR; following read return 0 too---just + like end of connection; I check errno for EINTR, clear it and return + to listen on poll/select in this case. + +2006-08-04 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: changes in thread entry function. + +2006-07-11 Petr Ovtchenkov <pt...@is...> + + * socksream, sockstream.cc: add constructor from in_addr + for basic_sockbuf and sockstreams; generate list of + network interfaces in user-defined container. + +2006-06-28 Petr Ovtchenkov <pt...@is...> + + * socksream: use Mutex wrapper from xmt instead + of STLport; consider compilation with libstdc++; + + * _sockstream.cc: ditto + + * _sockmgr.cc: ditto + + * sockstream.cc: use socklen_t insted size_t, as + in POSIX---useful for platforms where size_t and + socklen_t are different types (like amd64). + + * socksream: idem + + * libsockios: Version 1.8.0 + +2006-05-24 Petr Ovtchenkov <pt...@is...> + + * socksream: explicitly add stdexcept header. + +2005-12-22 Petr Ovtchenkov <pt...@is...> + + * sockstream: add forward declaration of reentrant + workarounds for DNS resolver. + +2005-12-21 Petr Ovtchenkov <pt...@is...> + + * sockstream, sockstream.cc: remove previous + dup socket [see record 2005-12-19]---wrong + [dup here leads to problem in implementation of + sockmgr]. + + * sockstream, sockstream.cc: add 'attach' functions + in basic_sockbuf and basic_sockstream---attach + to existent socket with duplication [dup] to do + real close only for last close call; near the same + effect may be established with _doclose flag + [may be useful for platforms without dup call]. + + * libsockios: Version 1.7.4 + +2005-12-20 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: wait for loop start; + use xmt namespace instead of __impl for xmt library. + +2005-12-19 Petr Ovtchenkov <pt...@is...> + + * sockstream, sockstream.cc: add timeout for + poll/select system calls. + + * sockstream.cc: use dup call to duplicate socket + descriptor, if open with descriptor. + +2005-12-12 Petr Ovtchenkov <pt...@is...> + + * Makefile.inc, freebsd/*: FreeBSD 4.11 has + non-reentrant res_*, getaddrinfor, ns_* functions; + we can use reentrant ones from FreeBSD 5.3 libc + instead. + + * freebsd/_freebsd_dummy.h: redefinition of functions + that will be replaced by reentrant ones + + * _sockstream.cc: use __FIT_GETHOSTBYADDR macro + + * libsockios: Version 1.7.3 + +2005-12-07 Petr Ovtchenkov <pt...@is...> + + * sockstream: add __FIT_GETHOSTBYADDR for platforms that + has no get*by*_r functions + +2005-12-01 Petr Ovtchenkov <pt...@is...> + + * sockstream: add gethostaddr and gethostaddr2 functions + that return list of all addresses for requested host + [via back insert iterator]. gethostaddr return objects of + type in_addr, while gethostaddr2 return objects of type + sockaddr (so it useful for IPv6 too). + + * unit_test.cc: tests for gethostaddr*. + + * libsockios: Version 1.7.2 + +2005-08-05 Petr Ovtchenkov <Pet...@Ka...> + + * sockstream: add function that return name of host, + this useful to take primary interface. + + * sockmgr.h, sockmgr.cc, _sockmgr.cc: add 'open' variants + that allow to bind on specific IP; as IP this interfaces + accept unsigned long [in host byteorder] or + in_addr [in network byteorder]; if no IP specified + INADDANY will be used. + + * libsockios: Version 1.7.1 + +2005-08-05 Petr Ovtchenkov <pt...@is...> + + * libsockios: Update license version, now + Academic Free License Version 2.1 + +2005-03-31 Petr Ovtchenkov <pt...@is...> + + * sockstream: add class scope to setstate call---it has + interference with char *setstate( char * ) in stdlib.h + [pseudorandom number generators] + + * sockstream, sockstream.cc: uClibc don't have stropts.h + +2005-03-25 Petr Ovtchenkov <pt...@is...> + + * Makefile: revision of Makefiles---path to stlport lib and + -lstlport went to common Makefiles. + +2004-11-05 Petr Ovtchenkov <pt...@Is...> + + * library naming changed. + +2003-07-05 Petr Ovtchenkov <pt...@Is...> + + * libsockios: Version 1.7.0 + + * libsockios: Update license version, now + Academic Free License Version 1.2 + + * libsockios: changes in sockmgr---set locks on change + descriptor of listened socket, due to this descriptor used in + separate thread, function loop, and changed outside this + thread in functions like close; add protected unsafe variants + of some functions; recover version with 'select' call in addition + to 'poll' system call; as 'poll' as 'select' variants are + accessible in one program, if this calls available in OS. + +2002-09-25 Petr Ovtchenkov <pt...@Is...> + + * libsockios: prepare for public on sourceforge.net under + the Academic Free License Version 1.0 + +2002-07-15 Petr Ovtchenkov <pt...@Is...> + + * sockmgr.h, sockmgr.cc (Repository): remove sockmgr + class, i.e. class with one Connection object per thread. + This functionality too reach, and if still need one can be + realized in sockmgr_MP clients. + + * sockstream, _sockstream.cc (Repository): provide + portable functions that return service by name and by port. + +2002-07-12 Petr Ovtchenkov <pt...@Is...> + + * libsockios: Version 1.6.0 + +2002-07-11 Petr Ovtchenkov <pt...@Is...> + + * sockmgr.cc, sockmgr.h (Repository): remove signaling to sockets + processing loop; remove signals handlers; call close() method + of ConnectionProcessing on close as server as socket. + + * _sockmgr.cc (Repository): shutdown binded socket before + close---otherwise problems with loop thread termination + on close. + +2002-06-23 Petr Ovtchenkov <pt...@Is...> + + * sockmgr.h, sockmgr.cc, _sockmgr.cc (Repository): remove signal + throw---seems not work properly; provide handler that make sanity + of socket_managerMP<> object by signal TERM---data pass via + thread-specific data with Thread iword/pword functions; + this still need to fix for solaris threads and Windows. + + +2002-06-15 Petr Ovtchenkov <pt...@Is...> + + * _sockstream.cc, sockmgr.cc, sockmgr.h, sockstream, sockstream.cc + (Repository): SELECT and POLL differentiation, depends from OS; + fix 0 bytes read problem on close socket---no ERR, like normal read, but + err will be detected only after attempt to read; + + No search of DNS resolution---optional non-class functions now. + + +2001-07-27 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: Version 1.5.1 + + * Makefile.gcc (Repository): provide workaround for + bug in GNU make 3.79*---it foget old value of variable when + tag-dependent variable use += operator, if includes of makefiles + is too deep---near deepth of 3. This influence to libraries building. + Add explicit link with other C++ shared libraries---this significantly + reduce library size. + +2001-06-05 Petr Ovtchenkov <pt...@Pa...> + + * Makefile.inc (Message): library version 1.5.0 + This reflect real major libsockios release. + +2001-06-04 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: Work with STLport 4.5 beta 8 (from stlport cvs); + remove obsolete in any case dependence from non-STLport iostreams + realization (it should not work). + +2001-06-01 Petr Ovtchenkov <pt...@Pa...> + + * libxmt: + The fork and become_daemon now in xmt library. + + * libxmt: + New exception class fork_in_parent added in xmt. + + * libsockios: + libsockios: version 0.5.0 + +2001-04-09 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + make workaround for bogus Linux define for htons + +2001-03-20 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Satisfy for STLport 4.1 beta 5. + + * libsockios: + Increment patch number. + +2001-03-01 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Removed fields _state and _open in basic_sockbuf; + Socket expected is open if it descriptor (_fd) is not -1; + Function setoptions moved from basic_sockbuf in the sockstream + and bug in passing options fixed (all options except linger)---we need + pass int, bool give an error in result. + + * libsockios: + findhost not set error state in _state (no more this field), + instead of return true/false. + + * libsockios: + Added check for open socket before poll (in underflow) and + check for error flag after. But one require NONBLOCK mode and + removing poll in case of NONBLOCK for Multiple Connections Single Flow + processing policy. + + * libsockios: + Removed shutdown function for socket manager---no sense for it here. + + * libsockios: + Removed fields _state and _open in sockmgr; + + * libsockios: + Incremented patch number (in version presentation) after sockstream + modifications. + +2001-02-15 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Change version + +2001-02-06 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Under hard load I see the same behavior as under HP-UX and Linux. + Fix code: remove difference in code between Solaris and non-Solaris + for MCSF polisy of socket manager. + +2001-01-23 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + The same code as for HP-UX: ERR may not come on poll, and socket + may be closed before + +2001-01-22 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Approach for fix problem with lost info about closed connections + on non-Solaris OSes. Should be checked on other OS, including Solaris + and non-MP variant. + +2000-12-08 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Change STLport version + +2000-11-04 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Fixed bug in Multiplexsor variant of Sock manager: + data from net, that was readed from net and buffered in sockbuf, + not extracted befor next data received (I wait on poll). + Now I check is available data in buffer and return this + sockstream if yes before calling poll. + +2000-09-12 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + ifdef #ident directive (for vary compilers) + Removed wrong 'explicit' declaration: + 'explicit' may be used only for converting constructors. + this-> for inherited functions (HP's aCC A.03.13 don't understand + inheritance and 'using' clause). Created Makefiles for HP's aCC + compiler. Workarounds for HP's aCC names resolution. + This is release that start working on HP-UX 11.00 (with aCC A.03.13). + +2000-06-01 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Artifical delays added when WSAStartup and WSAClean, and Mutex lock + in Init added. Hopes this help... + +2000-05-24 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Attempt to put explicit instantiated code in library. + Seems fail. Size of lib grow, and size of executable also. No sence. + +2000-02-24 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + DLL export/import/none + +2000-02-18 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Fix hidden sockets initialization error. Show MessageBox now. + +2000-01-27 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Remove DllMain + +2000-01-05 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Sockets in diffirent Wins should be initialized by different way (Wins) + +1999-09-16 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Try workaround Win 95 socket problem + +1999-09-14 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Check for WIN version, if winsock not 2.0, allow winsock 1.0 + for Win 95. + +1999-09-03 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Remove __DLLEXPORT definition; This work in DLL now. + +1999-05-25 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + DllMain added; __thr_key moved into _sockstream.cc, where used only + +1999-05-06 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + trying some thread-specific data... + +1999-02-09 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + make dllexport for sockbase (Win); + + * libsockios: + remove constructor/destructor of sockbase for __unix at all. + +1999-02-08 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Include fixes for Win + +1999-02-04 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Socket initialization back here. Counters are per-thread. + +1999-02-03 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Initial revision Added: trunk/explore/lib/sockios/Makefile.inc =================================================================== --- trunk/explore/lib/sockios/Makefile.inc (rev 0) +++ trunk/explore/lib/sockios/Makefile.inc 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,17 @@ +# -*- Makefile -*- Time-stamp: <06/09/21 22:08:04 ptr> + +LIBNAME = sockios +MAJOR = 1 +MINOR = 9 +PATCH = 0 +SRC_CC = _sockstream.cc _sockmgr.cc +SRC_C = freebsd/getaddrinfo.c \ + freebsd/ns_parse.c \ + freebsd/res_comp.c \ + freebsd/res_data.c \ + freebsd/res_init.c \ + freebsd/res_mkquery.c \ + freebsd/res_query.c \ + freebsd/res_send.c \ + freebsd/res_update.c \ + freebsd/nsdispatch.c This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2006-10-10 18:04:44
|
Revision: 1309 http://svn.sourceforge.net/complement/?rev=1309&view=rev Author: complement Date: 2006-10-10 11:04:29 -0700 (Tue, 10 Oct 2006) Log Message: ----------- user can read from socket immediate in Connect ctor, so check chars in buffer after ctor and push processing queue if available Modified Paths: -------------- trunk/explore/include/sockios/sockmgr.cc trunk/explore/lib/sockios/ChangeLog trunk/explore/test/libsockios/unit/Makefile.inc trunk/explore/test/libsockios/unit/bytes_in_socket.cc trunk/explore/test/libsockios/unit/unit_test.cc Added Paths: ----------- trunk/explore/test/libsockios/unit/bytes_in_socket2.cc Modified: trunk/explore/include/sockios/sockmgr.cc =================================================================== --- trunk/explore/include/sockios/sockmgr.cc 2006-10-10 15:49:34 UTC (rev 1308) +++ trunk/explore/include/sockios/sockmgr.cc 2006-10-10 18:04:29 UTC (rev 1309) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/09/25 15:12:12 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 21:47:30 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005, 2006 @@ -173,8 +173,10 @@ _xsockaddr addr; socklen_t sz = sizeof( sockaddr_in ); + bool _in_buf; do { + _in_buf = false; _pfd[0].revents = 0; _pfd[1].revents = 0; while ( poll( &_pfd[0], _pfd.size(), -1 ) < 0 ) { // wait infinite @@ -216,11 +218,29 @@ cl_new->s->open( _sd, addr.any ); cl_new->_proc = new Connect( *cl_new->s ); _M_c.push_back( cl_new ); + if ( cl_new->s->rdbuf()->in_avail() > 0 ) { + // this is the case when user read from sockstream + // in ctor above; push processing of this stream + MT_REENTRANT( _dlock, _1 ); + _conn_pool.push_back( cl_new ); + _pool_cnd.set( true ); + _observer_cnd.set( true ); + _in_buf = true; + } } else { // we can reuse old cl_new = *i; cl_new->s->open( _sd, addr.any ); delete cl_new->_proc; // may be new ( cl_new->_proc ) Connect( *cl_new->s ); cl_new->_proc = new Connect( *cl_new->s ); + if ( cl_new->s->rdbuf()->in_avail() > 0 ) { + // this is the case when user read from sockstream + // in ctor above; push processing of this stream + MT_REENTRANT( _dlock, _1 ); + _conn_pool.push_back( cl_new ); + _pool_cnd.set( true ); + _observer_cnd.set( true ); + _in_buf = true; + } } pollfd newfd; @@ -242,7 +262,7 @@ _pfd.push_back( rfd ); } - } while ( !_shift_fd() ); + } while ( !_shift_fd() && !_in_buf ); return true; // something was pushed in connection queue (by _shift_fd) } @@ -408,7 +428,7 @@ stream->close(); c->_proc->close(); } else if ( stream->is_open() ) { - if ( stream->rdbuf()->in_avail() > 0) { + if ( stream->rdbuf()->in_avail() > 0 ) { // socket has buffered data, push it back to queue MT_REENTRANT( me->_dlock, _1 ); me->_conn_pool.push_back( c ); Modified: trunk/explore/lib/sockios/ChangeLog =================================================================== --- trunk/explore/lib/sockios/ChangeLog 2006-10-10 15:49:34 UTC (rev 1308) +++ trunk/explore/lib/sockios/ChangeLog 2006-10-10 18:04:29 UTC (rev 1309) @@ -1,3 +1,9 @@ +2006-10-10 Petr Ovtchenkov <pt...@is...> + + * sockmgr.cc: user can read from socket immediate + in Connect ctor, so check chars in buffer after ctor + and push processing queue if available. + 2006-09-25 Petr Ovtchenkov <pt...@is...> * sockmgr.h, sockmgr.cc: introduce configuration parameters Modified: trunk/explore/test/libsockios/unit/Makefile.inc =================================================================== --- trunk/explore/test/libsockios/unit/Makefile.inc 2006-10-10 15:49:34 UTC (rev 1308) +++ trunk/explore/test/libsockios/unit/Makefile.inc 2006-10-10 18:04:29 UTC (rev 1309) @@ -2,4 +2,4 @@ PRGNAME = sockios_ut SRC_CC = unit_test.cc ConnectionProcessor.cc message.cc client.cc client-mw.cc \ - client-wc.cc close_socket.cc bytes_in_socket.cc read0_on_exec.cc + client-wc.cc close_socket.cc bytes_in_socket.cc bytes_in_socket2.cc read0_on_exec.cc Modified: trunk/explore/test/libsockios/unit/bytes_in_socket.cc =================================================================== --- trunk/explore/test/libsockios/unit/bytes_in_socket.cc 2006-10-10 15:49:34 UTC (rev 1308) +++ trunk/explore/test/libsockios/unit/bytes_in_socket.cc 2006-10-10 18:04:29 UTC (rev 1309) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/07/17 11:23:16 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 20:35:08 ptr> /* * @@ -33,8 +33,9 @@ /* * Server listen tcp socket; client connect to server and write 2 - * bytes, then flush stream; server read 1 byte in constructor - * and should read the remains byte in 'connect' function. + * bytes, then flush stream; server read 1 byte in one call + * to 'connect' and should read the remains byte in another call + * to 'connect' function. * Test show, that server (sockmgr_stream_MP) call 'connect' if some * buffered data remains, and do it without signal on poll. */ @@ -60,6 +61,13 @@ BOOST_REQUIRE( s.good() ); pr_lock.unlock(); + +#if 0 + /* + * Really I have choice: read in constructor, but worry + * about stream reading or read only in connect... + */ + // connect( s ); // cerr << "Server see connection\n"; // Be silent, avoid interference // with Input line prompt @@ -71,26 +79,33 @@ pr_lock.unlock(); BOOST_CHECK( c == '0' ); +#endif } void ConnectionProcessor4::connect( std::sockstream& s ) { + static int count = 0; + pr_lock.lock(); BOOST_MESSAGE( "Server start connection processing" ); BOOST_REQUIRE( s.good() ); pr_lock.unlock(); - char c = '2'; + char c = '1'; s.read( &c, 1 ); pr_lock.lock(); BOOST_REQUIRE( s.good() ); pr_lock.unlock(); - cnd.set( true ); + if ( count++ == 0 ) { + BOOST_CHECK( c == '0' ); + } else { + cnd.set( true ); - BOOST_CHECK( c == '3' ); + BOOST_CHECK( c == '3' ); + } pr_lock.lock(); // BOOST_REQUIRE( s.good() ); Added: trunk/explore/test/libsockios/unit/bytes_in_socket2.cc =================================================================== --- trunk/explore/test/libsockios/unit/bytes_in_socket2.cc (rev 0) +++ trunk/explore/test/libsockios/unit/bytes_in_socket2.cc 2006-10-10 18:04:29 UTC (rev 1309) @@ -0,0 +1,121 @@ +// -*- C++ -*- Time-stamp: <06/10/10 21:31:27 ptr> + +/* + * + * Copyright (c) 2006 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test_framework; + +#include <iostream> +#include <list> +#include <mt/xmt.h> + +#include <sockios/sockstream> +#include <sockios/sockmgr.h> + +using namespace std; +using namespace xmt; + +/* + * Server listen tcp socket; client connect to server and write 2 + * bytes, then flush stream; server read 1 byte in ctor + * and should read the remains byte in call to 'connect' function. + * Test show, that server (sockmgr_stream_MP) call 'connect' if some + * buffered data remains, and do it without signal on poll. + */ + +extern int port; +extern xmt::Mutex pr_lock; + +static Condition cnd; + +class ConnectionProcessor7 // dummy variant +{ + public: + ConnectionProcessor7( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); +}; + +ConnectionProcessor7::ConnectionProcessor7( std::sockstream& s ) +{ + pr_lock.lock(); + BOOST_MESSAGE( "Server seen connection" ); + + BOOST_REQUIRE( s.good() ); + pr_lock.unlock(); + + // connect( s ); + // cerr << "Server see connection\n"; // Be silent, avoid interference + // with Input line prompt + char c = '1'; + s.read( &c, 1 ); + + pr_lock.lock(); + BOOST_REQUIRE( s.good() ); + pr_lock.unlock(); + + BOOST_CHECK( c == '0' ); +} + +void ConnectionProcessor7::connect( std::sockstream& s ) +{ + pr_lock.lock(); + BOOST_MESSAGE( "Server start connection processing" ); + + BOOST_REQUIRE( s.good() ); + pr_lock.unlock(); + + char c = '1'; + s.read( &c, 1 ); + + pr_lock.lock(); + BOOST_REQUIRE( s.good() ); + pr_lock.unlock(); + + cnd.set( true ); + + BOOST_CHECK( c == '3' ); + + pr_lock.lock(); + // BOOST_REQUIRE( s.good() ); + BOOST_MESSAGE( "Server stop connection processing" ); + pr_lock.unlock(); + + return; +} + +void ConnectionProcessor7::close() +{ + pr_lock.lock(); + BOOST_MESSAGE( "Server: client close connection" ); + pr_lock.unlock(); +} + +void test_more_bytes_in_socket2() +{ +// #ifndef __FIT_NO_POLL + cnd.set( false ); + sockmgr_stream_MP<ConnectionProcessor7> srv( port ); // start server + + sockstream sock( "localhost", ::port ); + + char c[5] = { '0', '3', '4', '5', '6' }; + sock.write( c, 2 ); + sock.flush(); + + cnd.try_wait(); + srv.close(); // close server, so we don't wait server termination on next line + srv.wait(); // Wait for server stop to serve clients connections +// #else +// BOOST_ERROR( "select-based sockmgr not implemented on this platform" ); +// #endif +} Modified: trunk/explore/test/libsockios/unit/unit_test.cc =================================================================== --- trunk/explore/test/libsockios/unit/unit_test.cc 2006-10-10 15:49:34 UTC (rev 1308) +++ trunk/explore/test/libsockios/unit/unit_test.cc 2006-10-10 18:04:29 UTC (rev 1309) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/09/20 20:15:07 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 21:00:28 ptr> /* * @@ -343,6 +343,7 @@ void test_client_close_socket(); void test_more_bytes_in_socket(); +void test_more_bytes_in_socket2(); void test_read0(); void test_read0_srv(); @@ -525,8 +526,9 @@ ts->add( BOOST_TEST_CASE( &test_client_close_socket ) ); ts->add( BOOST_TEST_CASE( &test_more_bytes_in_socket ), 0, 5 ); - ts->add( BOOST_TEST_CASE( &test_read0 )/* , 0, 7 */ ); - ts->add( BOOST_TEST_CASE( &test_read0_srv ) ); + ts->add( BOOST_TEST_CASE( &test_more_bytes_in_socket2 ), 0, 5 ); + // ts->add( BOOST_TEST_CASE( &test_read0 ), 0, 7 ); + // ts->add( BOOST_TEST_CASE( &test_read0_srv ) ); return ts; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2006-10-10 18:14:10
|
Revision: 1310 http://svn.sourceforge.net/complement/?rev=1310&view=rev Author: complement Date: 2006-10-10 11:13:50 -0700 (Tue, 10 Oct 2006) Log Message: ----------- remove SessionMgr---it not used anyway. This functionality should be reimplemented in different manner. Modified Paths: -------------- trunk/explore/include/stem/EvManager.h trunk/explore/include/stem/EventHandler.h trunk/explore/include/stem/NetTransport.h trunk/explore/lib/stem/ChangeLog trunk/explore/lib/stem/EvManager.cc trunk/explore/lib/stem/NetTransport.cc trunk/explore/lib/stem/_EventHandler.cc trunk/explore/test/libstem/unit/Makefile.inc trunk/explore/test/libstem/unit/unit_test.cc Added Paths: ----------- trunk/explore/test/libstem/unit/Echo.cc trunk/explore/test/libstem/unit/Echo.h Modified: trunk/explore/include/stem/EvManager.h =================================================================== --- trunk/explore/include/stem/EvManager.h 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/include/stem/EvManager.h 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/09/30 09:42:35 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 18:11:49 ptr> /* * Copyright (c) 1995-1999, 2002, 2003, 2005, 2006 @@ -134,7 +134,6 @@ return unsafe_annotate( id ); } - __FIT_DECLSPEC key_type sid( addr_type object_id ) const; __FIT_DECLSPEC NetTransport_base *transport( addr_type object_id ) const; void push( const Event& e ) Modified: trunk/explore/include/stem/EventHandler.h =================================================================== --- trunk/explore/include/stem/EventHandler.h 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/include/stem/EventHandler.h 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/06/28 15:08:43 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 18:12:54 ptr> /* * Copyright (c) 1995-1999, 2002, 2003, 2005, 2006 @@ -601,7 +601,6 @@ __FIT_DECLSPEC const string& who_is( addr_type k ) const; __FIT_DECLSPEC bool is_avail( addr_type id ) const; - __FIT_DECLSPEC key_type sid( addr_type k ) const; static EvManager *manager() { return _mgr; } __FIT_DECLSPEC void Send( const Event& e ); Modified: trunk/explore/include/stem/NetTransport.h =================================================================== --- trunk/explore/include/stem/NetTransport.h 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/include/stem/NetTransport.h 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/06 19:39:22 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 18:09:19 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005, 2006 @@ -56,7 +56,6 @@ NetTransport_base() : _count( 0 ), - _sid( badkey ), net( 0 ), _net_ns( badaddr ) { } @@ -64,7 +63,6 @@ NetTransport_base( const char *info ) : EventHandler( info ), _count( 0 ), - _sid( badkey ), net( 0 ), _net_ns( badaddr ) { } @@ -85,54 +83,19 @@ __FIT_DECLSPEC addr_type make_map( addr_type k, const char *name ); - EvSessionManager::key_type sid() const - { return _sid; } - addr_type ns() const { return _net_ns; } - static stem::SessionInfo session_info( const EvSessionManager::key_type& k ) - { - smgr.lock(); - stem::SessionInfo si( smgr[k] ); - smgr.unlock(); - return si; - } - - static void session_control( const EvSessionManager::key_type& k, - const stem::addr_type& a ) - { - smgr.lock(); - smgr[k]._control = a; - smgr.unlock(); - } - - static std::string session_host( const EvSessionManager::key_type& k ) - { - smgr.lock(); - std::string h( smgr[k]._host ); - smgr.unlock(); - return h; - } - - static void erase_session( const EvSessionManager::key_type& k ) - { smgr.erase( k ); } - protected: - void establish_session( std::sockstream& s ) throw (std::domain_error); - void mark_session_onoff( bool ); addr_type rar_map( addr_type k, const std::string& name ); bool pop( Event& ); - void disconnect(); std::sockstream *net; - EvSessionManager::key_type _sid; uint32_t _count; // indeed rar can be inside connect(), but SunPro's CC 5.0 // to be very huffy about it. heap_type rar; // reverce address resolution table addr_type _net_ns; // reflection of address of remote name service - static __FIT_DECLSPEC EvSessionManager smgr; }; class NetTransport : @@ -179,7 +142,7 @@ public: NetTransportMP( std::sockstream& s ) : NetTransport_base( "stem::NetTransportMP" ) - { this->connect( s ); } + { net = &s; } __FIT_DECLSPEC void connect( std::sockstream& ); Modified: trunk/explore/lib/stem/ChangeLog =================================================================== --- trunk/explore/lib/stem/ChangeLog 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/lib/stem/ChangeLog 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,3 +1,11 @@ +2006-10-10 Petr Ovtchenkov <pt...@is...> + + * NetTransport.h, EventHandler.h, EvManager.h: remove + SessionMgr---it not used anyway. This functionality + should be reimplemented in different manner. + + * _EventHandler.cc, NetTransport.cc, EvManager.cc: ditto. + 2006-10-06 Petr Ovtchenkov <pt...@is...> * NetTransport.h, NetTransport.cc: move make_map Modified: trunk/explore/lib/stem/EvManager.cc =================================================================== --- trunk/explore/lib/stem/EvManager.cc 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/lib/stem/EvManager.cc 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/09/30 09:43:12 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 18:11:29 ptr> /* * @@ -228,18 +228,6 @@ } } -// return session id of object with address 'id' if this is external -// object; otherwise return -1; -__FIT_DECLSPEC key_type EvManager::sid( addr_type id ) const -{ - MT_REENTRANT( _lock_heap, _x1 ); - heap_type::const_iterator i = heap.find( id ); - if ( i == heap.end() || (*i).second.remote == 0 ) { - return badkey; - } - return (*i).second.remote->channel->sid(); -} - __FIT_DECLSPEC NetTransport_base *EvManager::transport( addr_type id ) const { MT_REENTRANT( _lock_heap, _x1 ); Modified: trunk/explore/lib/stem/NetTransport.cc =================================================================== --- trunk/explore/lib/stem/NetTransport.cc 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/lib/stem/NetTransport.cc 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/06 19:40:42 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 18:15:52 ptr> /* * @@ -90,42 +90,6 @@ } } -__FIT_DECLSPEC EvSessionManager NetTransport_base::smgr; - -void NetTransport_base::disconnect() -{ - if ( _sid == badkey ) { - _count = 0; - return; - } - try { - smgr.lock(); - if ( smgr.unsafe_is_avail( _sid ) ) { - SessionInfo& info = smgr[_sid]; - info.disconnect(); -// cerr << "EvManager::disconnect: " << _sid << endl; - if ( info._control != badaddr ) { - Event_base<key_type> ev_disconnect( EV_EDS_DISCONNECT, _sid ); - ev_disconnect.dest( info._control ); - _sid = badkey; - _count = 0; - smgr.unlock(); -// cerr << "EvManager::disconnect, info._control: " << info._control << endl; - Send( Event_convert<key_type>()(ev_disconnect) ); -// cerr << "===== Pass" << endl; - return; // required: smgr.unlock() done. - } - smgr.unsafe_erase( _sid ); - } - _sid = badkey; - _count = 0; - smgr.unlock(); - } - catch ( ... ) { - smgr.unlock(); - } -} - __FIT_DECLSPEC NetTransport_base::~NetTransport_base() { NetTransport_base::close(); @@ -136,7 +100,6 @@ // cerr << __FILE__ << ":" << __LINE__ << endl; if ( net != 0 ) { manager()->Remove( this ); - disconnect(); rar.clear(); net->close(); // cerr << __FILE__ << ":" << __LINE__ << endl; @@ -144,32 +107,6 @@ } } -__FIT_DECLSPEC -void NetTransport_base::establish_session( std::sockstream& s ) throw (std::domain_error) -{ - smgr.lock(); - _sid = smgr.unsafe_create(); - if ( _sid == badkey ) { - smgr.unlock(); - throw std::domain_error( "bad session id" ); - } - smgr[_sid]._host = hostname( s.rdbuf()->inet_addr() ); - smgr[_sid]._port = s.rdbuf()->port(); - smgr.unlock(); -} - -void NetTransport_base::mark_session_onoff( bool f ) -{ - smgr.lock(); - if ( smgr.unsafe_is_avail( _sid ) ) { - if ( f ) - smgr[ _sid ].connect(); - else - smgr[ _sid ].disconnect(); - } - smgr.unlock(); -} - const string __ns_at( "ns@" ); const string __at( "@" ); @@ -196,7 +133,6 @@ MT_IO_REENTRANT( *net ) if ( !net->read( (char *)buf, sizeof(uint32_t) ).good() ) { - // cerr << __FILE__ << ":" << __LINE__ << endl; return false; } // cerr << __FILE__ << ":" << __LINE__ << endl; @@ -247,21 +183,6 @@ #endif } - if ( _sid != badkey ) { - smgr.lock(); - if ( smgr.unsafe_is_avail( _sid ) ) { - SessionInfo& sess = smgr[_sid]; - sess.inc_from( 8 * sizeof(uint32_t) + str.size() ); - if ( sess._un_from != _x_count ) { - cerr << "EDS Incoming event(s) lost, or missrange event: " << sess._un_from - << ", " << _x_count << " (Session: " << _sid << ") --- "; - cerr << endl; - sess._un_from = _x_count; // Retransmit? - } - } - smgr.unlock(); - } - return net->good(); } @@ -270,7 +191,7 @@ bool NetTransport_base::push( const Event& _rs ) { // _STLP_ASSERT( net != 0 ); - if ( _sid == badkey || !net->good() ) { + if ( !net->good() ) { return false; } uint32_t buf[8]; @@ -296,26 +217,13 @@ ostream_iterator<char,char,char_traits<char> >(*net) ); net->flush(); - if ( _sid != badkey && net->good() ) { - smgr.lock(); - if ( smgr.unsafe_is_avail( _sid ) ) { - SessionInfo& sess = smgr[_sid]; - sess.inc_to( 8 * sizeof(uint32_t) + _rs.value().size() ); - if ( sess._un_to != _count ) { - cerr << "Outgoing event(s) lost, or missrange event: " << sess._un_to - << ", " << _count << " (Session " << _sid << ")" << endl; - // kill( getpid(), SIGQUIT ); - } - } - smgr.unlock(); - } else { + if ( !net->good() ) { throw ios_base::failure( "net not good" ); } } catch ( ios_base::failure& ) { if ( net != 0 ) { // clear connection: required by non-Solaris OS - disconnect(); // for MP connection policy - rar.clear(); + rar.clear(); // for MP connection policy net->close(); } } @@ -348,7 +256,6 @@ _at_hostname = __at + _hostname; try { - establish_session( s ); _net_ns = rar_map( ns_addr, __ns_at + _hostname ); } catch ( std::domain_error& ex ) { @@ -372,8 +279,6 @@ } catch ( ... ) { s.close(); - // disconnect(); - // throw; } // cerr << "Disconnected" << endl; } @@ -419,7 +324,6 @@ if ( net->good() ) { _net_ns = rar_map( ns_addr, __ns_at + hostname ); addr_type zero_object = rar_map( 0, __at + hostname ); - _sid = smgr.create(); _thr.launch( _loop, this, 0, PTHREAD_STACK_MIN * 2 ); // start thread here return zero_object; } @@ -472,21 +376,12 @@ void NetTransportMP::connect( sockstream& s ) { const string& _hostname = hostname( s.rdbuf()->inet_addr() ); - bool sock_dgr = (s.rdbuf()->stype() == std::sock_base::sock_stream) ? false : true; + // bool sock_dgr = (s.rdbuf()->stype() == std::sock_base::sock_stream) ? false : true; Event ev; // cerr << "Connected: " << _hostname << endl; try { - if ( _sid == badkey ) { - establish_session( s ); - net = &s; - } else if ( sock_dgr /* && _sid != badkey */ ) { - mark_session_onoff( true ); - } - // indeed here need more check: data of event - // and another: message can be break, and other datagram can be - // in the middle of message... if ( pop( ev ) ) { ev.src( rar_map( ev.src(), __at + _hostname ) ); // substitute my local id manager()->push( ev ); @@ -494,9 +389,6 @@ if ( !s.good() ) { throw ios_base::failure( "sockstream not good" ); } - if ( sock_dgr && _sid != badkey ) { - mark_session_onoff( false ); - } } catch ( ... ) { this->close(); // clear connection Modified: trunk/explore/lib/stem/_EventHandler.cc =================================================================== --- trunk/explore/lib/stem/_EventHandler.cc 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/lib/stem/_EventHandler.cc 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/09/30 09:44:46 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 18:12:26 ptr> /* * Copyright (c) 1995-1999, 2002, 2003, 2005, 2006 @@ -71,12 +71,6 @@ } __FIT_DECLSPEC -key_type EventHandler::sid( addr_type k ) const -{ - return _mgr->sid( k ); -} - -__FIT_DECLSPEC void EventHandler::Send( const Event& e ) { e.src( _id ); Added: trunk/explore/test/libstem/unit/Echo.cc =================================================================== --- trunk/explore/test/libstem/unit/Echo.cc (rev 0) +++ trunk/explore/test/libstem/unit/Echo.cc 2006-10-10 18:13:50 UTC (rev 1310) @@ -0,0 +1,98 @@ +// -*- C++ -*- Time-stamp: <06/10/10 22:07:21 ptr> + +/* + * Copyright (c) 2006 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#include "Echo.h" + +#include <stem/NetTransport.h> +#include <stem/EvManager.h> + +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test_framework; + +using namespace stem; + +StEMecho::StEMecho() +{ +} + +StEMecho::StEMecho( addr_type id ) : + EventHandler( id ) +{ +} + +StEMecho::StEMecho( addr_type id, const char *info ) : + EventHandler( id, info ) +{ +} + +void StEMecho::echo( const Event& ev ) +{ + Event eev( ev.code() ); + eev.value() = ev.value(); + + eev.dest( ev.src() ); + + Send( eev ); +} + +void StEMecho::regme( const stem::Event& ev ) +{ + stem::NetTransport_base *b = manager()->transport( ev.src() ); + if ( b != 0 ) { + b->make_map( ev.src(), (ev.value() /* + who_is( ev.src() ) */ ).c_str() ); + } +} + +DEFINE_RESPONSE_TABLE( StEMecho ) + EV_EDS( 0, NODE_EV_ECHO, echo ) + EV_EDS( 0, 0x5001, regme ) +END_RESPONSE_TABLE + +EchoClient::EchoClient() : + EventHandler(), + mess( "echo string" ) +{ + cnd.set( false ); +} + +EchoClient::EchoClient( stem::addr_type id ) : + EventHandler( id ), + mess( "echo string" ) +{ + cnd.set( false ); +} + +EchoClient::EchoClient( stem::addr_type id, const char *info ) : + EventHandler( id, info ), + mess( "echo string" ) +{ + cnd.set( false ); +} + +EchoClient::~EchoClient() +{ + // cnd.wait(); +} + +void EchoClient::handler1( const stem::Event& ev ) +{ + BOOST_CHECK( ev.value() == mess ); + cnd.set(true); +} + +void EchoClient::wait() +{ + cnd.try_wait(); +} + +DEFINE_RESPONSE_TABLE( EchoClient ) + EV_EDS(0,NODE_EV_ECHO,handler1) +END_RESPONSE_TABLE Added: trunk/explore/test/libstem/unit/Echo.h =================================================================== --- trunk/explore/test/libstem/unit/Echo.h (rev 0) +++ trunk/explore/test/libstem/unit/Echo.h 2006-10-10 18:13:50 UTC (rev 1310) @@ -0,0 +1,58 @@ +// -*- C++ -*- Time-stamp: <06/10/10 15:42:36 ptr> + +/* + * Copyright (c) 2006 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#ifndef __Echo_h +#define __Echo_h + +#include <string> +#include <mt/xmt.h> +#include <stem/EventHandler.h> +// #include <stem/Names.h> +// #include <list> + +class StEMecho : + public stem::EventHandler +{ + public: + StEMecho(); + StEMecho( stem::addr_type id ); + StEMecho( stem::addr_type id, const char * ); + + void echo( const stem::Event& ); + void regme( const stem::Event& ); + + private: + DECLARE_RESPONSE_TABLE( StEMecho, stem::EventHandler ); +}; + +class EchoClient : + public stem::EventHandler +{ + public: + EchoClient(); + EchoClient( stem::addr_type id ); + EchoClient( stem::addr_type id, const char *info ); + ~EchoClient(); + + void handler1( const stem::Event& ); + + void wait(); + + const std::string mess; + + private: + xmt::Condition cnd; + + DECLARE_RESPONSE_TABLE( EchoClient, stem::EventHandler ); +}; + +#define NODE_EV_ECHO 0x903 + +#endif // __Echo_h Modified: trunk/explore/test/libstem/unit/Makefile.inc =================================================================== --- trunk/explore/test/libstem/unit/Makefile.inc 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/test/libstem/unit/Makefile.inc 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,7 +1,7 @@ -# -*- makefile -*- Time-stamp: <06/09/29 22:09:31 ptr> +# -*- makefile -*- Time-stamp: <06/10/10 15:22:33 ptr> PRGNAME = stem_ut SRC_CC = unit_test.cc \ Node.cc \ - NameService.cc - + NameService.cc \ + Echo.cc Modified: trunk/explore/test/libstem/unit/unit_test.cc =================================================================== --- trunk/explore/test/libstem/unit/unit_test.cc 2006-10-10 18:04:29 UTC (rev 1309) +++ trunk/explore/test/libstem/unit/unit_test.cc 2006-10-10 18:13:50 UTC (rev 1310) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/04 11:18:42 ptr> +// -*- C++ -*- Time-stamp: <06/10/10 16:49:12 ptr> /* * Copyright (c) 2002, 2003, 2006 @@ -25,6 +25,10 @@ #include <dlfcn.h> +#include "Echo.h" +#include <stem/NetTransport.h> +#include <sockios/sockmgr.h> + using namespace std; struct stem_test @@ -37,6 +41,8 @@ void ns(); void ns1(); + void echo(); + static xmt::Thread::ret_code thr1( void * ); static xmt::Thread::ret_code thr1new( void * ); }; @@ -302,6 +308,41 @@ BOOST_CHECK( nm.lst1.empty() ); } +void stem_test::echo() +{ + try { + sockmgr_stream_MP<stem::NetTransport> srv( 6995 ); + stem::NetTransportMgr mgr; + + StEMecho echo( 0, "echo service"); // <= zero! + + stem::addr_type zero = mgr.open( "localhost", 6995 ); + + BOOST_CHECK( zero != stem::badaddr ); + BOOST_CHECK( zero != 0 ); + + EchoClient node; + + EDS::Event ev( NODE_EV_ECHO ); + + ev.dest( zero ); + ev.value() = node.mess; + + node.Send( ev ); + + node.wait(); + + mgr.close(); + // mgr.join(); + + srv.close(); + srv.wait(); + } + catch ( ... ) { + } + // cerr << "Fine\n"; +} + struct stem_test_suite : public test_suite { @@ -321,6 +362,7 @@ test_case *dl_tc = BOOST_CLASS_TEST_CASE( &stem_test::dl, instance ); test_case *ns_tc = BOOST_CLASS_TEST_CASE( &stem_test::ns, instance ); test_case *ns1_tc = BOOST_CLASS_TEST_CASE( &stem_test::ns1, instance ); + test_case *echo_tc = BOOST_CLASS_TEST_CASE( &stem_test::echo, instance ); basic2_tc->depends_on( basic1_tc ); basic1n_tc->depends_on( basic1_tc ); @@ -330,6 +372,8 @@ ns_tc->depends_on( basic1_tc ); ns1_tc->depends_on( basic1_tc ); + echo_tc->depends_on( basic2_tc ); + add( basic1_tc ); add( basic2_tc ); add( basic1n_tc ); @@ -337,6 +381,8 @@ add( dl_tc ); add( ns_tc ); add( ns1_tc ); + + add( echo_tc ); } test_suite *init_unit_test_suite( int argc, char **argv ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2006-10-11 11:51:20
|
Revision: 1313 http://svn.sourceforge.net/complement/?rev=1313&view=rev Author: complement Date: 2006-10-11 04:51:09 -0700 (Wed, 11 Oct 2006) Log Message: ----------- fix inconsistency with observer_run flag; test finish fine now Modified Paths: -------------- trunk/explore/include/sockios/sockmgr.cc trunk/explore/lib/sockios/ChangeLog trunk/explore/test/libstem/unit/Echo.cc trunk/explore/test/libstem/unit/unit_test.cc Modified: trunk/explore/include/sockios/sockmgr.cc =================================================================== --- trunk/explore/include/sockios/sockmgr.cc 2006-10-11 07:11:05 UTC (rev 1312) +++ trunk/explore/include/sockios/sockmgr.cc 2006-10-11 11:51:09 UTC (rev 1313) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/10 21:47:30 ptr> +// -*- C++ -*- Time-stamp: <06/10/11 15:30:02 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005, 2006 @@ -346,9 +346,12 @@ } me->_orlock.lock(); if ( !me->_observer_run ) { + me->_observer_run = true; + me->_orlock.unlock(); me->mgr.launch( observer, me, 0, 0, PTHREAD_STACK_MIN * 2 ); + } else { + me->_orlock.unlock(); } - me->_orlock.unlock(); } } catch ( ... ) { @@ -489,10 +492,6 @@ timespec now; std::fill( pool_size, pool_size + 3, 0 ); - me->_orlock.lock(); - me->_observer_run = true; - me->_orlock.unlock(); - try { do { // std::swap( pool_size[0], pool_size[1] ); Modified: trunk/explore/lib/sockios/ChangeLog =================================================================== --- trunk/explore/lib/sockios/ChangeLog 2006-10-11 07:11:05 UTC (rev 1312) +++ trunk/explore/lib/sockios/ChangeLog 2006-10-11 11:51:09 UTC (rev 1313) @@ -1,3 +1,8 @@ +2006-10-11 Petr Ovtchenkov <pt...@is...> + + * sockmgr.cc: fix inconsistency with observer_run + flag. + 2006-10-10 Petr Ovtchenkov <pt...@is...> * sockmgr.cc: user can read from socket immediate Modified: trunk/explore/test/libstem/unit/Echo.cc =================================================================== --- trunk/explore/test/libstem/unit/Echo.cc 2006-10-11 07:11:05 UTC (rev 1312) +++ trunk/explore/test/libstem/unit/Echo.cc 2006-10-11 11:51:09 UTC (rev 1313) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/11 01:25:24 ptr> +// -*- C++ -*- Time-stamp: <06/10/11 14:54:52 ptr> /* * Copyright (c) 2006 Modified: trunk/explore/test/libstem/unit/unit_test.cc =================================================================== --- trunk/explore/test/libstem/unit/unit_test.cc 2006-10-11 07:11:05 UTC (rev 1312) +++ trunk/explore/test/libstem/unit/unit_test.cc 2006-10-11 11:51:09 UTC (rev 1313) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/11 01:24:22 ptr> +// -*- C++ -*- Time-stamp: <06/10/11 15:36:32 ptr> /* * Copyright (c) 2002, 2003, 2006 @@ -27,6 +27,7 @@ #include "Echo.h" #include <stem/NetTransport.h> +#include <stem/EvManager.h> #include <sockios/sockmgr.h> using namespace std; @@ -346,37 +347,63 @@ void stem_test::peer() { - sockmgr_stream_MP<stem::NetTransport> srv( 6995 ); + /* + * Scheme: + * / NetTransport / c1 + * Local Event Manager - NetTransportMgr - c2 + * \ echo + * Due to all objects in the same process space, + * c1 and c2 use the same Local Event Manager + * but I try to bypass this fact. + * I.e. I try to simulate + * + * / NetTransport ~~ NetTransportMgr - LEM - c1 + * Local Event Manager \ + * \ echo ~~ NetTransportMgr - LEM - c2 + * + * and provide simulation of logical connection + * + * / c1 + * echo + * \ c2 + * + * (c1 <-> c2, through 'echo') + */ + + sockmgr_stream_MP<stem::NetTransport> srv( 6995 ); // server, it serve 'echo' + stem::NetTransportMgr mgr; - StEMecho echo( 0, "echo service"); // <= zero! - + StEMecho echo( 0, "echo service"); // <= zero! 'echo' server, default ('zero' address) + echo.cnd.set( false ); - stem::addr_type zero = mgr.open( "localhost", 6995 ); + stem::addr_type zero = mgr.open( "localhost", 6995 ); // take address of 'zero' (aka default) object via net transport from server + // It done like it should on client side BOOST_CHECK( zero != stem::badaddr ); BOOST_CHECK( zero != 0 ); + BOOST_CHECK( zero & stem::extbit ); // "external" address - PeerClient c1( "c1 local" ); + PeerClient c1( "c1 local" ); // c1 client stem::Event ev( NODE_EV_REGME ); ev.dest( zero ); ev.value() = "c1"; - c1.Send( ev ); + c1.Send( ev ); // 'register' c1 client on 'echo' server echo.cnd.try_wait(); echo.cnd.set( false ); - PeerClient c2( "c2 local" ); + PeerClient c2( "c2 local" ); // c2 client ev.value() = "c2"; - c2.Send( ev ); + c2.Send( ev ); // 'register' c2 client on 'echo' server echo.cnd.try_wait(); - Naming nm; + Naming nm; // use it to take names from NS // stem::Event ev_nm( EV_STEM_RQ_ADDR_LIST1 ); stem::Event ev_nm( EV_STEM_RQ_EXT_ADDR_LIST1 ); @@ -386,26 +413,38 @@ nm.wait(); stem::addr_type peer_addr = stem::badaddr; + + // This is to make chance for mapping address later: + stem::NetTransport_base *tr = c1.manager()->transport( mgr.ns() ); + + BOOST_CHECK( tr != 0 ); // processed via network transport, indeed + for ( Naming::nsrecords_type::const_iterator i = nm.lst1.begin(); i != nm.lst1.end(); ++i ) { + BOOST_CHECK( i->first & stem::extbit ); // "external" if ( i->second.find( "c2@" ) == 0 ) { - peer_addr = i->first; + // make pair: address on side of c1 -> address on side of 'echo' + // note: on side of 'echo' server there are mapping too, + // address on side of 'echo' -> address on side of c2 + peer_addr = tr->make_map( i->first, "c2@foreign" ); } // cerr << hex << i->first << dec << " => " << i->second << endl; + // cerr << hex << tr->make_map( i->first, "map" ) << dec << endl; } + BOOST_CHECK( peer_addr != stem::badaddr ); // address found + BOOST_CHECK( peer_addr & stem::extbit ); // address external stem::Event echo_ev( NODE_EV_ECHO ); - echo_ev.dest( 0x8000000b ); + echo_ev.dest( /* 0x8000000b */ peer_addr ); echo_ev.value() = "c2 local"; c1.Send( echo_ev ); c2.wait(); - cerr << "qq\n"; + mgr.close(); + srv.close(); - srv.close(); - cerr << "xx\n"; srv.wait(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2006-10-12 11:24:32
|
Revision: 1314 http://svn.sourceforge.net/complement/?rev=1314&view=rev Author: complement Date: 2006-10-12 04:24:15 -0700 (Thu, 12 Oct 2006) Log Message: ----------- remove make_map, it useless and even dangerous in practice Modified Paths: -------------- trunk/explore/include/stem/NetTransport.h trunk/explore/lib/stem/NetTransport.cc Modified: trunk/explore/include/stem/NetTransport.h =================================================================== --- trunk/explore/include/stem/NetTransport.h 2006-10-11 11:51:09 UTC (rev 1313) +++ trunk/explore/include/stem/NetTransport.h 2006-10-12 11:24:15 UTC (rev 1314) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/10 18:09:19 ptr> +// -*- C++ -*- Time-stamp: <06/10/12 14:24:02 ptr> /* * Copyright (c) 1997-1999, 2002, 2003, 2005, 2006 @@ -81,8 +81,6 @@ __FIT_DECLSPEC bool push( const Event& ); - __FIT_DECLSPEC addr_type make_map( addr_type k, const char *name ); - addr_type ns() const { return _net_ns; } Modified: trunk/explore/lib/stem/NetTransport.cc =================================================================== --- trunk/explore/lib/stem/NetTransport.cc 2006-10-11 11:51:09 UTC (rev 1313) +++ trunk/explore/lib/stem/NetTransport.cc 2006-10-12 11:24:15 UTC (rev 1314) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/10 18:15:52 ptr> +// -*- C++ -*- Time-stamp: <06/10/12 14:24:31 ptr> /* * @@ -236,15 +236,6 @@ return net->good(); } -__FIT_DECLSPEC addr_type NetTransport_base::make_map( addr_type k, const char *name ) -{ - string full_name = name; - full_name += __at; - full_name += hostname( net->rdbuf()->inet_addr() ); - - return rar_map( k, full_name ); -} - __FIT_DECLSPEC NetTransport::NetTransport( std::sockstream& s ) : NetTransport_base( "stem::NetTransport" ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2006-10-12 11:25:19
|
Revision: 1315 http://svn.sourceforge.net/complement/?rev=1315&view=rev Author: complement Date: 2006-10-12 04:25:06 -0700 (Thu, 12 Oct 2006) Log Message: ----------- allow change announce of object's info; return string object instead of const reference from annotate by safety reasons Modified Paths: -------------- trunk/explore/include/stem/EvManager.h trunk/explore/include/stem/EventHandler.h trunk/explore/lib/stem/ChangeLog trunk/explore/lib/stem/_EventHandler.cc trunk/explore/test/libstem/unit/Echo.cc trunk/explore/test/libstem/unit/unit_test.cc Modified: trunk/explore/include/stem/EvManager.h =================================================================== --- trunk/explore/include/stem/EvManager.h 2006-10-12 11:24:15 UTC (rev 1314) +++ trunk/explore/include/stem/EvManager.h 2006-10-12 11:25:06 UTC (rev 1315) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/10 18:11:49 ptr> +// -*- C++ -*- Time-stamp: <06/10/12 15:10:18 ptr> /* * Copyright (c) 1995-1999, 2002, 2003, 2005, 2006 @@ -122,18 +122,30 @@ return unsafe_is_avail(id); } - const string& who_is( addr_type id ) const + const std::string who_is( addr_type id ) const { MT_REENTRANT( _lock_heap, _x1 ); return unsafe_who_is( id ); } - const string& annotate( addr_type id ) const + const std::string annotate( addr_type id ) const { MT_REENTRANT( _lock_heap, _x1 ); return unsafe_annotate( id ); } + void change_announce( addr_type id, const std::string& info ) + { + MT_REENTRANT( _lock_heap, _x1 ); + unsafe_change_announce( id, info ); + } + + void change_announce( addr_type id, const char *info ) + { + MT_REENTRANT( _lock_heap, _x1 ); + unsafe_change_announce( id, info ); + } + __FIT_DECLSPEC NetTransport_base *transport( addr_type object_id ) const; void push( const Event& e ) @@ -149,17 +161,33 @@ bool unsafe_is_avail( addr_type id ) const { return heap.find( id ) != heap.end(); } - const string& unsafe_who_is( addr_type id ) const + const std::string& unsafe_who_is( addr_type id ) const { heap_type::const_iterator i = heap.find( id ); return i == heap.end() ? inv_key_str : (*i).second.info; } - const string& unsafe_annotate( addr_type id ) const + const std::string& unsafe_annotate( addr_type id ) const { heap_type::const_iterator i = heap.find( id ); return i == heap.end() ? inv_key_str : (*i).second.info; } + void unsafe_change_announce( addr_type id, const std::string& info ) + { + heap_type::iterator i = heap.find( id ); + if ( i != heap.end() ) { + i->second.info = info; + } + } + + void unsafe_change_announce( addr_type id, const char *info ) + { + heap_type::iterator i = heap.find( id ); + if ( i != heap.end() ) { + i->second.info = info; + } + } + private: void Send( const Event& e ); __FIT_DECLSPEC void unsafe_Remove( NetTransport_base * ); Modified: trunk/explore/include/stem/EventHandler.h =================================================================== --- trunk/explore/include/stem/EventHandler.h 2006-10-12 11:24:15 UTC (rev 1314) +++ trunk/explore/include/stem/EventHandler.h 2006-10-12 11:25:06 UTC (rev 1315) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/10 18:12:54 ptr> +// -*- C++ -*- Time-stamp: <06/10/12 14:12:15 ptr> /* * Copyright (c) 1995-1999, 2002, 2003, 2005, 2006 @@ -7,16 +7,8 @@ * Copyright (c) 1999-2001 * ParallelGraphics Ltd. * - * Licensed under the Academic Free License version 2.1 + * Licensed under the Academic Free License version 3.0 * - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. */ #ifndef __EventHandler_h @@ -535,19 +527,8 @@ } typedef std::list<state_type> HistoryContainer; -// #ifndef __FIT_TEMPLATE_TYPEDEF_BUG typedef HistoryContainer::iterator h_iterator; typedef HistoryContainer::const_iterator const_h_iterator; -// #else // __FIT_TEMPLATE_TYPEDEF_BUG -// be careful: list implementation dependence -// # ifndef __STL_DEBUG -// typedef _List_iterator<state_type, _Nonconst_traits<state_type> > h_iterator; -// typedef _List_iterator<state_type, _Const_traits<state_type> > const_h_iterator; -// # else // HP's aCC A.03.13 nevertheless fail here (or near). -// typedef _DBG_iter<__list<state_type,__STL_DEFAULT_ALLOCATOR(state_type) >, _Nonconst_traits<state_type> > h_iterator; -// typedef _DBG_iter<__list<state_type,__STL_DEFAULT_ALLOCATOR(state_type) >, _Const_traits<state_type> > const_h_iterator; -// # endif -// #endif // __FIT_TEMPLATE_TYPEDEF_BUG _STLP_TEMPLATE_NULL class __EvHandler<EventHandler,h_iterator > @@ -581,7 +562,7 @@ // See comment near EventHandler::EventHandler() implementation // HistoryContainer& theHistory; HistoryContainer theHistory; - __impl::MutexRS _theHistory_lock; + xmt::MutexRS _theHistory_lock; public: @@ -599,7 +580,7 @@ explicit __FIT_DECLSPEC EventHandler( addr_type id, const char *info = 0 ); virtual __FIT_DECLSPEC ~EventHandler(); - __FIT_DECLSPEC const string& who_is( addr_type k ) const; + __FIT_DECLSPEC const std::string who_is( addr_type k ) const; __FIT_DECLSPEC bool is_avail( addr_type id ) const; static EvManager *manager() { return _mgr; } Modified: trunk/explore/lib/stem/ChangeLog =================================================================== --- trunk/explore/lib/stem/ChangeLog 2006-10-12 11:24:15 UTC (rev 1314) +++ trunk/explore/lib/stem/ChangeLog 2006-10-12 11:25:06 UTC (rev 1315) @@ -1,3 +1,13 @@ +2006-10-12 Petr Ovtchenkov <pt...@is...> + + * NetTransport.h, NetTransport.cc: remove make_map, + it useless and even dangerous in practice. + + * EvManager.h, EventHandler.h, _EventHandler.cc: + allow change announce of object's info; return + string object instead of const reference from + annotate by safety reasons. + 2006-10-10 Petr Ovtchenkov <pt...@is...> * NetTransport.h, EventHandler.h, EvManager.h: remove Modified: trunk/explore/lib/stem/_EventHandler.cc =================================================================== --- trunk/explore/lib/stem/_EventHandler.cc 2006-10-12 11:24:15 UTC (rev 1314) +++ trunk/explore/lib/stem/_EventHandler.cc 2006-10-12 11:25:06 UTC (rev 1315) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/10 18:12:26 ptr> +// -*- C++ -*- Time-stamp: <06/10/12 14:09:20 ptr> /* * Copyright (c) 1995-1999, 2002, 2003, 2005, 2006 @@ -59,7 +59,7 @@ } __FIT_DECLSPEC -const string& EventHandler::who_is( addr_type k ) const +const string EventHandler::who_is( addr_type k ) const { return _mgr->who_is( k ); } Modified: trunk/explore/test/libstem/unit/Echo.cc =================================================================== --- trunk/explore/test/libstem/unit/Echo.cc 2006-10-12 11:24:15 UTC (rev 1314) +++ trunk/explore/test/libstem/unit/Echo.cc 2006-10-12 11:25:06 UTC (rev 1315) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/11 14:54:52 ptr> +// -*- C++ -*- Time-stamp: <06/10/12 15:12:19 ptr> /* * Copyright (c) 2006 @@ -45,12 +45,8 @@ void StEMecho::regme( const stem::Event& ev ) { + manager()->change_announce( ev.src(), ev.value() ); cnd.set( true ); - stem::NetTransport_base *b = manager()->transport( ev.src() ); - BOOST_CHECK( b != 0 ); - if ( b != 0 ) { - b->make_map( ev.src(), (ev.value() /* + who_is( ev.src() ) */ ).c_str() ); - } } DEFINE_RESPONSE_TABLE( StEMecho ) Modified: trunk/explore/test/libstem/unit/unit_test.cc =================================================================== --- trunk/explore/test/libstem/unit/unit_test.cc 2006-10-12 11:24:15 UTC (rev 1314) +++ trunk/explore/test/libstem/unit/unit_test.cc 2006-10-12 11:25:06 UTC (rev 1315) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/10/11 15:36:32 ptr> +// -*- C++ -*- Time-stamp: <06/10/12 15:15:13 ptr> /* * Copyright (c) 2002, 2003, 2006 @@ -390,7 +390,7 @@ stem::Event ev( NODE_EV_REGME ); ev.dest( zero ); - ev.value() = "c1"; + ev.value() = "c1@here"; c1.Send( ev ); // 'register' c1 client on 'echo' server echo.cnd.try_wait(); @@ -398,7 +398,7 @@ PeerClient c2( "c2 local" ); // c2 client - ev.value() = "c2"; + ev.value() = "c2@here"; c2.Send( ev ); // 'register' c2 client on 'echo' server echo.cnd.try_wait(); @@ -423,9 +423,7 @@ BOOST_CHECK( i->first & stem::extbit ); // "external" if ( i->second.find( "c2@" ) == 0 ) { // make pair: address on side of c1 -> address on side of 'echo' - // note: on side of 'echo' server there are mapping too, - // address on side of 'echo' -> address on side of c2 - peer_addr = tr->make_map( i->first, "c2@foreign" ); + peer_addr = c1.manager()->SubscribeRemote( tr, i->first, "c2@foreign" ); } // cerr << hex << i->first << dec << " => " << i->second << endl; // cerr << hex << tr->make_map( i->first, "map" ) << dec << endl; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2006-10-24 06:41:46
|
Revision: 1346 http://svn.sourceforge.net/complement/?rev=1346&view=rev Author: complement Date: 2006-10-23 23:41:35 -0700 (Mon, 23 Oct 2006) Log Message: ----------- move timespec functions to time.cc; move sleep-like functions from Thread to xmt namespace in time.cc Modified Paths: -------------- trunk/explore/include/mt/time.h trunk/explore/include/mt/xmt.h trunk/explore/lib/mt/ChangeLog trunk/explore/lib/mt/time.cc trunk/explore/lib/mt/xmt.cc Modified: trunk/explore/include/mt/time.h =================================================================== --- trunk/explore/include/mt/time.h 2006-10-24 06:40:06 UTC (rev 1345) +++ trunk/explore/include/mt/time.h 2006-10-24 06:41:35 UTC (rev 1346) @@ -1,40 +1,83 @@ -// -*- C++ -*- Time-stamp: <02/09/25 11:37:39 ptr> +// -*- C++ -*- Time-stamp: <06/10/24 09:28:28 ptr> /* - * - * Copyright (c) 2002 + * Copyright (c) 2002, 2006 * Petr Ovtchenkov * - * Licensed under the Academic Free License Version 1.0 + * Licensed under the Academic Free License version 3.0 * - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. */ -#ifndef __time_h -#define __time_h +#ifndef __mt_time_h +#define __mt_time_h -#ifdef __unix -# ifdef __HP_aCC -#pragma VERSIONID "@(#)$Id$" -# else -#ident "@(#)$Id$" -# endif -#endif - #ifndef __config_feature_h #include <config/feature.h> #endif +#ifdef WIN32 +# include <windows.h> +# include <memory> +# include <ctime> +# include <limits> +# pragma warning( disable : 4290) +#endif // WIN32 + #include <string> -#include <time.h> +#include <ctime> +#ifdef N_PLAT_NLM +# include <sys/time.h> // timespec, timespec_t +#endif + +#ifdef _WIN32 +extern "C" { + +typedef struct timespec { /* definition per POSIX.4 */ + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +} timespec_t; + +} // extern "C" +#endif // _WIN32 + +#if defined(_WIN32) || defined(N_PLAT_NLM) +extern "C" { + +typedef struct timespec timestruc_t; /* definition per SVr4 */ + +} // extern "C" +#endif + std::string calendar_time( time_t t ); -#endif // __time_h +timespec operator +( const timespec& a, const timespec& b ); +timespec operator -( const timespec& a, const timespec& b ); +timespec operator /( const timespec& a, unsigned b ); +timespec operator /( const timespec& a, unsigned long b ); + +// timespec& operator =( timespec& a, const timespec& b ); +timespec& operator +=( timespec& a, const timespec& b ); +timespec& operator -=( timespec& a, const timespec& b ); +timespec& operator /=( timespec& a, unsigned b ); +timespec& operator /=( timespec& a, unsigned long b ); + +bool operator >( const timespec& a, const timespec& b ); +bool operator >=( const timespec& a, const timespec& b ); +bool operator <( const timespec& a, const timespec& b ); +bool operator <=( const timespec& a, const timespec& b ); +bool operator ==( const timespec& a, const timespec& b ); +bool operator !=( const timespec& a, const timespec& b ); + +namespace xmt { + +// delay execution at least on time interval t +__FIT_DECLSPEC void delay( timespec *interval, timespec *remain ); +// sleep at least up to time t +__FIT_DECLSPEC void sleep( timespec *abstime, timespec *real_time ); +// get precise time +__FIT_DECLSPEC void gettime( timespec *t ); + +} // namespace xmt + +#endif // __mt_time_h Modified: trunk/explore/include/mt/xmt.h =================================================================== --- trunk/explore/include/mt/xmt.h 2006-10-24 06:40:06 UTC (rev 1345) +++ trunk/explore/include/mt/xmt.h 2006-10-24 06:41:35 UTC (rev 1346) @@ -1,23 +1,14 @@ -// -*- C++ -*- Time-stamp: <06/09/18 13:32:44 ptr> +// -*- C++ -*- Time-stamp: <06/10/24 09:24:01 ptr> /* - * - * Copyright (c) 1997-1999, 2002-2005 + * Copyright (c) 1997-1999, 2002-2006 * Petr Ovtchenkov * * Portion Copyright (c) 1999-2001 * Parallel Graphics Ltd. * - * Licensed under the Academic Free License Version 2.1 + * Licensed under the Academic Free License version 3.0 * - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. */ #ifndef __XMT_H @@ -38,7 +29,6 @@ #ifdef WIN32 # include <windows.h> # include <memory> -# include <ctime> # include <limits> # define ETIME 62 /* timer expired */ # pragma warning( disable : 4290) @@ -46,9 +36,6 @@ #ifdef __unix # if defined( _REENTRANT ) && !defined(_NOTHREADS) -# if defined( __STL_USE_NEW_STYLE_HEADERS ) && defined( __SUNPRO_CC ) -# include <ctime> -# endif # ifdef _PTHREADS # include <pthread.h> # include <semaphore.h> @@ -67,37 +54,15 @@ # include <nwthread.h> # include <nwsemaph.h> # include <nwproc.h> -# include <ctime> # elif !defined(_NOTHREADS) // !_REENTRANT # define _NOTHREADS # endif #endif -#ifdef N_PLAT_NLM -# include <sys/time.h> // timespec, timespec_t -#endif - #include <cerrno> -#ifdef _WIN32 -extern "C" { +#include <mt/time.h> -typedef struct timespec { /* definition per POSIX.4 */ - time_t tv_sec; /* seconds */ - long tv_nsec; /* and nanoseconds */ -} timespec_t; - -} // extern "C" -#endif // _WIN32 - -#if defined(_WIN32) || defined(N_PLAT_NLM) -extern "C" { - -typedef struct timespec timestruc_t; /* definition per SVr4 */ - -} // extern "C" -#endif - #ifdef _REENTRANT # define MT_REENTRANT(point,nm) xmt::Locker nm(point) @@ -1512,11 +1477,15 @@ static __FIT_DECLSPEC void signal_exit( int sig ); // signal handler // sleep at least up to time t - static __FIT_DECLSPEC void sleep( timespec *t, timespec *e = 0 ); + static void sleep( timespec *t, timespec *e = 0 ) + { xmt::sleep( t, e ); } // delay execution at least on time interval t - static __FIT_DECLSPEC void delay( timespec *t, timespec *e = 0 ); + static void delay( timespec *t, timespec *e = 0 ) + { xmt::delay( t, e ); } // get precise time - static __FIT_DECLSPEC void gettime( timespec *t ); + static void gettime( timespec *t ) + { xmt::gettime( t ); } + #ifndef _WIN32 static __FIT_DECLSPEC void fork() throw( fork_in_parent, std::runtime_error ); static __FIT_DECLSPEC void become_daemon() throw( fork_in_parent, std::runtime_error ); @@ -1703,7 +1672,7 @@ #endif #if defined(__FIT_UITHREADS) || defined(_PTHREADS) timespec ct; - Thread::gettime( &ct ); + xmt::gettime( &ct ); ct += *interval; int ret = 0; @@ -1824,7 +1793,7 @@ #endif #if defined(__FIT_UITHREADS) || defined(_PTHREADS) timespec ct; - Thread::gettime( &ct ); + xmt::gettime( &ct ); ct += *interval; return this->wait_time( &ct ); @@ -1845,21 +1814,4 @@ namespace __impl = xmt; // compatibility -timespec operator +( const timespec& a, const timespec& b ); -timespec operator -( const timespec& a, const timespec& b ); -timespec operator /( const timespec& a, unsigned b ); -timespec operator /( const timespec& a, unsigned long b ); - -// timespec& operator =( timespec& a, const timespec& b ); -timespec& operator +=( timespec& a, const timespec& b ); -timespec& operator -=( timespec& a, const timespec& b ); -timespec& operator /=( timespec& a, unsigned b ); -timespec& operator /=( timespec& a, unsigned long b ); - -bool operator >( const timespec& a, const timespec& b ); -bool operator >=( const timespec& a, const timespec& b ); -bool operator <( const timespec& a, const timespec& b ); -bool operator <=( const timespec& a, const timespec& b ); -bool operator ==( const timespec& a, const timespec& b ); - #endif // __XMT_H Modified: trunk/explore/lib/mt/ChangeLog =================================================================== --- trunk/explore/lib/mt/ChangeLog 2006-10-24 06:40:06 UTC (rev 1345) +++ trunk/explore/lib/mt/ChangeLog 2006-10-24 06:41:35 UTC (rev 1346) @@ -1,3 +1,9 @@ +2006-10-24 Petr Ovtchenkov <pt...@is...> + + * xmt.h, xmt.cc, time.h, time.cc: move timespec functions to + time.cc; move sleep-like functions from Thread to xmt namespace + in time.cc. + 2006-10-10 Petr Ovtchenkov <pt...@is...> * thr_mgr.cc: don't kill not finished threads in ThreadMgr's Modified: trunk/explore/lib/mt/time.cc =================================================================== --- trunk/explore/lib/mt/time.cc 2006-10-24 06:40:06 UTC (rev 1345) +++ trunk/explore/lib/mt/time.cc 2006-10-24 06:41:35 UTC (rev 1346) @@ -1,36 +1,18 @@ -// -*- C++ -*- Time-stamp: <03/09/24 21:04:53 ptr> +// -*- C++ -*- Time-stamp: <06/10/24 09:26:53 ptr> /* - * - * Copyright (c) 2002, 2003 + * Copyright (c) 2002, 2003, 2006 * Petr Ovtchenkov * - * Licensed under the Academic Free License Version 1.2 + * Licensed under the Academic Free License version 3.0 * - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. */ -#ifdef __unix -# ifdef __HP_aCC -#pragma VERSIONID "@(#)$Id$" -# else -#ident "@(#)$Id$" -# endif -#endif - #include <mt/time.h> +#include <mt/xmt.h> #ifdef _WIN32 -#include <mt/xmt.h> - -__impl::Mutex _l; +xmt::Mutex _l; #endif std::string calendar_time( time_t t ) @@ -63,3 +45,260 @@ return std::string( ctime( &t ) ); #endif } + +timespec operator +( const timespec& a, const timespec& b ) +{ + timespec c; + + c.tv_sec = a.tv_sec; + c.tv_nsec = a.tv_nsec; + c.tv_sec += b.tv_sec; + c.tv_nsec += b.tv_nsec; + c.tv_sec += c.tv_nsec / 1000000000; + c.tv_nsec %= 1000000000; + + return c; +} + +timespec operator -( const timespec& a, const timespec& b ) +{ + timespec c; + + c.tv_sec = a.tv_sec > b.tv_sec ? a.tv_sec - b.tv_sec : 0; // out_of_range? + if ( a.tv_nsec >= b.tv_nsec ) { + c.tv_nsec = a.tv_nsec - b.tv_nsec; + } else if ( c.tv_sec > 0 ) { + --c.tv_sec; + c.tv_nsec = 1000000000 - b.tv_nsec + a.tv_nsec; + } else { + c.tv_nsec = 0; // out_of_range? + } + + return c; +} + +timespec operator /( const timespec& a, unsigned b ) +{ + timespec c; + double d = a.tv_sec + 1.0e-9 * a.tv_nsec; + d /= b; + + c.tv_nsec = int(1.0e9 * modf( d, &d ) + 0.5); + c.tv_sec = int(d); + + return c; +} + +timespec operator /( const timespec& a, unsigned long b ) +{ + timespec c; + double d = a.tv_sec + 1.0e-9 * a.tv_nsec; + d /= b; + + c.tv_nsec = int(1.0e9 * modf( d, &d ) + 0.5); + c.tv_sec = int(d); + + return c; +} + +timespec& operator +=( timespec& a, const timespec& b ) +{ + a.tv_sec += b.tv_sec; + a.tv_nsec += b.tv_nsec; + a.tv_sec += a.tv_nsec / 1000000000; + a.tv_nsec %= 1000000000; + + return a; +} + +timespec& operator -=( timespec& a, const timespec& b ) +{ + a.tv_sec = a.tv_sec > b.tv_sec ? a.tv_sec - b.tv_sec : 0; // out_of_range? + if ( a.tv_nsec >= b.tv_nsec ) { + a.tv_nsec -= b.tv_nsec; + } else if ( a.tv_sec > 0 ) { + --a.tv_sec; + a.tv_nsec += 1000000000 - b.tv_nsec; + } else { + a.tv_nsec = 0; // out_of_range? + } + + return a; +} + +timespec& operator /=( timespec& a, unsigned b ) +{ + double d = a.tv_sec + 1.0e-9 * a.tv_nsec; + d /= b; + + a.tv_nsec = int(1.0e9 * modf( d, &d ) + 0.5); + a.tv_sec = int(d); + + return a; +} + +timespec& operator /=( timespec& a, unsigned long b ) +{ + double d = a.tv_sec + 1.0e-9 * a.tv_nsec; + d /= b; + + a.tv_nsec = int(1.0e9 * modf( d, &d ) + 0.5); + a.tv_sec = int(d); + + return a; +} + +bool operator ==( const timespec& a, const timespec& b ) +{ + return (a.tv_sec == b.tv_sec) && (a.tv_nsec == b.tv_nsec); +} + +bool operator !=( const timespec& a, const timespec& b ) +{ + return (a.tv_sec != b.tv_sec) || (a.tv_nsec != b.tv_nsec); +} + +bool operator >( const timespec& a, const timespec& b ) +{ + if ( a.tv_sec > b.tv_sec ) { + return true; + } else if ( b.tv_sec > a.tv_sec ) { + return false; + } + + return a.tv_nsec > b.tv_nsec; +} + +bool operator >=( const timespec& a, const timespec& b ) +{ + if ( a.tv_sec > b.tv_sec ) { + return true; + } else if ( b.tv_sec > a.tv_sec ) { + return false; + } + + return a.tv_nsec >= b.tv_nsec; +} + +bool operator <( const timespec& a, const timespec& b ) +{ + if ( a.tv_sec < b.tv_sec ) { + return true; + } else if ( b.tv_sec < a.tv_sec ) { + return false; + } + + return a.tv_nsec < b.tv_nsec; +} + +bool operator <=( const timespec& a, const timespec& b ) +{ + if ( a.tv_sec < b.tv_sec ) { + return true; + } else if ( b.tv_sec < a.tv_sec ) { + return false; + } + + return a.tv_nsec <= b.tv_nsec; +} + +namespace xmt { + +__FIT_DECLSPEC +void delay( timespec *interval, timespec *remain ) +{ +#ifdef __unix + nanosleep( interval, remain ); +#endif +#ifdef WIN32 + unsigned ms = interval->tv_sec * 1000 + interval->tv_nsec / 1000000; + Sleep( ms ); + if ( remain != 0 ) { // M$ not return remain time interval + remain->tv_sec = 0; + remain->tv_nsec = 0; + } +#endif +#ifdef __FIT_NETWARE + unsigned ms = interval->tv_sec * 1000 + interval->tv_nsec / 1000000; + ::delay( ms ); + if ( remain != 0 ) { // Novell not return remain time interval + remain->tv_sec = 0; + remain->tv_nsec = 0; + } +#endif +} + +__FIT_DECLSPEC +void sleep( timespec *abstime, timespec *real_time ) +{ +#ifdef __unix + timespec ct; + gettime( &ct ); + timespec st = *abstime; + + if ( st > ct ) { + st -= ct; + nanosleep( &st, real_time ); + if ( real_time != 0 ) { + *real_time += ct; + } + } else if ( real_time != 0 ) { + *real_time = ct; + } +#endif +#ifdef WIN32 + time_t ct = time( 0 ); + time_t _conv = abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000; + + unsigned ms = _conv >= ct ? _conv - ct : 1; + Sleep( ms ); + if ( real_time != 0 ) { // M$ not return elapsed time interval + real_time->tv_sec = abstime->tv_sec; + real_time->tv_nsec = abstime->tv_nsec; + } +#endif +#ifdef __FIT_NETWARE + time_t ct = time( 0 ); + time_t _conv = abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000; + + unsigned ms = _conv >= ct ? _conv - ct : 1; + ::delay( ms ); + if ( real_time != 0 ) { // Novell not return elapsed time interval + real_time->tv_sec = abstime->tv_sec; + real_time->tv_nsec = abstime->tv_nsec; + } +#endif +} + +__FIT_DECLSPEC +void gettime( timespec *t ) +{ +#if defined(__linux) || defined(__FreeBSD__) || defined(__OpenBSD__) + timeval tv; + gettimeofday( &tv, 0 ); + TIMEVAL_TO_TIMESPEC( &tv, t ); +#elif defined( WIN32 ) + union { + FILETIME ft; // 100 ns intervals since Jan 1 1601 (UTC) + __int64 t; + } ft; + GetSystemTimeAsFileTime( &ft.ft ); + t->tv_sec = int(ft.t / (__int64)10000000 - (__int64)(11644473600)); // 60 * 60 * 24 * 134774, 1970 - 1601 + t->tv_nsec = int(ft.t % (__int64)(10000000)) * 100; + + //time_t ct = time( 0 ); + //t->tv_sec = ct; // ct / 1000; + //t->tv_nsec = 0; // (ct % 1000) * 1000000; +#elif defined(__sun) || defined(__hpux) + clock_gettime( CLOCK_REALTIME, t ); +#elif defined(__FIT_NETWARE) + time_t ct = time(0); // GetHighResolutionTimer (ret current time in 100 microsec increments) + // GetSuperHighResolutionTimer() (ret current time in 838 nanosec increments) + t->tv_sec = ct; + t->tv_nsec = 0; +#else +#error "You should implement OS-dependent precise clock" +#endif +} + +} // namespace xmt Modified: trunk/explore/lib/mt/xmt.cc =================================================================== --- trunk/explore/lib/mt/xmt.cc 2006-10-24 06:40:06 UTC (rev 1345) +++ trunk/explore/lib/mt/xmt.cc 2006-10-24 06:41:35 UTC (rev 1346) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/09/22 22:19:40 ptr> +// -*- C++ -*- Time-stamp: <06/10/24 09:32:17 ptr> /* * Copyright (c) 1997-1999, 2002-2006 @@ -711,103 +711,6 @@ Thread::_exit( 0 ); } -__FIT_DECLSPEC -void Thread::delay( timespec *interval, timespec *remain ) -{ -#ifdef __unix - nanosleep( interval, remain ); -#endif -#ifdef WIN32 - unsigned ms = interval->tv_sec * 1000 + interval->tv_nsec / 1000000; - Sleep( ms ); - if ( remain != 0 ) { // M$ not return remain time interval - remain->tv_sec = 0; - remain->tv_nsec = 0; - } -#endif -#ifdef __FIT_NETWARE - unsigned ms = interval->tv_sec * 1000 + interval->tv_nsec / 1000000; - ::delay( ms ); - if ( remain != 0 ) { // Novell not return remain time interval - remain->tv_sec = 0; - remain->tv_nsec = 0; - } -#endif -} - -__FIT_DECLSPEC -void Thread::sleep( timespec *abstime, timespec *real_time ) -{ -#ifdef __unix - timespec ct; - gettime( &ct ); - timespec st = *abstime; - - if ( st > ct ) { - st -= ct; - nanosleep( &st, real_time ); - if ( real_time != 0 ) { - *real_time += ct; - } - } else if ( real_time != 0 ) { - *real_time = ct; - } -#endif -#ifdef WIN32 - time_t ct = time( 0 ); - time_t _conv = abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000; - - unsigned ms = _conv >= ct ? _conv - ct : 1; - Sleep( ms ); - if ( real_time != 0 ) { // M$ not return elapsed time interval - real_time->tv_sec = abstime->tv_sec; - real_time->tv_nsec = abstime->tv_nsec; - } -#endif -#ifdef __FIT_NETWARE - time_t ct = time( 0 ); - time_t _conv = abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000; - - unsigned ms = _conv >= ct ? _conv - ct : 1; - ::delay( ms ); - if ( real_time != 0 ) { // Novell not return elapsed time interval - real_time->tv_sec = abstime->tv_sec; - real_time->tv_nsec = abstime->tv_nsec; - } -#endif -} - -__FIT_DECLSPEC -void Thread::gettime( timespec *t ) -{ -#if defined(__linux) || defined(__FreeBSD__) || defined(__OpenBSD__) - timeval tv; - gettimeofday( &tv, 0 ); - TIMEVAL_TO_TIMESPEC( &tv, t ); -#elif defined( WIN32 ) - union { - FILETIME ft; // 100 ns intervals since Jan 1 1601 (UTC) - __int64 t; - } ft; - GetSystemTimeAsFileTime( &ft.ft ); - t->tv_sec = int(ft.t / (__int64)10000000 - (__int64)(11644473600)); // 60 * 60 * 24 * 134774, 1970 - 1601 - t->tv_nsec = int(ft.t % (__int64)(10000000)) * 100; - - //time_t ct = time( 0 ); - //t->tv_sec = ct; // ct / 1000; - //t->tv_nsec = 0; // (ct % 1000) * 1000000; -#elif defined(__sun) || defined(__hpux) - clock_gettime( CLOCK_REALTIME, t ); -#elif defined(__FIT_NETWARE) - time_t ct = time(0); // GetHighResolutionTimer (ret current time in 100 microsec increments) - // GetSuperHighResolutionTimer() (ret current time in 838 nanosec increments) - t->tv_sec = ct; - t->tv_nsec = 0; -#else -#error "You should implement OS-dependent precise clock" -#endif -} - #ifndef _WIN32 __FIT_DECLSPEC void Thread::fork() throw( fork_in_parent, std::runtime_error ) @@ -1102,155 +1005,3 @@ } } // namespace xmt - - -timespec operator +( const timespec& a, const timespec& b ) -{ - timespec c; - - c.tv_sec = a.tv_sec; - c.tv_nsec = a.tv_nsec; - c.tv_sec += b.tv_sec; - c.tv_nsec += b.tv_nsec; - c.tv_sec += c.tv_nsec / 1000000000; - c.tv_nsec %= 1000000000; - - return c; -} - -timespec operator -( const timespec& a, const timespec& b ) -{ - timespec c; - - c.tv_sec = a.tv_sec > b.tv_sec ? a.tv_sec - b.tv_sec : 0; // out_of_range? - if ( a.tv_nsec >= b.tv_nsec ) { - c.tv_nsec = a.tv_nsec - b.tv_nsec; - } else if ( c.tv_sec > 0 ) { - --c.tv_sec; - c.tv_nsec = 1000000000 - b.tv_nsec + a.tv_nsec; - } else { - c.tv_nsec = 0; // out_of_range? - } - - return c; -} - -timespec operator /( const timespec& a, unsigned b ) -{ - timespec c; - double d = a.tv_sec + 1.0e-9 * a.tv_nsec; - d /= b; - - c.tv_nsec = int(1.0e9 * modf( d, &d ) + 0.5); - c.tv_sec = int(d); - - return c; -} - -timespec operator /( const timespec& a, unsigned long b ) -{ - timespec c; - double d = a.tv_sec + 1.0e-9 * a.tv_nsec; - d /= b; - - c.tv_nsec = int(1.0e9 * modf( d, &d ) + 0.5); - c.tv_sec = int(d); - - return c; -} - -timespec& operator +=( timespec& a, const timespec& b ) -{ - a.tv_sec += b.tv_sec; - a.tv_nsec += b.tv_nsec; - a.tv_sec += a.tv_nsec / 1000000000; - a.tv_nsec %= 1000000000; - - return a; -} - -timespec& operator -=( timespec& a, const timespec& b ) -{ - a.tv_sec = a.tv_sec > b.tv_sec ? a.tv_sec - b.tv_sec : 0; // out_of_range? - if ( a.tv_nsec >= b.tv_nsec ) { - a.tv_nsec -= b.tv_nsec; - } else if ( a.tv_sec > 0 ) { - --a.tv_sec; - a.tv_nsec += 1000000000 - b.tv_nsec; - } else { - a.tv_nsec = 0; // out_of_range? - } - - return a; -} - -timespec& operator /=( timespec& a, unsigned b ) -{ - double d = a.tv_sec + 1.0e-9 * a.tv_nsec; - d /= b; - - a.tv_nsec = int(1.0e9 * modf( d, &d ) + 0.5); - a.tv_sec = int(d); - - return a; -} - -timespec& operator /=( timespec& a, unsigned long b ) -{ - double d = a.tv_sec + 1.0e-9 * a.tv_nsec; - d /= b; - - a.tv_nsec = int(1.0e9 * modf( d, &d ) + 0.5); - a.tv_sec = int(d); - - return a; -} - -bool operator ==( const timespec& a, const timespec& b ) -{ - return (a.tv_sec == b.tv_sec) && (a.tv_nsec == b.tv_nsec); -} - -bool operator >( const timespec& a, const timespec& b ) -{ - if ( a.tv_sec > b.tv_sec ) { - return true; - } else if ( b.tv_sec > a.tv_sec ) { - return false; - } - - return a.tv_nsec > b.tv_nsec; -} - -bool operator >=( const timespec& a, const timespec& b ) -{ - if ( a.tv_sec > b.tv_sec ) { - return true; - } else if ( b.tv_sec > a.tv_sec ) { - return false; - } - - return a.tv_nsec >= b.tv_nsec; -} - -bool operator <( const timespec& a, const timespec& b ) -{ - if ( a.tv_sec < b.tv_sec ) { - return true; - } else if ( b.tv_sec < a.tv_sec ) { - return false; - } - - return a.tv_nsec < b.tv_nsec; -} - -bool operator <=( const timespec& a, const timespec& b ) -{ - if ( a.tv_sec < b.tv_sec ) { - return true; - } else if ( b.tv_sec < a.tv_sec ) { - return false; - } - - return a.tv_nsec <= b.tv_nsec; -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |