[complement-svn] SF.net SVN: complement: [1522] trunk/complement/explore/test/sockios
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2007-02-09 10:34:43
|
Revision: 1522 http://svn.sourceforge.net/complement/?rev=1522&view=rev Author: complement Date: 2007-02-09 02:34:41 -0800 (Fri, 09 Feb 2007) Log Message: ----------- clean tests Modified Paths: -------------- trunk/complement/explore/test/sockios/Makefile.inc trunk/complement/explore/test/sockios/sockios_test.cc trunk/complement/explore/test/sockios/sockios_test.h trunk/complement/explore/test/sockios/sockios_test_suite.cc trunk/complement/explore/test/sockios/unit_test.cc Added Paths: ----------- trunk/complement/explore/test/sockios/names.cc Removed Paths: ------------- trunk/complement/explore/test/sockios/read0_on_exec.cc Modified: trunk/complement/explore/test/sockios/Makefile.inc =================================================================== --- trunk/complement/explore/test/sockios/Makefile.inc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/Makefile.inc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <06/12/18 16:43:21 ptr> +# -*- makefile -*- Time-stamp: <07/02/07 10:26:26 ptr> 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 bytes_in_socket2.cc read0_on_exec.cc \ - sockios_test.cc sockios_test_suite.cc + client-wc.cc close_socket.cc bytes_in_socket.cc bytes_in_socket2.cc \ + names.cc sockios_test.cc sockios_test_suite.cc Added: trunk/complement/explore/test/sockios/names.cc =================================================================== --- trunk/complement/explore/test/sockios/names.cc (rev 0) +++ trunk/complement/explore/test/sockios/names.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -0,0 +1,140 @@ +// -*- C++ -*- Time-stamp: <07/02/07 10:28:34 ptr> + +/* + * + * Copyright (c) 2002, 2003, 2005-2007 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#include "sockios_test.h" + +#include <boost/test/unit_test.hpp> + +#include <sockios/sockstream> +#include <sockios/sockmgr.h> + +#include <list> + +#include <arpa/inet.h> + +using namespace boost::unit_test_framework; +using namespace std; + +/* ************************************************************ */ + +void names_sockios_test::hostname_test() +{ + unsigned long local = htonl( 0x7f000001 ); // 127.0.0.1 + +#ifdef _LITTLE_ENDIAN + BOOST_CHECK_EQUAL( local, 0x0100007f ); +#endif + +#ifdef _BIG_ENDIAN + BOOST_CHECK_EQUAL( local, 0x7f000001 ); +#endif + + BOOST_CHECK_EQUAL( std::hostname( local ), "localhost [127.0.0.1]" ); + +#ifdef __unix + char buff[1024]; + + gethostname( buff, 1024 ); + + BOOST_CHECK_EQUAL( std::hostname(), buff ); +#endif +} + +/* ************************************************************ */ + +void names_sockios_test::service_test() +{ +#ifdef __unix + BOOST_CHECK( std::service( "ftp", "tcp" ) == 21 ); + BOOST_CHECK( std::service( 7, "udp" ) == "echo" ); +#else + BOOST_ERROR( "requests for service (/etc/services) not implemented on this platform" ); +#endif +} + +/* ************************************************************ */ + +void names_sockios_test::hostaddr_test1() +{ +#ifdef __unix + in_addr addr = std::findhost( "localhost" ); + +# ifdef _LITTLE_ENDIAN + BOOST_CHECK_EQUAL( addr.s_addr, 0x0100007f ); +# endif + +# ifdef _BIG_ENDIAN + BOOST_CHECK_EQUAL( addr.s_addr, 0x7f000001 ); +# endif + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} + +/* ************************************************************ */ + +void names_sockios_test::hostaddr_test2() +{ +#ifdef __unix + list<in_addr> haddrs; + std::gethostaddr( "localhost", back_inserter(haddrs) ); + + bool localhost_found = false; + + for ( list<in_addr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { + if ( i->s_addr == htonl( 0x7f000001 ) ) { // 127.0.0.1 + localhost_found = true; + break; + } + } + + BOOST_CHECK( localhost_found == true ); + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} + +/* ************************************************************ */ + +void names_sockios_test::hostaddr_test3() +{ +#ifdef __unix + list<sockaddr> haddrs; + gethostaddr2( "localhost", back_inserter(haddrs) ); + + bool localhost_found = false; + + for ( list<sockaddr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { + switch ( i->sa_family ) { + case PF_INET: + if ( ((sockaddr_in *)&*i)->sin_addr.s_addr == htonl( 0x7f000001 ) ) { + localhost_found = true; + } + break; + case PF_INET6: + if ( ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[0] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[1] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[2] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[3] == 1 ) { + localhost_found = true; + } + break; + } + } + + BOOST_CHECK( localhost_found == true ); + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} Deleted: trunk/complement/explore/test/sockios/read0_on_exec.cc =================================================================== --- trunk/complement/explore/test/sockios/read0_on_exec.cc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/read0_on_exec.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,259 +0,0 @@ -// -*- C++ -*- Time-stamp: <07/01/29 19:17:54 ptr> - -/* - * Copyright (c) 2006, 2007 - * 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 <mt/xmt.h> - -#include <sockios/sockstream> -#include <sockios/sockmgr.h> - -#include <sys/types.h> -#include <sys/wait.h> - -#include <mt/shm.h> - -using namespace std; -using namespace xmt; - -/* - * The problem: - * 1. Server listen socket (process A) - * 2. Client connect to server (process B, server --- process A) - * 3. Client try to read from socket (from server) and block on it, - * due to server write nothing (thread i) [Hmm, really here - poll with POLLIN flag and then read] - * 4. In another thread (thread ii) client call system() - * 5. Due to fork/execl (in system()) client return from read (step 3) - * with 0, i.e. as on close connection - * - * The POSIX say: - * (execl) - * If the Asynchronous Input and Output option is supported, any - * outstanding asynchronous I/O operations may be canceled. Those - * asynchronous I/O operations that are not canceled will complete - * as if the exec function had not yet occurred, but any associated - * signal notifications are suppressed. It is unspecified whether - * the exec function itself blocks awaiting such I/O completion. In no event, - * however, will the new process image created by the exec function be affected - * by the presence of outstanding asynchronous I/O operations at the time - * the exec function is called. Whether any I/O is cancelled, and which I/O may - * be cancelled upon exec, is implementation-dependent. - * - * Client open socket --------- system() - * \ - * read...[poll signaled, read -> 0] - * - * The same issue on server side: poll that wait POLLIN from clients - * signaled too. - * - */ - -extern int port; -extern xmt::Mutex pr_lock; - -// static __Condition<true> cndf; - -class ConnectionProcessor5 // dummy variant -{ - public: - ConnectionProcessor5( std::sockstream& ); - - void connect( std::sockstream& ); - void close(); -}; - -ConnectionProcessor5::ConnectionProcessor5( std::sockstream& s ) -{ - pr_lock.lock(); - BOOST_MESSAGE( "Server seen connection" ); - - BOOST_REQUIRE( s.good() ); - pr_lock.unlock(); - - // cerr << "ConnectionProcessor5::ConnectionProcessor5\n"; - delay( xmt::timespec(3,0) ); - - int n = 1; - // cerr << "ConnectionProcessor5::ConnectionProcessor5, write\n"; - s.write( (const char *)&n, sizeof( int ) ).flush(); -} - -void ConnectionProcessor5::connect( std::sockstream& s ) -{ -} - -void ConnectionProcessor5::close() -{ - pr_lock.lock(); - BOOST_MESSAGE( "Server: client close connection" ); - pr_lock.unlock(); -} - -Thread::ret_code thread_entry( void *par ) -{ - Thread::ret_code rt; - Condition& cnd = *reinterpret_cast<Condition *>(par); - - // sem.wait(); // wait server for listen us - sockstream sock( "localhost", ::port ); - int buff = 0; - // cerr << "thread_entry" << endl; - cnd.set( true ); - // Note: due to this is another process then main, boost can report - // about errors here, but don't count error it in summary, if it occur! - BOOST_CHECK( sock.read( (char *)&buff, sizeof(int) ).good() ); // <---- key line - BOOST_CHECK( buff == 1 ); - // cerr << "Read pass" << endl; - - rt.iword = 0; - return rt; -} - -void test_read0() -{ - const char fname[] = "/tmp/sockios_test.shm"; - try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); - // xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - - xmt::allocator_shm<xmt::__Condition<true>,0> shm; - - xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); - // nm.named( fcnd, 1 ); - fcnd.set( false ); - - try { - xmt::fork(); // <---- key line - fcnd.try_wait(); // wait server for listen us - - Condition cnd; - cnd.set( false ); - - xmt::Thread thr( thread_entry, &cnd ); - - cnd.try_wait(); // wait for read call - - delay( xmt::timespec(1,0) ); - - // cerr << "system" << endl; - system( "echo > /dev/null" ); // <------ key line - // cerr << "after system" << endl; - - thr.join(); - // cerr << "exit child" << endl; - exit( 0 ); - } - catch ( xmt::fork_in_parent& child ) { - // cerr << "** 3" << endl; - sockmgr_stream_MP<ConnectionProcessor5> srv( ::port ); // start server - - fcnd.set( true ); - - int stat; - waitpid( child.pid(), &stat, 0 ); - srv.close(); - srv.wait(); - } - - (&fcnd)->~__Condition<true>(); - shm.deallocate( &fcnd, 1 ); - - seg.deallocate(); - unlink( fname ); - } - catch ( xmt::shm_bad_alloc& err ) { - BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); - } -} - -class ConnectionProcessor6 // dummy variant -{ - public: - ConnectionProcessor6( std::sockstream& ); - - void connect( std::sockstream& ); - void close(); -}; - -static Condition cnd6; - -ConnectionProcessor6::ConnectionProcessor6( std::sockstream& s ) -{ - pr_lock.lock(); - BOOST_MESSAGE( "Server seen connection" ); - - BOOST_REQUIRE( s.good() ); - pr_lock.unlock(); - - cnd6.set( true ); -} - -void ConnectionProcessor6::connect( std::sockstream& s ) -{ -} - -void ConnectionProcessor6::close() -{ - pr_lock.lock(); - BOOST_MESSAGE( "Server: client close connection" ); - pr_lock.unlock(); -} - -void test_read0_srv() -{ - try { - sockmgr_stream_MP<ConnectionProcessor6> srv( ::port ); - - BOOST_CHECK( srv.good() ); - cnd6.set( false ); - - { - // It should work as before system call... - sockstream s( "localhost", ::port ); - - s << "1" << endl; - - BOOST_CHECK( s.good() ); - - cnd6.try_wait(); - } - - cnd6.set( false ); - - system( "echo > /dev/null" ); // <------ key line - - BOOST_CHECK( srv.good() ); - - { - // ... as after system call. - sockstream s( "localhost", ::port ); - - s << "1" << endl; - - BOOST_CHECK( s.good() ); - - cnd6.try_wait(); - } - - BOOST_CHECK( srv.good() ); // server must correctly process interrupt during system call - - srv.close(); - srv.wait(); - } - catch ( xmt::shm_bad_alloc& err ) { - BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); - } -} Modified: trunk/complement/explore/test/sockios/sockios_test.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.cc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/sockios_test.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/31 23:47:57 ptr> +// -*- C++ -*- Time-stamp: <07/02/07 11:32:06 ptr> /* * @@ -17,126 +17,44 @@ #include <sockios/sockstream> #include <sockios/sockmgr.h> -#include <list> - -#include <arpa/inet.h> - #include <mt/shm.h> - -// #include <sys/shm.h> #include <sys/wait.h> - #include <signal.h> using namespace boost::unit_test_framework; using namespace std; -void sockios_test::hostname_test() -{ - unsigned long local = htonl( 0x7f000001 ); // 127.0.0.1 +const char fname[] = "/tmp/sockios_test.shm"; +xmt::shm_alloc<0> seg; +xmt::allocator_shm<xmt::__Condition<true>,0> shm_cnd; +xmt::allocator_shm<xmt::__Barrier<true>,0> shm_b; -#ifdef _LITTLE_ENDIAN - BOOST_CHECK_EQUAL( local, 0x0100007f ); -#endif - -#ifdef _BIG_ENDIAN - BOOST_CHECK_EQUAL( local, 0x7f000001 ); -#endif - - BOOST_CHECK_EQUAL( std::hostname( local ), "localhost [127.0.0.1]" ); - -#ifdef __unix - char buff[1024]; - - gethostname( buff, 1024 ); - - BOOST_CHECK_EQUAL( std::hostname(), buff ); -#endif -} - -void sockios_test::service_test() +sockios_test::sockios_test() { -#ifdef __unix - BOOST_CHECK( std::service( "ftp", "tcp" ) == 21 ); - BOOST_CHECK( std::service( 7, "udp" ) == "echo" ); -#else - BOOST_ERROR( "requests for service (/etc/services) not implemented on this platform" ); -#endif } -void sockios_test::hostaddr_test1() +sockios_test::~sockios_test() { -#ifdef __unix - in_addr addr = std::findhost( "localhost" ); - -# ifdef _LITTLE_ENDIAN - BOOST_CHECK_EQUAL( addr.s_addr, 0x0100007f ); -# endif - -# ifdef _BIG_ENDIAN - BOOST_CHECK_EQUAL( addr.s_addr, 0x7f000001 ); -# endif - -#else - BOOST_ERROR( "Not implemented" ); -#endif } -void sockios_test::hostaddr_test2() +void sockios_test::init() { -#ifdef __unix - list<in_addr> haddrs; - std::gethostaddr( "localhost", back_inserter(haddrs) ); - - bool localhost_found = false; - - for ( list<in_addr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { - if ( i->s_addr == htonl( 0x7f000001 ) ) { // 127.0.0.1 - localhost_found = true; - break; - } + try { + seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); } - - BOOST_CHECK( localhost_found == true ); - -#else - BOOST_ERROR( "Not implemented" ); -#endif + catch ( const xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } } -void sockios_test::hostaddr_test3() +void sockios_test::finit() { -#ifdef __unix - list<sockaddr> haddrs; - gethostaddr2( "localhost", back_inserter(haddrs) ); + seg.deallocate(); + unlink( fname ); +} - bool localhost_found = false; +/* ************************************************************ */ - for ( list<sockaddr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { - switch ( i->sa_family ) { - case PF_INET: - if ( ((sockaddr_in *)&*i)->sin_addr.s_addr == htonl( 0x7f000001 ) ) { - localhost_found = true; - } - break; - case PF_INET6: - if ( ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[0] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[1] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[2] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[3] == 1 ) { - localhost_found = true; - } - break; - } - } - - BOOST_CHECK( localhost_found == true ); - -#else - BOOST_ERROR( "Not implemented" ); -#endif -} - class Cnt { public: @@ -182,7 +100,7 @@ BOOST_CHECK( s1.good() ); BOOST_CHECK( s1.is_open() ); while ( Cnt::get_visits() == 0 ) { - xmt::delay( xmt::timespec(0,10000) ); + xmt::Thread::yield(); } Cnt::lock.lock(); BOOST_CHECK( Cnt::cnt == 1 ); @@ -222,7 +140,7 @@ BOOST_CHECK( s2.good() ); BOOST_CHECK( s2.is_open() ); while ( Cnt::get_visits() < 2 ) { - xmt::delay( xmt::timespec(0,10000) ); + xmt::Thread::yield(); } Cnt::lock.lock(); BOOST_CHECK( Cnt::cnt == 2 ); @@ -242,6 +160,8 @@ Cnt::lock.unlock(); } +/* ************************************************************ */ + class loader { public: @@ -268,7 +188,7 @@ { } -xmt::Thread::ret_code client_thr( void * ) +xmt::Thread::ret_code client_thr( void *p ) { xmt::Thread::ret_code ret; @@ -280,11 +200,15 @@ fill( buf, buf + 1024, 0 ); + xmt::Barrier& b = *reinterpret_cast<xmt::Barrier *>(p); + b.wait(); + while( true ) { s.write( buf, 1024 ); s.flush(); s.read( buf, 1024 ); + xmt::Thread::yield(); } return ret; @@ -292,34 +216,22 @@ void sigpipe_handler( int sig, siginfo_t *si, void * ) { +#if 0 cerr << "-----------------------------------------------\n" << "my pid: " << xmt::getpid() << ", ppid: " << xmt::getppid() << "\n" << "signal: " << sig << ", number " << si->si_signo << " errno " << si->si_errno << " code " << si->si_code << endl; +#endif } void sockios_test::sigpipe() { - const char fname[] = "/tmp/sockios_test.shm"; - enum { - in_Child_Condition = 1, - threads_Started_Condition = 2 - }; try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); - xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - - xmt::allocator_shm<xmt::__Condition<true>,0> shm; - - xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); - nm.named( fcnd, in_Child_Condition ); + xmt::__Condition<true>& fcnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); fcnd.set( false ); - xmt::__Condition<true>& tcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); - nm.named( tcnd, threads_Started_Condition ); + xmt::__Condition<true>& tcnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); tcnd.set( false ); try { @@ -332,15 +244,15 @@ * This process will be killed, * so I don't care about safe termination. */ - xmt::Thread *th1 = new xmt::Thread( client_thr ); - for ( int i = 0; i < /* 10 */ 2; ++i ) { - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); + const int b_count = 10; + xmt::Barrier b( b_count ); + xmt::Thread *th1 = new xmt::Thread( client_thr, &b ); + + for ( int i = 0; i < (b_count - 1); ++i ) { + new xmt::Thread( client_thr, &b ); } - xmt::delay( xmt::timespec(1,0) ); + xmt::delay( xmt::timespec(0,500000000) ); tcnd.set( true ); @@ -373,18 +285,17 @@ } (&tcnd)->~__Condition<true>(); - shm.deallocate( &tcnd, 1 ); + shm_cnd.deallocate( &tcnd, 1 ); (&fcnd)->~__Condition<true>(); - shm.deallocate( &fcnd, 1 ); - - seg.deallocate(); - unlink( fname ); + shm_cnd.deallocate( &fcnd, 1 ); } catch ( xmt::shm_bad_alloc& err ) { BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); } } +/* ************************************************************ */ + class long_msg_processor // { public: @@ -420,21 +331,13 @@ xmt::__Condition<true> *long_msg_processor::cnd; -void sockios_test::long_msg_test() +void sockios_test::long_msg() { - const char fname[] = "/tmp/sockios_test.shm"; try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); - xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - - xmt::allocator_shm<xmt::__Condition<true>,0> shm; - - xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + xmt::__Condition<true>& fcnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); fcnd.set( false ); - xmt::__Condition<true>& srv_cnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + xmt::__Condition<true>& srv_cnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); srv_cnd.set( false ); long_msg_processor::cnd = &srv_cnd; @@ -478,16 +381,244 @@ } (&fcnd)->~__Condition<true>(); - shm.deallocate( &fcnd, 1 ); + shm_cnd.deallocate( &fcnd, 1 ); (&srv_cnd)->~__Condition<true>(); - shm.deallocate( &srv_cnd, 1 ); + shm_cnd.deallocate( &srv_cnd, 1 ); + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } +} - seg.deallocate(); - unlink( fname ); +/* ************************************************************ + * The problem: + * 1. Server listen socket (process A) + * 2. Client connect to server (process B, server --- process A) + * 3. Client try to read from socket (from server) and block on it, + * due to server write nothing (thread i) [Hmm, really here + * poll with POLLIN flag and then read] + * 4. In another thread (thread ii) client call system() + * 5. Due to fork/execl (in system()) client return from read (step 3) + * with 0, i.e. as on close connection + * + * The POSIX say: + * (execl) + * If the Asynchronous Input and Output option is supported, any + * outstanding asynchronous I/O operations may be canceled. Those + * asynchronous I/O operations that are not canceled will complete + * as if the exec function had not yet occurred, but any associated + * signal notifications are suppressed. It is unspecified whether + * the exec function itself blocks awaiting such I/O completion. In no event, + * however, will the new process image created by the exec function be affected + * by the presence of outstanding asynchronous I/O operations at the time + * the exec function is called. Whether any I/O is cancelled, and which I/O may + * be cancelled upon exec, is implementation-dependent. + * + * Client open socket --------- system() + * \ + * read...[poll signaled, read -> 0] + * + * The same issue on server side: poll that wait POLLIN from clients + * signaled too. + * + */ + +class ConnectionProcessor5 // dummy variant +{ + public: + ConnectionProcessor5( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); + + static xmt::__Barrier<true> *b; +}; + + +xmt::__Barrier<true> *ConnectionProcessor5::b = 0; + +ConnectionProcessor5::ConnectionProcessor5( std::sockstream& s ) +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server seen connection" ); + + BOOST_REQUIRE( s.good() ); + // pr_lock.unlock(); + + // cerr << "ConnectionProcessor5::ConnectionProcessor5\n"; + // delay( xmt::timespec(3,0) ); + + int n = 1; + // cerr << "ConnectionProcessor5::ConnectionProcessor5, write\n"; + b->wait(); + s.write( (const char *)&n, sizeof( int ) ).flush(); +} + +void ConnectionProcessor5::connect( std::sockstream& s ) +{ +} + +void ConnectionProcessor5::close() +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server: client close connection" ); + // pr_lock.unlock(); +} + +xmt::Thread::ret_code thread_entry( void *par ) +{ + xmt::Thread::ret_code rt; + xmt::Condition& cnd = *reinterpret_cast<xmt::Condition *>(par); + + // sem.wait(); // wait server for listen us + sockstream sock( "localhost", ::port ); + int buff = 0; + // cerr << "thread_entry" << endl; + cnd.set( true ); + // Note: due to this is another process then main, boost can report + // about errors here, but don't count error it in summary, if it occur! + BOOST_CHECK( sock.read( (char *)&buff, sizeof(int) ).good() ); // <---- key line + BOOST_CHECK( buff == 1 ); + // cerr << "Read pass" << endl; + + rt.iword = 0; + return rt; +} + +void sockios_test::read0() +{ + try { + xmt::__Condition<true>& fcnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); + xmt::__Barrier<true>& b = *new ( shm_b.allocate( 1 ) ) xmt::__Barrier<true>(); + ConnectionProcessor5::b = &b; + // nm.named( fcnd, 1 ); + fcnd.set( false ); + + try { + xmt::fork(); // <---- key line + fcnd.try_wait(); // wait server for listen us + + xmt::Condition cnd; + cnd.set( false ); + + xmt::Thread thr( thread_entry, &cnd ); + + cnd.try_wait(); // wait for read call + + // delay( xmt::timespec(1,0) ); + + // cerr << "system" << endl; + system( "echo > /dev/null" ); // <------ key line + // cerr << "after system" << endl; + + b.wait(); + + thr.join(); + // cerr << "exit child" << endl; + exit( 0 ); + } + catch ( xmt::fork_in_parent& child ) { + // cerr << "** 3" << endl; + sockmgr_stream_MP<ConnectionProcessor5> srv( ::port ); // start server + + fcnd.set( true ); + + int stat; + waitpid( child.pid(), &stat, 0 ); + srv.close(); + srv.wait(); + } + + (&b)->~__Barrier<true>(); + shm_b.deallocate( &b, 1 ); + (&fcnd)->~__Condition<true>(); + shm_cnd.deallocate( &fcnd, 1 ); } catch ( xmt::shm_bad_alloc& err ) { BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); } +} +/* ************************************************************ */ + +class ConnectionProcessor6 // dummy variant +{ + public: + ConnectionProcessor6( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); + + static xmt::Condition cnd; +}; + +xmt::Condition ConnectionProcessor6::cnd; + +ConnectionProcessor6::ConnectionProcessor6( std::sockstream& s ) +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server seen connection" ); + + BOOST_REQUIRE( s.good() ); + // pr_lock.unlock(); + + cnd.set( true ); } + +void ConnectionProcessor6::connect( std::sockstream& s ) +{ +} + +void ConnectionProcessor6::close() +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server: client close connection" ); + // pr_lock.unlock(); +} + +void sockios_test::read0_srv() +{ + try { + sockmgr_stream_MP<ConnectionProcessor6> srv( ::port ); + + BOOST_CHECK( srv.good() ); + ConnectionProcessor6::cnd.set( false ); + + { + // It should work as before system call... + sockstream s( "localhost", ::port ); + + s << "1" << endl; + + BOOST_CHECK( s.good() ); + + ConnectionProcessor6::cnd.try_wait(); + } + + ConnectionProcessor6::cnd.set( false ); + + system( "echo > /dev/null" ); // <------ key line + + BOOST_CHECK( srv.good() ); + + { + // ... as after system call. + sockstream s( "localhost", ::port ); + + s << "1" << endl; + + BOOST_CHECK( s.good() ); + + ConnectionProcessor6::cnd.try_wait(); + } + + BOOST_CHECK( srv.good() ); // server must correctly process interrupt during system call + + srv.close(); + srv.wait(); + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } +} Modified: trunk/complement/explore/test/sockios/sockios_test.h =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.h 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/sockios_test.h 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/30 10:55:51 ptr> +// -*- C++ -*- Time-stamp: <07/02/07 10:51:25 ptr> /* * @@ -12,7 +12,7 @@ #ifndef __sockios_test_h #define __sockios_test_h -struct sockios_test +struct names_sockios_test { void hostname_test(); void service_test(); @@ -20,11 +20,23 @@ void hostaddr_test1(); void hostaddr_test2(); void hostaddr_test3(); +}; +struct sockios_test +{ + sockios_test(); + ~sockios_test(); + + void init(); + void finit(); + void ctor_dtor(); + void long_msg(); + void sigpipe(); - void long_msg_test(); + void read0(); + void read0_srv(); }; #endif // __sockios_test_h Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/30 10:57:38 ptr> +// -*- C++ -*- Time-stamp: <07/02/07 11:00:07 ptr> /* * @@ -20,18 +20,14 @@ sockios_test_suite::sockios_test_suite() : test_suite( "sockios library test suite" ) { - boost::shared_ptr<sockios_test> instance( new sockios_test() ); - test_case *hostname_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostname_test, instance ); - test_case *service_tc = BOOST_CLASS_TEST_CASE( &sockios_test::service_test, instance ); + boost::shared_ptr<names_sockios_test> names_instance( new names_sockios_test() ); - test_case *hostaddr1_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test1, instance ); - test_case *hostaddr2_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test2, instance ); - test_case *hostaddr3_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test3, instance ); - test_case *ctor_dtor_tc = BOOST_CLASS_TEST_CASE( &sockios_test::ctor_dtor, instance ); - test_case *sigpipe_tc = BOOST_CLASS_TEST_CASE( &sockios_test::sigpipe, instance ); - test_case *long_msg_tc = BOOST_CLASS_TEST_CASE( &sockios_test::long_msg_test, instance ); + test_case *hostname_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::hostname_test, names_instance ); + test_case *service_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::service_test, names_instance ); - // hostaddr2_tc->depends_on( hostaddr1_tc ); + test_case *hostaddr1_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::hostaddr_test1, names_instance ); + test_case *hostaddr2_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::hostaddr_test2, names_instance ); + test_case *hostaddr3_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::hostaddr_test3, names_instance ); add( hostname_tc ); add( service_tc ); @@ -39,7 +35,32 @@ add( hostaddr1_tc ); add( hostaddr2_tc ); add( hostaddr3_tc ); + + + boost::shared_ptr<sockios_test> instance( new sockios_test() ); + test_case *init_tc = BOOST_CLASS_TEST_CASE( &sockios_test::init, instance ); + test_case *finit_tc = BOOST_CLASS_TEST_CASE( &sockios_test::finit, instance ); + + test_case *ctor_dtor_tc = BOOST_CLASS_TEST_CASE( &sockios_test::ctor_dtor, instance ); + test_case *long_msg_tc = BOOST_CLASS_TEST_CASE( &sockios_test::long_msg, instance ); + test_case *sigpipe_tc = BOOST_CLASS_TEST_CASE( &sockios_test::sigpipe, instance ); + + test_case *read0_tc = BOOST_CLASS_TEST_CASE( &sockios_test::read0, instance ); + test_case *read0_srv_tc = BOOST_CLASS_TEST_CASE( &sockios_test::read0_srv, instance ); + + long_msg_tc->depends_on( init_tc ); + long_msg_tc->depends_on( ctor_dtor_tc ); + sigpipe_tc->depends_on( ctor_dtor_tc ); + sigpipe_tc->depends_on( init_tc ); + read0_tc->depends_on( sigpipe_tc ); + read0_srv_tc->depends_on( sigpipe_tc ); + finit_tc->depends_on( init_tc ); + + add( init_tc ); add( ctor_dtor_tc ); + add( long_msg_tc ); add( sigpipe_tc ); - add( long_msg_tc ); + add( read0_tc, 0, 5 ); + add( read0_srv_tc ); + add( finit_tc ); } Modified: trunk/complement/explore/test/sockios/unit_test.cc =================================================================== --- trunk/complement/explore/test/sockios/unit_test.cc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/unit_test.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,8 +1,8 @@ -// -*- C++ -*- Time-stamp: <07/01/29 19:19:10 ptr> +// -*- C++ -*- Time-stamp: <07/02/07 10:09:14 ptr> /* * - * Copyright (c) 2002, 2003, 2005, 2006 + * Copyright (c) 2002, 2003, 2005-2007 * Petr Ovtchenkov * * Licensed under the Academic Free License version 3.0 @@ -344,23 +344,13 @@ void test_client_close_socket(); void test_more_bytes_in_socket(); void test_more_bytes_in_socket2(); -void test_read0(); -void test_read0_srv(); - test_suite *init_unit_test_suite( int argc, char **argv ) { test_suite *ts = BOOST_TEST_SUITE( "libsockios test" ); ts->add( new sockios_test_suite() ); - // ts->add( BOOST_TEST_CASE( &hostname_test ) ); - // ts->add( BOOST_TEST_CASE( &service_test ) ); - - // ts->add( BOOST_TEST_CASE( &hostaddr_test1 ) ); - // ts->add( BOOST_TEST_CASE( &hostaddr_test2 ) ); - // ts->add( BOOST_TEST_CASE( &hostaddr_test3 ) ); - ts->add( BOOST_TEST_CASE( &test_client_server_poll ) ); // ts->add( BOOST_TEST_CASE( &test_client_server_select ) ); @@ -385,8 +375,6 @@ 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_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. |