[complement-svn] SF.net SVN: complement: [1309] trunk/explore
Status: Pre-Alpha
Brought to you by:
complement
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. |