/
zOMGdev
/
cppcms
Обзор
Документация
Войти
/
zOMGdev
/
cppcms
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
booster/lib/aio/test/test_event_loop.cpp
250 строк
5 KB
Artyom Beilis
- Update copyright notice,
03 янв 2012, 17:58
03 янв 2012, 17:58
068d3f9
Код
Авторство
О чём код?
// // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh) // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // #include "aio_test.h" #include <booster/aio/io_service.h> #include <booster/posix_time.h> bool done; bool timer_done; using booster::ptime; struct sock1 { sock1(booster::aio::native_type f,booster::aio::io_service *s) : fd(f), srv(s), counter(0) { } booster::aio::native_type fd; booster::aio::io_service *srv; int counter; void async_run() { srv->set_io_event(fd,booster::aio::io_service::in,*this); } void operator()(booster::system::error_code const &e) { TEST(!e); char c=-1; int n = ::recv(fd,&c,1,0); if(counter == 10) { TEST(n==0); srv->stop(); done=true; } else { TEST(c==counter); counter++; async_run(); } } }; struct sock2 { sock2(booster::aio::native_type f,booster::aio::io_service *s) : fd(f), srv(s), counter(0) { } booster::aio::native_type fd; booster::aio::io_service *srv; int counter; void async_run() { srv->set_io_event(fd,booster::aio::io_service::out,*this); } void operator()(booster::system::error_code const &e) { TEST(!e); char c=counter++; int n = ::send(fd,&c,1,0); TEST(n==1); if(counter == 10) { #ifdef SHUT_RDWR shutdown(fd,SHUT_RDWR); #else shutdown(fd,SD_BOTH); #endif } else { async_run(); } } }; struct timer { booster::aio::io_service *srv; booster::ptime t; int event_id; bool cancel; void operator()(booster::system::error_code const &e) { if(cancel) { TEST(e==booster::system::error_code(booster::aio::aio_error::canceled,booster::aio::aio_error_cat)); srv->stop(); timer_done = true; } else { TEST(!e); TEST(booster::ptime::now() >= t); cancel=true; event_id = srv->set_timer_event(booster::ptime::now() + ptime::seconds(10),*this); canceler c = {event_id,srv}; srv->set_timer_event(booster::ptime::now() + ptime::milliseconds(100),c); } } struct canceler { int event_id; booster::aio::io_service *srv; void operator()(booster::system::error_code const &e) const { TEST(!e); srv->cancel_timer_event(event_id); } }; }; int cancel_called = 0; bool post_executed = false; struct cancel_handler { booster::aio::io_service *srv; void operator()() const { post_executed=true; srv->stop(); } void operator()(booster::system::error_code const &e) const { TEST(e==booster::system::error_code(booster::aio::aio_error::canceled,booster::aio::aio_error_cat)); cancel_called ++; srv->post(*this); } }; struct canceler { booster::aio::native_type fd; booster::aio::io_service *srv; void operator()(booster::system::error_code const &e) { TEST(!e); srv->cancel_io_events(fd); } }; booster::aio::io_service *the_service; booster::aio::native_type the_socket; bool got_error_called = false; void got_error(booster::system::error_code const &e) { TEST(e); got_error_called=true; the_service->stop(); } void run_closer() { booster::ptime::millisleep(100); #ifdef BOOSTER_WIN32 closesocket(the_socket); #else close(the_socket); #endif } void run_stopper(booster::system::error_code const &/*e*/) { the_service->stop(); } void post_executor() { post_executed = true; } void poster() { booster::ptime::millisleep(50); the_service->post(post_executor); booster::ptime::millisleep(50); the_service->stop(); } int main() { try { std::cout << "Testing IO events" << std::endl; booster::aio::io_service srv; { booster::aio::native_type fds[2]; pair(fds); sock1 s1(fds[0],&srv); sock2 s2(fds[1],&srv); s1.async_run(); s2.async_run(); srv.run(); TEST(done); } srv.reset(); { std::cout << "Testing timer events" << std::endl; timer tt = { &srv, booster::ptime::now() + ptime::milliseconds(100), 0, false }; srv.set_timer_event(tt.t,tt); srv.run(); TEST(timer_done); } srv.reset(); { std::cout << "Testing IO events cancelation" << std::endl; booster::aio::native_type fds[2]; pair(fds); cancel_handler ch = { &srv }; srv.set_io_event(fds[0],booster::aio::io_service::in,ch); canceler c = { fds[0], &srv }; srv.set_timer_event(booster::ptime::now() + ptime::milliseconds(100),c); srv.run(); TEST(cancel_called==1); std::cout << "Testing post()" << std::endl; TEST(post_executed); } the_service = &srv; srv.reset(); { std::cout << "Testing adding invalid socket id" << std::endl; srv.set_io_event(booster::aio::invalid_socket,booster::aio::io_service::in,got_error); got_error_called = false; srv.run(); TEST(got_error_called); } srv.reset(); { std::cout << "Testing event from other thread" << std::endl; post_executed = false; booster::thread p(poster); srv.run(); p.join(); TEST(post_executed); } } catch(std::exception const &e) { std::cout<<"Failed:"<< e.what() << std::endl; return 1; } if(return_code == 0) std::cout << "Ok" << std::endl; return return_code; }