Onega's profileOnegaBlogListsNetwork Tools Help

Blog


    September 30

    build boost_1_40_0.7z via Visual Studio 2008 Profession on Windows XP

    At first I build it in usual way as I did with boost 1.39, but bjam (Boost.Jam 03.1.17) prints a lot of errors like the following.

    cl : Command line error D8022 : cannot open 'bin.v2\libs\math\config\msvc-9.0\debug\link-static\threading-multi\has_long_double_support.obj.rsp'

    The file does exist on my disk. At last I resort to the tool File Monitor in order to find out the root cause. File Monitor captured the following error:

    1:53:37 PM    cl.exe:6324    OPEN    D:\bin.v2\libs\math\build\msvc-9.0\debug\threading-multi\pch.pch.rsp    PATH NOT FOUND    Options: Open  Access: Read   

    It seems that bjam was passing incorrect path to cl.exe. The error is known, and the fix is simple. I created the following batch file and build it successfully. Before starting, I already have d:\boost_1_40_0\bjam.exe in place. size of d:\boost_1_40_0 is 5.56 GB after build completed.

    subst x: D:\boost_1_40_0
    call "%VS90COMNTOOLS%\..\..\vc\bin\vcvars32.bat"
    SET PYTHON_ROOT=C:\Python26
    SET PYTHON_VERSION=2.6
    SET ICU_PATH=D:\opensource\ICU4C-4_2\icu
    cd /d x:\
    .\bjam.exe --without-mpi --toolset=msvc-9.0 stage --build-type=complete

     

    Command line to build single library:

    cd /d D:\opensource\boost\boost_1_40_0\libs\program_options\build
    D:\opensource\boost\bjam.exe "-sTOOLS=msvc" link=static threading=multi
    D:\opensource\boost\bjam.exe "-sTOOLS=msvc" link=static threading=multi variant=release
    D:\opensource\boost\bjam.exe "-sTOOLS=msvc" threading=multi variant=release
    D:\opensource\boost\bjam.exe "-sTOOLS=msvc" threading=multi variant=release

    Command line from "Building Boost with Visual Studio"

    .\bjam --toolset=msvc-9.0 --with-date_time --with-filesystem --with-iostreams -sBZIP2_INCLUDE=C:\bzip2-1.0.5 -sBZIP2_SOURCE=C:\bzip2-1.0.5 -sZLIB_INCLUDE=C:\zlib-1.2.3 -sZLIB_SOURCE=C:\zlib-1.2.3 --with-serialization --with-test --with-thread --build-type=complete stage

    Command line from boost-users@lists.boost.org

    bjam --layout=versioned --toolset=msvc-9.0 variant=debug threading=multi link=static runtime-link=static stage

    September 22

    file transfer over asynchronous TCP connection via boost.asio

    // another sample that send file name and content to Tcp server, but using asynchronous mode Tcp connection

    //
    // send a file to a tcp server via boost.asio library
    #include <iostream>
    #include <boost/asio.hpp>
    #include <boost/bind.hpp>
    #include <fstream>
    #include <sstream>
    using boost::asio::ip::tcp;
    class async_tcp_client
    {
    public:
        async_tcp_client(boost::asio::io_service& io_service,
            const std::string& server, const std::string& path)
            : resolver_(io_service),
            socket_(io_service)
        {
            size_t pos = server.find(':');
            if (pos==std::string::npos)
                return;
            std::string port_string = server.substr(pos+1);
            std::string server_ip_or_host = server.substr(0, pos);

            source_file.open(path.c_str(), std::ios_base::binary | std::ios_base::ate);
            if (!source_file)
            {
                std::cout << "failed to open " << path << std::endl;
                return ;
            }
            size_t file_size = source_file.tellg();
            source_file.seekg(0);
            // first send file name and file size to server
            std::ostream request_stream(&request_);
            request_stream << path << "\n"
                << file_size << "\n\n";
            std::cout << "request size:"<<request_.size()<<std::endl;
            // Start an asynchronous resolve to translate the server and service names
            // into a list of endpoints.
            tcp::resolver::query query(server_ip_or_host, port_string);
            resolver_.async_resolve(query,
                boost::bind(&async_tcp_client::handle_resolve, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::iterator));
        }

    private:
        void handle_resolve(const boost::system::error_code& err,
            tcp::resolver::iterator endpoint_iterator)
        {
            if (!err)
            {
                // Attempt a connection to the first endpoint in the list. Each endpoint
                // will be tried until we successfully establish a connection.
                tcp::endpoint endpoint = *endpoint_iterator;
                socket_.async_connect(endpoint,
                    boost::bind(&async_tcp_client::handle_connect, this,
                    boost::asio::placeholders::error, ++endpoint_iterator));
            }
            else
            {
                std::cout << "Error: " << err.message() << "\n";
            }
        }

        void handle_connect(const boost::system::error_code& err,
            tcp::resolver::iterator endpoint_iterator)
        {
            if (!err)
            {
                // The connection was successful. Send the request.
                boost::asio::async_write(socket_, request_,
                    boost::bind(&async_tcp_client::handle_write_file, this,
                    boost::asio::placeholders::error));
            }
            else if (endpoint_iterator != tcp::resolver::iterator())
            {
                // The connection failed. Try the next endpoint in the list.
                socket_.close();
                tcp::endpoint endpoint = *endpoint_iterator;
                socket_.async_connect(endpoint,
                    boost::bind(&async_tcp_client::handle_connect, this,
                    boost::asio::placeholders::error, ++endpoint_iterator));
            }
            else
            {
                std::cout << "Error: " << err.message() << "\n";
            }
        }

        void handle_write_file(const boost::system::error_code& err)
        {
            if (!err)
            {
                    if (source_file.eof()==false)
                    {
                        source_file.read(buf.c_array(), (std::streamsize)buf.size());
                        if (source_file.gcount()<=0)
                        {
                            std::cout << "read file error " << std::endl;
                            return;
                        }
                        std::cout << "send " <<source_file.gcount()<<" bytes, total:" << source_file.tellg() << " bytes.\n";
                        boost::asio::async_write(socket_,
                            boost::asio::buffer(buf.c_array(), source_file.gcount()),
                            boost::bind(&async_tcp_client::handle_write_file, this,
                            boost::asio::placeholders::error));
                        if (err)
                        {
                            std::cout << "send error:" << err << std::endl;
                            return;
                        }
                    }
                    else
                        return;
            }
            else
            {
                std::cout << "Error: " << err.message() << "\n";
            }

        }
        tcp::resolver resolver_;
        tcp::socket socket_;
        boost::array<char, 1024> buf;
        boost::asio::streambuf request_;
        std::ifstream source_file;
    };
    int main(int argc, char* argv[])
    {
        if (argc != 3)
        {
            std::cerr << "Usage: " << argv[0] << " <server-address> <file path>" << std::endl;
            std::cerr << "sample: " << argv[0] << " 127.0.0.1:1234 c:\\tmp\\a.txt" << std::endl;
            return __LINE__;
        }
        try
        {
            boost::asio::io_service io_service;
            async_tcp_client client(io_service, argv[1], argv[2]);
            io_service.run();

            std::cout << "send file " << argv[2] << " completed successfully.\n";
    //         system("pause");
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
        return 0;
    }

    // I also made an asynchronous Tcp server to accept work with above client.

    //receive a file from socket client via boost.asio
    #include <iostream>
    #include <string>
    #include <boost/asio.hpp>
    #include <fstream>
    #include <boost/bind.hpp>
    #include <boost/function.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/enable_shared_from_this.hpp>
    unsigned short tcp_port = 1234;
    class async_tcp_connection: public boost::enable_shared_from_this<async_tcp_connection>
    {
    public:
        async_tcp_connection(boost::asio::io_service& io_service)
            : socket_(io_service), file_size(0)
        {
        }
        void start()
        {
            std::cout << __FUNCTION__  << std::endl;
            async_read_until(socket_,
                request_buf, "\n\n",
                boost::bind(&async_tcp_connection::handle_read_request,
                shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
        }
        boost::asio::ip::tcp::socket& socket() { return socket_; }
    private:
        boost::asio::streambuf request_buf;
        size_t file_size;
        std::ofstream output_file;
        boost::asio::ip::tcp::socket socket_;
        boost::array<char, 40960> buf;
        void handle_read_request(const boost::system::error_code& err, std::size_t bytes_transferred)
        {
            if (err)
            {
                return handle_error(__FUNCTION__, err);
            }
            std::cout << __FUNCTION__ << "(" << bytes_transferred << ")"
                << ", in_avail=" << request_buf.in_avail()
                << ", size=" << request_buf.size()
                << ", max_size=" << request_buf.max_size() <<".\n";
            std::istream request_stream(&request_buf);
            std::string file_path;           
            request_stream >> file_path;
            request_stream >> file_size;
            request_stream.read(buf.c_array(), 2); // eat the "\n\n"
            std::cout << file_path << " size is " << file_size << ", tellg=" << request_stream.tellg()<< std::endl;
            size_t pos = file_path.find_last_of('\\');
            if (pos!=std::string::npos)
                file_path = file_path.substr(pos+1);
            output_file.open(file_path.c_str(), std::ios_base::binary);
            if (!output_file)
            {
                std::cout << "failed to open " << file_path << std::endl;
                return;
            }
            // write extra bytes to file
            do
            {
                request_stream.read(buf.c_array(), (std::streamsize)buf.size());
                std::cout << __FUNCTION__ << " write " << request_stream.gcount() << " bytes.\n";
                output_file.write(buf.c_array(), request_stream.gcount());
            } while (request_stream.gcount()>0);
            async_read(socket_, boost::asio::buffer(buf.c_array(), buf.size()),
                boost::bind(&async_tcp_connection::handle_read_file_content,
                shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));          
        }

        void handle_read_file_content(const boost::system::error_code& err, std::size_t bytes_transferred)
        {
            if (bytes_transferred>0)
            {
                output_file.write(buf.c_array(), (std::streamsize)bytes_transferred);
                std::cout << __FUNCTION__ << " recv " << output_file.tellp() << " bytes."<< std::endl;
                if (output_file.tellp()>=(std::streamsize)file_size)
                {
                    return;
                }
            }
            if (err)
            {
                return handle_error(__FUNCTION__, err);
            }
            async_read(socket_, boost::asio::buffer(buf.c_array(), buf.size()),
                boost::bind(&async_tcp_connection::handle_read_file_content,
                shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
        }
        void handle_error(const std::string& function_name, const boost::system::error_code& err)
        {
            std::cout << __FUNCTION__ << " in " << function_name <<" due to " << err <<" " << err.message()<< std::endl;
        }
    };

    class async_tcp_server : private boost::noncopyable
    {
    public:
        typedef boost::shared_ptr<async_tcp_connection> ptr_async_tcp_connection;

        async_tcp_server(unsigned short port)
            : acceptor_(io_service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), true)
        {
                ptr_async_tcp_connection new_connection_(new async_tcp_connection(io_service_));
                acceptor_.async_accept(new_connection_->socket(),
                boost::bind(&async_tcp_server::handle_accept, this,new_connection_,
                boost::asio::placeholders::error));
                io_service_.run();
       }   
        void handle_accept(ptr_async_tcp_connection current_connection, const boost::system::error_code& e)
        {
            std::cout << __FUNCTION__ << " " << e << ", " << e.message()<<std::endl;
            if (!e)
            {
                current_connection->start();
                //ptr_async_tcp_connection new_connection_(new async_tcp_connection(io_service_));
                //acceptor_.async_accept(new_connection_->socket(),
                //    boost::bind(&async_tcp_server::handle_accept, this,new_connection_,
                //    boost::asio::placeholders::error));
            }
        }
        ~async_tcp_server()
        {
            io_service_.stop();
        }
    private:
        boost::asio::io_service io_service_;
        boost::asio::ip::tcp::acceptor acceptor_;
    };

    int main(int argc, char* argv[])
    {
        try
        {
            if (argc==2)
            {
                tcp_port=atoi(argv[1]);
            }
            std::cout <<argv[0] << " listen on port " << tcp_port << std::endl;
            async_tcp_server *recv_file_tcp_server = new async_tcp_server(tcp_port);
            delete recv_file_tcp_server;
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
        return 0;
    }

    file transfer over synchronousTCP connection via boost.asio

    //First is a synchronous TCP client that send file name and file content to Tcp Server.

    //
    // send a file to a tcp server via boost.asio library
    #include <iostream>
    #include <boost/asio.hpp>
    #include <fstream>
    #include <sstream>
    using boost::asio::ip::tcp;
    int main(int argc, char* argv[])
    {
        if (argc != 3)
        {
            std::cerr << "Usage: " << argv[0] << " <server-address> <file path>" << std::endl;
            std::cerr << "sample: " << argv[0] << " 127.0.0.1:1234 c:\\tmp\\a.txt" << std::endl;
            return __LINE__;
        }
        try
        {
            std::string server_ip_or_host = argv[1];
            size_t pos = server_ip_or_host.find(':');
            if (pos==std::string::npos)
                return __LINE__;
            std::string port_string = server_ip_or_host.substr(pos+1);
            server_ip_or_host = server_ip_or_host.substr(0, pos);
            boost::asio::io_service io_service;
            tcp::resolver resolver(io_service);
            tcp::resolver::query query(server_ip_or_host, port_string);
            tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
            tcp::resolver::iterator end;
            tcp::socket socket(io_service);
            boost::system::error_code error = boost::asio::error::host_not_found;
            while (error && endpoint_iterator != end)
            {
                socket.close();
                socket.connect(*endpoint_iterator++, error);
            }
            if (error)
                return __LINE__;
            std::cout << "connected to " << argv[1] << std::endl;
            boost::array<char, 1024> buf;
            std::ifstream source_file(argv[2], std::ios_base::binary | std::ios_base::ate);
            if (!source_file)
            {
                std::cout << "failed to open " << argv[2] << std::endl;
                return __LINE__;
            }
            size_t file_size = source_file.tellg();
            source_file.seekg(0);
            // first send file name and file size to server
            boost::asio::streambuf request;
            std::ostream request_stream(&request);
            request_stream << argv[2] << "\n"
                << file_size << "\n\n";
            boost::asio::write(socket, request);
            std::cout << "start sending file content.\n";
            for (;;)
            {

                if (source_file.eof()==false)
                {
                    source_file.read(buf.c_array(), (std::streamsize)buf.size());
                    if (source_file.gcount()<=0)
                    {
                        std::cout << "read file error " << std::endl;
                        return __LINE__;
                    }
                    boost::asio::write(socket, boost::asio::buffer(buf.c_array(),
                        source_file.gcount()),
                        boost::asio::transfer_all(), error);
                    if (error)
                    {
                        std::cout << "send error:" << error << std::endl;
                        return __LINE__;
                    }
                }
                else
                    break;
            }
            std::cout << "send file " << argv[2] << " completed successfully.\n";
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
        return 0;
    }

     

    // next is a Tcp server working in synchronous mode that accept file from above Tcp client. This sample also demonstrate usage of async_read_until(). The trick with async_read_until is that it will read more than I want and those extra bytes must be properly handled.

    //receive a file from socket client via boost.asio
    #include <ctime>
    #include <iostream>
    #include <string>
    #include <boost/asio.hpp>
    #include <fstream>
    #include <sstream>
    unsigned short tcp_port = 1234;

    int main(int argc, char* argv[])
    {
        boost::array<char, 1024> buf;
        size_t file_size = 0;
        try
        {
            if (argc==2)
            {
                tcp_port=atoi(argv[1]);
            }
            std::cout <<argv[0] << " listen on port " << tcp_port << std::endl;
            boost::asio::io_service io_service;
            boost::asio::ip::tcp::acceptor acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), tcp_port));
            boost::system::error_code error;
            boost::asio::ip::tcp::socket socket(io_service);
            acceptor.accept(socket);
            std::cout << "get client connection." << std::endl;
            boost::asio::streambuf request_buf;
            boost::asio::read_until(socket, request_buf, "\n\n");
            std::cout<< "request size:" << request_buf.size() << "\n";
            std::istream request_stream(&request_buf);
            std::string file_path;           
            request_stream >> file_path;
            request_stream >> file_size;
            request_stream.read(buf.c_array(), 2); // eat the "\n\n"

            std::cout << file_path << " size is " << file_size << std::endl;
            size_t pos = file_path.find_last_of('\\');
            if (pos!=std::string::npos)
                file_path = file_path.substr(pos+1);
            std::ofstream output_file(file_path.c_str(), std::ios_base::binary);
            if (!output_file)
            {
                std::cout << "failed to open " << file_path << std::endl;
                return __LINE__;
            }

            // write extra bytes to file
            do
            {
                request_stream.read(buf.c_array(), (std::streamsize)buf.size());
                std::cout << __FUNCTION__ << " write " << request_stream.gcount() << " bytes.\n";
                output_file.write(buf.c_array(), request_stream.gcount());
            } while (request_stream.gcount()>0);

            for (;;)
            {
                size_t len = socket.read_some(boost::asio::buffer(buf), error);
                if (len>0)
                    output_file.write(buf.c_array(), (std::streamsize)len);
                if (output_file.tellp()== (std::fstream::pos_type)(std::streamsize)file_size)
                    break; // file was received
                if (error)
                {
                    std::cout << error << std::endl;
                    break;
                }
            }
            std::cout << "received " << output_file.tellp() << " bytes.\n";
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
        return 0;
    }

    July 04

    usage of boost::program_options::parse_config_file

    I just need to create options_description as usual, and prepare configuration file in the following format:

    #include <boost/program_options.hpp>
    namespace po = boost::program_options;

    std::stringstream ss;
    ss  << "CurrentX=1234"<<std::endl
        <<"CurrentY=456"<<std::endl;
        po::options_description desc("Allowed options");
        desc.add_options()
            ("help,h", "produce help message")
            ("CurrentX", po::value<int>(), "set CurrentX")
            ("CurrentY", po::value<int>(), "set CurrentY")
            ;

        po::variables_map vm;       
        po::store(po::parse_config_file(ss, desc, true), vm);

    May 28

    Build boost 1.39 with python 2.6 and ICU4.2 via VC++ 2008

    --build-type=complete option does not work with boost 1.39 (bjam reports error). So I am recording the following commands”

    ECHOE change code page to 1252
    chcp 1252
    rem chcp 1252 can't remove the warning about code page problem
    call "%VS90COMNTOOLS%\..\..\vc\bin\vcvars32.bat"
    SET PYTHON_ROOT=C:\Python26
    SET PYTHON_VERSION=2.6
    SET ICU_PATH=D:\opensource\ICU4C-4_2\icu
    cd /d D:\opensource\boost_1_39_0
    rem D:\opensource\boost_1_39_0\bjam.exe --without-mpi --toolset=msvc-9.0 stage --build-type=complete
    D:\opensource\boost_1_39_0\bjam.exe --without-mpi --toolset=msvc-9.0 debug release threading=multi
    D:\opensource\boost_1_39_0\bjam.exe --without-mpi --toolset=msvc-9.0 debug release threading=multi link=shared

    February 15

    Build boost 1.38 with python 3.0 and ICU via VC++ 2008

    Start “Visual Studio 2008 Command Prompt”,

    go to boost source folder and run following command:

    D:\src\boost\boost_1_38_0>..\bjam.exe --toolset=msvc stage --build-type=complete

    After building the folder size is 6.53GB. Size of D:\src\boost\boost_1_38_0\bin.v2 is 3.25GB, can be deleted.

    boost.python is not compatible with Python30. I following a post from Martin Walser to instruct bjam using python30 by adding something to  boost_1_38_0\tools\build\v2\user-config.jam

    using python
        : 3.0                         # Version
        : C:\\Python30\\python.exe    # Python Path
        : C:\\Python30\\Include        # include path(s) -they may be not really needed here
          : C:\\Python30\\libs        # lib path(s) - they may be not really needed here
          : <python-debugging>on <define>BOOST_ALL_NO_LIB=1
        ;

    But it turned out a lot of type is missing in python30, like PyString_Type.

    There is someone working on python30 support: Some thoughts on py3k support.

    build boost with python and ICU

    ECHOE change code page to 1252
    chcp 1252
    rem chcp 1252 can't remove the warning about code page problem
    call "%VS90COMNTOOLS%\..\..\vc\bin\vcvars32.bat"
    SET PYTHON_ROOT=C:\Python30
    SET PYTHON_VERSION=3.0
    SET ICU_PATH=D:\opensource\icu4c-3_8_1\icu
    cd /d D:\opensource\boost\boost_1_38_0
    D:\opensource\boost\bjam.exe  --toolset=msvc stage --build-type=complete
    rem ...updated 3022 targets...
    rem build start at 17:52
    rem build completed at 20:49
    rem size of boost_1_38_0 is 6.59 (size) ~ 6.67 GB (size on disk)
    rem size of boost_1_38_0\bin.v2 is 3.28 GB

    rem build python sample
    D:\opensource\boost\boost_1_38_0\libs\python\example\quickstart>d:\opensource\boost\bjam.exe "threading=multi"

    rem run the python sample
    D:\opensource\boost\boost_1_38_0\libs\python\example\quickstart\bin\msvc-9.0\debug\threading-multi\embedding.exe D:\opensource\boost\boost_1_38_0\libs\python\example\quickstart\script.py

    August 27

    Building pthreads-w32-2-8-0-release via VC++ 2008 SP1

    VC++ 2008 SP1 complains that pthread.dsp is corrupt and can't be loaded, so I created a LIB project from existing source code and defined "PTW32_BUILD", otherwise I got 83 compile errors. After some time I finally got the project pass build with the following modifications:

    File name Modification
    implement.h

    add   int  ptw32_spinlock_check_need_init (pthread_spinlock_t * lock);

    ptw32_MCS_lock.c switch order of pthread.h and implement.h
    ptw32_callUserDestroyRoutines.c add #include <eh.h>

    Preprocessors for debug configuration: WIN32;_DEBUG;_LIB;PTW32_BUILD;__CLEANUP_C;_WINDOWS

    Preprocessors for Release configuration: WIN32;NDEBUG;_LIB;PTW32_BUILD;__CLEANUP_C;_WINDOWS

    "pthread Property Pages"->"Configuration Properties"->"C/C++"->"Advanced"->"Compile As"="Compile as C++ (/TP)"

    Additional include directories: .

    Don't include version.rc.

    August 19

    build boost 1.36.0 via VC++ 2008

    Machine: Laptop

    OS: XP SP2

    Compiler: VC++ 2008 SP1

    Build command: D:\src\boost\boost_1_36_0>bjam --toolset=msvc stage --build-type=complete

    Start time: 12:49

    Stop time: 15:35

    Size of D:\src\boost\boost_1_36_0\bin.v2: 3.27 GB

    Size of D:\src\boost\boost_1_36_0\stage: 3.10 GB

     

    Machine: Desktop

    OS: XP SP2

    Compiler: VC++ 2008 + Feature Pack

    Build command: bjam --build-dir=build64 --stagedir=stage64 stage address-model=64 --toolset=msvc --build-type=complete

    Start time: 15:35

    Stop time: 17:37

    Size of Build64 folder: 3.78 GB

    Size of stage64: 3.53 GB

    But there are some errors pop up during the build process:

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\debug\address-model-64\link-static\runtime-link-static\threading-multi\no_std_wstreambuf_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\debug\address-model-64\link-static\runtime-link-static\threading-multi\no_std_wstreambuf_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\release\address-model-64\link-static\runtime-link-static\threading-multi\no_std_locale_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\release\address-model-64\link-static\runtime-link-static\threading-multi\no_std_locale_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\release\address-model-64\link-static\runtime-link-static\threading-multi\no_std_wstreambuf_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\release\address-model-64\link-static\runtime-link-static\threading-multi\no_std_wstreambuf_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\debug\address-model-64\threading-multi\no_std_locale_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\debug\address-model-64\threading-multi\no_std_locale_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\debug\address-model-64\threading-multi\no_std_wstreambuf_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\debug\address-model-64\threading-multi\no_std_wstreambuf_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\release\address-model-64\threading-multi\no_std_locale_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\release\address-model-64\threading-multi\no_std_locale_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\release\address-model-64\threading-multi\no_std_wstreambuf_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\release\address-model-64\threading-multi\no_std_wstreambuf_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\debug\address-model-64\link-static\threading-multi\no_std_locale_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\debug\address-model-64\link-static\threading-multi\no_std_locale_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\debug\address-model-64\link-static\threading-multi\no_std_wstreambuf_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\debug\address-model-64\link-static\threading-multi\no_std_wstreambuf_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\release\address-model-64\link-static\threading-multi\no_std_locale_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_locale_pass.test\msvc-9.0\release\address-model-64\link-static\threading-multi\no_std_locale_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\release\address-model-64\link-static\threading-multi\no_std_wstreambuf_pass.exe
    ---------------------------
    D:\opensource\boost\boost_1_36_0\build64\boost\bin.v2\libs\config\test\all\no_std_wstreambuf_pass.test\msvc-9.0\release\address-model-64\link-static\threading-multi\no_std_wstreambuf_pass.exe is not a valid Win32 application.
    ---------------------------
    OK  
    ---------------------------

     

    Build boost 1.36.0 with Python and ICU

    Create a batch file(build-boost.bat) with following content:

    REM clean PATH to avoid MkDir1 error: spawn: Invalid argument
    SET PATH=%SystemRoot%;%SystemRoot%\system32;
    call "%VS90COMNTOOLS%\..\..\vc\bin\vcvars32.bat"
    SET PYTHON_ROOT=C:\Python25
    SET PYTHON_VERSION=2.5
    SET ICU_PATH=D:\src\ICU\icu4c-3_8_1\icu
    cd /d D:\src\boost\boost_1_36_0
    bjam  --toolset=msvc stage --build-type=complete

    April 15

    start MPICH2 program on its own.

    The documentation specified two methods to start a task, via mpiexec (for normal use)  or setmpi2.bat (for debug). So comes out the following code snippet that does not depends on mpiexec or setmpi2.bat.

    #include <mpi.h>
    #include <iostream>

    #include <stdio.h>
    #include <tchar.h>
    #include <sstream>

    int main(int argc, char* argv[])
    {
        if (argc<2)
        {
            std::cout << "Usage: " << argv[0] << " <RankID>"<< std::endl;
            return(__LINE__);
        }
        std::stringstream ss;
        _putenv("PMI_ROOT_HOST=your-host-name"); // change to your host name
        _putenv("PMI_ROOT_PORT=9222");
        _putenv("PMI_ROOT_LOCAL=1");
        ss << "PMI_RANK="<< argv[1];
        _putenv(ss.str().c_str());
        _putenv("PMI_SIZE=2");
        _putenv("PMI_KVS=mpich2");

        MPI_Init(&argc, &argv);
        int rank;
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        if (rank == 0) {
            int value = 17;
            int result = MPI_Send(&value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
            if (result == MPI_SUCCESS)
                std::cout << "Rank 0 Hello, Onega!" << std::endl;
        } else if (rank == 1) {
            int value;
            int result = MPI_Recv(&value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
                MPI_STATUS_IGNORE);
            if (result == MPI_SUCCESS && value == 17)
                std::cout << "Rank 1 Hello, Onega!" << std::endl;
        }
        MPI_Finalize();
        return 0;
    }

    boost.mpi program can start on its own.

    #include <boost/mpi/environment.hpp>
    #include <boost/mpi/communicator.hpp>
    #include <iostream>
    #pragma comment(lib,"mpi.lib")
    namespace mpi = boost::mpi;

    int main(int argc, char* argv[])
    {
        mpi::environment env(argc, argv);
        mpi::communicator world;
        std::cout << "I am process " << world.rank() << " of " << world.size()
            << "." << std::endl;
        return 0;
    }

    April 13

    Build mpich2-1.0.7 via Visual C++ 2008

    There are some compatibility issues between MPICH2 and VC++ 9.0, so I log my build process here for reference.

    Run winconfigure.wsf first, which will produce two error message box.

    Convert mpich2.sln to VC90 solution, then remove the following projects from converted solution because I don't need Forturn, C# or Python bindings.

    mpich2f, mpich2ff, mpif90, wmpiconfig, wmpiexec, wmpiregister, MPICH2x64Installer.

    Modify the following files:

    comment out line 612 of mpich2-1.0.7\src\include\win32\mpichconf.h: //#define vsnprintf _vsnprintf

    comment out line 172 of mpich2-1.0.7\src\include\win32\mpe_logging_conf.h: //#define write _write //For VC90

    Set active configuration as ch3sockDebug - Win32 configuration and build the solution.

    Also needs to add necessary directories to "Additional Include path" fields to some projects.

    To run first sample:

    Create a console project in VC++ 2008, #include <mpi.h> before <stdio.h>, link with mpich2socksd.lib mpid.lib for debug configuration, add include search path to project: "E:\dev\mpich2-1.0.7\src\include\win32";"E:\dev\mpich2-1.0.7\src\include". VC++ 2008 project wizard will put <stdio.h> in stdafx.h by default, so you must be careful of the include order ( I put mpi.h into stdafx.h too, above stdio.h).

    Install MPI service by command: smpd -install

    Run my program by : mpiexec -localonly 2 e:\svn\mpich2test1\Debug\mpich2test.exe

    March 17

    boost asio async client sample

    #include <iomanip>
    #include <iostream>
    #include <string>
    #include <boost/asio.hpp>
    #include <boost/thread/xtime.hpp>
    #include <boost/thread/thread.hpp>

    static void test_post()
    {
        std::cout << __FUNCTION__ << std::endl;
    }

    void sleep(int seconds=1)
    {
        boost::xtime xt;
        boost::xtime_get(&xt, boost::TIME_UTC);
        xt.sec += seconds;
        boost::thread::sleep(xt);
    }

    boost::asio::io_service iosvc;
    void io_thread()
    {
        boost::asio::io_service::work work(iosvc);
        std::cout << __FUNCTION__ << " start "<< std::endl;
        iosvc.run();
        std::cout << __FUNCTION__ << " end" << std::endl;
    }

    int main(int argc, char* argv[])
    {
        boost::thread ioth(&io_thread);
        iosvc.post(&test_post);
        sleep(3);
        iosvc.stop();
        sleep(2);
        ioth.join();
        return 0;
    }

    build log:

    **** Build of configuration Debug for project asio1 ****

    make all
    make: Warning: File `objects.mk' has modification time 1.1 s in the future
    Building file: ../src/asio1.cpp
    Invoking: Cygwin C++ Compiler
    g++ -D__USE_W32_SOCKETS=1 -D_WIN32_WINNT=0x0501 -ID:/boost_1_34_1 -O0 -g3 -Wall -c -fmessage-length=0 -mthreads -mwindows -v -MMD -MP -MF"src/asio1.d" -MT"src/asio1.d" -o"src/asio1.o" "../src/asio1.cpp"
    Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
    Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug
    Thread model: posix
    gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/cc1plus.exe -quiet -v -ID:/boost_1_34_1 -MMD asio1.dsrc/asio1.o -MFsrc/asio1.d -MP -MTsrc/asio1.d -MQ src/asio1.o -dD -D__CYGWIN32__ -D__CYGWIN__ -Dunix -D__unix__ -D__unix -idirafter /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api -idirafter /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/../../include/w32api -D__USE_W32_SOCKETS=1 -D_WIN32_WINNT=0x0501 ../src/asio1.cpp -quiet -dumpbase asio1.cpp -mthreads -mwindows -mtune=pentiumpro -auxbase-strip src/asio1.o -g3 -O0 -Wall -version -fmessage-length=0 -o /cygdrive/c/DOCUME~1/ONEGA~1.ZHA/LOCALS~1/Temp/ccDpWVYc.s
    ignoring nonexistent directory "/usr/local/include"
    ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/include"
    ignoring duplicate directory "/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/../../include/w32api"
    #include "..." search starts here:
    #include <...> search starts here:
    D:/boost_1_34_1
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/i686-pc-cygwin
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/backward
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/include
    /usr/include
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api
    End of search list.
    GNU C++ version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) (i686-pc-cygwin)
        compiled by GNU C version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125).
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/as.exe -osrc/asio1.o /cygdrive/c/DOCUME~1/ONEGA~1.ZHA/LOCALS~1/Temp/ccDpWVYc.s
    Finished building: ../src/asio1.cpp
    Building target: asio1.exe
    Invoking: Cygwin C++ Linker
    g++ -L"D:\boost_1_34_1\stage\lib" -v  -debug -o"asio1.exe"  ./src/asio1.o   -lwsock32 -lboost_filesystem-gcc34-mt-d-1_34_1 -lboost_thread-gcc34-mt-d-1_34_1 -lboost_system-gcc34-mt-d-1_34_1
    Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
    Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug
    Thread model: posix
    gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe -Bdynamic --dll-search-prefix=cyg -oasio1.exe /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -LD:\boost_1_34_1\stage\lib -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. ./src/asio1.o -lwsock32 -lboost_filesystem-gcc34-mt-d-1_34_1 -lboost_thread-gcc34-mt-d-1_34_1 -lboost_system-gcc34-mt-d-1_34_1 -lstdc++ -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc
    Finished building target: asio1.exe
    make: warning:  Clock skew detected.  Your build may be incomplete.

     

    I can't fix the "Clock skew ..." warning, but the output executable seems to be a valid one.

    January 22

    Build CPPUNIT 1.12 via VC++ 2008

    Need to change d:\CPPUNIT\cppunit-1.12.0\src\msvc6\testrunner\MsDevCallerListCtrl.cpp

    #pragma warning( disable : 4278 )
    #pragma warning( disable : 4146 )
    #if _MSC_VER == 1300
    #import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("7.0") lcid("0") raw_interfaces_only named_guids
    #endif
    #if _MSC_VER == 1500
    #import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("9.0") lcid("0") raw_interfaces_only named_guids
    #endif

    #pragma warning( default : 4146 )
    #pragma warning( default : 4278 )

    I also add VC++ version name to be part of output name, ie. Debug\cppunit-vc90-md.lib, DebugUnicode\testrunner-vc90-ud.dll, $(TargetDir)$(TargetName).lib and $(TargetDir)$(TargetName).pdb. PDB file name is usually configured via property "Generate Program Database File" in "Linker->Debugging" page, but for static library project which does not have Linker settings, I have to set it via "Program Database File Name" property in "C/C++->Output Files" page, I insist on changing the default name "vc90.pdb" since it will cause trouble when using pdb files from multiple libraries.

    wxTestRunner 2.52 needs a few modification in TestBrowserDialog.cpp in order to work with wxWidgets 2.87, all are related to wxTreeItemId:

    line 90: bool traverseTreeRecursively(const wxTreeItemId& idParent, wxTreeItemIdValue/*long*/ cookie, ExamineFunc f);
    line 238: return traverseTreeRecursively( rootTid, reinterpret_cast<wxTreeItemIdValue>(-1), f );
    line 241: bool MyTreeCtrl::traverseTreeRecursively(const wxTreeItemId& idParent, wxTreeItemIdValue/*long*/ cookie, ExamineFunc f)
    line 250:         if ( cookie == reinterpret_cast<wxTreeItemIdValue>(-1) )
    line 264:             shouldContinue = traverseTreeRecursively(id, reinterpret_cast<wxTreeItemIdValue>(-1), f);

    January 15

    build boost.asio 0.39 via VC++ 2008

    unzip asio 0.39 to boost 1.34.1 folder

    invoke command: bjam --toolset=msvc stage

    update boost/config/auto_link.hpp

    //#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
    #elif defined(BOOST_MSVC) && (BOOST_MSVC == 1400)
       // vc80:
    #  define BOOST_LIB_TOOLSET "vc80"
    #elif defined(BOOST_MSVC) && (BOOST_MSVC > 1400)
       // vc90:
    #  define BOOST_LIB_TOOLSET "vc"

    Command line to building sample boost_asio_0_3_9\libs\asio\example\http\client

    CL /EHsc async_client.cpp

    EHsc is needed, otherwise you got boost::throw_exception link error.

    December 10

    GCC -pthread or -mthreads?

    Thread support is a mess in GCC.

    http://gcc.gnu.org/ml/gcc/2000-05/msg01141.html

    Alpha:
    	OSF: -pthread/-threads
    	Linux: -pthread
    
    ARM:
    	Linux: -pthread
    
    IA-64:
    	nothing yet
    
    i386:
    	Linux: -pthread
    	Solaris: -pthreads/-threads
    	Mingw32: -mthreads
    
    Mips:
    	Linux: -pthread
    
    PA-RISC:
    	HP/UX: -threads
    
    PowerPC:
    	AIX: -mthreads
    	Lynx: -mthreads
    	Linux: -pthread
    
    Sparc:
    	Solaris: -pthreads/-threads
    	Linux: -pthread
    	Lynx: -mthreads
    
    GENERIC:
    	FreeBSD: -pthread
    	Linux: -pthread
    	Lynx: -mthreads
    

     

    http://lists.freebsd.org/pipermail/freebsd-threads/2003-September/001203.html

    One people explained a little bit on this topic:

    The problem is that -pthread maps to one threads library,
    and we have multiple threads libraries from which to choose.
    We have libc_r, libkse (M:N mode), libkse (1:1 mode), and
    libthr.
    December 09

    FreeBSD or Linux?

    The FreeBSD is said to be stable than Linux, but I noticed that it lags far behind in many areas.

    Java seens only officially support RedHat Linux (hint by its rpm package). There is a FreeBSD Java project, which only ported JDK 1.5.7, but the latest JDK is JDK 6.0 Update 3.

    I need a live FreeBSD system in order to evaluate wxWidgets, boost, ACE, CPPUNIT, openssl, ICU and OpenMP. It seems that FreeBSD guys are doing some porting work for many libraries (including ACE, wxWidgets), will they introduce new bugs during the porting? They are all famous open source libraries, but it would need a lot of work in order to put them together. Linux or FreeBSD, it is a tough decision.

    December 07

    CDT 4.0.2

    It troubled me to upgrade from CDT 4.0.0 to CDT 4.0.2 (cdt-master-4.0.2.zip) because it depends on org.junit plugin. At last eclipse installed Eclipse Java Development Tools via online update only mean to install the missing org.junit plugin.

    This version is a little bit friendly to user. When using Cygwin as compiler, include path should be in cywin syntax (/cygdrive/d/boost_1_34_1), otherwise "Project->Build Project" fails with error message "*** multiple target patterns". If windows style path is used, managed build can only work when the project is clean (or you can do "Project->Clean..." to get a clean environment for the project).

    Use CDT build variables to set a list of include paths

    "Directory List" variable can be added (Window->Preferences...->CDT build variables) and also recognized by CDT in "Project->Property->C/C++ Build->Settings->Cygwin C++ Compiler->Directories".

    eg. CYGWIN_INCLUDES=/cygdrive/d/boost /cygdrive/d/wxWidgets

    ${CYGWIN_INCLUDES} can be added to "Include paths(-I)", but CDT does not treat the directory list correctly in command line (it will show -I"/cygdrive/d/boost /cygdrive/d/wxWidgets").

    Workaround

    Add a string variable CYGWIN_INCLUDES="-I/cygdrive/d/boost_1_34_1 -I/cygdrive/d/wxWidgets-2.8.7/include" and use it in "Project->Property->C/C++ Build->Settings->Cygwin C++ Compiler->Miscellaneous->Other flags" = "-c -fmessage-length=0 -mthreads ${CYGWIN_INCLUDES}", the the include paths will show up in compile command as expected!

    Cross Platform Development

    System V Message Queue is wrapped by ACE_SV_Message_Queue, but it is unsupported on Windows.

    Signal is wrapped by ACE_Sig_Action, ACE_SignalHandler and also works on Windows.

    FIFO is wrapped by ACE_FIFO, not equivalent to Windows named pipe. ACE_SPIPE_* is a portable local IPC mechanism.

    December 04

    boost.filesystem (1.34.1) under Cygwin

    There are some multiple defined symbols error in boost.filesystem under cygwin. The workaround is to add '-Wl,--allow-multiple-definition' linker option to GCC.

    November 28

    MOM is missing in C++ world

    I am a little surprised to the fact that there is no mature MOM open source and cross platform project in C++, while there are a lot in Java.

    October 28

    ACE test_cancel sample problem when remote peer close socket after sending data

    When sending socket was closed before the socket is canceled, the program runs into endless loop. It is produced by the following steps:

    Build the ACE_wrappers\examples\Reactor\Proactor\test_cancel project on windows XP via VC8 SP1 and start it,

    Start up the following python program:

    import socket
    import sys
    HOST = '127.0.0.1'    # The remote host
    data_to_send = 'Hello, world ASFAAAASSSSSSSSSDDDDDDDDFFFFGGGGHHHHHHHJJJJKKKKKKKK'
    def test_cancel():
        PORT = 13
        if len(sys.argv)>1:
            PORT = int(sys.argv[1])
        print 'Length of data to send:', len(data_to_send)
        print 'connect to ', PORT
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT))
        s.send(data_to_send)
        s.close()
        print 'Close socket after sending data, this break ACE test_cancel sample'
    test_cancel()
       

    Now the ACE program runs into trouble, but the following boost.asio code works well due to its Close as Cancel design.

    #include <ctime>
    #include <iostream>
    #include <string>
    #include <boost/bind.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/enable_shared_from_this.hpp>
    #include <boost/asio.hpp>

    using boost::asio::ip::tcp;
    namespace boost
    {
        void throw_exception(std::exception const &e)
        {
            std::cout << "exception:" << e.what() <<std::endl;
        }

    }

    class tcp_connection
      : public boost::enable_shared_from_this<tcp_connection>
    {
    public:
      typedef boost::shared_ptr<tcp_connection> pointer;

      static pointer create(boost::asio::io_service& io_service)
      {
        return pointer(new tcp_connection(io_service));
      }

      tcp::socket& socket()
      {
        return socket_;
      }

      void start()
      {
          start_read();
      }

    private:
        void start_read()
        {
            boost::asio::async_read(socket_, boost::asio::buffer(m_read_buf, 24),
                boost::bind(&tcp_connection::handle_read, shared_from_this(),
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));

        }
      tcp_connection(boost::asio::io_service& io_service)
        : socket_(io_service)
      {
      }

      void handle_read(const boost::asio::error& error,
          size_t bytes_transferred)
      {
          std::cout << "Read " << bytes_transferred << std::endl;
          if (bytes_transferred != 24 && error.code())
          {
              socket_.close();
              std::cout << "socket closed" << std::endl;
          }
          else
          {
            start_read();
          }
      }

      tcp::socket socket_;
      std::string message_;
      char m_read_buf[128];
    };

    class tcp_server
    {
    public:
      tcp_server(boost::asio::io_service& io_service)
        : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
      {
        start_accept();
      }
      unsigned short port()
      {
          return acceptor_.local_endpoint().port();
      }
    private:
      void start_accept()
      {
        tcp_connection::pointer new_connection =
          tcp_connection::create(acceptor_.io_service());

        acceptor_.async_accept(new_connection->socket(),
            boost::bind(&tcp_server::handle_accept, this, new_connection,
              boost::asio::placeholders::error));
      }

      void handle_accept(tcp_connection::pointer new_connection,
          const boost::asio::error& error)
      {
        if (!error)
        {
          new_connection->start();
          start_accept();
        }
      }

      tcp::acceptor acceptor_;
    };

    int main()
    {
      try
      {
        boost::asio::io_service io_service;
        tcp_server server(io_service);
        std::cout << "Listen on port " << server.port() << std::endl;
        std::cout << "Read 24 bytes each time, if the read count is not 24, close the socket" << std::endl;
        io_service.run();
      }
      catch (std::exception& e)
      {
        std::cerr << e.what() << std::endl;
      }

      return 0;
    }