/
zOMGdev
/
cppcms
Обзор
Документация
Войти
/
zOMGdev
/
cppcms
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
booster/lib/aio/src/basic_io_device.cpp
250 строк
4 KB
Artyom Beilis
Added async_write based on nonblocking_write
18 ноя 2015, 13:55
18 ноя 2015, 13:55
a13c972
Код
Авторство
О чём код?
// // 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) // #define BOOSTER_SOURCE #include "socket_details.h" #include <booster/aio/basic_io_device.h> #include <booster/aio/io_service.h> #include <booster/aio/aio_category.h> #include "category.h" //#define BOOSTER_AIO_FORCE_POLL namespace booster { namespace aio { struct basic_io_device::data{}; // for future use basic_io_device::basic_io_device() : fd_(invalid_socket), owner_(true), nonblocking_was_set_(false), srv_(0) { } basic_io_device::basic_io_device(io_service &srv) : fd_(invalid_socket), owner_(true), nonblocking_was_set_(false), srv_(&srv) { } basic_io_device::~basic_io_device() { if(!owner_ || fd_ == invalid_socket) return; close_file_descriptor(fd_); fd_=invalid_socket; } bool basic_io_device::has_io_service() { return srv_ != 0; } io_service &basic_io_device::get_io_service() { if(!has_io_service()) throw system::system_error(aio_error::no_service_provided,aio_error_cat); return *srv_; } void basic_io_device::reset_io_service() { if(has_io_service()) cancel(); srv_ = 0; } void basic_io_device::set_io_service(io_service &srv) { reset_io_service(); srv_ = &srv; } native_type basic_io_device::native() { return fd_; } void basic_io_device::attach(native_type fd) { system::error_code e; close(e); fd_ = fd; owner_ = false; nonblocking_was_set_ = false; } void basic_io_device::assign(native_type fd) { system::error_code e; close(e); fd_ = fd; owner_ = true; nonblocking_was_set_ = false; } native_type basic_io_device::release() { owner_ = false; return fd_; } void basic_io_device::close(system::error_code &e) { if(fd_ == invalid_socket) return; if(has_io_service()) cancel(); if(!owner_) return; if(close_file_descriptor(fd_)) e=geterror(); fd_ = invalid_socket; nonblocking_was_set_ = false; } void basic_io_device::close() { system::error_code e; close(e); if(e) throw system::system_error(e); } void basic_io_device::on_readable(event_handler const &h) { get_io_service().set_io_event(fd_,io_service::in,h); } void basic_io_device::on_writeable(event_handler const &h) { get_io_service().set_io_event(fd_,io_service::out,h); } void basic_io_device::cancel() { get_io_service().cancel_io_events(fd_); } void basic_io_device::set_non_blocking(bool nonblocking,system::error_code &e) { #if defined BOOSTER_WIN32 unsigned long opt = nonblocking; if(::ioctlsocket(fd_,FIONBIO,&opt) < 0) e=geterror(); #elif ! defined(O_NONBLOCK) int opt = nonblocking; if(::ioctl(fd_,FIONBIO,&opt) < 0) e=geterror(); #else int flags = ::fcntl(fd_,F_GETFL,0); if(flags < 0) { e=geterror(); return; } if(nonblocking) flags = flags | O_NONBLOCK; else flags = flags & ~O_NONBLOCK; if(::fcntl(fd_,F_SETFL,flags) < 0) e=geterror(); #endif nonblocking_was_set_=nonblocking; } void basic_io_device::set_non_blocking_if_needed(bool nonblocking) { if(nonblocking_was_set_ == nonblocking) return; set_non_blocking(nonblocking); } void basic_io_device::set_non_blocking_if_needed(bool nonblocking,booster::system::error_code &e) { if(nonblocking_was_set_ == nonblocking) return; set_non_blocking(nonblocking,e); } void basic_io_device::set_non_blocking(bool nonblocking) { system::error_code e; set_non_blocking(nonblocking,e); if(e) throw system::system_error(e); } basic_io_device &basic_io_device::lowest_layer() { return *this; } bool basic_io_device::would_block(system::error_code const &e) { int code = e.value(); bool block = 0 #ifdef EAGAIN || code==EAGAIN #endif #ifdef EINPROGRESS || code == EINPROGRESS #endif #ifdef EWOULDBLOCK || code == EWOULDBLOCK #endif #ifdef WSAEAGAIN || code==WSAEAGAIN #endif #ifdef WSAEINPROGRESS || code == WSAEINPROGRESS #endif #ifdef WSAEWOULDBLOCK || code == WSAEWOULDBLOCK #endif ; return block; } bool basic_io_device::dont_block(io_handler const &h) { if(nonblocking_was_set_) return true; system::error_code e; set_non_blocking(true,e); if(e) { get_io_service().post(h,e,0); return false; } nonblocking_was_set_ = true; return true; } bool basic_io_device::dont_block(event_handler const &h) { if(nonblocking_was_set_) return true; system::error_code e; set_non_blocking(true,e); if(e) { get_io_service().post(h,e); return false; } nonblocking_was_set_ = true; return true; } } // aio } // booster