feat add asio
All checks were successful
rpcrypto-build / build (Debug, himix200.toolchain.cmake) (push) Successful in 1m8s
rpcrypto-build / build (Debug, hisiv510.toolchain.cmake) (push) Successful in 1m8s
rpcrypto-build / build (Release, hisiv510.toolchain.cmake) (push) Successful in 1m17s
rpcrypto-build / build (Release, himix200.toolchain.cmake) (push) Successful in 1m21s
linux-hisiv500-gcc / linux-gcc-hisiv500 (push) Successful in 1m26s
linux-mips64-gcc / linux-gcc-mips64el (push) Successful in 1m43s
linux-x64-gcc / linux-gcc (push) Successful in 1m52s

This commit is contained in:
tqcq 2024-01-21 12:01:15 +08:00
parent 0529df0411
commit 6e1491fd41
6187 changed files with 765104 additions and 68 deletions

4
3party/asio/COPYING Normal file
View File

@ -0,0 +1,4 @@
Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)

5
3party/asio/INSTALL Normal file
View File

@ -0,0 +1,5 @@
See doc/index.html for information on:
- External dependencies
- Using, building, and configuring Asio
- Supported platforms
- How to build the tests and examples

View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

21
3party/asio/Makefile.am Normal file
View File

@ -0,0 +1,21 @@
AUTOMAKE_OPTIONS = foreign dist-bzip2 dist-zip
pkgconfig_DATA = asio.pc
SUBDIRS = include src
MAINTAINERCLEANFILES = \
$(srcdir)/aclocal.m4 \
$(srcdir)/configure \
$(srcdir)/config.guess \
$(srcdir)/config.sub \
$(srcdir)/depcomp \
$(srcdir)/install-sh \
$(srcdir)/missing \
$(srcdir)/mkinstalldirs \
$(srcdir)/Makefile.in \
asio-*.tar.gz
EXTRA_DIST = \
LICENSE_1_0.txt \
doc

845
3party/asio/Makefile.in Normal file
View File

@ -0,0 +1,845 @@
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES = asio.pc
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
DATA = $(pkgconfig_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/asio.pc.in COPYING \
INSTALL README compile config.guess config.sub depcomp \
install-sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip
GZIP_ENV = --best
DIST_TARGETS = dist-bzip2 dist-gzip dist-zip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgconfigdir = @pkgconfigdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign dist-bzip2 dist-zip
pkgconfig_DATA = asio.pc
SUBDIRS = include src
MAINTAINERCLEANFILES = \
$(srcdir)/aclocal.m4 \
$(srcdir)/configure \
$(srcdir)/config.guess \
$(srcdir)/config.sub \
$(srcdir)/depcomp \
$(srcdir)/install-sh \
$(srcdir)/missing \
$(srcdir)/mkinstalldirs \
$(srcdir)/Makefile.in \
asio-*.tar.gz
EXTRA_DIST = \
LICENSE_1_0.txt \
doc
all: all-recursive
.SUFFIXES:
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
asio.pc: $(top_builddir)/config.status $(srcdir)/asio.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $@
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
done
uninstall-pkgconfigDATA:
@$(NORMAL_UNINSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
clean-cscope:
-rm -f cscope.files
cscope.files: clean-cscope cscopelist
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
dist-zstd: distdir
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__post_remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
*.tar.zst*) \
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build/sub \
&& ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
echo 'ERROR: trying to run $@ with an empty' \
'$$(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
$(am__cd) '$(distuninstallcheck_dir)' || { \
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(DATA)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am: install-pkgconfigDATA
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-pkgconfigDATA
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--refresh check check-am clean clean-cscope clean-generic \
cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
dist-zstd distcheck distclean distclean-generic distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-pkgconfigDATA install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-pkgconfigDATA
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

4
3party/asio/README Normal file
View File

@ -0,0 +1,4 @@
asio version 1.28.0
Released Wednesday, 26 April 2023.
See doc/index.html for API documentation and a tutorial.

1462
3party/asio/aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

11
3party/asio/asio.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
Name: @PACKAGE_NAME@
Description: A cross-platform C++ library for network and low-level I/O programming that provides developers with a consistent asynchronous model using a modern C++ approach.
Version: @PACKAGE_VERSION@
Cflags: -I${includedir}
Lflags:
Requires:
Requires.private:

348
3party/asio/compile Executable file
View File

@ -0,0 +1,348 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN* | MSYS*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/* | msys/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

1748
3party/asio/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1884
3party/asio/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

7134
3party/asio/configure vendored Executable file

File diff suppressed because it is too large Load Diff

259
3party/asio/configure.ac Normal file
View File

@ -0,0 +1,259 @@
AC_INIT(asio, [1.28.0])
AC_CONFIG_SRCDIR(include/asio.hpp)
AM_MAINTAINER_MODE
AM_INIT_AUTOMAKE([tar-pax])
AC_CANONICAL_HOST
AM_PROG_CC_C_O
AC_PROG_CXX
AC_LANG(C++)
AC_PROG_RANLIB
PKG_INSTALLDIR
AC_DEFINE(_REENTRANT, [1], [Define this])
AC_ARG_WITH(boost,
AC_HELP_STRING([--with-boost=DIR],[location of boost distribution]),
[
if test "${withval}" = no; then
STANDALONE="yes"
else
if test "${withval}" != system; then
CPPFLAGS="$CPPFLAGS -I${withval}"
LIBS="$LIBS -L${withval}/stage/lib"
fi
CPPFLAGS="$CPPFLAGS -DASIO_ENABLE_BOOST -DBOOST_CHRONO_HEADER_ONLY -DBOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING"
fi
],
[
STANDALONE="yes"
])
AC_ARG_ENABLE(separate-compilation,
[ --enable-separate-compilation separate compilation of asio source],
[
SEPARATE_COMPILATION=yes
])
AC_ARG_ENABLE(boost-coroutine,
[ --enable-boost-coroutine use Boost.Coroutine to implement stackful coroutines],
[
HAVE_BOOST_COROUTINE=yes
])
if test "$STANDALONE" != yes; then
AC_CHECK_HEADER([boost/noncopyable.hpp],,
[
echo "Can't find boost headers. Please check the location of the boost"
echo "distribution and rerun configure using the --with-boost=DIR option."
echo "Alternatively, run with --without-boost to enable standalone build."
exit 1
],[])
fi
AC_ARG_WITH(openssl,
AC_HELP_STRING([--with-openssl=DIR],[location of openssl]),
[
CPPFLAGS="$CPPFLAGS -I${withval}/include"
LIBS="$LIBS -L${withval}/lib"
],[])
AC_CHECK_HEADER([openssl/ssl.h],,
[
OPENSSL_FOUND=no
],[])
if test x$OPENSSL_FOUND != xno; then
LIBS="$LIBS -lssl -lcrypto"
fi
AM_CONDITIONAL(HAVE_OPENSSL,test x$OPENSSL_FOUND != xno)
WINDOWS=no
case $host in
*-*-linux*)
CXXFLAGS="$CXXFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
LIBS="$LIBS -lrt"
;;
*-*-solaris*)
if test "$GXX" = yes; then
CXXFLAGS="$CXXFLAGS -D_PTHREADS"
else
# We'll assume Sun's CC.
CXXFLAGS="$CXXFLAGS -mt"
fi
LIBS="$LIBS -lsocket -lnsl -lpthread"
;;
*-*-mingw32*)
CXXFLAGS="$CXXFLAGS -mthreads"
LDFLAGS="$LDFLAGS -mthreads"
LIBS="$LIBS -lws2_32 -lmswsock"
WINDOWS=yes
;;
*-*-mingw64*)
CXXFLAGS="$CXXFLAGS -mthreads"
LDFLAGS="$LDFLAGS -mthreads"
LIBS="$LIBS -lws2_32 -lmswsock"
WINDOWS=yes
;;
*-pc-cygwin*)
CXXFLAGS="$CXXFLAGS -D__USE_W32_SOCKETS -D_WIN32_WINNT=0x0601"
LIBS="$LIBS -lws2_32 -lmswsock"
WINDOWS=yes
;;
*-apple-darwin*)
CXXFLAGS="$CXXFLAGS"
LDFLAGS="$LDFLAGS"
;;
*-*-freebsd*)
CXXFLAGS="$CXXFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
;;
*-*-netbsd*)
CXXFLAGS="$CXXFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
;;
*-*-haiku*)
CXXFLAGS="$CXXFLAGS -lnetwork"
LDFLAGS="$LDFLAGS -lnetwork"
esac
if test "$GXX" = yes; then
CXXFLAGS="$CXXFLAGS -ftemplate-depth-256"
fi
if test "$STANDALONE" = yes; then
CPPFLAGS="$CPPFLAGS -DASIO_STANDALONE"
fi
if test "$SEPARATE_COMPILATION" = yes; then
CPPFLAGS="$CPPFLAGS -DASIO_SEPARATE_COMPILATION"
fi
AC_MSG_CHECKING([whether C++11 is enabled])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if __cplusplus < 201103L]]
[[#error C++11 not available]]
[[#endif]])],
[AC_MSG_RESULT([yes])
HAVE_CXX11=yes;],
[AC_MSG_RESULT([no])
HAVE_CXX11=no;])
AC_MSG_CHECKING([whether C++14 is enabled])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if defined(__GNUC__) && !defined(__clang__)]]
[[# if (__GNUC__ <= 6)]]
[[# error C++14 support on this compiler not sufficiently compliant]]
[[# endif]]
[[#endif]]
[[#if __cplusplus < 201402L]]
[[#error C++14 not available]]
[[#endif]])],
[AC_MSG_RESULT([yes])
HAVE_CXX14=yes;],
[AC_MSG_RESULT([no])
HAVE_CXX14=no;])
AC_MSG_CHECKING([whether C++17 is enabled])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if __cplusplus < 201703L]]
[[#error C++17 not available]]
[[#endif]])],
[AC_MSG_RESULT([yes])
HAVE_CXX17=yes;],
[AC_MSG_RESULT([no])
HAVE_CXX17=no;])
AC_MSG_CHECKING([whether C++20 is enabled])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if __cplusplus < 202002L]]
[[#error C++20 not available]]
[[#endif]])],
[AC_MSG_RESULT([yes])
HAVE_CXX20=yes;],
[AC_MSG_RESULT([no])
HAVE_CXX20=no;])
AC_MSG_CHECKING([whether coroutines are enabled])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if defined(__clang__)]]
[[# if (__clang_major__ >= 14)]]
[[# if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)]]
[[# if __has_include(<coroutine>)]]
[[# define ASIO_HAS_CO_AWAIT 1]]
[[# endif]]
[[# elif (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)]]
[[# if __has_include(<experimental/coroutine>)]]
[[# define ASIO_HAS_CO_AWAIT 1]]
[[# endif]]
[[# endif]]
[[# else]]
[[# if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)]]
[[# if __has_include(<experimental/coroutine>)]]
[[# define ASIO_HAS_CO_AWAIT 1]]
[[# endif]]
[[# endif]]
[[# endif]]
[[#elif defined(__GNUC__)]]
[[# if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)]]
[[# if __has_include(<coroutine>)]]
[[# define ASIO_HAS_CO_AWAIT 1]]
[[# endif]]
[[# endif]]
[[#endif]]
[[#ifndef ASIO_HAS_CO_AWAIT]]
[[# error coroutines not available]]
[[#endif]])],
[AC_MSG_RESULT([yes])
HAVE_COROUTINES=yes;],
[AC_MSG_RESULT([no])
HAVE_COROUTINES=no;])
if test "$GXX" = yes; then
if test "$STANDALONE" = yes; then
if test "$HAVE_CXX11" = no; then
HAVE_CXX11=yes
CPPFLAGS="-std=c++0x $CPPFLAGS"
fi
fi
fi
AM_CONDITIONAL(STANDALONE,test x$STANDALONE = xyes)
AM_CONDITIONAL(SEPARATE_COMPILATION,test x$SEPARATE_COMPILATION = xyes)
AM_CONDITIONAL(HAVE_BOOST_COROUTINE,test x$HAVE_BOOST_COROUTINE = xyes)
AM_CONDITIONAL(WINDOWS_TARGET,test x$WINDOWS != xno)
AM_CONDITIONAL(HAVE_CXX11,test x$HAVE_CXX11 = xyes)
AM_CONDITIONAL(HAVE_CXX14,test x$HAVE_CXX14 = xyes)
AM_CONDITIONAL(HAVE_CXX17,test x$HAVE_CXX17 = xyes)
AM_CONDITIONAL(HAVE_CXX20,test x$HAVE_CXX20 = xyes)
AM_CONDITIONAL(HAVE_COROUTINES,test x$HAVE_COROUTINES = xyes)
AC_CONFIG_FILES([asio.pc])
AC_OUTPUT([
Makefile
include/Makefile
src/Makefile
src/tests/Makefile
src/tests/properties/Makefile
src/examples/cpp03/Makefile
src/examples/cpp11/Makefile
src/examples/cpp14/Makefile
src/examples/cpp17/Makefile
src/examples/cpp20/Makefile])

791
3party/asio/depcomp Executable file
View File

@ -0,0 +1,791 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

BIN
3party/asio/doc/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

BIN
3party/asio/doc/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

BIN
3party/asio/doc/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

BIN
3party/asio/doc/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

BIN
3party/asio/doc/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

BIN
3party/asio/doc/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

BIN
3party/asio/doc/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

BIN
3party/asio/doc/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

BIN
3party/asio/doc/asio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,62 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Examples</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Asio">
<link rel="up" href="../index.html" title="Asio">
<link rel="prev" href="tutorial/boost_bind.html" title="boost::bind">
<link rel="next" href="examples/cpp03_examples.html" title="C++03 Examples">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial/boost_bind.html"><img src="../prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../home.png" alt="Home"></a><a accesskey="n" href="examples/cpp03_examples.html"><img src="../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="asio.examples"></a><a class="link" href="examples.html" title="Examples">Examples</a>
</h2></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a class="link" href="examples/cpp03_examples.html" title="C++03 Examples">C++03 Examples</a>: Illustrates
the use of Asio using only C++03 language and library features. Where necessary,
the examples make use of selected Boost C++ libraries.
</li>
<li class="listitem">
<a class="link" href="examples/cpp11_examples.html" title="C++11 Examples">C++11 Examples</a>: Contains
a limited set of the C++03 Asio examples, updated to use only C++11 library
and language facilities. These examples do not make direct use of Boost
C++ libraries. To show the changes between C++03 and C++11, these examples
include a diff between the C++03 and C++11 versions.
</li>
<li class="listitem">
<a class="link" href="examples/cpp14_examples.html" title="C++14 Examples">C++14 Examples</a>: Contains
a limited set of the C++03 Asio examples, updated to use only C++14 library
and language facilities. These examples do not make direct use of Boost
C++ libraries.
</li>
<li class="listitem">
<a class="link" href="examples/cpp17_examples.html" title="C++17 Examples">C++17 Examples</a>: Selected
examples illustrating C++17 usage in conjunction with Technical Specifications.
</li>
<li class="listitem">
<a class="link" href="examples/cpp20_examples.html" title="C++20 Examples">C++20 Examples</a>: Selected
examples using C++20 language features.
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial/boost_bind.html"><img src="../prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../home.png" alt="Home"></a><a accesskey="n" href="examples/cpp03_examples.html"><img src="../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,633 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>C++03 Examples</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../examples.html" title="Examples">
<link rel="prev" href="../examples.html" title="Examples">
<link rel="next" href="cpp11_examples.html" title="C++11 Examples">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp11_examples.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.examples.cpp03_examples"></a><a class="link" href="cpp03_examples.html" title="C++03 Examples">C++03 Examples</a>
</h3></div></div></div>
<h5>
<a name="asio.examples.cpp03_examples.h0"></a>
<span><a name="asio.examples.cpp03_examples.allocation"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.allocation">Allocation</a>
</h5>
<p>
This example shows how to customise the allocation of memory associated with
asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/allocation/server.cpp" target="_top">../src/examples/cpp03/allocation/server.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h1"></a>
<span><a name="asio.examples.cpp03_examples.buffers"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.buffers">Buffers</a>
</h5>
<p>
This example demonstrates how to create reference counted buffers that can
be used with socket read and write operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/buffers/reference_counted.cpp" target="_top">../src/examples/cpp03/buffers/reference_counted.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h2"></a>
<span><a name="asio.examples.cpp03_examples.chat"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.chat">Chat</a>
</h5>
<p>
This example implements a chat server and client. The programs use a custom
protocol with a fixed length message header and variable length message body.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/chat/chat_message.hpp" target="_top">../src/examples/cpp03/chat/chat_message.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/chat/chat_client.cpp" target="_top">../src/examples/cpp03/chat/chat_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/chat/chat_server.cpp" target="_top">../src/examples/cpp03/chat/chat_server.cpp</a>
</li>
</ul></div>
<p>
The following POSIX-specific chat client demonstrates how to use the <a class="link" href="../reference/posix__stream_descriptor.html" title="posix::stream_descriptor">posix::stream_descriptor</a>
class to perform console input and output.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/chat/posix_chat_client.cpp" target="_top">../src/examples/cpp03/chat/posix_chat_client.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h3"></a>
<span><a name="asio.examples.cpp03_examples.echo"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.echo">Echo</a>
</h5>
<p>
A collection of simple clients and servers, showing the use of both synchronous
and asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/echo/async_tcp_echo_server.cpp" target="_top">../src/examples/cpp03/echo/async_tcp_echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/echo/async_udp_echo_server.cpp" target="_top">../src/examples/cpp03/echo/async_udp_echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/echo/blocking_tcp_echo_client.cpp" target="_top">../src/examples/cpp03/echo/blocking_tcp_echo_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/echo/blocking_tcp_echo_server.cpp" target="_top">../src/examples/cpp03/echo/blocking_tcp_echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/echo/blocking_udp_echo_client.cpp" target="_top">../src/examples/cpp03/echo/blocking_udp_echo_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/echo/blocking_udp_echo_server.cpp" target="_top">../src/examples/cpp03/echo/blocking_udp_echo_server.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h4"></a>
<span><a name="asio.examples.cpp03_examples.fork"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.fork">Fork</a>
</h5>
<p>
These POSIX-specific examples show how to use Asio in conjunction with the
<code class="computeroutput"><span class="identifier">fork</span><span class="special">()</span></code>
system call. The first example illustrates the steps required to start a
daemon process:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/fork/daemon.cpp" target="_top">../src/examples/cpp03/fork/daemon.cpp</a>
</li></ul></div>
<p>
The second example demonstrates how it is possible to fork a process from
within a completion handler.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/fork/process_per_connection.cpp" target="_top">../src/examples/cpp03/fork/process_per_connection.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h5"></a>
<span><a name="asio.examples.cpp03_examples.http_client"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.http_client">HTTP
Client</a>
</h5>
<p>
Example programs implementing simple HTTP 1.0 clients. These examples show
how to use the <a class="link" href="../reference/read_until.html" title="read_until">read_until</a>
and <a class="link" href="../reference/async_read_until.html" title="async_read_until">async_read_until</a>
functions.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/http/client/sync_client.cpp" target="_top">../src/examples/cpp03/http/client/sync_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/client/async_client.cpp" target="_top">../src/examples/cpp03/http/client/async_client.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h6"></a>
<span><a name="asio.examples.cpp03_examples.http_server"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.http_server">HTTP
Server</a>
</h5>
<p>
This example illustrates the use of asio in a simple single-threaded server
implementation of HTTP 1.0. It demonstrates how to perform a clean shutdown
by cancelling all outstanding asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/connection.cpp" target="_top">../src/examples/cpp03/http/server/connection.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/connection.hpp" target="_top">../src/examples/cpp03/http/server/connection.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/connection_manager.cpp" target="_top">../src/examples/cpp03/http/server/connection_manager.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/connection_manager.hpp" target="_top">../src/examples/cpp03/http/server/connection_manager.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/header.hpp" target="_top">../src/examples/cpp03/http/server/header.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/main.cpp" target="_top">../src/examples/cpp03/http/server/main.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/mime_types.cpp" target="_top">../src/examples/cpp03/http/server/mime_types.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/mime_types.hpp" target="_top">../src/examples/cpp03/http/server/mime_types.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/reply.cpp" target="_top">../src/examples/cpp03/http/server/reply.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/reply.hpp" target="_top">../src/examples/cpp03/http/server/reply.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/request.hpp" target="_top">../src/examples/cpp03/http/server/request.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/request_handler.cpp" target="_top">../src/examples/cpp03/http/server/request_handler.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/request_handler.hpp" target="_top">../src/examples/cpp03/http/server/request_handler.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/request_parser.cpp" target="_top">../src/examples/cpp03/http/server/request_parser.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/request_parser.hpp" target="_top">../src/examples/cpp03/http/server/request_parser.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/server.cpp" target="_top">../src/examples/cpp03/http/server/server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server/server.hpp" target="_top">../src/examples/cpp03/http/server/server.hpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h7"></a>
<span><a name="asio.examples.cpp03_examples.http_server_2"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.http_server_2">HTTP
Server 2</a>
</h5>
<p>
An HTTP server using an io_context-per-CPU design.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/connection.cpp" target="_top">../src/examples/cpp03/http/server2/connection.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/connection.hpp" target="_top">../src/examples/cpp03/http/server2/connection.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/header.hpp" target="_top">../src/examples/cpp03/http/server2/header.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/io_context_pool.cpp" target="_top">../src/examples/cpp03/http/server2/io_context_pool.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/io_context_pool.hpp" target="_top">../src/examples/cpp03/http/server2/io_context_pool.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/main.cpp" target="_top">../src/examples/cpp03/http/server2/main.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/mime_types.cpp" target="_top">../src/examples/cpp03/http/server2/mime_types.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/mime_types.hpp" target="_top">../src/examples/cpp03/http/server2/mime_types.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/reply.cpp" target="_top">../src/examples/cpp03/http/server2/reply.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/reply.hpp" target="_top">../src/examples/cpp03/http/server2/reply.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/request.hpp" target="_top">../src/examples/cpp03/http/server2/request.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/request_handler.cpp" target="_top">../src/examples/cpp03/http/server2/request_handler.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/request_handler.hpp" target="_top">../src/examples/cpp03/http/server2/request_handler.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/request_parser.cpp" target="_top">../src/examples/cpp03/http/server2/request_parser.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/request_parser.hpp" target="_top">../src/examples/cpp03/http/server2/request_parser.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/server.cpp" target="_top">../src/examples/cpp03/http/server2/server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server2/server.hpp" target="_top">../src/examples/cpp03/http/server2/server.hpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h8"></a>
<span><a name="asio.examples.cpp03_examples.http_server_3"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.http_server_3">HTTP
Server 3</a>
</h5>
<p>
An HTTP server using a single io_context and a thread pool calling <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/connection.cpp" target="_top">../src/examples/cpp03/http/server3/connection.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/connection.hpp" target="_top">../src/examples/cpp03/http/server3/connection.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/header.hpp" target="_top">../src/examples/cpp03/http/server3/header.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/main.cpp" target="_top">../src/examples/cpp03/http/server3/main.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/mime_types.cpp" target="_top">../src/examples/cpp03/http/server3/mime_types.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/mime_types.hpp" target="_top">../src/examples/cpp03/http/server3/mime_types.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/reply.cpp" target="_top">../src/examples/cpp03/http/server3/reply.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/reply.hpp" target="_top">../src/examples/cpp03/http/server3/reply.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/request.hpp" target="_top">../src/examples/cpp03/http/server3/request.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/request_handler.cpp" target="_top">../src/examples/cpp03/http/server3/request_handler.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/request_handler.hpp" target="_top">../src/examples/cpp03/http/server3/request_handler.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/request_parser.cpp" target="_top">../src/examples/cpp03/http/server3/request_parser.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/request_parser.hpp" target="_top">../src/examples/cpp03/http/server3/request_parser.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/server.cpp" target="_top">../src/examples/cpp03/http/server3/server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server3/server.hpp" target="_top">../src/examples/cpp03/http/server3/server.hpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h9"></a>
<span><a name="asio.examples.cpp03_examples.http_server_4"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.http_server_4">HTTP
Server 4</a>
</h5>
<p>
A single-threaded HTTP server implemented using stackless coroutines.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/file_handler.cpp" target="_top">../src/examples/cpp03/http/server4/file_handler.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/file_handler.hpp" target="_top">../src/examples/cpp03/http/server4/file_handler.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/header.hpp" target="_top">../src/examples/cpp03/http/server4/header.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/main.cpp" target="_top">../src/examples/cpp03/http/server4/main.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/mime_types.cpp" target="_top">../src/examples/cpp03/http/server4/mime_types.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/mime_types.hpp" target="_top">../src/examples/cpp03/http/server4/mime_types.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/reply.cpp" target="_top">../src/examples/cpp03/http/server4/reply.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/reply.hpp" target="_top">../src/examples/cpp03/http/server4/reply.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/request.hpp" target="_top">../src/examples/cpp03/http/server4/request.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/request_parser.cpp" target="_top">../src/examples/cpp03/http/server4/request_parser.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/request_parser.hpp" target="_top">../src/examples/cpp03/http/server4/request_parser.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/server.cpp" target="_top">../src/examples/cpp03/http/server4/server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/http/server4/server.hpp" target="_top">../src/examples/cpp03/http/server4/server.hpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h10"></a>
<span><a name="asio.examples.cpp03_examples.icmp"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.icmp">ICMP</a>
</h5>
<p>
This example shows how to use raw sockets with ICMP to ping a remote host.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/icmp/ping.cpp" target="_top">../src/examples/cpp03/icmp/ping.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/icmp/ipv4_header.hpp" target="_top">../src/examples/cpp03/icmp/ipv4_header.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/icmp/icmp_header.hpp" target="_top">../src/examples/cpp03/icmp/icmp_header.hpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h11"></a>
<span><a name="asio.examples.cpp03_examples.invocation"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.invocation">Invocation</a>
</h5>
<p>
This example shows how to customise handler invocation. Completion handlers
are added to a priority queue rather than executed immediately.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/invocation/prioritised_handlers.cpp" target="_top">../src/examples/cpp03/invocation/prioritised_handlers.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h12"></a>
<span><a name="asio.examples.cpp03_examples.iostreams"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.iostreams">Iostreams</a>
</h5>
<p>
Two examples showing how to use <a class="link" href="../reference/ip__tcp/iostream.html" title="ip::tcp::iostream">ip::tcp::iostream</a>.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/iostreams/daytime_client.cpp" target="_top">../src/examples/cpp03/iostreams/daytime_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/iostreams/daytime_server.cpp" target="_top">../src/examples/cpp03/iostreams/daytime_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/iostreams/http_client.cpp" target="_top">../src/examples/cpp03/iostreams/http_client.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h13"></a>
<span><a name="asio.examples.cpp03_examples.multicast"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.multicast">Multicast</a>
</h5>
<p>
An example showing the use of multicast to transmit packets to a group of
subscribers.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/multicast/receiver.cpp" target="_top">../src/examples/cpp03/multicast/receiver.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/multicast/sender.cpp" target="_top">../src/examples/cpp03/multicast/sender.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h14"></a>
<span><a name="asio.examples.cpp03_examples.serialization"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.serialization">Serialization</a>
</h5>
<p>
This example shows how Boost.Serialization can be used with asio to encode
and decode structures for transmission over a socket.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/serialization/client.cpp" target="_top">../src/examples/cpp03/serialization/client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/serialization/connection.hpp" target="_top">../src/examples/cpp03/serialization/connection.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/serialization/server.cpp" target="_top">../src/examples/cpp03/serialization/server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/serialization/stock.hpp" target="_top">../src/examples/cpp03/serialization/stock.hpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h15"></a>
<span><a name="asio.examples.cpp03_examples.services"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.services">Services</a>
</h5>
<p>
This example demonstrates how to integrate custom functionality (in this
case, for logging) into asio's <a class="link" href="../reference/io_context.html" title="io_context">io_context</a>,
and how to use a custom service with <a class="link" href="../reference/basic_stream_socket.html" title="basic_stream_socket">basic_stream_socket&lt;&gt;</a>.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/services/basic_logger.hpp" target="_top">../src/examples/cpp03/services/basic_logger.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/services/daytime_client.cpp" target="_top">../src/examples/cpp03/services/daytime_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/services/logger.hpp" target="_top">../src/examples/cpp03/services/logger.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/services/logger_service.cpp" target="_top">../src/examples/cpp03/services/logger_service.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/services/logger_service.hpp" target="_top">../src/examples/cpp03/services/logger_service.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/services/stream_socket_service.hpp" target="_top">../src/examples/cpp03/services/stream_socket_service.hpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h16"></a>
<span><a name="asio.examples.cpp03_examples.socks_4"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.socks_4">SOCKS
4</a>
</h5>
<p>
Example client program implementing the SOCKS 4 protocol for communication
via a proxy.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/socks4/sync_client.cpp" target="_top">../src/examples/cpp03/socks4/sync_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/socks4/socks4.hpp" target="_top">../src/examples/cpp03/socks4/socks4.hpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h17"></a>
<span><a name="asio.examples.cpp03_examples.ssl"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.ssl">SSL</a>
</h5>
<p>
Example client and server programs showing the use of the <a class="link" href="../reference/ssl__stream.html" title="ssl::stream">ssl::stream&lt;&gt;</a>
template with asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/ssl/client.cpp" target="_top">../src/examples/cpp03/ssl/client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/ssl/server.cpp" target="_top">../src/examples/cpp03/ssl/server.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h18"></a>
<span><a name="asio.examples.cpp03_examples.timeouts"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.timeouts">Timeouts</a>
</h5>
<p>
A collection of examples showing how to cancel long running asynchronous
operations after a period of time.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/timeouts/async_tcp_client.cpp" target="_top">../src/examples/cpp03/timeouts/async_tcp_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/timeouts/blocking_tcp_client.cpp" target="_top">../src/examples/cpp03/timeouts/blocking_tcp_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/timeouts/blocking_token_tcp_client.cpp" target="_top">../src/examples/cpp03/timeouts/blocking_token_tcp_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/timeouts/blocking_udp_client.cpp" target="_top">../src/examples/cpp03/timeouts/blocking_udp_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/timeouts/server.cpp" target="_top">../src/examples/cpp03/timeouts/server.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h19"></a>
<span><a name="asio.examples.cpp03_examples.timers"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.timers">Timers</a>
</h5>
<p>
Example showing how to customise basic_waitable_timer using a different clock
type.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/timers/time_t_timer.cpp" target="_top">../src/examples/cpp03/timers/time_t_timer.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h20"></a>
<span><a name="asio.examples.cpp03_examples.porthopper"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.porthopper">Porthopper</a>
</h5>
<p>
Example illustrating mixed synchronous and asynchronous operations, and how
to use Boost.Lambda with Asio.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/porthopper/protocol.hpp" target="_top">../src/examples/cpp03/porthopper/protocol.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/porthopper/client.cpp" target="_top">../src/examples/cpp03/porthopper/client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/porthopper/server.cpp" target="_top">../src/examples/cpp03/porthopper/server.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h21"></a>
<span><a name="asio.examples.cpp03_examples.nonblocking"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.nonblocking">Nonblocking</a>
</h5>
<p>
Example demonstrating reactor-style operations for integrating a third-party
library that wants to perform the I/O operations itself.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/nonblocking/third_party_lib.cpp" target="_top">../src/examples/cpp03/nonblocking/third_party_lib.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h22"></a>
<span><a name="asio.examples.cpp03_examples.spawn"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.spawn">Spawn</a>
</h5>
<p>
Example of using the asio::spawn() function, a wrapper around the <a href="http://www.boost.org/doc/libs/release/libs/coroutine/index.html" target="_top">Boost.Coroutine</a>
library, to implement a chain of asynchronous operations using stackful coroutines.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/spawn/echo_server.cpp" target="_top">../src/examples/cpp03/spawn/echo_server.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h23"></a>
<span><a name="asio.examples.cpp03_examples.unix_domain_sockets"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.unix_domain_sockets">UNIX
Domain Sockets</a>
</h5>
<p>
Examples showing how to use UNIX domain (local) sockets.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp03/local/connect_pair.cpp" target="_top">../src/examples/cpp03/local/connect_pair.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/local/iostream_client.cpp" target="_top">../src/examples/cpp03/local/iostream_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/local/stream_server.cpp" target="_top">../src/examples/cpp03/local/stream_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp03/local/stream_client.cpp" target="_top">../src/examples/cpp03/local/stream_client.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp03_examples.h24"></a>
<span><a name="asio.examples.cpp03_examples.windows"></a></span><a class="link" href="cpp03_examples.html#asio.examples.cpp03_examples.windows">Windows</a>
</h5>
<p>
An example showing how to use the Windows-specific function <code class="computeroutput"><span class="identifier">TransmitFile</span></code> with Asio.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp03/windows/transmit_file.cpp" target="_top">../src/examples/cpp03/windows/transmit_file.cpp</a>
</li></ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp11_examples.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,524 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>C++11 Examples</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../examples.html" title="Examples">
<link rel="prev" href="cpp03_examples.html" title="C++03 Examples">
<link rel="next" href="cpp14_examples.html" title="C++14 Examples">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp03_examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp14_examples.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.examples.cpp11_examples"></a><a class="link" href="cpp11_examples.html" title="C++11 Examples">C++11 Examples</a>
</h3></div></div></div>
<h5>
<a name="asio.examples.cpp11_examples.h0"></a>
<span><a name="asio.examples.cpp11_examples.allocation"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.allocation">Allocation</a>
</h5>
<p>
This example shows how to customise the allocation of memory associated with
asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/allocation/server.cpp" target="_top">../src/examples/cpp11/allocation/server.cpp</a>
(<a href="../../examples/diffs/allocation/server.cpp.html" target="_top">diff to C++03</a>)
</li></ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h1"></a>
<span><a name="asio.examples.cpp11_examples.buffers"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.buffers">Buffers</a>
</h5>
<p>
This example demonstrates how to create reference counted buffers that can
be used with socket read and write operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/buffers/reference_counted.cpp" target="_top">../src/examples/cpp11/buffers/reference_counted.cpp</a>
(<a href="../../examples/diffs/buffers/reference_counted.cpp.html" target="_top">diff
to C++03</a>)
</li></ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h2"></a>
<span><a name="asio.examples.cpp11_examples.chat"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.chat">Chat</a>
</h5>
<p>
This example implements a chat server and client. The programs use a custom
protocol with a fixed length message header and variable length message body.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/chat/chat_message.hpp" target="_top">../src/examples/cpp11/chat/chat_message.hpp</a>
(<a href="../../examples/diffs/chat/chat_message.hpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/chat/chat_client.cpp" target="_top">../src/examples/cpp11/chat/chat_client.cpp</a>
(<a href="../../examples/diffs/chat/chat_client.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/chat/chat_server.cpp" target="_top">../src/examples/cpp11/chat/chat_server.cpp</a>
(<a href="../../examples/diffs/chat/chat_server.cpp.html" target="_top">diff to C++03</a>)
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h3"></a>
<span><a name="asio.examples.cpp11_examples.echo"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.echo">Echo</a>
</h5>
<p>
A collection of simple clients and servers, showing the use of both synchronous
and asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/echo/async_tcp_echo_server.cpp" target="_top">../src/examples/cpp11/echo/async_tcp_echo_server.cpp</a>
(<a href="../../examples/diffs/echo/async_tcp_echo_server.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/echo/async_udp_echo_server.cpp" target="_top">../src/examples/cpp11/echo/async_udp_echo_server.cpp</a>
(<a href="../../examples/diffs/echo/async_udp_echo_server.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/echo/blocking_tcp_echo_client.cpp" target="_top">../src/examples/cpp11/echo/blocking_tcp_echo_client.cpp</a>
(<a href="../../examples/diffs/echo/blocking_tcp_echo_client.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/echo/blocking_tcp_echo_server.cpp" target="_top">../src/examples/cpp11/echo/blocking_tcp_echo_server.cpp</a>
(<a href="../../examples/diffs/echo/blocking_tcp_echo_server.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/echo/blocking_udp_echo_client.cpp" target="_top">../src/examples/cpp11/echo/blocking_udp_echo_client.cpp</a>
(<a href="../../examples/diffs/echo/blocking_udp_echo_client.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/echo/blocking_udp_echo_server.cpp" target="_top">../src/examples/cpp11/echo/blocking_udp_echo_server.cpp</a>
(<a href="../../examples/diffs/echo/blocking_udp_echo_server.cpp.html" target="_top">diff
to C++03</a>)
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h4"></a>
<span><a name="asio.examples.cpp11_examples.deferred"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.deferred">Deferred</a>
</h5>
<p>
Examples showing how to use the <a class="link" href="../reference/deferred.html" title="deferred"><code class="computeroutput"><span class="identifier">deferred</span></code></a> completion token.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/deferred/deferred_1.cpp" target="_top">../src/examples/cpp11/deferred/deferred_1.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/deferred/deferred_2.cpp" target="_top">../src/examples/cpp11/deferred/deferred_2.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h5"></a>
<span><a name="asio.examples.cpp11_examples.fork"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.fork">Fork</a>
</h5>
<p>
These POSIX-specific examples show how to use Asio in conjunction with the
<code class="computeroutput"><span class="identifier">fork</span><span class="special">()</span></code>
system call. The first example illustrates the steps required to start a
daemon process:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/fork/daemon.cpp" target="_top">../src/examples/cpp11/fork/daemon.cpp</a>
(<a href="../../examples/diffs/fork/daemon.cpp.html" target="_top">diff to C++03</a>)
</li></ul></div>
<p>
The second example demonstrates how it is possible to fork a process from
within a completion handler.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/fork/process_per_connection.cpp" target="_top">../src/examples/cpp11/fork/process_per_connection.cpp</a>
(<a href="../../examples/diffs/fork/process_per_connection.cpp.html" target="_top">diff
to C++03</a>)
</li></ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h6"></a>
<span><a name="asio.examples.cpp11_examples.futures"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.futures">Futures</a>
</h5>
<p>
This example demonstrates how to use std::future in conjunction with Asio's
asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/futures/daytime_client.cpp" target="_top">../src/examples/cpp11/futures/daytime_client.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h7"></a>
<span><a name="asio.examples.cpp11_examples.handler_tracking"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.handler_tracking">Handler
Tracking</a>
</h5>
<p>
This example header file shows how to implement custom handler tracking.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/handler_tracking/custom_tracking.hpp" target="_top">../src/examples/cpp11/handler_tracking/custom_tracking.hpp</a>
</li></ul></div>
<p>
This example program shows how to include source location information in
the handler tracking output.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/handler_tracking/async_tcp_echo_server.cpp" target="_top">../src/examples/cpp11/handler_tracking/async_tcp_echo_server.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h8"></a>
<span><a name="asio.examples.cpp11_examples.http_server"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.http_server">HTTP
Server</a>
</h5>
<p>
This example illustrates the use of asio in a simple single-threaded server
implementation of HTTP 1.0. It demonstrates how to perform a clean shutdown
by cancelling all outstanding asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/connection.cpp" target="_top">../src/examples/cpp11/http/server/connection.cpp</a>
(<a href="../../examples/diffs/http/server/connection.cpp.html" target="_top">diff to
C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/connection.hpp" target="_top">../src/examples/cpp11/http/server/connection.hpp</a>
(<a href="../../examples/diffs/http/server/connection.hpp.html" target="_top">diff to
C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/connection_manager.cpp" target="_top">../src/examples/cpp11/http/server/connection_manager.cpp</a>
(<a href="../../examples/diffs/http/server/connection_manager.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/connection_manager.hpp" target="_top">../src/examples/cpp11/http/server/connection_manager.hpp</a>
(<a href="../../examples/diffs/http/server/connection_manager.hpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/header.hpp" target="_top">../src/examples/cpp11/http/server/header.hpp</a>
(<a href="../../examples/diffs/http/server/header.hpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/main.cpp" target="_top">../src/examples/cpp11/http/server/main.cpp</a>
(<a href="../../examples/diffs/http/server/main.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/mime_types.cpp" target="_top">../src/examples/cpp11/http/server/mime_types.cpp</a>
(<a href="../../examples/diffs/http/server/mime_types.cpp.html" target="_top">diff to
C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/mime_types.hpp" target="_top">../src/examples/cpp11/http/server/mime_types.hpp</a>
(<a href="../../examples/diffs/http/server/mime_types.hpp.html" target="_top">diff to
C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/reply.cpp" target="_top">../src/examples/cpp11/http/server/reply.cpp</a>
(<a href="../../examples/diffs/http/server/reply.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/reply.hpp" target="_top">../src/examples/cpp11/http/server/reply.hpp</a>
(<a href="../../examples/diffs/http/server/reply.hpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/request.hpp" target="_top">../src/examples/cpp11/http/server/request.hpp</a>
(<a href="../../examples/diffs/http/server/request.hpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/request_handler.cpp" target="_top">../src/examples/cpp11/http/server/request_handler.cpp</a>
(<a href="../../examples/diffs/http/server/request_handler.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/request_handler.hpp" target="_top">../src/examples/cpp11/http/server/request_handler.hpp</a>
(<a href="../../examples/diffs/http/server/request_handler.hpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/request_parser.cpp" target="_top">../src/examples/cpp11/http/server/request_parser.cpp</a>
(<a href="../../examples/diffs/http/server/request_parser.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/request_parser.hpp" target="_top">../src/examples/cpp11/http/server/request_parser.hpp</a>
(<a href="../../examples/diffs/http/server/request_parser.hpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/server.cpp" target="_top">../src/examples/cpp11/http/server/server.cpp</a>
(<a href="../../examples/diffs/http/server/server.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/http/server/server.hpp" target="_top">../src/examples/cpp11/http/server/server.hpp</a>
(<a href="../../examples/diffs/http/server/server.hpp.html" target="_top">diff to C++03</a>)
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h9"></a>
<span><a name="asio.examples.cpp11_examples.multicast"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.multicast">Multicast</a>
</h5>
<p>
An example showing the use of multicast to transmit packets to a group of
subscribers.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/multicast/receiver.cpp" target="_top">../src/examples/cpp11/multicast/receiver.cpp</a>
(<a href="../../examples/diffs/multicast/receiver.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/multicast/sender.cpp" target="_top">../src/examples/cpp11/multicast/sender.cpp</a>
(<a href="../../examples/diffs/multicast/sender.cpp.html" target="_top">diff to C++03</a>)
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h10"></a>
<span><a name="asio.examples.cpp11_examples.nonblocking"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.nonblocking">Nonblocking</a>
</h5>
<p>
Example demonstrating reactor-style operations for integrating a third-party
library that wants to perform the I/O operations itself.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/nonblocking/third_party_lib.cpp" target="_top">../src/examples/cpp11/nonblocking/third_party_lib.cpp</a>
(<a href="../../examples/diffs/nonblocking/third_party_lib.cpp.html" target="_top">diff
to C++03</a>)
</li></ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h11"></a>
<span><a name="asio.examples.cpp11_examples.operations"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.operations">Operations</a>
</h5>
<p>
Examples showing how to implement composed asynchronous operations as reusable
library functions.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/operations/composed_1.cpp" target="_top">../src/examples/cpp11/operations/composed_1.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/operations/composed_2.cpp" target="_top">../src/examples/cpp11/operations/composed_2.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/operations/composed_3.cpp" target="_top">../src/examples/cpp11/operations/composed_3.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/operations/composed_4.cpp" target="_top">../src/examples/cpp11/operations/composed_4.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/operations/composed_5.cpp" target="_top">../src/examples/cpp11/operations/composed_5.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/operations/composed_6.cpp" target="_top">../src/examples/cpp11/operations/composed_6.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/operations/composed_7.cpp" target="_top">../src/examples/cpp11/operations/composed_7.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/operations/composed_8.cpp" target="_top">../src/examples/cpp11/operations/composed_8.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h12"></a>
<span><a name="asio.examples.cpp11_examples.parallel_groups"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.parallel_groups">Parallel
Groups</a>
</h5>
<p>
Examples showing how to use the <a class="link" href="../reference/experimental__make_parallel_group.html" title="experimental::make_parallel_group"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">make_parallel_group</span></code></a> operation.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/parallel_group/wait_for_all.cpp" target="_top">../src/examples/cpp11/parallel_group/wait_for_all.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/parallel_group/wait_for_one.cpp" target="_top">../src/examples/cpp11/parallel_group/wait_for_one.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/parallel_group/wait_for_one_error.cpp" target="_top">../src/examples/cpp11/parallel_group/wait_for_one_error.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/parallel_group/wait_for_one_success.cpp" target="_top">../src/examples/cpp11/parallel_group/wait_for_one_success.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/parallel_group/ranged_wait_for_all.cpp" target="_top">../src/examples/cpp11/parallel_group/ranged_wait_for_all.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h13"></a>
<span><a name="asio.examples.cpp11_examples.socks_4"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.socks_4">SOCKS
4</a>
</h5>
<p>
Example client program implementing the SOCKS 4 protocol for communication
via a proxy.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/socks4/sync_client.cpp" target="_top">../src/examples/cpp11/socks4/sync_client.cpp</a>
(<a href="../../examples/diffs/socks4/sync_client.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/socks4/socks4.hpp" target="_top">../src/examples/cpp11/socks4/socks4.hpp</a>
(<a href="../../examples/diffs/socks4/socks4.hpp.html" target="_top">diff to C++03</a>)
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h14"></a>
<span><a name="asio.examples.cpp11_examples.spawn"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.spawn">Spawn</a>
</h5>
<p>
Example of using the asio::spawn() function, a wrapper around the <a href="http://www.boost.org/doc/libs/release/libs/coroutine/index.html" target="_top">Boost.Coroutine</a>
library, to implement a chain of asynchronous operations using stackful coroutines.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/spawn/echo_server.cpp" target="_top">../src/examples/cpp11/spawn/echo_server.cpp</a>
(<a href="../../examples/diffs/spawn/echo_server.cpp.html" target="_top">diff to C++03</a>)
</li></ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h15"></a>
<span><a name="asio.examples.cpp11_examples.ssl"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.ssl">SSL</a>
</h5>
<p>
Example client and server programs showing the use of the <a class="link" href="../reference/ssl__stream.html" title="ssl::stream">ssl::stream&lt;&gt;</a>
template with asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/ssl/client.cpp" target="_top">../src/examples/cpp11/ssl/client.cpp</a>
(<a href="../../examples/diffs/ssl/client.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/ssl/server.cpp" target="_top">../src/examples/cpp11/ssl/server.cpp</a>
(<a href="../../examples/diffs/ssl/server.cpp.html" target="_top">diff to C++03</a>)
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h16"></a>
<span><a name="asio.examples.cpp11_examples.timeouts"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.timeouts">Timeouts</a>
</h5>
<p>
A collection of examples showing how to cancel long running asynchronous
operations after a period of time.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/timeouts/async_tcp_client.cpp" target="_top">../src/examples/cpp11/timeouts/async_tcp_client.cpp</a>
(<a href="../../examples/diffs/timeouts/async_tcp_client.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/timeouts/blocking_tcp_client.cpp" target="_top">../src/examples/cpp11/timeouts/blocking_tcp_client.cpp</a>
(<a href="../../examples/diffs/timeouts/blocking_tcp_client.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/timeouts/blocking_token_tcp_client.cpp" target="_top">../src/examples/cpp11/timeouts/blocking_token_tcp_client.cpp</a>
(<a href="../../examples/diffs/timeouts/blocking_token_tcp_client.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/timeouts/blocking_udp_client.cpp" target="_top">../src/examples/cpp11/timeouts/blocking_udp_client.cpp</a>
(<a href="../../examples/diffs/timeouts/blocking_udp_client.cpp.html" target="_top">diff
to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/timeouts/server.cpp" target="_top">../src/examples/cpp11/timeouts/server.cpp</a>
(<a href="../../examples/diffs/timeouts/server.cpp.html" target="_top">diff to C++03</a>)
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h17"></a>
<span><a name="asio.examples.cpp11_examples.timers"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.timers">Timers</a>
</h5>
<p>
Example showing how to customise basic_waitable_timer using a different clock
type.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp11/timers/time_t_timer.cpp" target="_top">../src/examples/cpp11/timers/time_t_timer.cpp</a>
(<a href="../../examples/diffs/timers/time_t_timer.cpp.html" target="_top">diff to C++03</a>)
</li></ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h18"></a>
<span><a name="asio.examples.cpp11_examples.type_erasure"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.type_erasure">Type
Erasure</a>
</h5>
<p>
Example showing how to use <a class="link" href="../reference/any_completion_handler.html" title="any_completion_handler"><code class="computeroutput"><span class="identifier">any_completion_handler</span></code></a> to enable
separate compilation of asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/type_erasure/main.cpp" target="_top">../src/examples/cpp11/type_erasure/main.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/type_erasure/line_reader.hpp" target="_top">../src/examples/cpp11/type_erasure/line_reader.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/type_erasure/stdin_line_reader.hpp" target="_top">../src/examples/cpp11/type_erasure/stdin_line_reader.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/type_erasure/stdin_line_reader.cpp" target="_top">../src/examples/cpp11/type_erasure/stdin_line_reader.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/type_erasure/sleep.hpp" target="_top">../src/examples/cpp11/type_erasure/sleep.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/type_erasure/sleep.cpp" target="_top">../src/examples/cpp11/type_erasure/sleep.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp11_examples.h19"></a>
<span><a name="asio.examples.cpp11_examples.unix_domain_sockets"></a></span><a class="link" href="cpp11_examples.html#asio.examples.cpp11_examples.unix_domain_sockets">UNIX
Domain Sockets</a>
</h5>
<p>
Examples showing how to use UNIX domain (local) sockets.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp11/local/connect_pair.cpp" target="_top">../src/examples/cpp11/local/connect_pair.cpp</a>
(<a href="../../examples/diffs/local/connect_pair.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/local/iostream_client.cpp" target="_top">../src/examples/cpp11/local/iostream_client.cpp</a>
(<a href="../../examples/diffs/local/iostream_client.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/local/stream_server.cpp" target="_top">../src/examples/cpp11/local/stream_server.cpp</a>
(<a href="../../examples/diffs/local/stream_server.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/local/stream_client.cpp" target="_top">../src/examples/cpp11/local/stream_client.cpp</a>
(<a href="../../examples/diffs/local/stream_client.cpp.html" target="_top">diff to C++03</a>)
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/local/fd_passing_stream_server.cpp" target="_top">../src/examples/cpp11/local/fd_passing_stream_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp11/local/fd_passing_stream_client.cpp" target="_top">../src/examples/cpp11/local/fd_passing_stream_client.cpp</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp03_examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp14_examples.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,208 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>C++14 Examples</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../examples.html" title="Examples">
<link rel="prev" href="cpp11_examples.html" title="C++11 Examples">
<link rel="next" href="cpp17_examples.html" title="C++17 Examples">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp11_examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp17_examples.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.examples.cpp14_examples"></a><a class="link" href="cpp14_examples.html" title="C++14 Examples">C++14 Examples</a>
</h3></div></div></div>
<h5>
<a name="asio.examples.cpp14_examples.h0"></a>
<span><a name="asio.examples.cpp14_examples.deferred"></a></span><a class="link" href="cpp14_examples.html#asio.examples.cpp14_examples.deferred">Deferred</a>
</h5>
<p>
Examples showing how to use the <a class="link" href="../reference/deferred.html" title="deferred"><code class="computeroutput"><span class="identifier">deferred</span></code></a> completion token.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp14/deferred/deferred_1.cpp" target="_top">../src/examples/cpp14/deferred/deferred_1.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/deferred/deferred_2.cpp" target="_top">../src/examples/cpp14/deferred/deferred_2.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/deferred/deferred_3.cpp" target="_top">../src/examples/cpp14/deferred/deferred_3.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/deferred/deferred_4.cpp" target="_top">../src/examples/cpp14/deferred/deferred_4.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/deferred/deferred_5.cpp" target="_top">../src/examples/cpp14/deferred/deferred_5.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/deferred/deferred_6.cpp" target="_top">../src/examples/cpp14/deferred/deferred_6.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/deferred/deferred_7.cpp" target="_top">../src/examples/cpp14/deferred/deferred_7.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp14_examples.h1"></a>
<span><a name="asio.examples.cpp14_examples.echo"></a></span><a class="link" href="cpp14_examples.html#asio.examples.cpp14_examples.echo">Echo</a>
</h5>
<p>
A collection of simple clients and servers, showing the use of both synchronous
and asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp14/echo/async_tcp_echo_server.cpp" target="_top">../src/examples/cpp14/echo/async_tcp_echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/echo/async_udp_echo_server.cpp" target="_top">../src/examples/cpp14/echo/async_udp_echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/echo/blocking_tcp_echo_client.cpp" target="_top">../src/examples/cpp14/echo/blocking_tcp_echo_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/echo/blocking_tcp_echo_server.cpp" target="_top">../src/examples/cpp14/echo/blocking_tcp_echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/echo/blocking_udp_echo_client.cpp" target="_top">../src/examples/cpp14/echo/blocking_udp_echo_client.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/echo/blocking_udp_echo_server.cpp" target="_top">../src/examples/cpp14/echo/blocking_udp_echo_server.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp14_examples.h2"></a>
<span><a name="asio.examples.cpp14_examples.executors"></a></span><a class="link" href="cpp14_examples.html#asio.examples.cpp14_examples.executors">Executors</a>
</h5>
<p>
Examples showing how to use the executor-related facilities.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp14/executors/actor.cpp" target="_top">../src/examples/cpp14/executors/actor.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/executors/async_1.cpp" target="_top">../src/examples/cpp14/executors/async_1.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/executors/async_2.cpp" target="_top">../src/examples/cpp14/executors/async_2.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/executors/bank_account_1.cpp" target="_top">../src/examples/cpp14/executors/bank_account_1.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/executors/bank_account_2.cpp" target="_top">../src/examples/cpp14/executors/bank_account_2.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/executors/fork_join.cpp" target="_top">../src/examples/cpp14/executors/fork_join.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/executors/pipeline.cpp" target="_top">../src/examples/cpp14/executors/pipeline.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/executors/priority_scheduler.cpp" target="_top">../src/examples/cpp14/executors/priority_scheduler.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp14_examples.h3"></a>
<span><a name="asio.examples.cpp14_examples.iostreams"></a></span><a class="link" href="cpp14_examples.html#asio.examples.cpp14_examples.iostreams">Iostreams</a>
</h5>
<p>
Two examples showing how to use <a class="link" href="../reference/ip__tcp/iostream.html" title="ip::tcp::iostream">ip::tcp::iostream</a>.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp14/iostreams/http_client.cpp" target="_top">../src/examples/cpp14/iostreams/http_client.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp14_examples.h4"></a>
<span><a name="asio.examples.cpp14_examples.operations"></a></span><a class="link" href="cpp14_examples.html#asio.examples.cpp14_examples.operations">Operations</a>
</h5>
<p>
Examples showing how to implement composed asynchronous operations as reusable
library functions.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/composed_1.cpp" target="_top">../src/examples/cpp14/operations/composed_1.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/composed_2.cpp" target="_top">../src/examples/cpp14/operations/composed_2.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/composed_3.cpp" target="_top">../src/examples/cpp14/operations/composed_3.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/composed_4.cpp" target="_top">../src/examples/cpp14/operations/composed_4.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/composed_5.cpp" target="_top">../src/examples/cpp14/operations/composed_5.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/composed_6.cpp" target="_top">../src/examples/cpp14/operations/composed_6.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/composed_7.cpp" target="_top">../src/examples/cpp14/operations/composed_7.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/composed_8.cpp" target="_top">../src/examples/cpp14/operations/composed_8.cpp</a>
</li>
</ul></div>
<p>
Examples showing how to expose callback-based APIs as asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/callback_wrapper.cpp" target="_top">../src/examples/cpp14/operations/callback_wrapper.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/operations/c_callback_wrapper.cpp" target="_top">../src/examples/cpp14/operations/c_callback_wrapper.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp14_examples.h5"></a>
<span><a name="asio.examples.cpp14_examples.parallel_groups"></a></span><a class="link" href="cpp14_examples.html#asio.examples.cpp14_examples.parallel_groups">Parallel
Groups</a>
</h5>
<p>
Examples showing how to use the <a class="link" href="../reference/experimental__make_parallel_group.html" title="experimental::make_parallel_group"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">make_parallel_group</span></code></a> operation.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp14/parallel_group/parallel_sort.cpp" target="_top">../src/examples/cpp14/parallel_group/parallel_sort.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/parallel_group/wait_for_all.cpp" target="_top">../src/examples/cpp14/parallel_group/wait_for_all.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/parallel_group/wait_for_one.cpp" target="_top">../src/examples/cpp14/parallel_group/wait_for_one.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/parallel_group/wait_for_one_error.cpp" target="_top">../src/examples/cpp14/parallel_group/wait_for_one_error.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/parallel_group/wait_for_one_success.cpp" target="_top">../src/examples/cpp14/parallel_group/wait_for_one_success.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp14/parallel_group/ranged_wait_for_all.cpp" target="_top">../src/examples/cpp14/parallel_group/ranged_wait_for_all.cpp</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp11_examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp17_examples.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,57 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>C++17 Examples</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../examples.html" title="Examples">
<link rel="prev" href="cpp14_examples.html" title="C++14 Examples">
<link rel="next" href="cpp20_examples.html" title="C++20 Examples">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp14_examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp20_examples.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.examples.cpp17_examples"></a><a class="link" href="cpp17_examples.html" title="C++17 Examples">C++17 Examples</a>
</h3></div></div></div>
<h5>
<a name="asio.examples.cpp17_examples.h0"></a>
<span><a name="asio.examples.cpp17_examples.coroutines_ts_support"></a></span><a class="link" href="cpp17_examples.html#asio.examples.cpp17_examples.coroutines_ts_support">Coroutines
TS Support</a>
</h5>
<p>
Examples showing how to implement a chain of asynchronous operations using
the Coroutines TS.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp17/coroutines_ts/echo_server.cpp" target="_top">../src/examples/cpp17/coroutines_ts/echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp17/coroutines_ts/refactored_echo_server.cpp" target="_top">../src/examples/cpp17/coroutines_ts/refactored_echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp17/coroutines_ts/chat_server.cpp" target="_top">../src/examples/cpp17/coroutines_ts/chat_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp17/coroutines_ts/range_based_for.cpp" target="_top">../src/examples/cpp17/coroutines_ts/range_based_for.cpp</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp14_examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp20_examples.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,155 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>C++20 Examples</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../examples.html" title="Examples">
<link rel="prev" href="cpp17_examples.html" title="C++17 Examples">
<link rel="next" href="../reference.html" title="Reference">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp17_examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.examples.cpp20_examples"></a><a class="link" href="cpp20_examples.html" title="C++20 Examples">C++20 Examples</a>
</h3></div></div></div>
<h5>
<a name="asio.examples.cpp20_examples.h0"></a>
<span><a name="asio.examples.cpp20_examples.channels"></a></span><a class="link" href="cpp20_examples.html#asio.examples.cpp20_examples.channels">Channels</a>
</h5>
<p>
Example showing how to use a channel in conjunction with C++20 coroutines.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="../../../src/examples/cpp20/channels/throttling_proxy.cpp" target="_top">../src/examples/cpp20/channels/throttling_proxy.cpp</a>
</li></ul></div>
<h5>
<a name="asio.examples.cpp20_examples.h1"></a>
<span><a name="asio.examples.cpp20_examples.coroutines"></a></span><a class="link" href="cpp20_examples.html#asio.examples.cpp20_examples.coroutines">Coroutines</a>
</h5>
<p>
Examples showing how to implement a chain of asynchronous operations using
C++20 Coroutines.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/echo_server.cpp" target="_top">../src/examples/cpp20/coroutines/echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/echo_server_with_default.cpp" target="_top">../src/examples/cpp20/coroutines/echo_server_with_default.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/echo_server_with_as_tuple_default.cpp" target="_top">../src/examples/cpp20/coroutines/echo_server_with_as_tuple_default.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/echo_server_with_as_single_default.cpp" target="_top">../src/examples/cpp20/coroutines/echo_server_with_as_single_default.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/echo_server_with_deferred.cpp" target="_top">../src/examples/cpp20/coroutines/echo_server_with_deferred.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/echo_server_with_deferred_default.cpp" target="_top">../src/examples/cpp20/coroutines/echo_server_with_deferred_default.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/refactored_echo_server.cpp" target="_top">../src/examples/cpp20/coroutines/refactored_echo_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/chat_server.cpp" target="_top">../src/examples/cpp20/coroutines/chat_server.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/coroutines/timeout.cpp" target="_top">../src/examples/cpp20/coroutines/timeout.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp20_examples.h2"></a>
<span><a name="asio.examples.cpp20_examples.operations"></a></span><a class="link" href="cpp20_examples.html#asio.examples.cpp20_examples.operations">Operations</a>
</h5>
<p>
Examples showing how to implement composed asynchronous operations as reusable
library functions.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/composed_1.cpp" target="_top">../src/examples/cpp20/operations/composed_1.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/composed_2.cpp" target="_top">../src/examples/cpp20/operations/composed_2.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/composed_3.cpp" target="_top">../src/examples/cpp20/operations/composed_3.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/composed_4.cpp" target="_top">../src/examples/cpp20/operations/composed_4.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/composed_5.cpp" target="_top">../src/examples/cpp20/operations/composed_5.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/composed_6.cpp" target="_top">../src/examples/cpp20/operations/composed_6.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/composed_7.cpp" target="_top">../src/examples/cpp20/operations/composed_7.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/composed_8.cpp" target="_top">../src/examples/cpp20/operations/composed_8.cpp</a>
</li>
</ul></div>
<p>
Examples showing how to expose callback-based APIs as asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/callback_wrapper.cpp" target="_top">../src/examples/cpp20/operations/callback_wrapper.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/operations/c_callback_wrapper.cpp" target="_top">../src/examples/cpp20/operations/c_callback_wrapper.cpp</a>
</li>
</ul></div>
<h5>
<a name="asio.examples.cpp20_examples.h3"></a>
<span><a name="asio.examples.cpp20_examples.type_erasure"></a></span><a class="link" href="cpp20_examples.html#asio.examples.cpp20_examples.type_erasure">Type
Erasure</a>
</h5>
<p>
Example showing how to use <a class="link" href="../reference/any_completion_handler.html" title="any_completion_handler"><code class="computeroutput"><span class="identifier">any_completion_handler</span></code></a> to enable
separate compilation of asynchronous operations.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a href="../../../src/examples/cpp20/type_erasure/main.cpp" target="_top">../src/examples/cpp20/type_erasure/main.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/type_erasure/line_reader.hpp" target="_top">../src/examples/cpp20/type_erasure/line_reader.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/type_erasure/stdin_line_reader.hpp" target="_top">../src/examples/cpp20/type_erasure/stdin_line_reader.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/type_erasure/stdin_line_reader.cpp" target="_top">../src/examples/cpp20/type_erasure/stdin_line_reader.cpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/type_erasure/sleep.hpp" target="_top">../src/examples/cpp20/type_erasure/sleep.hpp</a>
</li>
<li class="listitem">
<a href="../../../src/examples/cpp20/type_erasure/sleep.cpp" target="_top">../src/examples/cpp20/type_erasure/sleep.cpp</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp17_examples.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,271 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Overview</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Asio">
<link rel="up" href="../index.html" title="Asio">
<link rel="prev" href="../index.html" title="Asio">
<link rel="next" href="overview/rationale.html" title="Rationale">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../home.png" alt="Home"></a><a accesskey="n" href="overview/rationale.html"><img src="../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="asio.overview"></a><a class="link" href="overview.html" title="Overview">Overview</a>
</h2></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a class="link" href="overview/rationale.html" title="Rationale">Rationale</a>
</li>
<li class="listitem">
<a class="link" href="overview/basics.html" title="Basic Asio Anatomy">Basic Asio Anatomy</a>
</li>
<li class="listitem">
<a class="link" href="overview/model.html" title="Asynchronous Model">Asynchronous Model</a>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<a class="link" href="overview/model/async_ops.html" title="Asynchronous Operations">Asynchronous Operations</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/async_agents.html" title="Asynchronous Agents">Asynchronous Agents</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/associators.html" title="Associated Characteristics and Associators">Associated Characteristics
and Associators</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/child_agents.html" title="Child Agents">Child Agents</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/executors.html" title="Executors">Executors</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/allocators.html" title="Allocators">Allocators</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/cancellation.html" title="Cancellation">Cancellation</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/completion_tokens.html" title="Completion Tokens">Completion
Tokens</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/library_elements.html" title="Supporting Library Elements">Supporting Library
Elements</a>
</li>
<li class="listitem">
<a class="link" href="overview/model/higher_levels.html" title="Higher Level Abstractions">Higher Level Abstractions</a>
</li>
</ul></div>
</li>
<li class="listitem">
<a class="link" href="overview/core.html" title="Core Concepts and Functionality">Core Concepts and Functionality</a>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<a class="link" href="overview/core/async.html" title="The Proactor Design Pattern: Concurrency Without Threads">The Proactor Design Pattern:
Concurrency Without Threads</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/threads.html" title="Threads and Asio">Threads and Asio</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/strands.html" title="Strands: Use Threads Without Explicit Locking">Strands: Use Threads Without
Explicit Locking</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/buffers.html" title="Buffers">Buffers</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/streams.html" title="Streams, Short Reads and Short Writes">Streams, Short Reads and
Short Writes</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/reactor.html" title="Reactor-Style Operations">Reactor-Style Operations</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/line_based.html" title="Line-Based Operations">Line-Based Operations</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/allocation.html" title="Custom Memory Allocation">Custom Memory Allocation</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/cancellation.html" title="Per-Operation Cancellation">Per-Operation Cancellation</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/handler_tracking.html" title="Handler Tracking">Handler Tracking</a>
</li>
<li class="listitem">
<a class="link" href="overview/core/concurrency_hint.html" title="Concurrency Hints">Concurrency Hints</a>
</li>
</ul></div>
</li>
<li class="listitem">
<a class="link" href="overview/composition.html" title="Composition and Completion Tokens">Composition and Completion Tokens</a>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<a class="link" href="overview/composition/coroutine.html" title="Stackless Coroutines">Stackless Coroutines</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/spawn.html" title="Stackful Coroutines">Stackful Coroutines</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/futures.html" title="Futures">Futures</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/cpp20_coroutines.html" title="C++20 Coroutines Support">C++20
Coroutines Support</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/coro.html" title="Resumable C++ 20 Coroutines">Resumable C++20 Coroutines
(experimental)</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/deferred.html" title="Deferred Operations">Deferred Operations
(experimental)</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/promises.html" title="Promises">Promises (experimental)</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/parallel_group.html" title="Co-ordinating Parallel Operations">Co-ordinating
Parallel Operations (experimental)</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/compose.html" title="Compositions as Asynchronous Operations">Compositions as
Asynchronous Operations</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/token_adapters.html" title="Completion Token Adapters">Completion
Token Adapters</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/type_erasure.html" title="Type Erasure, Separate Compilation and Virtual Functions">Type Erasure,
Separate Compilation and Virtual Functions</a>
</li>
<li class="listitem">
<a class="link" href="overview/composition/immediate_completion.html" title="Customising Immediate Completion">Customising
Immediate Completion</a>
</li>
</ul></div>
</li>
<li class="listitem">
<a class="link" href="overview/networking.html" title="Networking">Networking</a>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<a class="link" href="overview/networking/protocols.html" title="TCP, UDP and ICMP">TCP, UDP and ICMP</a>
</li>
<li class="listitem">
<a class="link" href="overview/networking/other_protocols.html" title="Support for Other Protocols">Support
for Other Protocols</a>
</li>
<li class="listitem">
<a class="link" href="overview/networking/iostreams.html" title="Socket Iostreams">Socket Iostreams</a>
</li>
<li class="listitem">
<a class="link" href="overview/networking/bsd_sockets.html" title="The BSD Socket API and Asio">The BSD Socket
API and Asio</a>
</li>
</ul></div>
</li>
<li class="listitem">
<a class="link" href="overview/timers.html" title="Timers">Timers</a>
</li>
<li class="listitem">
<a class="link" href="overview/files.html" title="Files">Files</a>
</li>
<li class="listitem">
<a class="link" href="overview/pipes.html" title="Pipes">Pipes</a>
</li>
<li class="listitem">
<a class="link" href="overview/serial_ports.html" title="Serial Ports">Serial Ports</a>
</li>
<li class="listitem">
<a class="link" href="overview/signals.html" title="Signal Handling">Signal Handling</a>
</li>
<li class="listitem">
<a class="link" href="overview/channels.html" title="Channels">Channels (experimental)</a>
</li>
<li class="listitem">
<a class="link" href="overview/posix.html" title="POSIX-Specific Functionality">POSIX-Specific Functionality</a>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<a class="link" href="overview/posix/local.html" title="UNIX Domain Sockets">UNIX Domain Sockets</a>
</li>
<li class="listitem">
<a class="link" href="overview/posix/stream_descriptor.html" title="Stream-Oriented File Descriptors">Stream-Oriented
File Descriptors</a>
</li>
<li class="listitem">
<a class="link" href="overview/posix/fork.html" title="Fork">Fork</a>
</li>
</ul></div>
</li>
<li class="listitem">
<a class="link" href="overview/windows.html" title="Windows-Specific Functionality">Windows-Specific Functionality</a>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<a class="link" href="overview/windows/stream_handle.html" title="Stream-Oriented HANDLEs">Stream-Oriented
HANDLEs</a>
</li>
<li class="listitem">
<a class="link" href="overview/windows/random_access_handle.html" title="Random-Access HANDLEs">Random-Access
HANDLEs</a>
</li>
<li class="listitem">
<a class="link" href="overview/windows/object_handle.html" title="Object HANDLEs">Object HANDLEs</a>
</li>
</ul></div>
</li>
<li class="listitem">
<a class="link" href="overview/ssl.html" title="SSL">SSL</a>
</li>
<li class="listitem">
<a class="link" href="overview/cpp2011.html" title="C++ 2011 Support">C++ 2011 Support</a>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<a class="link" href="overview/cpp2011/move_objects.html" title="Movable I/O Objects">Movable I/O Objects</a>
</li>
<li class="listitem">
<a class="link" href="overview/cpp2011/move_handlers.html" title="Movable Handlers">Movable Handlers</a>
</li>
<li class="listitem">
<a class="link" href="overview/cpp2011/variadic.html" title="Variadic Templates">Variadic Templates</a>
</li>
<li class="listitem">
<a class="link" href="overview/cpp2011/array.html" title="Array Container">Array Container</a>
</li>
<li class="listitem">
<a class="link" href="overview/cpp2011/atomic.html" title="Atomics">Atomics</a>
</li>
<li class="listitem">
<a class="link" href="overview/cpp2011/shared_ptr.html" title="Shared Pointers">Shared Pointers</a>
</li>
<li class="listitem">
<a class="link" href="overview/cpp2011/chrono.html" title="Chrono">Chrono</a>
</li>
</ul></div>
</li>
<li class="listitem">
<a class="link" href="overview/implementation.html" title="Platform-Specific Implementation Notes">Platform-Specific Implementation
Notes</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../home.png" alt="Home"></a><a accesskey="n" href="overview/rationale.html"><img src="../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,167 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Basic Asio Anatomy</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="rationale.html" title="Rationale">
<link rel="next" href="model.html" title="Asynchronous Model">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="rationale.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="model.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.basics"></a><a class="link" href="basics.html" title="Basic Asio Anatomy">Basic Asio Anatomy</a>
</h3></div></div></div>
<p>
Asio may be used to perform both synchronous and asynchronous operations
on I/O objects such as sockets. Before using Asio it may be useful to get
a conceptual picture of the various parts of Asio, your program, and how
they work together.
</p>
<p>
As an introductory example, let's consider what happens when you perform
a connect operation on a socket. We shall start by examining synchronous
operations.
</p>
<p>
<span class="inlinemediaobject"><img src="../../sync_op.png"></span>
</p>
<p>
<span class="bold"><strong>Your program</strong></span> will have at least one <span class="bold"><strong>I/O execution context</strong></span>, such as an <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span></code>
object, <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">thread_pool</span></code> object, or <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">system_context</span></code>.
This <span class="bold"><strong>I/O execution context</strong></span> represents <span class="bold"><strong>your program</strong></span>'s link to the <span class="bold"><strong>operating
system</strong></span>'s I/O services.
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span> <span class="identifier">io_context</span><span class="special">;</span>
</pre>
<p>
To perform I/O operations <span class="bold"><strong>your program</strong></span> will
need an <span class="bold"><strong>I/O object</strong></span> such as a TCP socket:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">io_context</span><span class="special">);</span>
</pre>
<p>
When a synchronous connect operation is performed, the following sequence
of events occurs:
</p>
<p>
1. <span class="bold"><strong>Your program</strong></span> initiates the connect operation
by calling the <span class="bold"><strong>I/O object</strong></span>:
</p>
<pre class="programlisting"><span class="identifier">socket</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">server_endpoint</span><span class="special">);</span>
</pre>
<p>
2. The <span class="bold"><strong>I/O object</strong></span> forwards the request to
the <span class="bold"><strong>I/O execution context</strong></span>.
</p>
<p>
3. The <span class="bold"><strong>I/O execution context</strong></span> calls on the
<span class="bold"><strong>operating system</strong></span> to perform the connect
operation.
</p>
<p>
4. The <span class="bold"><strong>operating system</strong></span> returns the result
of the operation to the <span class="bold"><strong>I/O execution context</strong></span>.
</p>
<p>
5. The <span class="bold"><strong>I/O execution context</strong></span> translates
any error resulting from the operation into an object of type <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span></code>. An <code class="computeroutput"><span class="identifier">error_code</span></code>
may be compared with specific values, or tested as a boolean (where a <code class="computeroutput"><span class="keyword">false</span></code> result means that no error occurred).
The result is then forwarded back up to the <span class="bold"><strong>I/O object</strong></span>.
</p>
<p>
6. The <span class="bold"><strong>I/O object</strong></span> throws an exception of
type <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">system_error</span></code> if the operation failed. If
the code to initiate the operation had instead been written as:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">;</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">server_endpoint</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span>
</pre>
<p>
then the <code class="computeroutput"><span class="identifier">error_code</span></code> variable
<code class="computeroutput"><span class="identifier">ec</span></code> would be set to the result
of the operation, and no exception would be thrown.
</p>
<p>
When an asynchronous operation is used, a different sequence of events occurs.
</p>
<p>
<span class="inlinemediaobject"><img src="../../async_op1.png"></span>
</p>
<p>
1. <span class="bold"><strong>Your program</strong></span> initiates the connect operation
by calling the <span class="bold"><strong>I/O object</strong></span>:
</p>
<pre class="programlisting"><span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_connect</span><span class="special">(</span><span class="identifier">server_endpoint</span><span class="special">,</span> <span class="identifier">your_completion_handler</span><span class="special">);</span>
</pre>
<p>
where <code class="computeroutput"><span class="identifier">your_completion_handler</span></code>
is a function or function object with the signature:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">your_completion_handler</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">);</span>
</pre>
<p>
The exact signature required depends on the asynchronous operation being
performed. The reference documentation indicates the appropriate form for
each operation.
</p>
<p>
2. The <span class="bold"><strong>I/O object</strong></span> forwards the request to
the <span class="bold"><strong>I/O execution context</strong></span>.
</p>
<p>
3. The <span class="bold"><strong>I/O execution context</strong></span> signals to
the <span class="bold"><strong>operating system</strong></span> that it should start
an asynchronous connect.
</p>
<p>
Time passes. (In the synchronous case this wait would have been contained
entirely within the duration of the connect operation.)
</p>
<p>
<span class="inlinemediaobject"><img src="../../async_op2.png"></span>
</p>
<p>
4. The <span class="bold"><strong>operating system</strong></span> indicates that the
connect operation has completed by placing the result on a queue, ready to
be picked up by the <span class="bold"><strong>I/O execution context</strong></span>.
</p>
<p>
5. When using an <code class="computeroutput"><span class="identifier">io_context</span></code>
as the <span class="bold"><strong>I/O execution context</strong></span>, <span class="bold"><strong>your program</strong></span> must make a call to <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>
(or to one of the similar <code class="computeroutput"><span class="identifier">io_context</span></code>
member functions) in order for the result to be retrieved. A call to <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code> blocks
while there are unfinished asynchronous operations, so you would typically
call it as soon as you have started your first asynchronous operation.
</p>
<p>
6. While inside the call to <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>,
the <span class="bold"><strong>I/O execution context</strong></span> dequeues the result
of the operation, translates it into an <code class="computeroutput"><span class="identifier">error_code</span></code>,
and then passes it to <span class="bold"><strong>your completion handler</strong></span>.
</p>
<p>
This is a simplified picture of how Asio operates. You will want to delve
further into the documentation if your needs are more advanced, such as extending
Asio to perform other types of asynchronous operations.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="rationale.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="model.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,92 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Channels</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="signals.html" title="Signal Handling">
<link rel="next" href="posix.html" title="POSIX-Specific Functionality">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="signals.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="posix.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.channels"></a><a class="link" href="channels.html" title="Channels">Channels</a>
</h3></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This is an experimental feature.
</p></td></tr>
</table></div>
<p>
The templates <a class="link" href="../reference/experimental__basic_channel.html" title="experimental::basic_channel">experimental::basic_channel</a>
and <a class="link" href="../reference/experimental__basic_concurrent_channel.html" title="experimental::basic_concurrent_channel">experimental::basic_concurrent_channel</a>,
with aliases <code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">channel</span></code>
and <code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">concurrent_channel</span></code>, may be used to send
messages between different parts of the same application. A <span class="emphasis"><em>message</em></span>
is defined as a collection of arguments to be passed to a completion handler,
and the set of messages supported by a channel is specified by its template
parameters. Messages may be sent and received using asynchronous or non-blocking
synchronous operations.
</p>
<p>
For example:
</p>
<pre class="programlisting"><span class="comment">// Create a channel with no buffer space.</span>
<span class="identifier">channel</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">)&gt;</span> <span class="identifier">ch</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span>
<span class="comment">// The call to try_send fails as there is no buffer</span>
<span class="comment">// space and no waiting receive operations.</span>
<span class="keyword">bool</span> <span class="identifier">ok</span> <span class="special">=</span> <span class="identifier">ch</span><span class="special">.</span><span class="identifier">try_send</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error</span><span class="special">::</span><span class="identifier">eof</span><span class="special">,</span> <span class="number">123</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">ok</span><span class="special">);</span>
<span class="comment">// The async_send operation is outstanding until</span>
<span class="comment">// a receive operation consumes the message.</span>
<span class="identifier">ch</span><span class="special">.</span><span class="identifier">async_send</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error</span><span class="special">::</span><span class="identifier">eof</span><span class="special">,</span> <span class="number">123</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">});</span>
<span class="comment">// The async_receive consumes the message. Both the</span>
<span class="comment">// async_send and async_receive operations complete</span>
<span class="comment">// immediately.</span>
<span class="identifier">ch</span><span class="special">.</span><span class="identifier">async_receive</span><span class="special">(</span>
<span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">});</span>
</pre>
<h5>
<a name="asio.overview.channels.h0"></a>
<span><a name="asio.overview.channels.see_also"></a></span><a class="link" href="channels.html#asio.overview.channels.see_also">See
Also</a>
</h5>
<p>
<a class="link" href="../reference/experimental__basic_channel.html" title="experimental::basic_channel">experimental::basic_channel</a>,
<a class="link" href="../reference/experimental__basic_concurrent_channel.html" title="experimental::basic_concurrent_channel">experimental::basic_concurrent_channel</a>,
<a class="link" href="../examples/cpp20_examples.html#asio.examples.cpp20_examples.channels">Channels examples (C++20)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="signals.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="posix.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,81 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Composition and Completion Tokens</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="core/concurrency_hint.html" title="Concurrency Hints">
<link rel="next" href="composition/coroutine.html" title="Stackless Coroutines">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="core/concurrency_hint.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="composition/coroutine.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.composition"></a><a class="link" href="composition.html" title="Composition and Completion Tokens">Composition and Completion
Tokens</a>
</h3></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a class="link" href="composition/coroutine.html" title="Stackless Coroutines">Stackless Coroutines</a>
</li>
<li class="listitem">
<a class="link" href="composition/spawn.html" title="Stackful Coroutines">Stackful Coroutines</a>
</li>
<li class="listitem">
<a class="link" href="composition/futures.html" title="Futures">Futures</a>
</li>
<li class="listitem">
<a class="link" href="composition/cpp20_coroutines.html" title="C++20 Coroutines Support">C++20 Coroutines
Support</a>
</li>
<li class="listitem">
<a class="link" href="composition/coro.html" title="Resumable C++ 20 Coroutines">Resumable C++20 Coroutines
(experimental)</a>
</li>
<li class="listitem">
<a class="link" href="composition/deferred.html" title="Deferred Operations">Deferred Operations
(experimental)</a>
</li>
<li class="listitem">
<a class="link" href="composition/promises.html" title="Promises">Promises (experimental)</a>
</li>
<li class="listitem">
<a class="link" href="composition/parallel_group.html" title="Co-ordinating Parallel Operations">Co-ordinating
Parallel Operations (experimental)</a>
</li>
<li class="listitem">
<a class="link" href="composition/compose.html" title="Compositions as Asynchronous Operations">Compositions as Asynchronous
Operations</a>
</li>
<li class="listitem">
<a class="link" href="composition/token_adapters.html" title="Completion Token Adapters">Completion Token
Adapters</a>
</li>
<li class="listitem">
<a class="link" href="composition/type_erasure.html" title="Type Erasure, Separate Compilation and Virtual Functions">Type Erasure,
Separate Compilation and Virtual Functions</a>
</li>
<li class="listitem">
<a class="link" href="composition/immediate_completion.html" title="Customising Immediate Completion">Customising
Immediate Completion</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="core/concurrency_hint.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="composition/coroutine.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,136 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Compositions as Asynchronous Operations</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="parallel_group.html" title="Co-ordinating Parallel Operations">
<link rel="next" href="token_adapters.html" title="Completion Token Adapters">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="parallel_group.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="token_adapters.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.compose"></a><a class="link" href="compose.html" title="Compositions as Asynchronous Operations">Compositions as
Asynchronous Operations</a>
</h4></div></div></div>
<p>
Application developers may wish to package their own compositions as conforming
<a class="link" href="../model/async_ops.html" title="Asynchronous Operations">asynchronous operations</a>
within the <a class="link" href="../model.html" title="Asynchronous Model">asynchronous model</a>.
Doing so facilitates seamless composition of these operations together
with the operations already provided by Asio.
</p>
<p>
While these operations may be written from scratch to conform with the
<a class="link" href="../../reference/asynchronous_operations.html" title="Requirements on asynchronous operations">requirements on
asynchronous operations</a>, Asio includes the <a class="link" href="../../reference/async_compose.html" title="async_compose"><code class="computeroutput"><span class="identifier">async_compose</span></code></a> function to simplify
this process. The <code class="computeroutput"><span class="identifier">async_compose</span></code>
implementation automatically provides an intermediate completion handler
that correctly propagates the <a class="link" href="../model/associators.html" title="Associated Characteristics and Associators">associated
characteristics</a> and tracks outstanding work against the I/O executor
and completion executor.
</p>
<p>
The following example illustrates an asynchronous echo loop (i.e. read,
followed by write, and so on), expressed as a simple state machine.
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">async_echo_implementation</span>
<span class="special">{</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">socket_</span><span class="special">;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">mutable_buffer</span> <span class="identifier">buffer_</span><span class="special">;</span>
<span class="keyword">enum</span> <span class="special">{</span> <span class="identifier">starting</span><span class="special">,</span> <span class="identifier">reading</span><span class="special">,</span> <span class="identifier">writing</span> <span class="special">}</span> <span class="identifier">state_</span><span class="special">;</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Self</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Self</span><span class="special">&amp;</span> <span class="identifier">self</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">error</span> <span class="special">=</span> <span class="special">{},</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">switch</span> <span class="special">(</span><span class="identifier">state_</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">case</span> <span class="identifier">starting</span><span class="special">:</span>
<span class="identifier">state_</span> <span class="special">=</span> <span class="identifier">reading</span><span class="special">;</span>
<span class="identifier">socket_</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">buffer_</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">self</span><span class="special">));</span>
<span class="keyword">break</span><span class="special">;</span>
<span class="keyword">case</span> <span class="identifier">reading</span><span class="special">:</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">error</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">self</span><span class="special">.</span><span class="identifier">complete</span><span class="special">(</span><span class="identifier">error</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="identifier">state_</span> <span class="special">=</span> <span class="identifier">writing</span><span class="special">;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">socket_</span><span class="special">,</span> <span class="identifier">buffer_</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">transfer_exactly</span><span class="special">(</span><span class="identifier">n</span><span class="special">),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">self</span><span class="special">));</span>
<span class="special">}</span>
<span class="keyword">break</span><span class="special">;</span>
<span class="keyword">case</span> <span class="identifier">writing</span><span class="special">:</span>
<span class="identifier">self</span><span class="special">.</span><span class="identifier">complete</span><span class="special">(</span><span class="identifier">error</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span>
<span class="keyword">break</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
This implementation is then used in an initiating function, which trivially
wraps <code class="computeroutput"><span class="identifier">async_compose</span></code>:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_echo</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">socket</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">mutable_buffer</span> <span class="identifier">buffer</span><span class="special">,</span>
<span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span> <span class="special">-&gt;</span>
<span class="keyword">typename</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_result</span><span class="special">&lt;</span>
<span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">,</span>
<span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">)&gt;::</span><span class="identifier">return_type</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_compose</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span>
<span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">)&gt;(</span>
<span class="identifier">async_echo_implementation</span><span class="special">{</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">,</span>
<span class="identifier">async_echo_implementation</span><span class="special">::</span><span class="identifier">starting</span><span class="special">},</span>
<span class="identifier">token</span><span class="special">,</span> <span class="identifier">socket</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
Here, <code class="computeroutput"><span class="identifier">async_compose</span></code> is
first passed the function object that contains the implementation of the
composed asynchronous operation. The first argument to the function object
is a non-const reference to the enclosing intermediate completion handler.
The remaining arguments are any arguments that originate from the completion
handlers of any asynchronous operations performed by the implementation.
</p>
<p>
The <code class="computeroutput"><span class="identifier">async_compose</span></code> function
is also passed the completion token, and zero or more I/O objects or I/O
executors for which outstanding work must be maintained.
</p>
<h6>
<a name="asio.overview.composition.compose.h0"></a>
<span><a name="asio.overview.composition.compose.see_also"></a></span><a class="link" href="compose.html#asio.overview.composition.compose.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/async_compose.html" title="async_compose">async_compose</a>, <a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.operations">Operations examples (C++11)</a>,
<a class="link" href="../../examples/cpp14_examples.html#asio.examples.cpp14_examples.operations">Operations examples
(C++14)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="parallel_group.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="token_adapters.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,587 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Resumable C++ 20 Coroutines</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="cpp20_coroutines.html" title="C++20 Coroutines Support">
<link rel="next" href="deferred.html" title="Deferred Operations">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp20_coroutines.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="deferred.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.coro"></a><a class="link" href="coro.html" title="Resumable C++ 20 Coroutines">Resumable C++ 20 Coroutines</a>
</h4></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This is an experimental feature.
</p></td></tr>
</table></div>
<p>
The <a class="link" href="../../reference/experimental__coro.html" title="experimental::coro"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">coro</span></code></a>
class provides support for a universal C++20 coroutine. These coroutines
can be used as tasks, generators and transfomers, depending on their signature.
</p>
<pre class="programlisting"><span class="identifier">coro</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span><span class="special">&gt;</span> <span class="identifier">line_reader</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">stream</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">stream</span><span class="special">.</span><span class="identifier">is_open</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="number">4096</span><span class="special">&gt;</span> <span class="identifier">buf</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">read</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">buf</span><span class="special">),</span> <span class="identifier">deferred</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">read</span> <span class="special">==</span> <span class="number">0u</span><span class="special">)</span>
<span class="keyword">continue</span><span class="special">;</span>
<span class="identifier">co_yield</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span> <span class="special">{</span> <span class="identifier">buf</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">read</span> <span class="special">};</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">line_logger</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">stream</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">lines_read</span> <span class="special">=</span> <span class="number">0u</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">reader</span> <span class="special">=</span> <span class="identifier">line_reader</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">stream</span><span class="special">));</span>
<span class="keyword">while</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">reader</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Read: '"</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">l</span> <span class="special">&lt;&lt;</span> <span class="string">"'"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">lines_read</span><span class="special">++;</span>
<span class="special">}</span>
<span class="identifier">co_return</span> <span class="identifier">lines_read</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">read_lines</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">sock</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">co_spawn</span><span class="special">(</span><span class="identifier">line_logger</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sock</span><span class="special">),</span>
<span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">lines</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span> <span class="special">&lt;&lt;</span> <span class="string">"Read "</span> <span class="special">&lt;&lt;</span> <span class="identifier">lines</span> <span class="special">&lt;&lt;</span> <span class="string">" lines"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}));</span>
<span class="special">}</span>
</pre>
<p>
A <a class="link" href="../../reference/experimental__coro.html" title="experimental::coro"><code class="computeroutput"><span class="identifier">coro</span></code></a>
is highly configurable, so that it can cover a set of different use cases.
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span>
<span class="keyword">typename</span> <span class="identifier">Yield</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">Return</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">Executor</span> <span class="special">=</span> <span class="identifier">any_io_executor</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">coro</span><span class="special">;</span>
</pre>
<h6>
<a name="asio.overview.composition.coro.h0"></a>
<span><a name="asio.overview.composition.coro.yield"></a></span><a class="link" href="coro.html#asio.overview.composition.coro.yield">Yield</a>
</h6>
<p>
The <code class="computeroutput"><span class="identifier">Yield</span></code> parameter designates
how a <code class="computeroutput"><span class="identifier">co_yield</span></code> statement
behaves. It can either be a type, like <code class="computeroutput"><span class="keyword">int</span></code>
or a signature with zero or one types:
</p>
<pre class="programlisting"><span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="comment">// A coroutine with no yield</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="comment">// A coroutine that can yield int</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">()&gt;</span> <span class="comment">// A coroutine with no yield</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">()&gt;</span> <span class="comment">// A coroutine that can yield int</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">(</span><span class="keyword">double</span><span class="special">)&gt;</span> <span class="comment">// A coroutine that can yield int and receive double</span>
</pre>
<p>
Receiving a value means that the <code class="computeroutput"><span class="identifier">co_yield</span></code>
statement returns a value.
</p>
<pre class="programlisting"><span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">(</span><span class="keyword">int</span><span class="special">)&gt;</span> <span class="identifier">my_sum</span><span class="special">(</span><span class="identifier">any_io_executor</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="keyword">true</span><span class="special">)</span>
<span class="identifier">value</span> <span class="special">+=</span> <span class="identifier">co_yield</span> <span class="identifier">value</span><span class="special">;</span> <span class="comment">//sum up all values</span>
<span class="special">}</span>
</pre>
<p>
Putting values into a coroutine can be done it two ways: either by direct
resumption (from another coro) or through async_resume. The first value
gets ignored because the coroutines are lazy.
</p>
<pre class="programlisting"><span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">c</span><span class="special">(</span><span class="identifier">any_io_executor</span> <span class="identifier">exec</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="identifier">my_sum</span><span class="special">(</span><span class="identifier">exec</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="number">0</span> <span class="special">==</span> <span class="identifier">co_await</span> <span class="identifier">sum</span><span class="special">(-</span><span class="number">1</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="number">0</span> <span class="special">==</span> <span class="identifier">co_await</span> <span class="identifier">sum</span><span class="special">(</span><span class="number">10</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="number">10</span> <span class="special">==</span> <span class="identifier">co_await</span> <span class="identifier">sum</span><span class="special">(</span><span class="number">15</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="number">25</span> <span class="special">==</span> <span class="identifier">co_await</span> <span class="identifier">sum</span><span class="special">(</span><span class="number">0</span><span class="special">));</span>
<span class="special">}</span>
<span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="identifier">my_sum</span><span class="special">(</span><span class="identifier">co_await</span> <span class="identifier">this_coro</span><span class="special">::</span><span class="identifier">executor</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="number">0</span> <span class="special">==</span> <span class="identifier">co_await</span> <span class="identifier">sum</span><span class="special">.</span><span class="identifier">async_resume</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="identifier">use_awaitable</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="number">0</span> <span class="special">==</span> <span class="identifier">co_await</span> <span class="identifier">sum</span><span class="special">.</span><span class="identifier">async_resume</span><span class="special">(</span><span class="number">10</span><span class="special">,</span> <span class="identifier">use_awaitable</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="number">10</span> <span class="special">==</span> <span class="identifier">co_await</span> <span class="identifier">sum</span><span class="special">.</span><span class="identifier">async_resume</span><span class="special">(</span><span class="number">15</span><span class="special">,</span> <span class="identifier">use_awaitable</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="number">25</span> <span class="special">==</span> <span class="identifier">co_await</span> <span class="identifier">sum</span><span class="special">.</span><span class="identifier">async_resume</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">use_awaitable</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<h6>
<a name="asio.overview.composition.coro.h1"></a>
<span><a name="asio.overview.composition.coro._code__phrase_role__keyword__noexcept__phrase___code_"></a></span><a class="link" href="coro.html#asio.overview.composition.coro._code__phrase_role__keyword__noexcept__phrase___code_"><code class="computeroutput"><span class="keyword">noexcept</span></code></a>
</h6>
<p>
A coro may be noexcept:
</p>
<pre class="programlisting"><span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">&gt;</span> <span class="identifier">c</span><span class="special">;</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">&gt;</span> <span class="identifier">c</span><span class="special">;</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">(</span><span class="keyword">double</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">&gt;</span> <span class="identifier">c</span><span class="special">;</span>
</pre>
<p>
This will change its @c async_resume signature, from <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">)</span></code> to <code class="computeroutput"><span class="keyword">void</span><span class="special">()</span></code> or <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">,</span> <span class="identifier">T</span><span class="special">)</span></code>
to <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code>. A
noexcept coro that ends with an exception will cause <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code>
to be called.
</p>
<p>
Furthermore, calls of <code class="computeroutput"><span class="identifier">async_resume</span></code>
and <code class="computeroutput"><span class="identifier">co_await</span></code> of an expired
noexcept coro will cause undefined behaviour.
</p>
<h6>
<a name="asio.overview.composition.coro.h2"></a>
<span><a name="asio.overview.composition.coro.return"></a></span><a class="link" href="coro.html#asio.overview.composition.coro.return">Return</a>
</h6>
<p>
A coro can also define a type that can be used with <code class="computeroutput"><span class="identifier">co_return</span></code>:
</p>
<pre class="programlisting"><span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">c</span><span class="special">(</span><span class="identifier">any_io_executor</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">co_return</span> <span class="number">42</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
A coro can have both a <code class="computeroutput"><span class="identifier">Yield</span></code>
and <code class="computeroutput"><span class="identifier">Return</span></code> that are non
void at the same time.
</p>
<h6>
<a name="asio.overview.composition.coro.h3"></a>
<span><a name="asio.overview.composition.coro.result"></a></span><a class="link" href="coro.html#asio.overview.composition.coro.result">Result</a>
</h6>
<p>
The result type of a coroutine is dermined by both <code class="computeroutput"><span class="identifier">Yield</span></code>
and <code class="computeroutput"><span class="identifier">Return</span></code>. Note that in
the follwing table only the yield output value is considered, i.e. <code class="computeroutput"><span class="identifier">T</span><span class="special">(</span><span class="identifier">U</span><span class="special">)</span></code> means <code class="computeroutput"><span class="identifier">T</span></code>.
</p>
<div class="table">
<a name="asio.overview.composition.coro.result_type"></a><p class="title"><b>Table 2. Result type deduction</b></p>
<div class="table-contents"><table class="table" summary="Result type deduction">
<colgroup>
<col>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Yield
</p>
</th>
<th>
<p>
Return
</p>
</th>
<th>
<p>
<code class="computeroutput"><span class="keyword">noexcept</span></code>
</p>
</th>
<th>
<p>
<code class="computeroutput"><span class="identifier">result_type</span></code>
</p>
</th>
<th>
<p>
<code class="computeroutput"><span class="identifier">completion_signature</span></code>
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">T</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">U</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">false</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span>
<span class="identifier">U</span><span class="special">&gt;</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">,</span>
<span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span>
<span class="identifier">U</span><span class="special">&gt;)</span></code>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">T</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">U</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">true</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span>
<span class="identifier">U</span><span class="special">&gt;</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span>
<span class="identifier">U</span><span class="special">&gt;)</span></code>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">T</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">false</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">,</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;)</span></code>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">T</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">true</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;)</span></code>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">false</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">)</span></code>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">true</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span><span class="special">()</span></code>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">T</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">false</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">,</span>
<span class="identifier">T</span><span class="special">)</span></code>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">T</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">true</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code>
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><h6>
<a name="asio.overview.composition.coro.h4"></a>
<span><a name="asio.overview.composition.coro.executor"></a></span><a class="link" href="coro.html#asio.overview.composition.coro.executor">Executor</a>
</h6>
<p>
Every coroutine needs to have its own executor. Since the coroutine gets
called multiple times, it cannot take the executor from the caller like
an <code class="computeroutput"><span class="identifier">awaitable</span></code>. Therefore
a <code class="computeroutput"><span class="identifier">coro</span></code> requires to get
an executor or an execution_context passed in as the first parameter.
</p>
<pre class="programlisting"><span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">with_executor</span><span class="special">(</span><span class="identifier">any_io_executor</span><span class="special">);</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">with_context</span><span class="special">(</span><span class="identifier">io_context</span> <span class="special">&amp;);</span>
</pre>
<p>
It is to note, that an execution_context is defined as loosely as possible.
An execution context is any object that has a <code class="computeroutput"><span class="identifier">get_executor</span><span class="special">()</span></code> function, which returns an executor that
can be transformed into the executor_type of the coroutine. This allows
most io_objects to be used as the source of the executor:
</p>
<pre class="programlisting"><span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">with_socket</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">);</span>
</pre>
<p>
Additionally, a <code class="computeroutput"><span class="identifier">coro</span></code> that
is a member function will check the <code class="computeroutput"><span class="keyword">this</span></code>
pointer as well, either if it's an executor or an execution context:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_io_object</span>
<span class="special">{</span>
<span class="identifier">any_io_executor</span> <span class="identifier">get_executor</span><span class="special">();</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">my_coro</span><span class="special">();</span>
<span class="special">};</span>
</pre>
<p>
Finally, a member coro can be given an explicit executor or execution context,
to override the one of the object:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_io_object</span>
<span class="special">{</span>
<span class="identifier">any_io_executor</span> <span class="identifier">get_executor</span><span class="special">();</span>
<span class="identifier">coro</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">my_coro</span><span class="special">(</span><span class="identifier">any_io_executor</span> <span class="identifier">exec</span><span class="special">);</span> <span class="comment">// it will use exec</span>
<span class="special">};</span>
</pre>
<h6>
<a name="asio.overview.composition.coro.h5"></a>
<span><a name="asio.overview.composition.coro._code__phrase_role__identifier__co_await__phrase___code_"></a></span><a class="link" href="coro.html#asio.overview.composition.coro._code__phrase_role__identifier__co_await__phrase___code_"><code class="computeroutput"><span class="identifier">co_await</span></code></a>
</h6>
<p>
The @c co_await within a <code class="computeroutput"><span class="identifier">coro</span></code>
is not the same as <code class="computeroutput"><span class="identifier">async_resume</span><span class="special">(</span><span class="identifier">deferred</span><span class="special">)</span></code>, unless both coros use different executors.
If they use the same, the <code class="computeroutput"><span class="identifier">coro</span></code>
will direclty suspend and resume the executor, without any usage of the
executor.
</p>
<p>
<code class="computeroutput"><span class="identifier">co_await</span> <span class="identifier">this_coro</span><span class="special">::</span></code> behaves the same as coroutines that use
@c asio::awaitable.
</p>
<h6>
<a name="asio.overview.composition.coro.h6"></a>
<span><a name="asio.overview.composition.coro.integrating_with_awaitable"></a></span><a class="link" href="coro.html#asio.overview.composition.coro.integrating_with_awaitable">Integrating
with awaitable</a>
</h6>
<p>
As the <code class="computeroutput"><span class="identifier">coro</span></code> member function
<code class="computeroutput"><span class="identifier">async_resume</span></code> is an asynchronous
operation, it may also be used in conjunction with <code class="computeroutput"><span class="identifier">awaitable</span></code>
coroutines in a single control flow. For example:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">asio</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">asio</span><span class="special">/</span><span class="identifier">experimental</span><span class="special">/</span><span class="identifier">coro</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">using</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">coro</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">reader</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">sock</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">buf</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">sock</span><span class="special">.</span><span class="identifier">is_open</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_read_until</span><span class="special">(</span>
<span class="identifier">sock</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">dynamic_buffer</span><span class="special">(</span><span class="identifier">buf</span><span class="special">),</span> <span class="char">'\n'</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">);</span>
<span class="identifier">co_yield</span> <span class="identifier">buf</span><span class="special">.</span><span class="identifier">substr</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span>
<span class="identifier">buf</span><span class="special">.</span><span class="identifier">erase</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">consumer</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">sock</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">reader</span><span class="special">(</span><span class="identifier">sock</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">msg1</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">async_resume</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Message 1: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">msg1</span><span class="special">.</span><span class="identifier">value_or</span><span class="special">(</span><span class="string">"\n"</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">msg2</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">async_resume</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Message 2: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">msg2</span><span class="special">.</span><span class="identifier">value_or</span><span class="special">(</span><span class="string">"\n"</span><span class="special">);</span>
<span class="special">}</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">listen</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">acceptor</span><span class="special">&amp;</span> <span class="identifier">acceptor</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="identifier">co_spawn</span><span class="special">(</span>
<span class="identifier">acceptor</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(),</span>
<span class="identifier">consumer</span><span class="special">(</span><span class="identifier">co_await</span> <span class="identifier">acceptor</span><span class="special">.</span><span class="identifier">async_accept</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">)),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">detached</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span> <span class="identifier">ctx</span><span class="special">;</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">acceptor</span> <span class="identifier">acceptor</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span> <span class="special">{</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">v4</span><span class="special">(),</span> <span class="number">54321</span><span class="special">});</span>
<span class="identifier">co_spawn</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">listen</span><span class="special">(</span><span class="identifier">acceptor</span><span class="special">),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">detached</span><span class="special">);</span>
<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
<span class="special">}</span>
</pre>
<h6>
<a name="asio.overview.composition.coro.h7"></a>
<span><a name="asio.overview.composition.coro.see_also"></a></span><a class="link" href="coro.html#asio.overview.composition.coro.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/co_spawn.html" title="co_spawn">co_spawn</a>, <a class="link" href="../../reference/experimental__coro.html" title="experimental::coro">experimental::coro</a>,
<a class="link" href="cpp20_coroutines.html" title="C++20 Coroutines Support">C++20 Coroutines</a>,
<a class="link" href="spawn.html" title="Stackful Coroutines">Stackful Coroutines</a>,
<a class="link" href="coroutine.html" title="Stackless Coroutines">Stackless Coroutines</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp20_coroutines.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="deferred.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,82 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Stackless Coroutines</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="../composition.html" title="Composition and Completion Tokens">
<link rel="next" href="spawn.html" title="Stackful Coroutines">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../composition.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="spawn.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.coroutine"></a><a class="link" href="coroutine.html" title="Stackless Coroutines">Stackless Coroutines</a>
</h4></div></div></div>
<p>
The <a class="link" href="../../reference/coroutine.html" title="coroutine"><code class="computeroutput"><span class="identifier">coroutine</span></code></a>
class provides support for stackless coroutines. Stackless coroutines enable
programs to implement asynchronous logic in a synchronous manner, with
minimal overhead, as shown in the following example:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">session</span> <span class="special">:</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">coroutine</span>
<span class="special">{</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span> <span class="identifier">socket_</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">buffer_</span><span class="special">;</span>
<span class="identifier">session</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span> <span class="identifier">socket</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">socket_</span><span class="special">(</span><span class="identifier">socket</span><span class="special">),</span>
<span class="identifier">buffer_</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="number">1024</span><span class="special">))</span>
<span class="special">{</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span> <span class="special">=</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span> <span class="identifier">reenter</span> <span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="identifier">yield</span> <span class="identifier">socket_</span><span class="special">-&gt;</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(*</span><span class="identifier">buffer_</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
<span class="identifier">yield</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(*</span><span class="identifier">socket_</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(*</span><span class="identifier">buffer_</span><span class="special">,</span> <span class="identifier">n</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">coroutine</span></code> class is
used in conjunction with the pseudo-keywords <code class="computeroutput"><span class="identifier">reenter</span></code>,
<code class="computeroutput"><span class="identifier">yield</span></code> and <code class="computeroutput"><span class="identifier">fork</span></code>. These are preprocessor macros,
and are implemented in terms of a <code class="computeroutput"><span class="keyword">switch</span></code>
statement using a technique similar to Duff's Device. The <a class="link" href="../../reference/coroutine.html" title="coroutine"><code class="computeroutput"><span class="identifier">coroutine</span></code></a> class's documentation
provides a complete description of these pseudo-keywords.
</p>
<h6>
<a name="asio.overview.composition.coroutine.h0"></a>
<span><a name="asio.overview.composition.coroutine.see_also"></a></span><a class="link" href="coroutine.html#asio.overview.composition.coroutine.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/coroutine.html" title="coroutine">coroutine</a>, <a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.http_server_4">HTTP
Server 4 example</a>, <a class="link" href="spawn.html" title="Stackful Coroutines">Stackful
Coroutines</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../composition.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="spawn.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,360 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>C++20 Coroutines Support</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="futures.html" title="Futures">
<link rel="next" href="coro.html" title="Resumable C++ 20 Coroutines">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="futures.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="coro.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.cpp20_coroutines"></a><a class="link" href="cpp20_coroutines.html" title="C++20 Coroutines Support">C++20 Coroutines
Support</a>
</h4></div></div></div>
<p>
Support for C++20 Coroutines is provided via the <a class="link" href="../../reference/awaitable.html" title="awaitable"><code class="computeroutput"><span class="identifier">awaitable</span></code></a> class template, the
<a class="link" href="../../reference/use_awaitable_t.html" title="use_awaitable_t"><code class="computeroutput"><span class="identifier">use_awaitable</span></code></a>
completion token, and the <a class="link" href="../../reference/co_spawn.html" title="co_spawn"><code class="computeroutput"><span class="identifier">co_spawn</span><span class="special">()</span></code></a>
function. These facilities allow programs to implement asynchronous logic
in a synchronous manner, in conjunction with the <code class="computeroutput"><span class="identifier">co_await</span></code>
keyword, as shown in the following example:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">co_spawn</span><span class="special">(</span><span class="identifier">executor</span><span class="special">,</span> <span class="identifier">echo</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">socket</span><span class="special">)),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">detached</span><span class="special">);</span>
<span class="comment">// ...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">echo</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">try</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">1024</span><span class="special">];</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">);</span>
<span class="identifier">co_await</span> <span class="identifier">async_write</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">n</span><span class="special">),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"echo Exception: %s\n"</span><span class="special">,</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">());</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
The first argument to <code class="computeroutput"><span class="identifier">co_spawn</span><span class="special">()</span></code> is an <a class="link" href="../../reference/Executor1.html" title="Executor requirements">executor</a>
that determines the context in which the coroutine is permitted to execute.
For example, a server's per-client object may consist of multiple coroutines;
they should all run on the same <code class="computeroutput"><span class="identifier">strand</span></code>
so that no explicit synchronisation is required.
</p>
<p>
The second argument is an <a class="link" href="../../reference/awaitable.html" title="awaitable"><code class="computeroutput"><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="identifier">R</span><span class="special">&gt;</span></code></a>,
that is the result of the coroutine's entry point function, and in the
above example is the result of the call to <code class="computeroutput"><span class="identifier">echo</span></code>.
(Alternatively, this argument can be a function object that returns the
<a class="link" href="../../reference/awaitable.html" title="awaitable"><code class="computeroutput"><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="identifier">R</span><span class="special">&gt;</span></code></a>.) The template parameter <code class="computeroutput"><span class="identifier">R</span></code> is the type of return value produced
by the coroutine. In the above example, the coroutine returns <code class="computeroutput"><span class="keyword">void</span></code>.
</p>
<p>
The third argument is a completion token, and this is used by <code class="computeroutput"><span class="identifier">co_spawn</span><span class="special">()</span></code>
to produce a completion handler with signature <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">,</span> <span class="identifier">R</span><span class="special">)</span></code>.
This completion handler is invoked with the result of the coroutine once
it has finished. In the above example we pass a completion token type,
<a class="link" href="../../reference/detached.html" title="detached"><code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detached</span></code></a>,
which is used to explicitly ignore the result of an asynchronous operation.
</p>
<p>
In this example the body of the coroutine is implemented in the <code class="computeroutput"><span class="identifier">echo</span></code> function. When the <code class="computeroutput"><span class="identifier">use_awaitable</span></code> completion token is passed
to an asynchronous operation, the operation's initiating function returns
an <code class="computeroutput"><span class="identifier">awaitable</span></code> that may be
used with the <code class="computeroutput"><span class="identifier">co_await</span></code>
keyword:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">);</span>
</pre>
<p>
Where an asynchronous operation's handler signature has the form:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">result_type</span> <span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
the resulting type of the <code class="computeroutput"><span class="identifier">co_await</span></code>
expression is <code class="computeroutput"><span class="identifier">result_type</span></code>.
In the <code class="computeroutput"><span class="identifier">async_read_some</span></code>
example above, this is <code class="computeroutput"><span class="identifier">size_t</span></code>.
If the asynchronous operation fails, the <code class="computeroutput"><span class="identifier">error_code</span></code>
is converted into a <code class="computeroutput"><span class="identifier">system_error</span></code>
exception and thrown.
</p>
<p>
Where a handler signature has the form:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">);</span>
</pre>
<p>
the <code class="computeroutput"><span class="identifier">co_await</span></code> expression
produces a <code class="computeroutput"><span class="keyword">void</span></code> result. As
above, an error is passed back to the coroutine as a <code class="computeroutput"><span class="identifier">system_error</span></code>
exception.
</p>
<h6>
<a name="asio.overview.composition.cpp20_coroutines.h0"></a>
<span><a name="asio.overview.composition.cpp20_coroutines.error_handling"></a></span><a class="link" href="cpp20_coroutines.html#asio.overview.composition.cpp20_coroutines.error_handling">Error
Handling</a>
</h6>
<p>
To perform explicit error handling, rather than the default exception-throwing
behaviour, use the <a class="link" href="../../reference/as_tuple.html" title="as_tuple"><code class="computeroutput"><span class="identifier">as_tuple</span></code></a> or <a class="link" href="../../reference/redirect_error.html" title="redirect_error"><code class="computeroutput"><span class="identifier">redirect_error</span></code></a> completion token
adapters.
</p>
<p>
The <code class="computeroutput"><span class="identifier">as_tuple</span></code> completion
token adapter packages the completion handler arguments into a single tuple,
which is then returned as the result of the awaited operation. For example:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">echo</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">1024</span><span class="special">];</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">result</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">as_tuple</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">));</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">))</span>
<span class="special">{</span>
<span class="comment">// success</span>
<span class="special">}</span>
<span class="comment">// ...</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
The result can also be captured directly into a structured binding:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">echo</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">1024</span><span class="special">];</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="special">[</span><span class="identifier">ec</span><span class="special">,</span> <span class="identifier">n</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">as_tuple</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">));</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// success</span>
<span class="special">}</span>
<span class="comment">// ...</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
Alternatively, the <code class="computeroutput"><span class="identifier">redirect_error</span></code>
completion token adapter may be used to capture the error into a supplied
<code class="computeroutput"><span class="identifier">error_code</span></code> variable:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">echo</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">1024</span><span class="special">];</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">redirect_error</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">));</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// success</span>
<span class="special">}</span>
<span class="comment">// ...</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<h6>
<a name="asio.overview.composition.cpp20_coroutines.h1"></a>
<span><a name="asio.overview.composition.cpp20_coroutines.coroutines_and_per_operation_cancellation"></a></span><a class="link" href="cpp20_coroutines.html#asio.overview.composition.cpp20_coroutines.coroutines_and_per_operation_cancellation">Coroutines
and Per-Operation Cancellation</a>
</h6>
<p>
All threads of execution created by <code class="computeroutput"><span class="identifier">co_spawn</span></code>
have a cancellation state that records the current state of any cancellation
requests made to the coroutine. To access this state, use <a class="link" href="../../reference/this_coro__cancellation_state.html" title="this_coro::cancellation_state"><code class="computeroutput"><span class="identifier">this_coro</span><span class="special">::</span><span class="identifier">cancellation_state</span></code></a> as follows:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">my_coroutine</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">cancellation_state</span> <span class="identifier">cs</span>
<span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">this_coro</span><span class="special">::</span><span class="identifier">cancellation_state</span><span class="special">;</span>
<span class="comment">// ...</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">cs</span><span class="special">.</span><span class="identifier">cancelled</span><span class="special">()</span> <span class="special">!=</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">cancellation_type</span><span class="special">::</span><span class="identifier">none</span><span class="special">)</span>
<span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<p>
When first created by <code class="computeroutput"><span class="identifier">co_spawn</span></code>,
the thread of execution has a cancellation state that supports <code class="computeroutput"><span class="identifier">cancellation_type</span><span class="special">::</span><span class="identifier">terminal</span></code> values only. To change the cancellation
state, call <a class="link" href="../../reference/this_coro__reset_cancellation_state.html" title="this_coro::reset_cancellation_state"><code class="computeroutput"><span class="identifier">this_coro</span><span class="special">::</span><span class="identifier">reset_cancellation_state</span></code></a>.
</p>
<p>
By default, continued execution of a cancelled coroutine will trigger an
exception from any subsequent <code class="computeroutput"><span class="identifier">co_await</span></code>
of an <code class="computeroutput"><span class="identifier">awaitable</span><span class="special">&lt;&gt;</span></code>
object. This behaviour can be changed by using <a class="link" href="../../reference/this_coro__throw_if_cancelled.html" title="this_coro::throw_if_cancelled"><code class="computeroutput"><span class="identifier">this_coro</span><span class="special">::</span><span class="identifier">throw_if_cancelled</span></code></a>.
</p>
<h6>
<a name="asio.overview.composition.cpp20_coroutines.h2"></a>
<span><a name="asio.overview.composition.cpp20_coroutines.co_ordinating_parallel_coroutines"></a></span><a class="link" href="cpp20_coroutines.html#asio.overview.composition.cpp20_coroutines.co_ordinating_parallel_coroutines">Co-ordinating
Parallel Coroutines</a>
</h6>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This is an experimental feature.
</p></td></tr>
</table></div>
<p>
The logical operators <code class="computeroutput"><span class="special">||</span></code> and
<code class="computeroutput"><span class="special">&amp;&amp;</span></code> have been overloaded
for <code class="computeroutput"><span class="identifier">awaitable</span><span class="special">&lt;&gt;</span></code>,
to allow coroutines to be trivially awaited in parallel.
</p>
<p>
When awaited using <code class="computeroutput"><span class="special">&amp;&amp;</span></code>,
the <code class="computeroutput"><span class="identifier">co_await</span></code> expression
waits until both operations have completed successfully. As a "short-circuit"
evaluation, if one operation fails with an exception, the other is immediately
cancelled. For example:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">results</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="special">(</span>
<span class="identifier">async_read</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">input_buffer</span><span class="special">,</span> <span class="identifier">use_awaitable</span><span class="special">)</span>
<span class="special">&amp;&amp;</span> <span class="identifier">async_write</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">output_buffer</span><span class="special">,</span> <span class="identifier">use_awaitable</span><span class="special">)</span>
<span class="special">);</span>
</pre>
<p>
Following completion of a <code class="computeroutput"><span class="special">&amp;&amp;</span></code>
operation, the results of all operations are concatenated into a tuple.
In the above example, the first <code class="computeroutput"><span class="identifier">size_t</span></code>
represents the non-exceptional component of the <code class="computeroutput"><span class="identifier">async_read</span></code>
result, and the second <code class="computeroutput"><span class="identifier">size_t</span></code>
is the result of the <code class="computeroutput"><span class="identifier">async_write</span></code>.
</p>
<p>
When awaited using <code class="computeroutput"><span class="special">||</span></code>, the
<code class="computeroutput"><span class="identifier">co_await</span></code> expression waits
until either operation succeeds. As a "short-circuit" evaluation,
if one operation succeeds without throwing an exception, the other is immediately
cancelled. For example:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">monostate</span><span class="special">&gt;</span> <span class="identifier">results</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="special">(</span>
<span class="identifier">async_read</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">input_buffer</span><span class="special">,</span> <span class="identifier">use_awaitable</span><span class="special">)</span>
<span class="special">||</span> <span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">use_awaitable</span><span class="special">)</span>
<span class="special">);</span>
</pre>
<p>
Following completion of a <code class="computeroutput"><span class="special">||</span></code>
operation, the result of the first operation to complete non-exceptionally
is placed into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span></code>. The active index of the variant
reflects which of the operations completed first. In the above example,
index <code class="computeroutput"><span class="number">0</span></code> corresponds to the
<code class="computeroutput"><span class="identifier">async_read</span></code> operation.
</p>
<p>
These operators may be enabled by adding the <code class="computeroutput"><span class="preprocessor">#include</span></code>:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">asio</span><span class="special">/</span><span class="identifier">experimental</span><span class="special">/</span><span class="identifier">awaitable_operators</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
and then bringing the contents of the <code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">awaitable_operators</span></code>
namespace into scope:
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">awaitable_operators</span><span class="special">;</span>
</pre>
<h6>
<a name="asio.overview.composition.cpp20_coroutines.h3"></a>
<span><a name="asio.overview.composition.cpp20_coroutines.lightweight_coroutines_implementing_asynchonous_operations"></a></span><a class="link" href="cpp20_coroutines.html#asio.overview.composition.cpp20_coroutines.lightweight_coroutines_implementing_asynchonous_operations">Lightweight
Coroutines Implementing Asynchonous Operations</a>
</h6>
<p>
The <code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">co_composed</span></code> template facilitates a lightweight
implementation of user-defined asynchronous operations using C++20 coroutines.
The following example illustrates a simple asynchronous operation that
implements an echo protocol in terms of a coroutine:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_echo</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">socket</span><span class="special">,</span>
<span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_initiate</span><span class="special">&lt;</span>
<span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">)&gt;(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">co_composed</span><span class="special">&lt;</span>
<span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">)&gt;(</span>
<span class="special">[](</span><span class="keyword">auto</span> <span class="identifier">state</span><span class="special">,</span> <span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">socket</span><span class="special">)</span> <span class="special">-&gt;</span> <span class="keyword">void</span>
<span class="special">{</span>
<span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">state</span><span class="special">.</span><span class="identifier">throw_if_cancelled</span><span class="special">(</span><span class="keyword">true</span><span class="special">);</span>
<span class="identifier">state</span><span class="special">.</span><span class="identifier">reset_cancellation_state</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">enable_terminal_cancellation</span><span class="special">());</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">1024</span><span class="special">];</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">);</span>
<span class="identifier">co_await</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">n</span><span class="special">),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">system_error</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">co_return</span> <span class="special">{</span><span class="identifier">e</span><span class="special">.</span><span class="identifier">code</span><span class="special">()};</span>
<span class="special">}</span>
<span class="special">},</span> <span class="identifier">socket</span><span class="special">),</span>
<span class="identifier">token</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">socket</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<h6>
<a name="asio.overview.composition.cpp20_coroutines.h4"></a>
<span><a name="asio.overview.composition.cpp20_coroutines.see_also"></a></span><a class="link" href="cpp20_coroutines.html#asio.overview.composition.cpp20_coroutines.see_also">See Also</a>
</h6>
<p>
<a class="link" href="../../reference/co_spawn.html" title="co_spawn">co_spawn</a>, <a class="link" href="../../reference/detached.html" title="detached">detached</a>,
<a class="link" href="../../reference/as_tuple.html" title="as_tuple">as_tuple</a>, <a class="link" href="../../reference/redirect_error.html" title="redirect_error">redirect_error</a>,
<a class="link" href="../../reference/awaitable.html" title="awaitable">awaitable</a>, <a class="link" href="../../reference/use_awaitable_t.html" title="use_awaitable_t">use_awaitable_t</a>,
<a class="link" href="../../reference/use_awaitable.html" title="use_awaitable">use_awaitable</a>, <a class="link" href="../../reference/this_coro__executor.html" title="this_coro::executor">this_coro::executor</a>,
<a class="link" href="../../reference/experimental__co_composed.html" title="experimental::co_composed">experimental::co_composed</a>,
<a class="link" href="../../examples/cpp17_examples.html#asio.examples.cpp17_examples.coroutines_ts_support">Coroutines
examples</a>, <a class="link" href="coro.html" title="Resumable C++ 20 Coroutines">Resumable
C++20 Coroutines</a>, <a class="link" href="spawn.html" title="Stackful Coroutines">Stackful
Coroutines</a>, <a class="link" href="coroutine.html" title="Stackless Coroutines">Stackless
Coroutines</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="futures.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="coro.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,86 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Deferred Operations</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="coro.html" title="Resumable C++ 20 Coroutines">
<link rel="next" href="promises.html" title="Promises">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="coro.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="promises.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.deferred"></a><a class="link" href="deferred.html" title="Deferred Operations">Deferred Operations</a>
</h4></div></div></div>
<p>
The <a class="link" href="../../reference/deferred.html" title="deferred"><code class="computeroutput"><span class="identifier">deferred</span></code></a>,
completion token takes a call to an asynchronous operation's initiating
function and turns it into a function object that accepts a completion
token. For example:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">deferred_op</span> <span class="special">=</span>
<span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">deferred_op</span><span class="special">)(</span>
<span class="special">[](</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">){</span> <span class="special">...</span> <span class="special">});</span>
</pre>
<p>
or:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">deferred_op</span> <span class="special">=</span>
<span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="special">=</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">deferred_op</span><span class="special">)(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_future</span><span class="special">);</span>
</pre>
<p>
The deferred token also supports chaining, to create simple compositions:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">deferred_op</span> <span class="special">=</span>
<span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">(</span>
<span class="special">[&amp;](</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">timer</span><span class="special">.</span><span class="identifier">expires_after</span><span class="special">(</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">1</span><span class="special">));</span>
<span class="keyword">return</span> <span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">);</span>
<span class="special">});</span>
<span class="special">...</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">deferred_op</span><span class="special">)(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_future</span><span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.composition.deferred.h0"></a>
<span><a name="asio.overview.composition.deferred.see_also"></a></span><a class="link" href="deferred.html#asio.overview.composition.deferred.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/deferred.html" title="deferred">deferred</a>, <a class="link" href="../../reference/deferred_t.html" title="deferred_t">deferred_t</a>,
<a class="link" href="../../examples/cpp14_examples.html#asio.examples.cpp14_examples.deferred">Deferred examples
(C++11)</a>, <a class="link" href="../../examples/cpp14_examples.html#asio.examples.cpp14_examples.deferred">Deferred
examples (C++14)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="coro.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="promises.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,78 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Futures</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="spawn.html" title="Stackful Coroutines">
<link rel="next" href="cpp20_coroutines.html" title="C++20 Coroutines Support">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="spawn.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="cpp20_coroutines.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.futures"></a><a class="link" href="futures.html" title="Futures">Futures</a>
</h4></div></div></div>
<p>
The <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_future</span></code> completion token provides
first-class support for returning a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span></code>
from an asynchronous operation's initiating function.
</p>
<p>
To use <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_future</span></code>, pass it to an asynchronous
operation instead of a completion handler. For example:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">length</span> <span class="special">=</span>
<span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_future</span><span class="special">);</span>
</pre>
<p>
Where a completion signature has the form:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">result_type</span> <span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
the initiating function returns a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span></code>
templated on <code class="computeroutput"><span class="identifier">result_type</span></code>.
In the above example, this is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span></code>.
If the asynchronous operation fails, the <code class="computeroutput"><span class="identifier">error_code</span></code>
is converted into a <code class="computeroutput"><span class="identifier">system_error</span></code>
exception and passed back to the caller through the future.
</p>
<p>
Where a completion signature has the form:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">);</span>
</pre>
<p>
the initiating function returns <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>. As above, an error is passed back
in the future as a <code class="computeroutput"><span class="identifier">system_error</span></code>
exception.
</p>
<h6>
<a name="asio.overview.composition.futures.h0"></a>
<span><a name="asio.overview.composition.futures.see_also"></a></span><a class="link" href="futures.html#asio.overview.composition.futures.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/use_future.html" title="use_future">use_future</a>, <a class="link" href="../../reference/use_future_t.html" title="use_future_t">use_future_t</a>,
<a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.futures">Futures example (C++11)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="spawn.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="cpp20_coroutines.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,82 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customising Immediate Completion</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="type_erasure.html" title="Type Erasure, Separate Compilation and Virtual Functions">
<link rel="next" href="../networking.html" title="Networking">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="type_erasure.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../networking.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.immediate_completion"></a><a class="link" href="immediate_completion.html" title="Customising Immediate Completion">Customising
Immediate Completion</a>
</h4></div></div></div>
<p>
The <code class="computeroutput"><span class="identifier">associated_immediate_executor</span></code>
associator trait, along with the <code class="computeroutput"><span class="identifier">bind_immediate_executor</span></code>
function, provide the ability to customise the execution of a completion
handler when an asynchronous operation completes immediately.
</p>
<p>
When a supported operation completes immediately (that is, within the initiating
function) the associated immmediate executor is obtained, and the completion
handler is delivered through that executor as if by using <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">dispatch</span></code> on that executor. By default,
the immediate executor delivers the completion handler as if using <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">post</span></code> via the operation's I/O executor.
</p>
<p>
For example, to allow a recursive call to the completion handler of an
<code class="computeroutput"><span class="identifier">async_read_some</span></code> operation,
we may specify that immediate completion is delivered via a <code class="computeroutput"><span class="identifier">system_executor</span></code>:
</p>
<pre class="programlisting"><span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">bind_immediate_executor</span><span class="special">(</span>
<span class="identifier">system_executor</span><span class="special">(),</span>
<span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}</span>
<span class="special">)</span>
<span class="special">);</span>
</pre>
<p>
Immediate execution is currently supported for asynchronous operations
on reactor-based sockets and descriptors, and for asynchronous operations
on channels.
</p>
<p>
<span class="bold"><strong>Note:</strong></span> When enabling the immediate execution
of completion handlers, care must be taken to ensure that unbounded recursion
and stack overflow do not occur. Furthermore, use of immediate completion
may impact the fairness of completion handler scheduling, with a potential
for starvation for other pending work.
</p>
<h6>
<a name="asio.overview.composition.immediate_completion.h0"></a>
<span><a name="asio.overview.composition.immediate_completion.see_also"></a></span><a class="link" href="immediate_completion.html#asio.overview.composition.immediate_completion.see_also">See Also</a>
</h6>
<p>
<a class="link" href="../../reference/associated_immediate_executor.html" title="associated_immediate_executor">associated_immediate_executor</a>,
<a class="link" href="../../reference/bind_immediate_executor.html" title="bind_immediate_executor">bind_immediate_executor</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="type_erasure.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../networking.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,104 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Co-ordinating Parallel Operations</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="promises.html" title="Promises">
<link rel="next" href="compose.html" title="Compositions as Asynchronous Operations">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="promises.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="compose.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.parallel_group"></a><a class="link" href="parallel_group.html" title="Co-ordinating Parallel Operations">Co-ordinating
Parallel Operations</a>
</h4></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This is an experimental feature.
</p></td></tr>
</table></div>
<p>
The <a class="link" href="../../reference/experimental__make_parallel_group.html" title="experimental::make_parallel_group"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">make_parallel_group</span></code></a> function may
be used to launch work that is performed in parallel, and wait for one
or all of the operations to complete. A <code class="computeroutput"><span class="identifier">parallel_group</span></code>
implements automatic cancellation of incomplete operations. For example:
</p>
<pre class="programlisting"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">make_parallel_group</span><span class="special">(</span>
<span class="special">[&amp;](</span><span class="keyword">auto</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">token</span><span class="special">);</span>
<span class="special">},</span>
<span class="special">[&amp;](</span><span class="keyword">auto</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">token</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">).</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">experimental</span><span class="special">::</span><span class="identifier">wait_for_one</span><span class="special">(),</span>
<span class="special">[](</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="identifier">completion_order</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec1</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n1</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec2</span>
<span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}</span>
<span class="special">);</span>
</pre>
<p>
The conditions for completion of the group may be specified using one of
the four provided function objects <a class="link" href="../../reference/experimental__wait_for_all.html" title="experimental::wait_for_all"><code class="computeroutput"><span class="identifier">wait_for_all</span></code></a>, <a class="link" href="../../reference/experimental__wait_for_one.html" title="experimental::wait_for_one"><code class="computeroutput"><span class="identifier">wait_for_one</span></code></a>, <a class="link" href="../../reference/experimental__wait_for_one_success.html" title="experimental::wait_for_one_success"><code class="computeroutput"><span class="identifier">wait_for_one_success</span></code></a>, <a class="link" href="../../reference/experimental__wait_for_one_error.html" title="experimental::wait_for_one_error"><code class="computeroutput"><span class="identifier">wait_for_one_error</span></code></a>, or with a
custom function.
</p>
<p>
The <code class="computeroutput"><span class="identifier">parallel_group</span></code> facility
can also be combined with <a class="link" href="../../reference/deferred.html" title="deferred"><code class="computeroutput"><span class="identifier">deferred</span></code></a> as follows:
</p>
<pre class="programlisting"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">make_parallel_group</span><span class="special">(</span>
<span class="identifier">stream</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">deferred</span><span class="special">),</span>
<span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">)</span>
<span class="special">).</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="comment">// ...</span>
<span class="special">);</span>
</pre>
<p>
Note: for maximum flexibility, <code class="computeroutput"><span class="identifier">parallel_group</span></code>
does not propagate the executor automatically to the operations within
the group.
</p>
<h6>
<a name="asio.overview.composition.parallel_group.h0"></a>
<span><a name="asio.overview.composition.parallel_group.see_also"></a></span><a class="link" href="parallel_group.html#asio.overview.composition.parallel_group.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/experimental__make_parallel_group.html" title="experimental::make_parallel_group">experimental::make_parallel_group</a>,
<a class="link" href="../../reference/experimental__parallel_group.html" title="experimental::parallel_group">experimental::parallel_group</a>,
<a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.parallel_groups">Parallel Groups
examples (C++11)</a>, <a class="link" href="../../examples/cpp14_examples.html#asio.examples.cpp14_examples.parallel_groups">Parallel
Groups examples (C++14)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="promises.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="compose.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,131 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Promises</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="deferred.html" title="Deferred Operations">
<link rel="next" href="parallel_group.html" title="Co-ordinating Parallel Operations">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="deferred.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="parallel_group.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.promises"></a><a class="link" href="promises.html" title="Promises">Promises</a>
</h4></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This is an experimental feature.
</p></td></tr>
</table></div>
<p>
The <a class="link" href="../../reference/experimental__promise.html" title="experimental::promise"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">promise</span></code></a> type and <a class="link" href="../../reference/experimental__use_promise.html" title="experimental::use_promise"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">use_promise</span></code></a> completion token allow
eager execution and synchronisation of asynchronous operations. For example:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">promise</span> <span class="special">=</span> <span class="identifier">async_read</span><span class="special">(</span>
<span class="identifier">stream</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">use_promise</span><span class="special">);</span>
<span class="special">...</span> <span class="keyword">do</span> <span class="identifier">other</span> <span class="identifier">stuff</span> <span class="keyword">while</span> <span class="identifier">the</span> <span class="identifier">read</span> <span class="identifier">is</span> <span class="identifier">going</span> <span class="identifier">on</span> <span class="special">...</span>
<span class="identifier">promise</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span> <span class="comment">// completion the operation</span>
<span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_read</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">...</span>
<span class="special">});</span>
</pre>
<p>
Promises can be safely disregarded if the result is no longer required.
Different operations can be combined to either wait for all to complete
or for one to complete (and cancel the rest). For example, to wait for
one to complete:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">timeout_promise</span> <span class="special">=</span>
<span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">use_promise</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">read_promise</span> <span class="special">=</span> <span class="identifier">async_read</span><span class="special">(</span>
<span class="identifier">stream</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">use_promise</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">promise</span> <span class="special">=</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">make_parallel_group</span><span class="special">(</span>
<span class="identifier">timeout_promise</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">),</span>
<span class="identifier">read_promise</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">)</span>
<span class="special">).</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">wait_for_one</span><span class="special">(),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">use_promise</span><span class="special">);</span>
<span class="identifier">promise</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="identifier">order</span><span class="special">,</span>
<span class="identifier">error_code</span> <span class="identifier">timer_ec</span><span class="special">,</span>
<span class="identifier">error_code</span> <span class="identifier">read_ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">read_size</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">order</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// timed out</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="comment">// completed in time</span>
<span class="special">}</span>
<span class="special">});</span>
</pre>
<p>
or to wait for all to complete:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">write_promise</span> <span class="special">=</span> <span class="identifier">async_write</span><span class="special">(</span>
<span class="identifier">stream</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">my_write_buffer</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">use_promise</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">read_promise</span> <span class="special">=</span> <span class="identifier">async_read</span><span class="special">(</span>
<span class="identifier">stream</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">use_promise</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">promise</span> <span class="special">=</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">make_parallel_group</span><span class="special">(</span>
<span class="identifier">timeout_promise</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">),</span>
<span class="identifier">read_promise</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">)</span>
<span class="special">).</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">wait_for_all</span><span class="special">(),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">use_promise</span><span class="special">);</span>
<span class="identifier">promise</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="identifier">order</span><span class="special">,</span>
<span class="identifier">error_code</span> <span class="identifier">timer_ec</span><span class="special">,</span>
<span class="identifier">error_code</span> <span class="identifier">read_ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">read_size</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">});</span>
</pre>
<h6>
<a name="asio.overview.composition.promises.h0"></a>
<span><a name="asio.overview.composition.promises.see_also"></a></span><a class="link" href="promises.html#asio.overview.composition.promises.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/experimental__promise.html" title="experimental::promise">promise</a>, <a class="link" href="../../reference/experimental__use_promise.html" title="experimental::use_promise">use_promise</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="deferred.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="parallel_group.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,144 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Stackful Coroutines</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="coroutine.html" title="Stackless Coroutines">
<link rel="next" href="futures.html" title="Futures">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="coroutine.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="futures.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.spawn"></a><a class="link" href="spawn.html" title="Stackful Coroutines">Stackful Coroutines</a>
</h4></div></div></div>
<p>
The <a class="link" href="../../reference/spawn.html" title="spawn"><code class="computeroutput"><span class="identifier">spawn</span><span class="special">()</span></code></a> function is a high-level wrapper
for running stackful coroutines. It is based on the Boost.Coroutine library.
The <code class="computeroutput"><span class="identifier">spawn</span><span class="special">()</span></code>
function enables programs to implement asynchronous logic in a synchronous
manner, as shown in the following example:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">spawn</span><span class="special">(</span><span class="identifier">my_strand</span><span class="special">,</span> <span class="identifier">do_echo</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">detached</span><span class="special">);</span>
<span class="comment">// ...</span>
<span class="keyword">void</span> <span class="identifier">do_echo</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">yield_context</span> <span class="identifier">yield</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">try</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">128</span><span class="special">];</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span> <span class="special">=</span>
<span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">);</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">my_socket</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">length</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
The first argument to <code class="computeroutput"><span class="identifier">spawn</span><span class="special">()</span></code> may be an executor or execution context.
This argument determines the context in which the coroutine is permitted
to execute. For example, a server's per-client object may consist of multiple
coroutines; they should all run on the same <code class="computeroutput"><span class="identifier">strand</span></code>
so that no explicit synchronisation is required.
</p>
<p>
The second argument is a function object with signature:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">coroutine</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">yield_context</span> <span class="identifier">yield</span><span class="special">);</span>
</pre>
<p>
that specifies the code to be run as part of the coroutine. The parameter
<code class="computeroutput"><span class="identifier">yield</span></code> may be passed to
an asynchronous operation in place of the completion handler, as in:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span> <span class="special">=</span>
<span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">);</span>
</pre>
<p>
This starts the asynchronous operation and suspends the coroutine. The
coroutine will be resumed automatically when the asynchronous operation
completes.
</p>
<p>
Where an asynchronous operation's handler signature has the form:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">result_type</span> <span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
the initiating function returns the result_type. In the <code class="computeroutput"><span class="identifier">async_read_some</span></code>
example above, this is <code class="computeroutput"><span class="identifier">size_t</span></code>.
If the asynchronous operation fails, the <code class="computeroutput"><span class="identifier">error_code</span></code>
is converted into a <code class="computeroutput"><span class="identifier">system_error</span></code>
exception and thrown.
</p>
<p>
Where a handler signature has the form:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">);</span>
</pre>
<p>
the initiating function returns <code class="computeroutput"><span class="keyword">void</span></code>.
As above, an error is passed back to the coroutine as a <code class="computeroutput"><span class="identifier">system_error</span></code>
exception.
</p>
<p>
To collect the <code class="computeroutput"><span class="identifier">error_code</span></code>
from an operation, rather than have it throw an exception, associate the
output variable with the <code class="computeroutput"><span class="identifier">yield_context</span></code>
as follows:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span> <span class="special">=</span>
<span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">[</span><span class="identifier">ec</span><span class="special">]);</span>
</pre>
<p>
<span class="bold"><strong>Note:</strong></span> if <code class="computeroutput"><span class="identifier">spawn</span><span class="special">()</span></code> is used with a specified executor of
type <code class="computeroutput"><span class="identifier">Executor</span></code>, the function
object signature is actually:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">coroutine</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">basic_yield_context</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span> <span class="identifier">yield</span><span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.composition.spawn.h0"></a>
<span><a name="asio.overview.composition.spawn.see_also"></a></span><a class="link" href="spawn.html#asio.overview.composition.spawn.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/spawn.html" title="spawn">spawn</a>, <a class="link" href="../../reference/yield_context.html" title="yield_context">yield_context</a>,
<a class="link" href="../../reference/basic_yield_context.html" title="basic_yield_context">basic_yield_context</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.spawn">Spawn example (C++03)</a>,
<a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.spawn">Spawn example (C++11)</a>,
<a class="link" href="coroutine.html" title="Stackless Coroutines">Stackless Coroutines</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="coroutine.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="futures.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,316 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Completion Token Adapters</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="compose.html" title="Compositions as Asynchronous Operations">
<link rel="next" href="type_erasure.html" title="Type Erasure, Separate Compilation and Virtual Functions">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="compose.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="type_erasure.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.token_adapters"></a><a class="link" href="token_adapters.html" title="Completion Token Adapters">Completion
Token Adapters</a>
</h4></div></div></div>
<p>
A <span class="emphasis"><em>completion token adapter</em></span> is a utility that can be
generically applied to a <a class="link" href="../model/completion_tokens.html" title="Completion Tokens">completion
token</a>, to produce a new completion token with modified behaviour.
Common uses of completion token adapters include:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Automatically wrapping the completion handler to add <a class="link" href="../model/associators.html" title="Associated Characteristics and Associators">associated
characteristics</a>.
</li>
<li class="listitem">
Transforming the completion signature and arguments passed to the completion
handler.
</li>
</ul></div>
<p>
Asio includes a number of completion token adapters as described below.
</p>
<h6>
<a name="asio.overview.composition.token_adapters.h0"></a>
<span><a name="asio.overview.composition.token_adapters.bind_executor__bind_allocator__and_bind_cancellation_slot"></a></span><a class="link" href="token_adapters.html#asio.overview.composition.token_adapters.bind_executor__bind_allocator__and_bind_cancellation_slot">bind_executor,
bind_allocator, and bind_cancellation_slot</a>
</h6>
<p>
The <a class="link" href="../../reference/bind_executor.html" title="bind_executor"><code class="computeroutput"><span class="identifier">bind_executor</span></code></a>
function adapts a completion token to imbue the completion handler with
an <a class="link" href="../model/executors.html" title="Executors">associated executor</a>.
</p>
<p>
This example shows the <code class="computeroutput"><span class="identifier">bind_executor</span></code>
adapter applied to a lambda, to specify that the handler should execute
in the specified strand. The arguments to the completion handler are passed
through as-is.
</p>
<pre class="programlisting"><span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">my_strand</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">error</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_transferred</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}));</span>
</pre>
<p>
When applied to completion tokens that cause the initiating function to
produce a result, such as <a class="link" href="../../reference/use_awaitable.html" title="use_awaitable"><code class="computeroutput"><span class="identifier">use_awaitable</span></code></a>, the result is returned
unmodified.
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">my_coroutine</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_transferred</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">my_strand</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">));</span>
<span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<p>
The <a class="link" href="../../reference/bind_allocator.html" title="bind_allocator"><code class="computeroutput"><span class="identifier">bind_allocator</span></code></a>
and <a class="link" href="../../reference/bind_cancellation_slot.html" title="bind_cancellation_slot"><code class="computeroutput"><span class="identifier">bind_cancellation_slot</span></code></a> adapters
work similarly, to imbue the completion handler with an <a class="link" href="../model/allocators.html" title="Allocators">associated
allocator</a> or <a class="link" href="../model/cancellation.html" title="Cancellation">associated
cancellation slot</a> respectively.
</p>
<h6>
<a name="asio.overview.composition.token_adapters.h1"></a>
<span><a name="asio.overview.composition.token_adapters.redirect_error"></a></span><a class="link" href="token_adapters.html#asio.overview.composition.token_adapters.redirect_error">redirect_error</a>
</h6>
<p>
The <a class="link" href="../../reference/redirect_error.html" title="redirect_error"><code class="computeroutput"><span class="identifier">redirect_error</span></code></a>
function adapts a completion token to capture the <code class="computeroutput"><span class="identifier">error_code</span></code>
produced by an operation into a specified variable. In doing so, it modifies
the completion signature to remove the initial <code class="computeroutput"><span class="identifier">error_code</span></code>
parameter.
</p>
<p>
This example shows the <code class="computeroutput"><span class="identifier">redirect_error</span></code>
adapter applied to a lambda, to specify that the error should be captured
into <code class="computeroutput"><span class="identifier">my_error</span></code>. The <code class="computeroutput"><span class="identifier">error_code</span></code> is no longer passed to the
completion handler, but the remaining arguments are passed through as-is.
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">my_error</span><span class="special">;</span> <span class="comment">// N.B. must be valid until operation completes</span>
<span class="comment">// ...</span>
<span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">redirect_error</span><span class="special">(</span>
<span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_transferred</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">},</span> <span class="identifier">my_error</span><span class="special">));</span>
</pre>
<p>
When applied to completion tokens that cause the initiating function to
produce a result, such as <a class="link" href="../../reference/use_awaitable.html" title="use_awaitable"><code class="computeroutput"><span class="identifier">use_awaitable</span></code></a>, the result is returned
unmodified. However, if the operation fails, the <code class="computeroutput"><span class="identifier">co_await</span></code>
expression will no longer throw an exception on resumption.
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">my_coroutine</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">my_error</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_transferred</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">redirect_error</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">,</span> <span class="identifier">my_error</span><span class="special">));</span>
<span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<h6>
<a name="asio.overview.composition.token_adapters.h2"></a>
<span><a name="asio.overview.composition.token_adapters.as_tuple"></a></span><a class="link" href="token_adapters.html#asio.overview.composition.token_adapters.as_tuple">as_tuple</a>
</h6>
<p>
The <a class="link" href="../../reference/as_tuple.html" title="as_tuple"><code class="computeroutput"><span class="identifier">as_tuple</span></code></a>
adapter can be used to specify that the completion handler arguments should
be combined into a single tuple argument.
</p>
<p>
For example, the <code class="computeroutput"><span class="identifier">as_tuple</span></code>
adapter may be used in conjunction with <a class="link" href="../../reference/use_awaitable.html" title="use_awaitable"><code class="computeroutput"><span class="identifier">use_awaitable</span></code></a> and structured bindings
as follows:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="special">[</span><span class="identifier">e</span><span class="special">,</span> <span class="identifier">n</span><span class="special">]</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">as_tuple</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable</span><span class="special">));</span>
</pre>
<p>
This adapter may also be used as a default completion token:
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">default_token</span> <span class="special">=</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">as_tuple_t</span><span class="special">&lt;</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_awaitable_t</span><span class="special">&lt;&gt;&gt;;</span>
<span class="keyword">using</span> <span class="identifier">tcp_socket</span> <span class="special">=</span> <span class="identifier">default_token</span><span class="special">::</span><span class="identifier">as_default_on_t</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;;</span>
<span class="comment">// ...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">do_read</span><span class="special">(</span><span class="identifier">tcp_socket</span> <span class="identifier">my_socket</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="keyword">auto</span> <span class="special">[</span><span class="identifier">e</span><span class="special">,</span> <span class="identifier">n</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">co_await</span> <span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">);</span>
<span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<h6>
<a name="asio.overview.composition.token_adapters.h3"></a>
<span><a name="asio.overview.composition.token_adapters.as_single"></a></span><a class="link" href="token_adapters.html#asio.overview.composition.token_adapters.as_single">as_single</a>
</h6>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This is an experimental feature.
</p></td></tr>
</table></div>
<p>
The <a class="link" href="../../reference/experimental__as_single.html" title="experimental::as_single"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">as_single</span></code></a> adapter can be used
to specify that the completion handler arguments should be combined into
a single argument. For completion signatures with a single parameter, the
argument is passed through as-is. For signatures with two or more parameters,
the arguments are combined into a tuple.
</p>
<p>
For example, when applied to a timer wait operation, the single <code class="computeroutput"><span class="identifier">error_code</span></code> argument is passed directly
to the completion handler:
</p>
<pre class="programlisting"><span class="identifier">my_timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">as_single</span><span class="special">(</span>
<span class="special">[](</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">error</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}));</span>
</pre>
<p>
When applied to a socket read operation, where the completion signature
specifies two parameters, the handler is passed the result as a tuple:
</p>
<pre class="programlisting"><span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">as_single</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}));</span>
</pre>
<h6>
<a name="asio.overview.composition.token_adapters.h4"></a>
<span><a name="asio.overview.composition.token_adapters.append"></a></span><a class="link" href="token_adapters.html#asio.overview.composition.token_adapters.append">append</a>
</h6>
<p>
The <a class="link" href="../../reference/append.html" title="append"><code class="computeroutput"><span class="identifier">append</span></code></a>
completion token adapter can be used to pass additional completion handler
arguments at the end of the completion signature.
</p>
<p>
For example:
</p>
<pre class="programlisting"><span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">append</span><span class="special">(</span>
<span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">},</span>
<span class="number">42</span>
<span class="special">)</span>
<span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">append</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_future</span><span class="special">,</span>
<span class="number">42</span>
<span class="special">)</span>
<span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.composition.token_adapters.h5"></a>
<span><a name="asio.overview.composition.token_adapters.prepend"></a></span><a class="link" href="token_adapters.html#asio.overview.composition.token_adapters.prepend">prepend</a>
</h6>
<p>
The <a class="link" href="../../reference/prepend.html" title="prepend"><code class="computeroutput"><span class="identifier">prepend</span></code></a>
completion token adapter can be used to pass additional completion handler
arguments before the existing completion handler arguments.
</p>
<p>
For example:
</p>
<pre class="programlisting"><span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">prepend</span><span class="special">(</span>
<span class="special">[](</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">},</span>
<span class="number">42</span>
<span class="special">)</span>
<span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">&gt;&gt;</span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">timer</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">prepend</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_future</span><span class="special">,</span>
<span class="number">42</span>
<span class="special">)</span>
<span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.composition.token_adapters.h6"></a>
<span><a name="asio.overview.composition.token_adapters.consign"></a></span><a class="link" href="token_adapters.html#asio.overview.composition.token_adapters.consign">consign</a>
</h6>
<p>
The <a class="link" href="../../reference/consign.html" title="consign"><code class="computeroutput"><span class="identifier">consign</span></code></a>
completion token adapter can be used to attach additional values to a completion
handler. This is typically used to keep at least one copy of an object,
such as a smart pointer, alive until the completion handler is called.
</p>
<p>
For example:
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">timer1</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">steady_timer</span><span class="special">&gt;(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">timer1</span><span class="special">-&gt;</span><span class="identifier">expires_after</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">1</span><span class="special">));</span>
<span class="identifier">timer1</span><span class="special">-&gt;</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">consign</span><span class="special">(</span>
<span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">},</span>
<span class="identifier">timer1</span>
<span class="special">)</span>
<span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">timer2</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">steady_timer</span><span class="special">&gt;(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">timer2</span><span class="special">-&gt;</span><span class="identifier">expires_after</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">30</span><span class="special">));</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">f</span> <span class="special">=</span>
<span class="identifier">timer2</span><span class="special">-&gt;</span><span class="identifier">async_wait</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">consign</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">use_future</span><span class="special">,</span>
<span class="identifier">timer2</span>
<span class="special">)</span>
<span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.composition.token_adapters.h7"></a>
<span><a name="asio.overview.composition.token_adapters.see_also"></a></span><a class="link" href="token_adapters.html#asio.overview.composition.token_adapters.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/bind_executor.html" title="bind_executor">bind_executor</a>, <a class="link" href="../../reference/bind_allocator.html" title="bind_allocator">bind_allocator</a>, <a class="link" href="../../reference/bind_cancellation_slot.html" title="bind_cancellation_slot">bind_cancellation_slot</a>,
<a class="link" href="../../reference/redirect_error.html" title="redirect_error">redirect_error</a>, <a class="link" href="../../reference/as_tuple.html" title="as_tuple">as_tuple</a>, <a class="link" href="../../reference/experimental__as_single.html" title="experimental::as_single">experimental::as_single</a>,
<a class="link" href="../../reference/append.html" title="append">append</a>, <a class="link" href="../../reference/prepend.html" title="prepend">prepend</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="compose.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="type_erasure.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,126 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Type Erasure, Separate Compilation and Virtual Functions</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../composition.html" title="Composition and Completion Tokens">
<link rel="prev" href="token_adapters.html" title="Completion Token Adapters">
<link rel="next" href="immediate_completion.html" title="Customising Immediate Completion">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="token_adapters.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="immediate_completion.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.composition.type_erasure"></a><a class="link" href="type_erasure.html" title="Type Erasure, Separate Compilation and Virtual Functions">Type Erasure,
Separate Compilation and Virtual Functions</a>
</h4></div></div></div>
<p>
The <code class="computeroutput"><span class="identifier">any_completion_handler</span><span class="special">&lt;&gt;</span></code> class template can be used to type-erase
completion handlers. This template stores a completion handler in a runtime-polymorphic
wrapper, and forwards the function call operator, associated executor,
associated allocator, and associated cancellation slot to the target handler.
</p>
<p>
One use case is to enable separate compilation of asynchronous operation
implementations. For example, we can declare our implementation function
in a header file, and provide a thin asynchronous operation wrapper:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">async_sleep_impl</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">any_completion_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">)&gt;</span> <span class="identifier">handler</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">any_io_executor</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">nanoseconds</span> <span class="identifier">duration</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">inline</span> <span class="keyword">auto</span> <span class="identifier">async_sleep</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">any_io_executor</span> <span class="identifier">ex</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">nanoseconds</span> <span class="identifier">duration</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_initiate</span><span class="special">&lt;</span>
<span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">)&gt;(</span>
<span class="identifier">async_sleep_impl</span><span class="special">,</span> <span class="identifier">token</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ex</span><span class="special">),</span> <span class="identifier">duration</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
By wrapping a call to <code class="computeroutput"><span class="identifier">async_initiate</span></code>,
the <code class="computeroutput"><span class="identifier">async_sleep</span></code> template
function adds full support for completion tokens. The definition of <code class="computeroutput"><span class="identifier">async_sleep_impl</span></code> is then put into a separately
compiled source file:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">async_sleep_impl</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">any_completion_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">)&gt;</span> <span class="identifier">handler</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">any_io_executor</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">nanoseconds</span> <span class="identifier">duration</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="identifier">timer</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">steady_timer</span><span class="special">&gt;(</span><span class="identifier">ex</span><span class="special">,</span> <span class="identifier">duration</span><span class="special">);</span>
<span class="identifier">timer</span><span class="special">-&gt;</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">consign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">handler</span><span class="special">),</span> <span class="identifier">timer</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<p>
Another use for <code class="computeroutput"><span class="identifier">any_completion_handler</span><span class="special">&lt;&gt;</span></code> is to vary the implementation behind
an asynchronous operation at runtime, by using virtual functions:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">line_reader</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// ...</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_read_line</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">prompt</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_initiate</span><span class="special">&lt;</span>
<span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)&gt;(</span>
<span class="special">[](</span><span class="keyword">auto</span> <span class="identifier">handler</span><span class="special">,</span> <span class="identifier">line_reader</span><span class="special">*</span> <span class="identifier">self</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">prompt</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">self</span><span class="special">-&gt;</span><span class="identifier">async_read_line_impl</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">prompt</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">handler</span><span class="special">));</span>
<span class="special">},</span> <span class="identifier">token</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">prompt</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">async_read_line_impl</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">prompt</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">any_completion_handler</span><span class="special">&lt;</span>
<span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)&gt;</span> <span class="identifier">handler</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
A derived class provides the implementation of the operation:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">stdin_line_reader</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">line_reader</span>
<span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="comment">// ...</span>
<span class="keyword">void</span> <span class="identifier">async_read_line_impl</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">prompt</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">any_completion_handler</span><span class="special">&lt;</span>
<span class="keyword">void</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)&gt;</span> <span class="identifier">handler</span><span class="special">)</span> <span class="identifier">override</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<h6>
<a name="asio.overview.composition.type_erasure.h0"></a>
<span><a name="asio.overview.composition.type_erasure.see_also"></a></span><a class="link" href="type_erasure.html#asio.overview.composition.type_erasure.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/any_completion_handler.html" title="any_completion_handler">any_completion_handler</a>,
<a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.type_erasure">type erasure
examples (C++11)</a>, <a class="link" href="../../examples/cpp20_examples.html#asio.examples.cpp20_examples.type_erasure">type
erasure examples (C++20)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="token_adapters.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../composition.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="immediate_completion.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,72 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Core Concepts and Functionality</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="model/higher_levels.html" title="Higher Level Abstractions">
<link rel="next" href="core/async.html" title="The Proactor Design Pattern: Concurrency Without Threads">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="model/higher_levels.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="core/async.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.core"></a><a class="link" href="core.html" title="Core Concepts and Functionality">Core Concepts and Functionality</a>
</h3></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a class="link" href="core/async.html" title="The Proactor Design Pattern: Concurrency Without Threads">The Proactor Design Pattern:
Concurrency Without Threads</a>
</li>
<li class="listitem">
<a class="link" href="core/threads.html" title="Threads and Asio">Threads and Asio</a>
</li>
<li class="listitem">
<a class="link" href="core/strands.html" title="Strands: Use Threads Without Explicit Locking">Strands: Use Threads Without
Explicit Locking</a>
</li>
<li class="listitem">
<a class="link" href="core/buffers.html" title="Buffers">Buffers</a>
</li>
<li class="listitem">
<a class="link" href="core/streams.html" title="Streams, Short Reads and Short Writes">Streams, Short Reads and Short
Writes</a>
</li>
<li class="listitem">
<a class="link" href="core/reactor.html" title="Reactor-Style Operations">Reactor-Style Operations</a>
</li>
<li class="listitem">
<a class="link" href="core/line_based.html" title="Line-Based Operations">Line-Based Operations</a>
</li>
<li class="listitem">
<a class="link" href="core/allocation.html" title="Custom Memory Allocation">Custom Memory Allocation</a>
</li>
<li class="listitem">
<a class="link" href="core/cancellation.html" title="Per-Operation Cancellation">Per-Operation Cancellation</a>
</li>
<li class="listitem">
<a class="link" href="core/handler_tracking.html" title="Handler Tracking">Handler Tracking</a>
</li>
<li class="listitem">
<a class="link" href="core/concurrency_hint.html" title="Concurrency Hints">Concurrency Hints</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="model/higher_levels.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="core/async.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,139 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Custom Memory Allocation</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="line_based.html" title="Line-Based Operations">
<link rel="next" href="cancellation.html" title="Per-Operation Cancellation">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="line_based.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="cancellation.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.allocation"></a><a class="link" href="allocation.html" title="Custom Memory Allocation">Custom Memory Allocation</a>
</h4></div></div></div>
<p>
Many asynchronous operations need to allocate an object to store state
associated with the operation. For example, a Win32 implementation needs
<code class="computeroutput"><span class="identifier">OVERLAPPED</span></code>-derived objects
to pass to Win32 API functions.
</p>
<p>
Furthermore, programs typically contain easily identifiable chains of asynchronous
operations. A half duplex protocol implementation (e.g. an HTTP server)
would have a single chain of operations per client (receives followed by
sends). A full duplex protocol implementation would have two chains executing
in parallel. Programs should be able to leverage this knowledge to reuse
memory for all asynchronous operations in a chain.
</p>
<p>
Given a copy of a user-defined <code class="computeroutput"><span class="identifier">Handler</span></code>
object <code class="computeroutput"><span class="identifier">h</span></code>, if the implementation
needs to allocate memory associated with that handler it will obtain an
allocator using the <code class="computeroutput"><span class="identifier">get_associated_allocator</span></code>
function. For example:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">associated_allocator_t</span><span class="special">&lt;</span><span class="identifier">Handler</span><span class="special">&gt;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span>
</pre>
<p>
The associated allocator must satisfy the standard Allocator requirements.
</p>
<p>
By default, handlers use the standard allocator (which is implemented in
terms of <code class="computeroutput"><span class="special">::</span><span class="keyword">operator</span>
<span class="keyword">new</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="special">::</span><span class="keyword">operator</span>
<span class="keyword">delete</span><span class="special">()</span></code>).
The allocator may be customised for a particular handler type by specifying
a nested type <code class="computeroutput"><span class="identifier">allocator_type</span></code>
and member function <code class="computeroutput"><span class="identifier">get_allocator</span><span class="special">()</span></code>:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_handler</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// Custom implementation of Allocator type requirements.</span>
<span class="keyword">typedef</span> <span class="identifier">my_allocator</span> <span class="identifier">allocator_type</span><span class="special">;</span>
<span class="comment">// Return a custom allocator implementation.</span>
<span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">my_allocator</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
In more complex cases, the <code class="computeroutput"><span class="identifier">associated_allocator</span></code>
template may be partially specialised directly:
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">asio</span> <span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">my_handler</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="comment">// Custom implementation of Allocator type requirements.</span>
<span class="keyword">typedef</span> <span class="identifier">my_allocator</span> <span class="identifier">type</span><span class="special">;</span>
<span class="comment">// Return a custom allocator implementation.</span>
<span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">my_handler</span><span class="special">&amp;,</span>
<span class="keyword">const</span> <span class="identifier">Allocator</span><span class="special">&amp;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">())</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">my_allocator</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="special">}</span> <span class="comment">// namespace asio</span>
</pre>
<p>
The implementation guarantees that the deallocation will occur before the
associated handler is invoked, which means the memory is ready to be reused
for any new asynchronous operations started by the handler.
</p>
<p>
The custom memory allocation functions may be called from any user-created
thread that is calling an Asio library function. The implementation guarantees,
for the asynchronous operations included with the library, that within
the context of an individual operation the implementation will not make
concurrent calls to the memory allocation functions for that handler. The
implementation will insert appropriate memory barriers to ensure correct
memory visibility should an asynchronous operation need to call the allocation
functions from different threads. (Note: If the same allocator is shared
across multiple concurrent asynchronous operations, this can result in
concurrent calls to the memory allocation functions. Use of a <a class="link" href="strands.html" title="Strands: Use Threads Without Explicit Locking">strand</a>
does not prevent these concurrent calls, as an operation may need to allocate
memory from outside the strand. In this case, the shared allocator is responsible
for providing the necessary thread safety guarantees.)
</p>
<h6>
<a name="asio.overview.core.allocation.h0"></a>
<span><a name="asio.overview.core.allocation.see_also"></a></span><a class="link" href="allocation.html#asio.overview.core.allocation.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/associated_allocator.html" title="associated_allocator">associated_allocator</a>,
<a class="link" href="../../reference/get_associated_allocator.html" title="get_associated_allocator">get_associated_allocator</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.allocation">custom memory allocation
example (C++03)</a>, <a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.allocation">custom
memory allocation example (C++11)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="line_based.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="cancellation.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,278 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The Proactor Design Pattern: Concurrency Without Threads</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="../core.html" title="Core Concepts and Functionality">
<link rel="next" href="threads.html" title="Threads and Asio">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../core.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="threads.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.async"></a><a class="link" href="async.html" title="The Proactor Design Pattern: Concurrency Without Threads">The Proactor Design Pattern:
Concurrency Without Threads</a>
</h4></div></div></div>
<p>
The Asio library offers side-by-side support for synchronous and asynchronous
operations. The asynchronous support is based on the Proactor design pattern
<a class="link" href="async.html#asio.overview.core.async.references">[POSA2]</a>. The
advantages and disadvantages of this approach, when compared to a synchronous-only
or Reactor approach, are outlined below.
</p>
<h6>
<a name="asio.overview.core.async.h0"></a>
<span><a name="asio.overview.core.async.proactor_and_asio"></a></span><a class="link" href="async.html#asio.overview.core.async.proactor_and_asio">Proactor
and Asio</a>
</h6>
<p>
Let us examine how the Proactor design pattern is implemented in Asio,
without reference to platform-specific details.
</p>
<p>
<span class="inlinemediaobject"><img src="../../../proactor.png"></span>
</p>
<p>
<span class="bold"><strong>Proactor design pattern (adapted from [POSA2])</strong></span>
</p>
<p>
— Asynchronous Operation
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Defines an operation that is executed asynchronously, such as an asynchronous
read or write on a socket.
</p></blockquote></div>
<p>
— Asynchronous Operation Processor
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Executes asynchronous operations and queues events on a completion event
queue when operations complete. From a high-level point of view, internal
services like <code class="computeroutput"><span class="identifier">reactive_socket_service</span></code>
are asynchronous operation processors.
</p></blockquote></div>
<p>
— Completion Event Queue
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Buffers completion events until they are dequeued by an asynchronous
event demultiplexer.
</p></blockquote></div>
<p>
— Completion Handler
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Processes the result of an asynchronous operation. These are function
objects, often created using <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span></code>.
</p></blockquote></div>
<p>
— Asynchronous Event Demultiplexer
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Blocks waiting for events to occur on the completion event queue, and
returns a completed event to its caller.
</p></blockquote></div>
<p>
— Proactor
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Calls the asynchronous event demultiplexer to dequeue events, and dispatches
the completion handler (i.e. invokes the function object) associated
with the event. This abstraction is represented by the <code class="computeroutput"><span class="identifier">io_context</span></code> class.
</p></blockquote></div>
<p>
— Initiator
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Application-specific code that starts asynchronous operations. The initiator
interacts with an asynchronous operation processor via a high-level interface
such as <code class="computeroutput"><span class="identifier">basic_stream_socket</span></code>,
which in turn delegates to a service like <code class="computeroutput"><span class="identifier">reactive_socket_service</span></code>.
</p></blockquote></div>
<h6>
<a name="asio.overview.core.async.h1"></a>
<span><a name="asio.overview.core.async.implementation_using_reactor"></a></span><a class="link" href="async.html#asio.overview.core.async.implementation_using_reactor">Implementation
Using Reactor</a>
</h6>
<p>
On many platforms, Asio implements the Proactor design pattern in terms
of a Reactor, such as <code class="computeroutput"><span class="identifier">select</span></code>,
<code class="computeroutput"><span class="identifier">epoll</span></code> or <code class="computeroutput"><span class="identifier">kqueue</span></code>. This implementation approach
corresponds to the Proactor design pattern as follows:
</p>
<p>
— Asynchronous Operation Processor
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
A reactor implemented using <code class="computeroutput"><span class="identifier">select</span></code>,
<code class="computeroutput"><span class="identifier">epoll</span></code> or <code class="computeroutput"><span class="identifier">kqueue</span></code>. When the reactor indicates
that the resource is ready to perform the operation, the processor executes
the asynchronous operation and enqueues the associated completion handler
on the completion event queue.
</p></blockquote></div>
<p>
— Completion Event Queue
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
A linked list of completion handlers (i.e. function objects).
</p></blockquote></div>
<p>
— Asynchronous Event Demultiplexer
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
This is implemented by waiting on an event or condition variable until
a completion handler is available in the completion event queue.
</p></blockquote></div>
<h6>
<a name="asio.overview.core.async.h2"></a>
<span><a name="asio.overview.core.async.implementation_using_windows_overlapped_i_o"></a></span><a class="link" href="async.html#asio.overview.core.async.implementation_using_windows_overlapped_i_o">Implementation
Using Windows Overlapped I/O</a>
</h6>
<p>
On Windows NT, 2000 and XP, Vista, 7 and later, Asio takes advantage of
overlapped I/O to provide an efficient implementation of the Proactor design
pattern. This implementation approach corresponds to the Proactor design
pattern as follows:
</p>
<p>
— Asynchronous Operation Processor
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
This is implemented by the operating system. Operations are initiated
by calling an overlapped function such as <code class="computeroutput"><span class="identifier">AcceptEx</span></code>.
</p></blockquote></div>
<p>
— Completion Event Queue
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
This is implemented by the operating system, and is associated with an
I/O completion port. There is one I/O completion port for each <code class="computeroutput"><span class="identifier">io_context</span></code> instance.
</p></blockquote></div>
<p>
— Asynchronous Event Demultiplexer
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Called by Asio to dequeue events and their associated completion handlers.
</p></blockquote></div>
<h6>
<a name="asio.overview.core.async.h3"></a>
<span><a name="asio.overview.core.async.advantages"></a></span><a class="link" href="async.html#asio.overview.core.async.advantages">Advantages</a>
</h6>
<p>
— Portability.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Many operating systems offer a native asynchronous I/O API (such as overlapped
I/O on <span class="emphasis"><em>Windows</em></span>) as the preferred option for developing
high performance network applications. The library may be implemented
in terms of native asynchronous I/O. However, if native support is not
available, the library may also be implemented using synchronous event
demultiplexors that typify the Reactor pattern, such as <span class="emphasis"><em>POSIX</em></span>
<code class="computeroutput"><span class="identifier">select</span><span class="special">()</span></code>.
</p></blockquote></div>
<p>
— Decoupling threading from concurrency.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Long-duration operations are performed asynchronously by the implementation
on behalf of the application. Consequently applications do not need to
spawn many threads in order to increase concurrency.
</p></blockquote></div>
<p>
— Performance and scalability.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Implementation strategies such as thread-per-connection (which a synchronous-only
approach would require) can degrade system performance, due to increased
context switching, synchronisation and data movement among CPUs. With
asynchronous operations it is possible to avoid the cost of context switching
by minimising the number of operating system threads — typically a limited
resource — and only activating the logical threads of control that have
events to process.
</p></blockquote></div>
<p>
— Simplified application synchronisation.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Asynchronous operation completion handlers can be written as though they
exist in a single-threaded environment, and so application logic can
be developed with little or no concern for synchronisation issues.
</p></blockquote></div>
<p>
— Function composition.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Function composition refers to the implementation of functions to provide
a higher-level operation, such as sending a message in a particular format.
Each function is implemented in terms of multiple calls to lower-level
read or write operations.
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
For example, consider a protocol where each message consists of a fixed-length
header followed by a variable length body, where the length of the body
is specified in the header. A hypothetical read_message operation could
be implemented using two lower-level reads, the first to receive the
header and, once the length is known, the second to receive the body.
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
To compose functions in an asynchronous model, asynchronous operations
can be chained together. That is, a completion handler for one operation
can initiate the next. Starting the first call in the chain can be encapsulated
so that the caller need not be aware that the higher-level operation
is implemented as a chain of asynchronous operations.
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
The ability to compose new operations in this way simplifies the development
of higher levels of abstraction above a networking library, such as functions
to support a specific protocol.
</p></blockquote></div>
<h6>
<a name="asio.overview.core.async.h4"></a>
<span><a name="asio.overview.core.async.disadvantages"></a></span><a class="link" href="async.html#asio.overview.core.async.disadvantages">Disadvantages</a>
</h6>
<p>
— Program complexity.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
It is more difficult to develop applications using asynchronous mechanisms
due to the separation in time and space between operation initiation
and completion. Applications may also be harder to debug due to the inverted
flow of control.
</p></blockquote></div>
<p>
— Memory usage.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Buffer space must be committed for the duration of a read or write operation,
which may continue indefinitely, and a separate buffer is required for
each concurrent operation. The Reactor pattern, on the other hand, does
not require buffer space until a socket is ready for reading or writing.
</p></blockquote></div>
<h6>
<a name="asio.overview.core.async.h5"></a>
<span><a name="asio.overview.core.async.references"></a></span><a class="link" href="async.html#asio.overview.core.async.references">References</a>
</h6>
<p>
[POSA2] D. Schmidt et al, <span class="emphasis"><em>Pattern Oriented Software Architecture,
Volume 2</em></span>. Wiley, 2000.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../core.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="threads.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,258 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Buffers</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="strands.html" title="Strands: Use Threads Without Explicit Locking">
<link rel="next" href="streams.html" title="Streams, Short Reads and Short Writes">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="strands.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="streams.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.buffers"></a><a class="link" href="buffers.html" title="Buffers">Buffers</a>
</h4></div></div></div>
<p>
Fundamentally, I/O involves the transfer of data to and from contiguous
regions of memory, called buffers. These buffers can be simply expressed
as a tuple consisting of a pointer and a size in bytes. However, to allow
the development of efficient network applications, Asio includes support
for scatter-gather operations. These operations involve one or more buffers:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
A scatter-read receives data into multiple buffers.
</li>
<li class="listitem">
A gather-write transmits multiple buffers.
</li>
</ul></div>
<p>
Therefore we require an abstraction to represent a collection of buffers.
The approach used in Asio is to define a type (actually two types) to represent
a single buffer. These can be stored in a container, which may be passed
to the scatter-gather operations.
</p>
<p>
In addition to specifying buffers as a pointer and size in bytes, Asio
makes a distinction between modifiable memory (called mutable) and non-modifiable
memory (where the latter is created from the storage for a const-qualified
variable). These two types could therefore be defined as follows:
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">*,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">mutable_buffer</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">const_buffer</span><span class="special">;</span>
</pre>
<p>
Here, a mutable_buffer would be convertible to a const_buffer, but conversion
in the opposite direction is not valid.
</p>
<p>
However, Asio does not use the above definitions as-is, but instead defines
two classes: <code class="computeroutput"><span class="identifier">mutable_buffer</span></code>
and <code class="computeroutput"><span class="identifier">const_buffer</span></code>. The goal
of these is to provide an opaque representation of contiguous memory, where:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Types behave as std::pair would in conversions. That is, a <code class="computeroutput"><span class="identifier">mutable_buffer</span></code> is convertible to
a <code class="computeroutput"><span class="identifier">const_buffer</span></code>, but
the opposite conversion is disallowed.
</li>
<li class="listitem">
There is protection against buffer overruns. Given a buffer instance,
a user can only create another buffer representing the same range of
memory or a sub-range of it. To provide further safety, the library
also includes mechanisms for automatically determining the size of
a buffer from an array, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></code>
or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> of POD elements, or from a
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
</li>
<li class="listitem">
The underlying memory is explicitly accessed using the <code class="computeroutput"><span class="identifier">data</span><span class="special">()</span></code>
member function. In general an application should never need to do
this, but it is required by the library implementation to pass the
raw memory to the underlying operating system functions.
</li>
</ul></div>
<p>
Finally, multiple buffers can be passed to scatter-gather operations (such
as <a class="link" href="../../reference/read.html" title="read">read()</a> or <a class="link" href="../../reference/write.html" title="write">write()</a>)
by putting the buffer objects into a container. The <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code>
and <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code>
concepts have been defined so that containers such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>,
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span></code>, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code>
or <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></code> can be used.
</p>
<h6>
<a name="asio.overview.core.buffers.h0"></a>
<span><a name="asio.overview.core.buffers.streambuf_for_integration_with_iostreams"></a></span><a class="link" href="buffers.html#asio.overview.core.buffers.streambuf_for_integration_with_iostreams">Streambuf
for Integration with Iostreams</a>
</h6>
<p>
The class <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">basic_streambuf</span></code> is derived from <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_streambuf</span></code> to associate the input
sequence and output sequence with one or more objects of some character
array type, whose elements store arbitrary values. These character array
objects are internal to the streambuf object, but direct access to the
array elements is provided to permit them to be used with I/O operations,
such as the send or receive operations of a socket:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
The input sequence of the streambuf is accessible via the <a class="link" href="../../reference/basic_streambuf/data.html" title="basic_streambuf::data">data()</a>
member function. The return type of this function meets the <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code> requirements.
</li>
<li class="listitem">
The output sequence of the streambuf is accessible via the <a class="link" href="../../reference/basic_streambuf/prepare.html" title="basic_streambuf::prepare">prepare()</a>
member function. The return type of this function meets the <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code> requirements.
</li>
<li class="listitem">
Data is transferred from the front of the output sequence to the back
of the input sequence by calling the <a class="link" href="../../reference/basic_streambuf/commit.html" title="basic_streambuf::commit">commit()</a>
member function.
</li>
<li class="listitem">
Data is removed from the front of the input sequence by calling the
<a class="link" href="../../reference/basic_streambuf/consume.html" title="basic_streambuf::consume">consume()</a>
member function.
</li>
</ul></div>
<p>
The streambuf constructor accepts a <code class="computeroutput"><span class="identifier">size_t</span></code>
argument specifying the maximum of the sum of the sizes of the input sequence
and output sequence. Any operation that would, if successful, grow the
internal data beyond this limit will throw a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">length_error</span></code>
exception.
</p>
<h6>
<a name="asio.overview.core.buffers.h1"></a>
<span><a name="asio.overview.core.buffers.bytewise_traversal_of_buffer_sequences"></a></span><a class="link" href="buffers.html#asio.overview.core.buffers.bytewise_traversal_of_buffer_sequences">Bytewise
Traversal of Buffer Sequences</a>
</h6>
<p>
The <code class="computeroutput"><span class="identifier">buffers_iterator</span><span class="special">&lt;&gt;</span></code>
class template allows buffer sequences (i.e. types meeting <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code> or <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code> requirements) to
be traversed as though they were a contiguous sequence of bytes. Helper
functions called buffers_begin() and buffers_end() are also provided, where
the buffers_iterator&lt;&gt; template parameter is automatically deduced.
</p>
<p>
As an example, to read a single line from a socket and into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, you may write:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span> <span class="identifier">sb</span><span class="special">;</span>
<span class="special">...</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">read_until</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">sb</span><span class="special">,</span> <span class="char">'\n'</span><span class="special">);</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span><span class="special">::</span><span class="identifier">const_buffers_type</span> <span class="identifier">bufs</span> <span class="special">=</span> <span class="identifier">sb</span><span class="special">.</span><span class="identifier">data</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffers_begin</span><span class="special">(</span><span class="identifier">bufs</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffers_begin</span><span class="special">(</span><span class="identifier">bufs</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">n</span><span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.core.buffers.h2"></a>
<span><a name="asio.overview.core.buffers.buffer_literals"></a></span><a class="link" href="buffers.html#asio.overview.core.buffers.buffer_literals">Buffer
Literals</a>
</h6>
<p>
The <code class="computeroutput"><span class="identifier">_buf</span></code> literal suffix,
defined in namespace <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer_literals</span></code>,
may be used to create <code class="computeroutput"><span class="identifier">const_buffer</span></code>
objects from string, binary integer, and hexadecimal integer literals.
These buffer literals may be arbitrarily long. For example:
</p>
<pre class="programlisting">using namespace asio::buffer_literals;
asio::const_buffer b1 = "hello"_buf;
asio::const_buffer b2 = 0xdeadbeef_buf;
asio::const_buffer b3 = 0x01234567'89abcdef'01234567'89abcdef_buf;
asio::const_buffer b4 = 0b1010101011001100_buf;
</pre>
<p>
The memory associated with a buffer literal is valid for the lifetime of
the program. This means that the buffer can be safely used with asynchronous
operations:
</p>
<pre class="programlisting"><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">my_socket</span><span class="special">,</span> <span class="string">"hello"</span><span class="identifier">_buf</span><span class="special">,</span> <span class="identifier">my_handler</span><span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.core.buffers.h3"></a>
<span><a name="asio.overview.core.buffers.buffer_debugging"></a></span><a class="link" href="buffers.html#asio.overview.core.buffers.buffer_debugging">Buffer
Debugging</a>
</h6>
<p>
Some standard library implementations, such as the one that ships with
Microsoft Visual C++ 8.0 and later, provide a feature called iterator debugging.
What this means is that the validity of iterators is checked at runtime.
If a program tries to use an iterator that has been invalidated, an assertion
will be triggered. For example:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v</span><span class="special">(</span><span class="number">1</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
<span class="identifier">v</span><span class="special">.</span><span class="identifier">clear</span><span class="special">();</span> <span class="comment">// invalidates iterators</span>
<span class="special">*</span><span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// assertion!</span>
</pre>
<p>
Asio takes advantage of this feature to add buffer debugging. Consider
the following code:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">dont_do_this</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"Hello, world!"</span><span class="special">;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">msg</span><span class="special">),</span> <span class="identifier">my_handler</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
When you call an asynchronous read or write you need to ensure that the
buffers for the operation are valid until the completion handler is called.
In the above example, the buffer is the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
variable <code class="computeroutput"><span class="identifier">msg</span></code>. This variable
is on the stack, and so it goes out of scope before the asynchronous operation
completes. If you're lucky then the application will crash, but random
failures are more likely.
</p>
<p>
When buffer debugging is enabled, Asio stores an iterator into the string
until the asynchronous operation completes, and then dereferences it to
check its validity. In the above example you would observe an assertion
failure just before Asio tries to call the completion handler.
</p>
<p>
This feature is automatically made available for Microsoft Visual Studio
8.0 or later and for GCC when <code class="computeroutput"><span class="identifier">_GLIBCXX_DEBUG</span></code>
is defined. There is a performance cost to this checking, so buffer debugging
is only enabled in debug builds. For other compilers it may be enabled
by defining <code class="computeroutput"><span class="identifier">ASIO_ENABLE_BUFFER_DEBUGGING</span></code>.
It can also be explicitly disabled by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_BUFFER_DEBUGGING</span></code>.
</p>
<h6>
<a name="asio.overview.core.buffers.h4"></a>
<span><a name="asio.overview.core.buffers.see_also"></a></span><a class="link" href="buffers.html#asio.overview.core.buffers.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/buffer.html" title="buffer">buffer</a>, <a class="link" href="../../reference/buffers_begin.html" title="buffers_begin">buffers_begin</a>,
<a class="link" href="../../reference/buffers_end.html" title="buffers_end">buffers_end</a>, <a class="link" href="../../reference/buffers_iterator.html" title="buffers_iterator">buffers_iterator</a>,
<a class="link" href="../../reference/const_buffer.html" title="const_buffer">const_buffer</a>, <a class="link" href="../../reference/const_buffers_1.html" title="const_buffers_1">const_buffers_1</a>, <a class="link" href="../../reference/mutable_buffer.html" title="mutable_buffer">mutable_buffer</a>, <a class="link" href="../../reference/mutable_buffers_1.html" title="mutable_buffers_1">mutable_buffers_1</a>,
<a class="link" href="../../reference/streambuf.html" title="streambuf">streambuf</a>, <a class="link" href="../../reference/ConstBufferSequence.html" title="Constant buffer sequence requirements">ConstBufferSequence</a>,
<a class="link" href="../../reference/MutableBufferSequence.html" title="Mutable buffer sequence requirements">MutableBufferSequence</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.buffers">buffers example (C++03)</a>,
<a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.buffers">buffers example (c++11)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="strands.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="streams.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,386 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Per-Operation Cancellation</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="allocation.html" title="Custom Memory Allocation">
<link rel="next" href="handler_tracking.html" title="Handler Tracking">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="allocation.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="handler_tracking.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.cancellation"></a><a class="link" href="cancellation.html" title="Per-Operation Cancellation">Per-Operation Cancellation</a>
</h4></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
These type requirements and classes are the low level building blocks
of cancellation. For most use cases, consider using a higher level abstraction,
such as <a class="link" href="../../reference/experimental__make_parallel_group.html" title="experimental::make_parallel_group">experimental::make_parallel_group</a>
or the <a class="link" href="../composition/cpp20_coroutines.html#asio.overview.composition.cpp20_coroutines.co_ordinating_parallel_coroutines">logical
operators</a> for <code class="computeroutput"><span class="identifier">awaitable</span></code>.
</p></td></tr>
</table></div>
<p>
I/O objects, such as sockets and timers, support object-wide cancellation
of outstanding asynchronous operations via their <code class="computeroutput"><span class="identifier">close</span></code>
or <code class="computeroutput"><span class="identifier">cancel</span></code> member functions.
However, certain asynchronous operations also support individual, targeted
cancellation. This per-operation cancellation is enabled by specifying
that a completion handler has an <a class="link" href="../../reference/associated_cancellation_slot.html" title="associated_cancellation_slot">associated
cancellation slot</a> which satisfies the <a class="link" href="../../reference/CancellationSlot.html" title="Cancellation slot requirements">CancellationSlot</a>
type requirements. A cancellation slot is a lightweight channel used for
delivering a cancellation request.
</p>
<p>
Given a copy of a user-defined <code class="computeroutput"><span class="identifier">Handler</span></code>
object <code class="computeroutput"><span class="identifier">h</span></code>, if an asynchronous
operation supports cancellation it will obtain a cancellation slot using
the <code class="computeroutput"><span class="identifier">get_associated_cancellation_slot</span></code>
function. For example:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">associated_cancellation_slot_t</span><span class="special">&lt;</span><span class="identifier">Handler</span><span class="special">&gt;</span> <span class="identifier">s</span>
<span class="special">=</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">get_associated_cancellation_slot</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span>
</pre>
<p>
The associated cancellation slot must satisfy the CancellationSlot type
requirements.
</p>
<p>
By default, handlers use a default-constructed <a class="link" href="../../reference/cancellation_slot.html" title="cancellation_slot"><code class="computeroutput"><span class="identifier">cancellation_slot</span></code></a>, which means
that per-operation cancellation is disabled. The cancellation slot may
be customised for a particular handler type by specifying a nested type
<code class="computeroutput"><span class="identifier">cancellation_slot_type</span></code>
and member function <code class="computeroutput"><span class="identifier">get_cancellation_slot</span><span class="special">()</span></code>:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_handler</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// Custom implementation of CancellationSlot type requirements.</span>
<span class="keyword">typedef</span> <span class="identifier">my_cancellation_slot</span> <span class="identifier">cancellation_slot_type</span><span class="special">;</span>
<span class="comment">// Return a custom cancellation slot implementation.</span>
<span class="identifier">cancellation_slot_type</span> <span class="identifier">get_cancellation_slot</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">my_cancellation_slot</span><span class="special">(...);</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
In more complex cases, the <code class="computeroutput"><span class="identifier">associated_cancellation_slot</span></code>
template may be partially specialised directly:
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">asio</span> <span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">CancellationSlot</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">associated_cancellation_slot</span><span class="special">&lt;</span><span class="identifier">my_handler</span><span class="special">,</span> <span class="identifier">CancellationSlot</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="comment">// Custom implementation of CancellationSlot type requirements.</span>
<span class="keyword">typedef</span> <span class="identifier">my_cancellation_slot</span> <span class="identifier">type</span><span class="special">;</span>
<span class="comment">// Return a custom cancellation_slot implementation.</span>
<span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">my_handler</span><span class="special">&amp;,</span>
<span class="keyword">const</span> <span class="identifier">CancellationSlot</span><span class="special">&amp;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">CancellationSlot</span><span class="special">())</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">my_cancellation_slot</span><span class="special">(...);</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="special">}</span> <span class="comment">// namespace asio</span>
</pre>
<p>
For convenience, a cancellation slot may be associated with a handler by
using the <a class="link" href="../../reference/bind_cancellation_slot.html" title="bind_cancellation_slot"><code class="computeroutput"><span class="identifier">bind_cancellation_slot</span></code></a> function.
This is particularly useful when associating a cancellation slot with a
lambda:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_read</span><span class="special">(</span><span class="identifier">my_socket</span><span class="special">,</span> <span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_cancellation_slot</span><span class="special">(</span>
<span class="identifier">my_cancellation_slot</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">...</span>
<span class="special">}</span>
<span class="special">)</span>
<span class="special">);</span>
</pre>
<p>
Asio provides a ready-to-use cancellation slot in the form of <a class="link" href="../../reference/cancellation_slot.html" title="cancellation_slot"><code class="computeroutput"><span class="identifier">cancellation_slot</span></code></a> and its counterpart
<a class="link" href="../../reference/cancellation_signal.html" title="cancellation_signal"><code class="computeroutput"><span class="identifier">cancellation_signal</span></code></a>.
These two classes implement a one-to-one pairing of producer (signal) and
consumer (slot) interfaces. The following example shows its use:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">session</span>
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">enable_shared_from_this</span><span class="special">&lt;</span><span class="identifier">proxy</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="special">...</span>
<span class="keyword">void</span> <span class="identifier">do_read</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="identifier">self</span> <span class="special">=</span> <span class="identifier">shared_from_this</span><span class="special">();</span>
<span class="identifier">socket_</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data_</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_cancellation_slot</span><span class="special">(</span>
<span class="identifier">cancel_signal_</span><span class="special">.</span><span class="identifier">slot</span><span class="special">(),</span>
<span class="special">[</span><span class="identifier">self</span><span class="special">](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">error</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">...</span>
<span class="special">}</span>
<span class="special">)</span>
<span class="special">);</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="keyword">void</span> <span class="identifier">request_cancel</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">cancel_signal_</span><span class="special">.</span><span class="identifier">emit</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">cancellation_type</span><span class="special">::</span><span class="identifier">total</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">cancellation_signal</span> <span class="identifier">cancel_signal_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
A <code class="computeroutput"><span class="identifier">cancellation_signal</span></code> contains
a single slot, and consequently a cancellation signal/slot pair may be
used with at most one operation at a time. However, the same slot may be
reused for subsequent operations.
</p>
<p>
To support cancellation, an asynchronous operation installs a cancellation
handler into the slot by calling the slot's <code class="computeroutput"><span class="identifier">assign</span></code>
or <code class="computeroutput"><span class="identifier">emplace</span></code> functions. This
handler will be invoked when a cancellation signal is emitted. A slot holds
exactly one handler at a time, and installing a new handler will overwrite
any previously installed handler.
</p>
<p>
When emitting a cancellation signal, the caller must specify a <a class="link" href="../../reference/cancellation_type.html" title="cancellation_type">cancellation
type</a>. This value is a bitmask that dictates what guarantees the
cancellation target must make if successful cancellation occurs. The possible
bit values are, from weakest to strongest guarantee, are:
</p>
<div class="table">
<a name="asio.overview.core.cancellation.t0"></a><p class="title"><b>Table 1. cancellation types</b></p>
<div class="table-contents"><table class="table" summary="cancellation types">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Bit
</p>
</th>
<th>
<p>
Guarantee if cancellation is successful
</p>
</th>
<th>
<p>
Examples where this is the strongest supported guarantee
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">terminal</span></code>
</p>
</td>
<td>
<p>
The operation had unspecified side effects, and it is only safe
to close or destroy the I/O object.
</p>
</td>
<td>
<p>
A stateful implementation of a message framing protocol, where
an asynchronous operation sends or receives a complete message.
If cancellation occurs part-way through the message body, it
is not possible to report a sensible state to the completion
handler.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">partial</span></code>
</p>
</td>
<td>
<p>
The operation had well-defined side effects, and the completion
handler for the operation indicates what these side effects were.
</p>
</td>
<td>
<p>
Composed operations such as <code class="computeroutput"><span class="identifier">async_read</span></code>
and <code class="computeroutput"><span class="identifier">async_write</span></code>.
If cancellation occurs before all bytes are transferred, the
completion handler is passed the total bytes transferred so far.
The caller may use this information to start another operation
to transfer the remaining bytes.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">total</span></code>
</p>
</td>
<td>
<p>
The operation had no side effects that are observable through
the API.
</p>
</td>
<td>
<p>
Low level system calls that transfer either zero or non-zero
bytes.<br> <br> Wait-for-readiness operations that have no
side effects, even when successful.<br> <br> A fully buffered
message framing protocol implementation, where partial messages
are stored so that they may be reused on the next operation.
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><p>
For example, if application logic requires that an operation complete with
all-or-nothing side effects, it should emit only the <code class="computeroutput"><span class="identifier">total</span></code>
cancellation type. If this type is unsupported by the target operation,
no cancellation will occur.
</p>
<p>
Furthermore, a stronger guarantee always satisfies the requirements of
a weaker guarantee. The <code class="computeroutput"><span class="identifier">partial</span></code>
guarantee still satisfies the <code class="computeroutput"><span class="identifier">terminal</span></code>
guarantee. The <code class="computeroutput"><span class="identifier">total</span></code> guarantee
satisfies both <code class="computeroutput"><span class="identifier">partial</span></code>
and <code class="computeroutput"><span class="identifier">total</span></code>. This means that
when an operation supports a given cancellation type as its strongest guarantee,
it should honour cancellation requests for any of the weaker guarantees.
</p>
<p>
Cancellation requests should not be emitted during an asynchronous operation's
initiating function. Cancellation requests that are emitted before an operation
starts have no effect. Similarly, cancellation requests made after completion
have no effect.
</p>
<p>
When emitting a cancellation signal, the thread safety rules apply as if
calling a member function on the target operation's I/O object. For non-composed
operations, this means that it is safe to emit the cancellation signal
from any thread provided there are no other concurrent calls to the I/O
object, and no other concurrent cancellation signal requests. For composed
operations, care must be taken to ensure the cancellation request does
not occur concurrently with the operation's intermediate completion handlers.
</p>
<h6>
<a name="asio.overview.core.cancellation.h0"></a>
<span><a name="asio.overview.core.cancellation.supported_operations"></a></span><a class="link" href="cancellation.html#asio.overview.core.cancellation.supported_operations">Supported
Operations</a>
</h6>
<p>
Consult the documentation for individual asynchronous operations for their
supported cancellation types, if any. The ability to cancel individual
operations, or composed operations, is currently supported by:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
timers
</li>
<li class="listitem">
sockets on POSIX and Windows
</li>
<li class="listitem">
POSIX descriptors
</li>
<li class="listitem">
Windows HANDLEs
</li>
<li class="listitem">
signal sets
</li>
<li class="listitem">
serial ports
</li>
<li class="listitem">
SSL streams
</li>
<li class="listitem">
all Asio-provided composed operations such as <code class="computeroutput"><span class="identifier">async_read</span></code>
and <code class="computeroutput"><span class="identifier">async_write</span></code>
</li>
<li class="listitem">
compositions based on <code class="computeroutput"><span class="identifier">async_compose</span></code>
</li>
<li class="listitem">
C++20 coroutines that use <code class="computeroutput"><span class="identifier">awaitable</span></code>
</li>
<li class="listitem">
C++20 coroutines that use <code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">coro</span></code>
</li>
<li class="listitem">
the <code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">parallel_group</span></code> operation
</li>
<li class="listitem">
the <code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">promise</span></code> class
</li>
</ul></div>
<h6>
<a name="asio.overview.core.cancellation.h1"></a>
<span><a name="asio.overview.core.cancellation.see_also"></a></span><a class="link" href="cancellation.html#asio.overview.core.cancellation.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/CancellationSlot.html" title="Cancellation slot requirements">CancellationSlot</a>,
<a class="link" href="../../reference/associated_cancellation_slot.html" title="associated_cancellation_slot">associated_cancellation_slot</a>,
<a class="link" href="../../reference/bind_cancellation_slot.html" title="bind_cancellation_slot">bind_cancellation_slot</a>,
<a class="link" href="../../reference/cancellation_signal.html" title="cancellation_signal">cancellation_signal</a>,
<a class="link" href="../../reference/cancellation_slot.html" title="cancellation_slot">cancellation_slot</a>,
<a class="link" href="../../reference/cancellation_state.html" title="cancellation_state">cancellation_state</a>,
<a class="link" href="../../reference/cancellation_type.html" title="cancellation_type">cancellation_type</a>,
<a class="link" href="../../reference/get_associated_cancellation_slot.html" title="get_associated_cancellation_slot">get_associated_cancellation_slot</a>,
<a class="link" href="../../reference/experimental__parallel_group.html" title="experimental::parallel_group">experimental::parallel_group</a>,
<a class="link" href="../../reference/experimental__make_parallel_group.html" title="experimental::make_parallel_group">experimental::make_parallel_group</a>
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="allocation.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="handler_tracking.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,173 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Concurrency Hints</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="handler_tracking.html" title="Handler Tracking">
<link rel="next" href="../composition.html" title="Composition and Completion Tokens">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="handler_tracking.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../composition.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.concurrency_hint"></a><a class="link" href="concurrency_hint.html" title="Concurrency Hints">Concurrency Hints</a>
</h4></div></div></div>
<p>
The <a class="link" href="../../reference/io_context/io_context.html" title="io_context::io_context"><code class="computeroutput"><span class="identifier">io_context</span></code> constructor</a> allows
programs to specify a concurrency hint. This is a suggestion to the <code class="computeroutput"><span class="identifier">io_context</span></code> implementation as to the number
of active threads that should be used for running completion handlers.
</p>
<p>
When the Windows I/O completion port backend is in use, this value is passed
to <code class="literal">CreateIoCompletionPort</code>.
</p>
<p>
When a reactor-based backend is used, the implementation recognises the
following special concurrency hint values:
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Value
</p>
</th>
<th>
<p>
Description
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><span class="number">1</span></code>
</p>
</td>
<td>
<p>
The implementation assumes that the <code class="computeroutput"><span class="identifier">io_context</span></code>
will be run from a single thread, and applies several optimisations
based on this assumption.
</p>
<p>
For example, when a handler is posted from within another handler,
the new handler is added to a fast thread-local queue (with the
consequence that the new handler is held back until the currently
executing handler finishes).
</p>
<p>
The <code class="computeroutput"><span class="identifier">io_context</span></code>
still provides full thread safety, and distinct I/O objects may
be used from any thread.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_CONCURRENCY_HINT_UNSAFE</span></code>
</p>
</td>
<td>
<p>
This special concurrency hint disables locking in both the scheduler
and reactor I/O. This hint has the following restrictions:
</p>
<p>
— Care must be taken to ensure that all operations on the <code class="computeroutput"><span class="identifier">io_context</span></code> and any of its associated
I/O objects (such as sockets and timers) occur in only one thread
at a time.
</p>
<p>
— Asynchronous resolve operations fail with <code class="computeroutput"><span class="identifier">operation_not_supported</span></code>.
</p>
<p>
— If a <code class="computeroutput"><span class="identifier">signal_set</span></code>
is used with the <code class="computeroutput"><span class="identifier">io_context</span></code>,
<code class="computeroutput"><span class="identifier">signal_set</span></code> objects
cannot be used with any other io_context in the program.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_CONCURRENCY_HINT_UNSAFE_IO</span></code>
</p>
</td>
<td>
<p>
This special concurrency hint disables locking in the reactor
I/O. This hint has the following restrictions:
</p>
<p>
— Care must be taken to ensure that the <span class="emphasis"><em>run functions</em></span>
on the <code class="computeroutput"><span class="identifier">io_context</span></code>
(i.e. <code class="computeroutput"><span class="identifier">run</span></code>, <code class="computeroutput"><span class="identifier">run_for</span></code>, <code class="computeroutput"><span class="identifier">run_until</span></code>,
<code class="computeroutput"><span class="identifier">run_one</span></code>, <code class="computeroutput"><span class="identifier">run_one_for</span></code>, <code class="computeroutput"><span class="identifier">run_one_until</span></code>, <code class="computeroutput"><span class="identifier">poll</span></code>, and <code class="computeroutput"><span class="identifier">poll_one</span></code>),
and all operations on the context's associated I/O objects (such
as sockets and timers), occur in only one thread at a time.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_CONCURRENCY_HINT_SAFE</span></code>
</p>
</td>
<td>
<p>
The default. The <code class="computeroutput"><span class="identifier">io_context</span></code>
provides full thread safety, and distinct I/O objects may be
used from any thread.
</p>
</td>
</tr>
</tbody>
</table></div>
<p>
The concurrency hint used by default-constructed <code class="computeroutput">io_context</code>
objects can be overridden at compile time by defining the <code class="computeroutput">ASIO_CONCURRENCY_HINT_DEFAULT</code>
macro. For example, specifying
</p>
<pre class="programlisting">-DASIO_CONCURRENCY_HINT_DEFAULT=1
</pre>
<p>
on the compiler command line means that a concurrency hint of <code class="computeroutput">1</code>
is used for all default-constructed <code class="computeroutput">io_context</code> objects in
the program. Similarly, the concurrency hint used by <code class="computeroutput">io_context</code>
objects constructed with <code class="computeroutput">1</code> can be overridden by defining
<code class="computeroutput">ASIO_CONCURRENCY_HINT_1</code>. For example, passing
</p>
<pre class="programlisting">-DASIO_CONCURRENCY_HINT_1=ASIO_CONCURRENCY_HINT_UNSAFE
</pre>
<p>
to the compiler will disable thread safety for all of these objects.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="handler_tracking.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../composition.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,487 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Handler Tracking</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="cancellation.html" title="Per-Operation Cancellation">
<link rel="next" href="concurrency_hint.html" title="Concurrency Hints">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cancellation.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="concurrency_hint.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.handler_tracking"></a><a class="link" href="handler_tracking.html" title="Handler Tracking">Handler Tracking</a>
</h4></div></div></div>
<p>
To aid in debugging asynchronous programs, Asio provides support for handler
tracking. When enabled by defining <code class="computeroutput"><span class="identifier">ASIO_ENABLE_HANDLER_TRACKING</span></code>,
Asio writes debugging output to the standard error stream. The output records
asynchronous operations and the relationships between their handlers.
</p>
<p>
This feature is useful when debugging and you need to know how your asynchronous
operations are chained together, or what the pending asynchronous operations
are. As an illustration, here is the output when you run the HTTP Server
example, handle a single request, then shut down via Ctrl+C:
</p>
<pre class="programlisting">@asio|1589424178.741850|0*1|signal_set@0x7ffee977d878.async_wait
@asio|1589424178.742593|0*2|socket@0x7ffee977d8a8.async_accept
@asio|1589424178.742619|.2|non_blocking_accept,ec=asio.system:11
@asio|1589424178.742625|0|resolver@0x7ffee977d760.cancel
@asio|1589424195.830382|.2|non_blocking_accept,ec=system:0
@asio|1589424195.830413|&gt;2|ec=system:0
@asio|1589424195.830473|2*3|socket@0x7fa71d808230.async_receive
@asio|1589424195.830496|.3|non_blocking_recv,ec=system:0,bytes_transferred=151
@asio|1589424195.830503|2*4|socket@0x7ffee977d8a8.async_accept
@asio|1589424195.830507|.4|non_blocking_accept,ec=asio.system:11
@asio|1589424195.830510|&lt;2|
@asio|1589424195.830529|&gt;3|ec=system:0,bytes_transferred=151
@asio|1589424195.831143|3^5|in 'async_write' (./../../../include/asio/impl/write.hpp:330)
@asio|1589424195.831143|3*5|socket@0x7fa71d808230.async_send
@asio|1589424195.831186|.5|non_blocking_send,ec=system:0,bytes_transferred=1090
@asio|1589424195.831194|&lt;3|
@asio|1589424195.831218|&gt;5|ec=system:0,bytes_transferred=1090
@asio|1589424195.831263|5|socket@0x7fa71d808230.close
@asio|1589424195.831298|&lt;5|
@asio|1589424199.793770|&gt;1|ec=system:0,signal_number=2
@asio|1589424199.793781|1|socket@0x7ffee977d8a8.close
@asio|1589424199.793809|&lt;1|
@asio|1589424199.793840|&gt;4|ec=asio.system:125
@asio|1589424199.793854|&lt;4|
@asio|1589424199.793883|0|signal_set@0x7ffee977d878.cancel
</pre>
<p>
Each line is of the form:
</p>
<pre class="programlisting">&lt;tag&gt;|&lt;timestamp&gt;|&lt;action&gt;|&lt;description&gt;
</pre>
<p>
The <code class="computeroutput">&lt;tag&gt;</code> is always <code class="computeroutput">@asio</code>, and is used
to identify and extract the handler tracking messages from the program
output.
</p>
<p>
The <code class="computeroutput">&lt;timestamp&gt;</code> is seconds and microseconds from 1 Jan
1970 UTC.
</p>
<p>
The <code class="computeroutput">&lt;action&gt;</code> takes one of the following forms:
</p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">&gt;n</span></dt>
<dd><p>
The program entered the handler number <code class="computeroutput">n</code>. The <code class="computeroutput">&lt;description&gt;</code>
shows the arguments to the handler.
</p></dd>
<dt><span class="term">&lt;n</span></dt>
<dd><p>
The program left handler number <code class="computeroutput">n</code>.
</p></dd>
<dt><span class="term">!n</span></dt>
<dd><p>
The program left handler number n due to an exception.
</p></dd>
<dt><span class="term">~n</span></dt>
<dd><p>
The handler number <code class="computeroutput">n</code> was destroyed without having been
invoked. This is usually the case for any unfinished asynchronous
operations when the <code class="computeroutput">io_context</code> is destroyed.
</p></dd>
<dt><span class="term">n^m</span></dt>
<dd><p>
The handler number <code class="computeroutput">n</code> is about to create a new asynchronous
operation with completion handler number <code class="computeroutput">m</code>. The <code class="computeroutput">&lt;description&gt;</code>
contains source location information to help identify where in the
program the asynchronous operation is being started.
</p></dd>
<dt><span class="term">n*m</span></dt>
<dd><p>
The handler number <code class="computeroutput">n</code> created a new asynchronous operation
with completion handler number <code class="computeroutput">m</code>. The <code class="computeroutput">&lt;description&gt;</code>
shows what asynchronous operation was started.
</p></dd>
<dt><span class="term">n</span></dt>
<dd><p>
The handler number <code class="computeroutput">n</code> performed some other operation.
The <code class="computeroutput">&lt;description&gt;</code> shows what function was called.
Currently only <code class="computeroutput">close()</code> and <code class="computeroutput">cancel()</code> operations
are logged, as these may affect the state of pending asynchronous
operations.
</p></dd>
<dt><span class="term">.n</span></dt>
<dd><p>
The implementation performed a system call as part of the asynchronous
operation for which handler number <code class="computeroutput">n</code> is the completion
handler. The <code class="computeroutput">&lt;description&gt;</code> shows what function
was called and its results. These tracking events are only emitted
when using a reactor-based implementation.
</p></dd>
</dl>
</div>
<p>
Where the <code class="computeroutput">&lt;description&gt;</code> shows a synchronous or asynchronous
operation, the format is <code class="computeroutput">&lt;object-type&gt;@&lt;pointer&gt;.&lt;operation&gt;</code>.
For handler entry, it shows a comma-separated list of arguments and their
values.
</p>
<p>
As shown above, Each handler is assigned a numeric identifier. Where the
handler tracking output shows a handler number of 0, it means that the
action was performed outside of any handler.
</p>
<h6>
<a name="asio.overview.core.handler_tracking.h0"></a>
<span><a name="asio.overview.core.handler_tracking.adding_location_information"></a></span><a class="link" href="handler_tracking.html#asio.overview.core.handler_tracking.adding_location_information">Adding
Location Information</a>
</h6>
<p>
Programs may augment the handler tracking output's location information
by using the macro <code class="computeroutput"><span class="identifier">ASIO_HANDLER_LOCATION</span></code>
in the source code. For example:
</p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">HANDLER_LOCATION</span> <span class="special">\</span>
<span class="identifier">ASIO_HANDLER_LOCATION</span><span class="special">((</span><span class="identifier">__FILE__</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">,</span> <span class="identifier">__func__</span><span class="special">))</span>
<span class="comment">// ...</span>
<span class="keyword">void</span> <span class="identifier">do_read</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">HANDLER_LOCATION</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">self</span><span class="special">(</span><span class="identifier">shared_from_this</span><span class="special">());</span>
<span class="identifier">socket_</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data_</span><span class="special">,</span> <span class="identifier">max_length</span><span class="special">),</span>
<span class="special">[</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">self</span><span class="special">](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">HANDLER_LOCATION</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">do_write</span><span class="special">(</span><span class="identifier">length</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">});</span>
<span class="special">}</span>
</pre>
<p>
With the additional location information available, the handler tracking
output may include a call stack of source locations:
</p>
<pre class="programlisting">@asio|1589423304.861944|&gt;7|ec=system:0,bytes_transferred=5
@asio|1589423304.861952|7^8|in 'async_write' (./../../../include/asio/impl/write.hpp:330)
@asio|1589423304.861952|7^8|called from 'do_write' (handler_tracking/async_tcp_echo_server.cpp:62)
@asio|1589423304.861952|7^8|called from 'operator()' (handler_tracking/async_tcp_echo_server.cpp:51)
@asio|1589423304.861952|7*8|socket@0x7ff61c008230.async_send
@asio|1589423304.861975|.8|non_blocking_send,ec=system:0,bytes_transferred=5
@asio|1589423304.861980|&lt;7|
</pre>
<p>
Furthermore, if <code class="computeroutput">std::source_location</code> or <code class="computeroutput">std::experimental::source_location</code>
are available, the <a class="link" href="../../reference/use_awaitable_t.html" title="use_awaitable_t"><code class="computeroutput">use_awaitable_t</code></a>
token (when default-constructed or used as a default completion token)
will also cause handler tracking to output a source location for each newly
created asynchronous operation. A <code class="computeroutput">use_awaitable_t</code> object may
also be explicitly constructed with location information.
</p>
<h6>
<a name="asio.overview.core.handler_tracking.h1"></a>
<span><a name="asio.overview.core.handler_tracking.visual_representations"></a></span><a class="link" href="handler_tracking.html#asio.overview.core.handler_tracking.visual_representations">Visual
Representations</a>
</h6>
<p>
The handler tracking output may be post-processed using the included <code class="literal">handlerviz.pl</code>
tool to create a visual representation of the handlers (requires the GraphViz
tool <code class="literal">dot</code>).
</p>
<h6>
<a name="asio.overview.core.handler_tracking.h2"></a>
<span><a name="asio.overview.core.handler_tracking.custom_tracking"></a></span><a class="link" href="handler_tracking.html#asio.overview.core.handler_tracking.custom_tracking">Custom Tracking</a>
</h6>
<p>
Handling tracking may be customised by defining the <code class="computeroutput"><span class="identifier">ASIO_CUSTOM_HANDLER_TRACKING</span></code>
macro to the name of a header file (enclosed in <code class="computeroutput"><span class="string">""</span></code>
or <code class="computeroutput"><span class="special">&lt;&gt;</span></code>). This header
file must implement the following preprocessor macros:
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Macro
</p>
</th>
<th>
<p>
Description
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_INHERIT_TRACKED_HANDLER</span></code>
</p>
</td>
<td>
<p>
Specifies a base class for classes that implement asynchronous
operations. When used, the macro immediately follows the class
name, so it must have the form <code class="computeroutput"><span class="special">:</span>
<span class="keyword">public</span> <span class="identifier">my_class</span></code>.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_ALSO_INHERIT_TRACKED_HANDLER</span></code>
</p>
</td>
<td>
<p>
Specifies a base class for classes that implement asynchronous
operations. When used, the macro follows other base classes,
so it must have the form <code class="computeroutput"><span class="special">,</span>
<span class="keyword">public</span> <span class="identifier">my_class</span></code>.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_TRACKING_INIT</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is used to initialise the tracking mechanism.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_LOCATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
A variable declaration that is used to define a source code location.
<code class="computeroutput"><span class="identifier">args</span></code> is a parenthesised
function argument list containing the file name, line number,
and function name.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_CREATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is called on creation of an asynchronous operation.
<code class="computeroutput"><span class="identifier">args</span></code> is a parenthesised
function argument list containing the owning execution context,
the tracked handler, the name of the object type, a pointer to
the object, the object's native handle, and the operation name.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_COMPLETION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is called on completion of an asynchronous
operation. <code class="computeroutput"><span class="identifier">args</span></code>
is a parenthesised function argument list containing the tracked
handler.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_INVOCATION_BEGIN</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is called immediately before a completion
handler is invoked. <code class="computeroutput"><span class="identifier">args</span></code>
is a parenthesised function argument list containing the arguments
to the completion handler.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_INVOCATION_END</span></code>
</p>
</td>
<td>
<p>
An expression that is called immediately after a completion handler
is invoked.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_OPERATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is called when some synchronous object operation
is called (such as <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">cancel</span><span class="special">()</span></code>). <code class="computeroutput"><span class="identifier">args</span></code>
is a parenthesised function argument list containing the owning
execution context, the name of the object type, a pointer to
the object, the object's native handle, and the operation name.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_REACTOR_REGISTRATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is called when an object is registered with
the reactor. <code class="computeroutput"><span class="identifier">args</span></code>
is a parenthesised function argument list containing the owning
execution context, the object's native handle, and a unique registration
key.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_REACTOR_DEREGISTRATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is called when an object is deregistered from
the reactor. <code class="computeroutput"><span class="identifier">args</span></code>
is a parenthesised function argument list containing the owning
execution context, the object's native handle, and a unique registration
key.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_REACTOR_READ_EVENT</span></code>
</p>
</td>
<td>
<p>
A bitmask constant used to identify reactor read readiness events.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_REACTOR_WRITE_EVENT</span></code>
</p>
</td>
<td>
<p>
A bitmask constant used to identify reactor write readiness events.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_REACTOR_ERROR_EVENT</span></code>
</p>
</td>
<td>
<p>
A bitmask constant used to identify reactor error readiness events.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_REACTOR_EVENTS</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is called when an object registered with the
reactor becomes ready. <code class="computeroutput"><span class="identifier">args</span></code>
is a parenthesised function argument list containing the owning
execution context, the unique registration key, and a bitmask
of the ready events.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ASIO_HANDLER_REACTOR_OPERATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
An expression that is called when the implementation performs
a system call as part of a reactor-based asynchronous operation.
<code class="computeroutput"><span class="identifier">args</span></code> is a parenthesised
function argument list containing the tracked handler, the operation
name, the error code produced by the operation, and (optionally)
the number of bytes transferred.
</p>
</td>
</tr>
</tbody>
</table></div>
<h6>
<a name="asio.overview.core.handler_tracking.h3"></a>
<span><a name="asio.overview.core.handler_tracking.see_also"></a></span><a class="link" href="handler_tracking.html#asio.overview.core.handler_tracking.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.handler_tracking">Handler tracking
examples</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cancellation.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="concurrency_hint.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,155 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Line-Based Operations</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="reactor.html" title="Reactor-Style Operations">
<link rel="next" href="allocation.html" title="Custom Memory Allocation">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="reactor.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="allocation.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.line_based"></a><a class="link" href="line_based.html" title="Line-Based Operations">Line-Based Operations</a>
</h4></div></div></div>
<p>
Many commonly-used internet protocols are line-based, which means that
they have protocol elements that are delimited by the character sequence
<code class="computeroutput"><span class="string">"\r\n"</span></code>. Examples
include HTTP, SMTP and FTP. To more easily permit the implementation of
line-based protocols, as well as other protocols that use delimiters, Asio
includes the functions <code class="computeroutput"><span class="identifier">read_until</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code>.
</p>
<p>
The following example illustrates the use of <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code> in an HTTP server, to receive the first
line of an HTTP request from a client:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">http_connection</span>
<span class="special">{</span>
<span class="special">...</span>
<span class="keyword">void</span> <span class="identifier">start</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_read_until</span><span class="special">(</span><span class="identifier">socket_</span><span class="special">,</span> <span class="identifier">data_</span><span class="special">,</span> <span class="string">"\r\n"</span><span class="special">,</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">http_connection</span><span class="special">::</span><span class="identifier">handle_request_line</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">));</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">handle_request_line</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">method</span><span class="special">,</span> <span class="identifier">uri</span><span class="special">,</span> <span class="identifier">version</span><span class="special">;</span>
<span class="keyword">char</span> <span class="identifier">sp1</span><span class="special">,</span> <span class="identifier">sp2</span><span class="special">,</span> <span class="identifier">cr</span><span class="special">,</span> <span class="identifier">lf</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span> <span class="identifier">is</span><span class="special">(&amp;</span><span class="identifier">data_</span><span class="special">);</span>
<span class="identifier">is</span><span class="special">.</span><span class="identifier">unsetf</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">skipws</span><span class="special">);</span>
<span class="identifier">is</span> <span class="special">&gt;&gt;</span> <span class="identifier">method</span> <span class="special">&gt;&gt;</span> <span class="identifier">sp1</span> <span class="special">&gt;&gt;</span> <span class="identifier">uri</span> <span class="special">&gt;&gt;</span> <span class="identifier">sp2</span> <span class="special">&gt;&gt;</span> <span class="identifier">version</span> <span class="special">&gt;&gt;</span> <span class="identifier">cr</span> <span class="special">&gt;&gt;</span> <span class="identifier">lf</span><span class="special">;</span>
<span class="special">...</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket_</span><span class="special">;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span> <span class="identifier">data_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">streambuf</span></code> data member
serves as a place to store the data that has been read from the socket
before it is searched for the delimiter. It is important to remember that
there may be additional data <span class="emphasis"><em>after</em></span> the delimiter.
This surplus data should be left in the <code class="computeroutput"><span class="identifier">streambuf</span></code>
so that it may be inspected by a subsequent call to <code class="computeroutput"><span class="identifier">read_until</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code>.
</p>
<p>
The delimiters may be specified as a single <code class="computeroutput"><span class="keyword">char</span></code>,
a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> or a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">regex</span></code>.
The <code class="computeroutput"><span class="identifier">read_until</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code>
functions also include overloads that accept a user-defined function object
called a match condition. For example, to read data into a streambuf until
whitespace is encountered:
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffers_iterator</span><span class="special">&lt;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span><span class="special">::</span><span class="identifier">const_buffers_type</span><span class="special">&gt;</span> <span class="identifier">iterator</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">iterator</span><span class="special">,</span> <span class="keyword">bool</span><span class="special">&gt;</span>
<span class="identifier">match_whitespace</span><span class="special">(</span><span class="identifier">iterator</span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">iterator</span> <span class="identifier">end</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">begin</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">)</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">isspace</span><span class="special">(*</span><span class="identifier">i</span><span class="special">++))</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="keyword">false</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span> <span class="identifier">b</span><span class="special">;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">read_until</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">match_whitespace</span><span class="special">);</span>
</pre>
<p>
To read data into a streambuf until a matching character is found:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">match_char</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">explicit</span> <span class="identifier">match_char</span><span class="special">(</span><span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">c_</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">bool</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()(</span>
<span class="identifier">Iterator</span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">end</span><span class="special">)</span> <span class="keyword">const</span>
<span class="special">{</span>
<span class="identifier">Iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">begin</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">)</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">c_</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">i</span><span class="special">++)</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="keyword">false</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">char</span> <span class="identifier">c_</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">namespace</span> <span class="identifier">asio</span> <span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;&gt;</span> <span class="keyword">struct</span> <span class="identifier">is_match_condition</span><span class="special">&lt;</span><span class="identifier">match_char</span><span class="special">&gt;</span>
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">true_type</span> <span class="special">{};</span>
<span class="special">}</span> <span class="comment">// namespace asio</span>
<span class="special">...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span> <span class="identifier">b</span><span class="special">;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">read_until</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">match_char</span><span class="special">(</span><span class="char">'a'</span><span class="special">));</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">is_match_condition</span><span class="special">&lt;&gt;</span></code> type trait automatically evaluates
to true for functions, and for function objects with a nested <code class="computeroutput"><span class="identifier">result_type</span></code> typedef. For other types
the trait must be explicitly specialised, as shown above.
</p>
<h6>
<a name="asio.overview.core.line_based.h0"></a>
<span><a name="asio.overview.core.line_based.see_also"></a></span><a class="link" href="line_based.html#asio.overview.core.line_based.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/async_read_until.html" title="async_read_until">async_read_until()</a>,
<a class="link" href="../../reference/is_match_condition.html" title="is_match_condition">is_match_condition</a>,
<a class="link" href="../../reference/read_until.html" title="read_until">read_until()</a>, <a class="link" href="../../reference/streambuf.html" title="streambuf">streambuf</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.http_client">HTTP client example</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="reactor.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="allocation.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,76 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Reactor-Style Operations</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="streams.html" title="Streams, Short Reads and Short Writes">
<link rel="next" href="line_based.html" title="Line-Based Operations">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="streams.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="line_based.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.reactor"></a><a class="link" href="reactor.html" title="Reactor-Style Operations">Reactor-Style Operations</a>
</h4></div></div></div>
<p>
Sometimes a program must be integrated with a third-party library that
wants to perform the I/O operations itself. To facilitate this, Asio includes
synchronous and asynchronous operations that may be used to wait for a
socket to become ready to read, ready to write, or to have a pending error
condition.
</p>
<p>
As an example, to perform a non-blocking read something like the following
may be used:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">non_blocking</span><span class="special">(</span><span class="keyword">true</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">::</span><span class="identifier">wait_read</span><span class="special">,</span> <span class="identifier">read_handler</span><span class="special">);</span>
<span class="special">...</span>
<span class="keyword">void</span> <span class="identifier">read_handler</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">buf</span><span class="special">(</span><span class="identifier">socket</span><span class="special">.</span><span class="identifier">available</span><span class="special">());</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">read_some</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">buf</span><span class="special">));</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
These operations are supported for sockets on all platforms, and for the
POSIX stream-oriented descriptor classes.
</p>
<h6>
<a name="asio.overview.core.reactor.h0"></a>
<span><a name="asio.overview.core.reactor.see_also"></a></span><a class="link" href="reactor.html#asio.overview.core.reactor.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/basic_socket/wait.html" title="basic_socket::wait">basic_socket::wait()</a>,
<a class="link" href="../../reference/basic_socket/async_wait.html" title="basic_socket::async_wait">basic_socket::async_wait()</a>,
<a class="link" href="../../reference/basic_socket/non_blocking.html" title="basic_socket::non_blocking">basic_socket::non_blocking()</a>,
<a class="link" href="../../reference/basic_socket/native_non_blocking.html" title="basic_socket::native_non_blocking">basic_socket::native_non_blocking()</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.nonblocking">nonblocking example</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="streams.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="line_based.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,158 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Strands: Use Threads Without Explicit Locking</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="threads.html" title="Threads and Asio">
<link rel="next" href="buffers.html" title="Buffers">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="threads.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="buffers.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.strands"></a><a class="link" href="strands.html" title="Strands: Use Threads Without Explicit Locking">Strands: Use Threads Without
Explicit Locking</a>
</h4></div></div></div>
<p>
A strand is defined as a strictly sequential invocation of event handlers
(i.e. no concurrent invocation). Use of strands allows execution of code
in a multithreaded program without the need for explicit locking (e.g.
using mutexes).
</p>
<p>
Strands may be either implicit or explicit, as illustrated by the following
alternative approaches:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Calling io_context::run() from only one thread means all event handlers
execute in an implicit strand, due to the io_context's guarantee that
handlers are only invoked from inside run().
</li>
<li class="listitem">
Where there is a single chain of asynchronous operations associated
with a connection (e.g. in a half duplex protocol implementation like
HTTP) there is no possibility of concurrent execution of the handlers.
This is an implicit strand.
</li>
<li class="listitem">
An explicit strand is an instance of <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;&gt;</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">strand</span></code>.
All event handler function objects need to be bound to the strand using
<code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_executor</span><span class="special">()</span></code>
or otherwise posted/dispatched through the strand object.
</li>
</ul></div>
<p>
In the case of composed asynchronous operations, such as <code class="computeroutput"><span class="identifier">async_read</span><span class="special">()</span></code>
or <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code>,
if a completion handler goes through a strand, then all intermediate handlers
should also go through the same strand. This is needed to ensure thread
safe access for any objects that are shared between the caller and the
composed operation (in the case of <code class="computeroutput"><span class="identifier">async_read</span><span class="special">()</span></code> it's the socket, which the caller can
<code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>
to cancel the operation).
</p>
<p>
To achieve this, all asynchronous operations obtain the handler's associated
executor by using the <code class="computeroutput"><span class="identifier">get_associated_executor</span></code>
function. For example:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">Handler</span><span class="special">&gt;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span>
</pre>
<p>
The associated executor must satisfy the Executor requirements. It will
be used by the asynchronous operation to submit both intermediate and final
handlers for execution.
</p>
<p>
The executor may be customised for a particular handler type by specifying
a nested type <code class="computeroutput"><span class="identifier">executor_type</span></code>
and member function <code class="computeroutput"><span class="identifier">get_executor</span><span class="special">()</span></code>:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_handler</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// Custom implementation of Executor type requirements.</span>
<span class="keyword">typedef</span> <span class="identifier">my_executor</span> <span class="identifier">executor_type</span><span class="special">;</span>
<span class="comment">// Return a custom executor implementation.</span>
<span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">my_executor</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
In more complex cases, the <code class="computeroutput"><span class="identifier">associated_executor</span></code>
template may be partially specialised directly:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_handler</span>
<span class="special">{</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
<span class="special">};</span>
<span class="keyword">namespace</span> <span class="identifier">asio</span> <span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">my_handler</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="comment">// Custom implementation of Executor type requirements.</span>
<span class="keyword">typedef</span> <span class="identifier">my_executor</span> <span class="identifier">type</span><span class="special">;</span>
<span class="comment">// Return a custom executor implementation.</span>
<span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">my_handler</span><span class="special">&amp;,</span>
<span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="special">=</span> <span class="identifier">Executor</span><span class="special">())</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">my_executor</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="special">}</span> <span class="comment">// namespace asio</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_executor</span><span class="special">()</span></code>
function is a helper to bind a specific executor object, such as a strand,
to a completion handler. This binding automatically associates an executor
as shown above. For example, to bind a strand to a completion handler we
would simply write:
</p>
<pre class="programlisting"><span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">my_strand</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">length</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}));</span>
</pre>
<h6>
<a name="asio.overview.core.strands.h0"></a>
<span><a name="asio.overview.core.strands.see_also"></a></span><a class="link" href="strands.html#asio.overview.core.strands.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/associated_executor.html" title="associated_executor">associated_executor</a>,
<a class="link" href="../../reference/get_associated_executor.html" title="get_associated_executor">get_associated_executor</a>,
<a class="link" href="../../reference/bind_executor.html" title="bind_executor">bind_executor</a>, <a class="link" href="../../reference/strand.html" title="strand">strand</a>, <a class="link" href="../../reference/io_context__strand.html" title="io_context::strand">io_context::strand</a>,
<a class="link" href="../../tutorial/tuttimer5.html" title="Timer.5 - Synchronising completion handlers in multithreaded programs">tutorial Timer.5</a>, <a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.http_server_3">HTTP server 3 example</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="threads.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="buffers.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,118 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Streams, Short Reads and Short Writes</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="buffers.html" title="Buffers">
<link rel="next" href="reactor.html" title="Reactor-Style Operations">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="buffers.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="reactor.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.streams"></a><a class="link" href="streams.html" title="Streams, Short Reads and Short Writes">Streams, Short Reads and
Short Writes</a>
</h4></div></div></div>
<p>
Many I/O objects in Asio are stream-oriented. This means that:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
There are no message boundaries. The data being transferred is a continuous
sequence of bytes.
</li>
<li class="listitem">
Read or write operations may transfer fewer bytes than requested. This
is referred to as a short read or short write.
</li>
</ul></div>
<p>
Objects that provide stream-oriented I/O model one or more of the following
type requirements:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<code class="computeroutput"><span class="identifier">SyncReadStream</span></code>, where
synchronous read operations are performed using a member function called
<code class="computeroutput"><span class="identifier">read_some</span><span class="special">()</span></code>.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">AsyncReadStream</span></code>, where
asynchronous read operations are performed using a member function
called <code class="computeroutput"><span class="identifier">async_read_some</span><span class="special">()</span></code>.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">SyncWriteStream</span></code>, where
synchronous write operations are performed using a member function
called <code class="computeroutput"><span class="identifier">write_some</span><span class="special">()</span></code>.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">AsyncWriteStream</span></code>, where
asynchronous write operations are performed using a member function
called <code class="computeroutput"><span class="identifier">async_write_some</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Examples of stream-oriented I/O objects include <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span></code>,
<code class="computeroutput"><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span><span class="special">&lt;&gt;</span></code>,
<code class="computeroutput"><span class="identifier">posix</span><span class="special">::</span><span class="identifier">stream_descriptor</span></code>, <code class="computeroutput"><span class="identifier">windows</span><span class="special">::</span><span class="identifier">stream_handle</span></code>,
etc.
</p>
<p>
Programs typically want to transfer an exact number of bytes. When a short
read or short write occurs the program must restart the operation, and
continue to do so until the required number of bytes has been transferred.
Asio provides generic functions that do this automatically: <code class="computeroutput"><span class="identifier">read</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">async_read</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">write</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">async_write</span><span class="special">()</span></code>.
</p>
<h6>
<a name="asio.overview.core.streams.h0"></a>
<span><a name="asio.overview.core.streams.why_eof_is_an_error"></a></span><a class="link" href="streams.html#asio.overview.core.streams.why_eof_is_an_error">Why
EOF is an Error</a>
</h6>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
The end of a stream can cause <code class="computeroutput"><span class="identifier">read</span></code>,
<code class="computeroutput"><span class="identifier">async_read</span></code>, <code class="computeroutput"><span class="identifier">read_until</span></code> or <code class="computeroutput"><span class="identifier">async_read_until</span></code>
functions to violate their contract. E.g. a read of N bytes may finish
early due to EOF.
</li>
<li class="listitem">
An EOF error may be used to distinguish the end of a stream from a
successful read of size 0.
</li>
</ul></div>
<h6>
<a name="asio.overview.core.streams.h1"></a>
<span><a name="asio.overview.core.streams.see_also"></a></span><a class="link" href="streams.html#asio.overview.core.streams.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/async_read.html" title="async_read">async_read()</a>, <a class="link" href="../../reference/async_write.html" title="async_write">async_write()</a>,
<a class="link" href="../../reference/read.html" title="read">read()</a>, <a class="link" href="../../reference/write.html" title="write">write()</a>,
<a class="link" href="../../reference/AsyncReadStream.html" title="Buffer-oriented asynchronous read stream requirements">AsyncReadStream</a>,
<a class="link" href="../../reference/AsyncWriteStream.html" title="Buffer-oriented asynchronous write stream requirements">AsyncWriteStream</a>,
<a class="link" href="../../reference/SyncReadStream.html" title="Buffer-oriented synchronous read stream requirements">SyncReadStream</a>, <a class="link" href="../../reference/SyncWriteStream.html" title="Buffer-oriented synchronous write stream requirements">SyncWriteStream</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="buffers.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="reactor.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,121 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Threads and Asio</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="async.html" title="The Proactor Design Pattern: Concurrency Without Threads">
<link rel="next" href="strands.html" title="Strands: Use Threads Without Explicit Locking">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="async.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="strands.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.core.threads"></a><a class="link" href="threads.html" title="Threads and Asio">Threads and Asio</a>
</h4></div></div></div>
<h6>
<a name="asio.overview.core.threads.h0"></a>
<span><a name="asio.overview.core.threads.thread_safety"></a></span><a class="link" href="threads.html#asio.overview.core.threads.thread_safety">Thread
Safety</a>
</h6>
<p>
In general, it is safe to make concurrent use of distinct objects, but
unsafe to make concurrent use of a single object. However, types such as
<code class="computeroutput"><span class="identifier">io_context</span></code> provide a stronger
guarantee that it is safe to use a single object concurrently.
</p>
<h6>
<a name="asio.overview.core.threads.h1"></a>
<span><a name="asio.overview.core.threads.thread_pools"></a></span><a class="link" href="threads.html#asio.overview.core.threads.thread_pools">Thread
Pools</a>
</h6>
<p>
Multiple threads may call <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code> to set up a pool of threads from which
completion handlers may be invoked. This approach may also be used with
<code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
as a means to perform arbitrary computational tasks across a thread pool.
</p>
<p>
Note that all threads that have joined an <code class="computeroutput"><span class="identifier">io_context</span></code>'s
pool are considered equivalent, and the <code class="computeroutput"><span class="identifier">io_context</span></code>
may distribute work across them in an arbitrary fashion.
</p>
<h6>
<a name="asio.overview.core.threads.h2"></a>
<span><a name="asio.overview.core.threads.internal_threads"></a></span><a class="link" href="threads.html#asio.overview.core.threads.internal_threads">Internal
Threads</a>
</h6>
<p>
The implementation of this library for a particular platform may make use
of one or more internal threads to emulate asynchronicity. As far as possible,
these threads must be invisible to the library user. In particular, the
threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
must not call the user's code directly; and
</li>
<li class="listitem">
must block all signals.
</li>
</ul></div>
<p>
This approach is complemented by the following guarantee:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Asynchronous completion handlers will only be called from threads that
are currently calling <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>.
</li></ul></div>
<p>
Consequently, it is the library user's responsibility to create and manage
all threads to which the notifications will be delivered.
</p>
<p>
The reasons for this approach include:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
By only calling <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code> from a single thread, the user's
code can avoid the development complexity associated with synchronisation.
For example, a library user can implement scalable servers that are
single-threaded (from the user's point of view).
</li>
<li class="listitem">
A library user may need to perform initialisation in a thread shortly
after the thread starts and before any other application code is executed.
For example, users of Microsoft's COM must call <code class="computeroutput"><span class="identifier">CoInitializeEx</span></code>
before any other COM operations can be called from that thread.
</li>
<li class="listitem">
The library interface is decoupled from interfaces for thread creation
and management, and permits implementations on platforms where threads
are not available.
</li>
</ul></div>
<h6>
<a name="asio.overview.core.threads.h3"></a>
<span><a name="asio.overview.core.threads.see_also"></a></span><a class="link" href="threads.html#asio.overview.core.threads.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/io_context.html" title="io_context">io_context</a>, <a class="link" href="../../reference/post.html" title="post">post</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="async.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="strands.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,59 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>C++ 2011 Support</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="ssl.html" title="SSL">
<link rel="next" href="cpp2011/system_error.html" title="System Errors and Error Codes">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="ssl.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp2011/system_error.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.cpp2011"></a><a class="link" href="cpp2011.html" title="C++ 2011 Support">C++ 2011 Support</a>
</h3></div></div></div>
<p>
<a class="link" href="cpp2011/system_error.html" title="System Errors and Error Codes">System Errors and Error
Codes</a>
</p>
<p>
<a class="link" href="cpp2011/move_objects.html" title="Movable I/O Objects">Movable I/O Objects</a>
</p>
<p>
<a class="link" href="cpp2011/move_handlers.html" title="Movable Handlers">Movable Handlers</a>
</p>
<p>
<a class="link" href="cpp2011/variadic.html" title="Variadic Templates">Variadic Templates</a>
</p>
<p>
<a class="link" href="cpp2011/array.html" title="Array Container">Array Container</a>
</p>
<p>
<a class="link" href="cpp2011/atomic.html" title="Atomics">Atomics</a>
</p>
<p>
<a class="link" href="cpp2011/shared_ptr.html" title="Shared Pointers">Shared Pointers</a>
</p>
<p>
<a class="link" href="cpp2011/chrono.html" title="Chrono">Chrono</a>
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="ssl.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp2011/system_error.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,60 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Array Container</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="prev" href="variadic.html" title="Variadic Templates">
<link rel="next" href="atomic.html" title="Atomics">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="variadic.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="atomic.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.cpp2011.array"></a><a class="link" href="array.html" title="Array Container">Array Container</a>
</h4></div></div></div>
<p>
Where the standard library provides <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;&gt;</span></code>, Asio:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Provides overloads for the <a class="link" href="../../reference/buffer.html" title="buffer">buffer()</a>
function.
</li>
<li class="listitem">
Uses it in preference to <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;&gt;</span></code> for the <a class="link" href="../../reference/ip__address_v4/bytes_type.html" title="ip::address_v4::bytes_type">ip::address_v4::bytes_type</a>
and <a class="link" href="../../reference/ip__address_v6/bytes_type.html" title="ip::address_v6::bytes_type">ip::address_v6::bytes_type</a>
types.
</li>
<li class="listitem">
Uses it in preference to <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;&gt;</span></code> where a fixed size array type
is needed in the implementation.
</li>
</ul></div>
<p>
Support for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;&gt;</span></code>
is automatically enabled for <code class="literal">g++</code> 4.3 and later, when
the <code class="literal">-std=c++0x</code> or <code class="literal">-std=gnu++0x</code> compiler
options are used, as well as for Microsoft Visual C++ 10. It may be disabled
by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_STD_ARRAY</span></code>,
or explicitly enabled for other compilers by defining <code class="computeroutput"><span class="identifier">ASIO_HAS_STD_ARRAY</span></code>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="variadic.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="atomic.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,44 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Atomics</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="prev" href="array.html" title="Array Container">
<link rel="next" href="shared_ptr.html" title="Shared Pointers">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="array.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="shared_ptr.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.cpp2011.atomic"></a><a class="link" href="atomic.html" title="Atomics">Atomics</a>
</h4></div></div></div>
<p>
Asio's implementation can use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code> in preference to <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">atomic_count</span></code>.
</p>
<p>
Support for the standard atomic integer template is automatically enabled
for <code class="literal">g++</code> 4.5 and later, when the <code class="literal">-std=c++0x</code>
or <code class="literal">-std=gnu++0x</code> compiler options are used. It may be
disabled by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_STD_ATOMIC</span></code>,
or explicitly enabled for other compilers by defining <code class="computeroutput"><span class="identifier">ASIO_HAS_STD_ATOMIC</span></code>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="array.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="shared_ptr.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,56 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Chrono</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="prev" href="shared_ptr.html" title="Shared Pointers">
<link rel="next" href="../implementation.html" title="Platform-Specific Implementation Notes">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="shared_ptr.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../implementation.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.cpp2011.chrono"></a><a class="link" href="chrono.html" title="Chrono">Chrono</a>
</h4></div></div></div>
<p>
Asio provides timers based on the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span></code>
facilities via the <a class="link" href="../../reference/basic_waitable_timer.html" title="basic_waitable_timer">basic_waitable_timer</a>
class template. The typedefs <a class="link" href="../../reference/system_timer.html" title="system_timer">system_timer</a>,
<a class="link" href="../../reference/steady_timer.html" title="steady_timer">steady_timer</a> and <a class="link" href="../../reference/high_resolution_timer.html" title="high_resolution_timer">high_resolution_timer</a>
utilise the standard clocks <code class="computeroutput"><span class="identifier">system_clock</span></code>,
<code class="computeroutput"><span class="identifier">steady_clock</span></code> and <code class="computeroutput"><span class="identifier">high_resolution_clock</span></code> respectively.
</p>
<p>
Support for the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span></code> facilities is automatically enabled
for <code class="literal">g++</code> 4.6 and later, when the <code class="literal">-std=c++0x</code>
or <code class="literal">-std=gnu++0x</code> compiler options are used. (Note that,
for <code class="literal">g++</code>, the draft-standard <code class="computeroutput"><span class="identifier">monotonic_clock</span></code>
is used in place of <code class="computeroutput"><span class="identifier">steady_clock</span></code>.)
Support may be disabled by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_STD_CHRONO</span></code>,
or explicitly enabled for other compilers by defining <code class="computeroutput"><span class="identifier">ASIO_HAS_STD_CHRONO</span></code>.
</p>
<p>
When standard <code class="computeroutput"><span class="identifier">chrono</span></code> is
unavailable, Asio will otherwise use the Boost.Chrono library. The <a class="link" href="../../reference/basic_waitable_timer.html" title="basic_waitable_timer">basic_waitable_timer</a>
class template may be used with either.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="shared_ptr.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../implementation.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,77 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Movable Handlers</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="prev" href="move_objects.html" title="Movable I/O Objects">
<link rel="next" href="variadic.html" title="Variadic Templates">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="move_objects.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="variadic.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.cpp2011.move_handlers"></a><a class="link" href="move_handlers.html" title="Movable Handlers">Movable Handlers</a>
</h4></div></div></div>
<p>
With C++11 and later, user-defined completion handlers are only required
to be move constructible, and are not required to be copy constructible.
</p>
<p>
When move support is enabled, asynchronous that are documented as follows:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Handler</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">async_XYZ</span><span class="special">(...,</span> <span class="identifier">Handler</span> <span class="identifier">handler</span><span class="special">);</span>
</pre>
<p>
are actually declared as:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Handler</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">async_XYZ</span><span class="special">(...,</span> <span class="identifier">Handler</span><span class="special">&amp;&amp;</span> <span class="identifier">handler</span><span class="special">);</span>
</pre>
<p>
The handler argument is perfectly forwarded and the move construction occurs
within the body of <code class="computeroutput"><span class="identifier">async_XYZ</span><span class="special">()</span></code>. This ensures that all other function
arguments are evaluated prior to the move. This is critical when the other
arguments to <code class="computeroutput"><span class="identifier">async_XYZ</span><span class="special">()</span></code> are members of the handler. For example:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_operation</span>
<span class="special">{</span>
<span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span> <span class="identifier">socket</span><span class="special">;</span>
<span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;&gt;</span> <span class="identifier">buffer</span><span class="special">;</span>
<span class="special">...</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">(</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">length</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">...</span>
<span class="identifier">socket</span><span class="special">-&gt;</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(*</span><span class="identifier">buffer</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(*</span><span class="keyword">this</span><span class="special">));</span>
<span class="special">...</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
Move support is automatically enabled for <code class="literal">g++</code> 4.5 and
later, when the <code class="literal">-std=c++0x</code> or <code class="literal">-std=gnu++0x</code>
compiler options are used. It may be disabled by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_MOVE</span></code>, or explicitly enabled
for other compilers by defining <code class="computeroutput"><span class="identifier">ASIO_HAS_MOVE</span></code>.
Note that these macros also affect the availability of <a class="link" href="move_objects.html" title="Movable I/O Objects">movable
I/O objects</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="move_objects.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="variadic.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,99 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Movable I/O Objects</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="prev" href="system_error.html" title="System Errors and Error Codes">
<link rel="next" href="move_handlers.html" title="Movable Handlers">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="system_error.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="move_handlers.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.cpp2011.move_objects"></a><a class="link" href="move_objects.html" title="Movable I/O Objects">Movable I/O Objects</a>
</h4></div></div></div>
<p>
When move support is available (via rvalue references), Asio allows move
construction and assignment of sockets, serial ports, POSIX descriptors
and Windows handles.
</p>
<p>
Move support allows you to write code like:
</p>
<pre class="programlisting"><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">make_socket</span><span class="special">(</span><span class="identifier">io_context</span><span class="special">&amp;</span> <span class="identifier">i</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">s</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">s</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
or:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">connection</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">enable_shared_from_this</span><span class="special">&lt;</span><span class="identifier">connection</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket_</span><span class="special">;</span>
<span class="special">...</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">connection</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;&amp;</span> <span class="identifier">s</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">socket_</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">s</span><span class="special">))</span> <span class="special">{}</span>
<span class="special">...</span>
<span class="special">};</span>
<span class="special">...</span>
<span class="keyword">class</span> <span class="identifier">server</span>
<span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">acceptor</span> <span class="identifier">acceptor_</span><span class="special">;</span>
<span class="special">...</span>
<span class="keyword">void</span> <span class="identifier">handle_accept</span><span class="special">(</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span><span class="identifier">connection</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">socket</span><span class="special">))-&gt;</span><span class="identifier">go</span><span class="special">();</span>
<span class="identifier">acceptor_</span><span class="special">.</span><span class="identifier">async_accept</span><span class="special">(...);</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="special">};</span>
</pre>
<p>
as well as:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span> <span class="identifier">sockets</span><span class="special">;</span>
<span class="identifier">sockets</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">(...));</span>
</pre>
<p>
A word of warning: There is nothing stopping you from moving these objects
while there are pending asynchronous operations, but it is unlikely to
be a good idea to do so. In particular, composed operations like <a class="link" href="../../reference/async_read.html" title="async_read">async_read()</a> store a reference
to the stream object. Moving during the composed operation means that the
composed operation may attempt to access a moved-from object.
</p>
<p>
Move support is automatically enabled for <code class="literal">g++</code> 4.5 and
later, when the <code class="literal">-std=c++0x</code> or <code class="literal">-std=gnu++0x</code>
compiler options are used. It may be disabled by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_MOVE</span></code>, or explicitly enabled
for other compilers by defining <code class="computeroutput"><span class="identifier">ASIO_HAS_MOVE</span></code>.
Note that these macros also affect the availability of <a class="link" href="move_handlers.html" title="Movable Handlers">movable
handlers</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="system_error.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="move_handlers.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,44 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Shared Pointers</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="prev" href="atomic.html" title="Atomics">
<link rel="next" href="chrono.html" title="Chrono">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="atomic.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="chrono.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.cpp2011.shared_ptr"></a><a class="link" href="shared_ptr.html" title="Shared Pointers">Shared Pointers</a>
</h4></div></div></div>
<p>
Asio's implementation can use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;&gt;</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">weak_ptr</span><span class="special">&lt;&gt;</span></code> in preference to the Boost equivalents.
</p>
<p>
Support for the standard smart pointers is automatically enabled for <code class="literal">g++</code>
4.3 and later, when the <code class="literal">-std=c++0x</code> or <code class="literal">-std=gnu++0x</code>
compiler options are used, as well as for Microsoft Visual C++ 10. It may
be disabled by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_STD_SHARED_PTR</span></code>,
or explicitly enabled for other compilers by defining <code class="computeroutput"><span class="identifier">ASIO_HAS_STD_SHARED_PTR</span></code>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="atomic.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="chrono.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,48 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>System Errors and Error Codes</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="prev" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="next" href="move_objects.html" title="Movable I/O Objects">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../cpp2011.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="move_objects.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.cpp2011.system_error"></a><a class="link" href="system_error.html" title="System Errors and Error Codes">System Errors and
Error Codes</a>
</h4></div></div></div>
<p>
When available, Asio can use the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span></code>
and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">system_error</span></code> classes for reporting errors.
In this case, the names <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span></code>
and <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">system_error</span></code> will be typedefs for these
standard classes.
</p>
<p>
System error support is automatically enabled for <code class="literal">g++</code>
4.6 and later, when the <code class="literal">-std=c++0x</code> or <code class="literal">-std=gnu++0x</code>
compiler options are used. It may be disabled by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_STD_SYSTEM_ERROR</span></code>, or explicitly
enabled for other compilers by defining <code class="computeroutput"><span class="identifier">ASIO_HAS_STD_SYSTEM_ERROR</span></code>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../cpp2011.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="move_objects.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,46 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Variadic Templates</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../cpp2011.html" title="C++ 2011 Support">
<link rel="prev" href="move_handlers.html" title="Movable Handlers">
<link rel="next" href="array.html" title="Array Container">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="move_handlers.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="array.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.cpp2011.variadic"></a><a class="link" href="variadic.html" title="Variadic Templates">Variadic Templates</a>
</h4></div></div></div>
<p>
When supported by a compiler, Asio can use variadic templates to implement
the <a class="link" href="../../reference/basic_socket_streambuf/connect.html" title="basic_socket_streambuf::connect">basic_socket_streambuf::connect()</a>
and <a class="link" href="../../reference/basic_socket_iostream/connect.html" title="basic_socket_iostream::connect">basic_socket_iostream::connect()</a>
functions.
</p>
<p>
Support for variadic templates is automatically enabled for <code class="literal">g++</code>
4.3 and later, when the <code class="literal">-std=c++0x</code> or <code class="literal">-std=gnu++0x</code>
compiler options are used. It may be disabled by defining <code class="computeroutput"><span class="identifier">ASIO_DISABLE_VARIADIC_TEMPLATES</span></code>, or explicitly
enabled for other compilers by defining <code class="computeroutput"><span class="identifier">ASIO_HAS_VARIADIC_TEMPLATES</span></code>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="move_handlers.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../cpp2011.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="array.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,85 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Files</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="timers.html" title="Timers">
<link rel="next" href="pipes.html" title="Pipes">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="timers.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="pipes.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.files"></a><a class="link" href="files.html" title="Files">Files</a>
</h3></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This feature requires I/O completion ports on Windows, and io_uring on
Linux (define <code class="computeroutput"><span class="identifier">ASIO_HAS_IO_URING</span></code>
to enable).
</p></td></tr>
</table></div>
<p>
Asio provides support for manipulating stream-oriented and random-access
files. For example, to write to a newly created stream-oriented file:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">stream_file</span> <span class="identifier">file</span><span class="special">(</span>
<span class="identifier">my_io_context</span><span class="special">,</span> <span class="string">"/path/to/file"</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">stream_file</span><span class="special">::</span><span class="identifier">write_only</span>
<span class="special">|</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">stream_file</span><span class="special">::</span><span class="identifier">create</span>
<span class="special">|</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">stream_file</span><span class="special">::</span><span class="identifier">truncate</span><span class="special">);</span>
<span class="identifier">file</span><span class="special">.</span><span class="identifier">async_write_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">});</span>
</pre>
<p>
or to read from a random-access file:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">random_access_file</span> <span class="identifier">file</span><span class="special">(</span>
<span class="identifier">my_io_context</span><span class="special">,</span> <span class="string">"/path/to/file"</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">random_access_file</span><span class="special">::</span><span class="identifier">read_only</span><span class="special">);</span>
<span class="identifier">file</span><span class="special">.</span><span class="identifier">async_read_some_at</span><span class="special">(</span><span class="number">1234</span><span class="special">,</span> <span class="identifier">my_buffer</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">});</span>
</pre>
<h5>
<a name="asio.overview.files.h0"></a>
<span><a name="asio.overview.files.see_also"></a></span><a class="link" href="files.html#asio.overview.files.see_also">See
Also</a>
</h5>
<p>
<a class="link" href="../reference/basic_file.html" title="basic_file">basic_file</a>, <a class="link" href="../reference/basic_random_access_file.html" title="basic_random_access_file">basic_random_access_file</a>,
<a class="link" href="../reference/basic_stream_file.html" title="basic_stream_file">basic_stream_file</a>,
<a class="link" href="../reference/file_base.html" title="file_base">file_base</a>, <a class="link" href="../reference/random_access_file.html" title="random_access_file">random_access_file</a>,
<a class="link" href="../reference/stream_file.html" title="stream_file">stream_file</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="timers.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="pipes.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,553 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Platform-Specific Implementation Notes</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="cpp2011/chrono.html" title="Chrono">
<link rel="next" href="../using.html" title="Using, Building, and Configuring Asio">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp2011/chrono.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="../using.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.implementation"></a><a class="link" href="implementation.html" title="Platform-Specific Implementation Notes">Platform-Specific Implementation
Notes</a>
</h3></div></div></div>
<p>
This section lists platform-specific implementation details, such as the
default demultiplexing mechanism, the number of threads created internally,
and when threads are created.
</p>
<h5>
<a name="asio.overview.implementation.h0"></a>
<span><a name="asio.overview.implementation.linux_kernel_2_4"></a></span><a class="link" href="implementation.html#asio.overview.implementation.linux_kernel_2_4">Linux
Kernel 2.4</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">select</span></code> for demultiplexing.
This means that the number of file descriptors in the process cannot
be permitted to exceed <code class="computeroutput"><span class="identifier">FD_SETSIZE</span></code>.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">select</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h1"></a>
<span><a name="asio.overview.implementation.linux_kernel_2_6"></a></span><a class="link" href="implementation.html#asio.overview.implementation.linux_kernel_2_6">Linux
Kernel 2.6</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">epoll</span></code> for demultiplexing.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">epoll</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h2"></a>
<span><a name="asio.overview.implementation.linux_kernel_5_10"></a></span><a class="link" href="implementation.html#asio.overview.implementation.linux_kernel_5_10">Linux
Kernel 5.10</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
If <code class="computeroutput"><span class="identifier">ASIO_HAS_IO_URING</span></code>
is defined, uses <code class="computeroutput"><span class="identifier">io_uring</span></code>
for file-related asynchonous operations.
</li>
<li class="listitem">
Uses <code class="computeroutput"><span class="identifier">epoll</span></code> for demultiplexing
other event sources.
</li>
<li class="listitem">
Optionally uses <code class="computeroutput"><span class="identifier">io_uring</span></code>
for all asynchronous operations if, in addition to <code class="computeroutput"><span class="identifier">ASIO_HAS_IO_URING</span></code>,
<code class="computeroutput"><span class="identifier">ASIO_DISABLE_EPOLL</span></code> is
defined to disable <code class="computeroutput"><span class="identifier">epoll</span></code>.
</li>
</ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">epoll</span></code>
and <code class="computeroutput"><span class="identifier">io_uring</span></code> is performed
in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h3"></a>
<span><a name="asio.overview.implementation.solaris"></a></span><a class="link" href="implementation.html#asio.overview.implementation.solaris">Solaris</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="literal">/dev/poll</code> for demultiplexing.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="literal">/dev/poll</code> is performed in one
of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h4"></a>
<span><a name="asio.overview.implementation.qnx_neutrino"></a></span><a class="link" href="implementation.html#asio.overview.implementation.qnx_neutrino">QNX
Neutrino</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">select</span></code> for demultiplexing.
This means that the number of file descriptors in the process cannot
be permitted to exceed <code class="computeroutput"><span class="identifier">FD_SETSIZE</span></code>.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">select</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h5"></a>
<span><a name="asio.overview.implementation.mac_os_x"></a></span><a class="link" href="implementation.html#asio.overview.implementation.mac_os_x">Mac
OS X</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">kqueue</span></code> for demultiplexing.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">kqueue</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h6"></a>
<span><a name="asio.overview.implementation.freebsd"></a></span><a class="link" href="implementation.html#asio.overview.implementation.freebsd">FreeBSD</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">kqueue</span></code> for demultiplexing.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">kqueue</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h7"></a>
<span><a name="asio.overview.implementation.aix"></a></span><a class="link" href="implementation.html#asio.overview.implementation.aix">AIX</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">select</span></code> for demultiplexing.
This means that the number of file descriptors in the process cannot
be permitted to exceed <code class="computeroutput"><span class="identifier">FD_SETSIZE</span></code>.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">select</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h8"></a>
<span><a name="asio.overview.implementation.hp_ux"></a></span><a class="link" href="implementation.html#asio.overview.implementation.hp_ux">HP-UX</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">select</span></code> for demultiplexing.
This means that the number of file descriptors in the process cannot
be permitted to exceed <code class="computeroutput"><span class="identifier">FD_SETSIZE</span></code>.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">select</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h9"></a>
<span><a name="asio.overview.implementation.tru64"></a></span><a class="link" href="implementation.html#asio.overview.implementation.tru64">Tru64</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">select</span></code> for demultiplexing.
This means that the number of file descriptors in the process cannot
be permitted to exceed <code class="computeroutput"><span class="identifier">FD_SETSIZE</span></code>.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">select</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
At most <code class="computeroutput"><span class="identifier">min</span><span class="special">(</span><span class="number">64</span><span class="special">,</span><span class="identifier">IOV_MAX</span><span class="special">)</span></code> buffers may be transferred in a single
operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h10"></a>
<span><a name="asio.overview.implementation.windows_95__98_and_me"></a></span><a class="link" href="implementation.html#asio.overview.implementation.windows_95__98_and_me">Windows
95, 98 and Me</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses <code class="computeroutput"><span class="identifier">select</span></code> for demultiplexing.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using <code class="computeroutput"><span class="identifier">select</span></code>
is performed in one of the threads that calls <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
For sockets, at most 16 buffers may be transferred in a single operation.
</li></ul></div>
<h5>
<a name="asio.overview.implementation.h11"></a>
<span><a name="asio.overview.implementation.windows_nt__2000__xp__2003__vista__7__8__10_and_11"></a></span><a class="link" href="implementation.html#asio.overview.implementation.windows_nt__2000__xp__2003__vista__7__8__10_and_11">Windows
NT, 2000, XP, 2003, Vista, 7, 8, 10 and 11</a>
</h5>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Uses overlapped I/O and I/O completion ports for all asynchronous socket
operations except for asynchronous connect.
</li>
<li class="listitem">
Uses <code class="computeroutput"><span class="identifier">select</span></code> for emulating
asynchronous connect.
</li>
</ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Demultiplexing using I/O completion ports is performed in all threads
that call <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run_one</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">poll_one</span><span class="special">()</span></code>.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to trigger timers. This thread is created on construction of
the first <code class="computeroutput"><span class="identifier">basic_deadline_timer</span></code>
or <code class="computeroutput"><span class="identifier">basic_waitable_timer</span></code>
objects.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
may be used for <code class="computeroutput"><span class="identifier">select</span></code>
demultiplexing. This thread is created on the first call to:
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
A socket <code class="computeroutput"><span class="identifier">async_wait</span><span class="special">()</span></code> function, except when using
<code class="computeroutput"><span class="identifier">wait_read</span></code> on a
stream-oriented socket. (For <code class="computeroutput"><span class="identifier">wait_read</span></code>
on a stream-oriented socket, the overlapped I/O operation <code class="computeroutput"><span class="identifier">WSARecv</span></code> is used and no additional
thread is required.)
</li>
<li class="listitem">
A socket <code class="computeroutput"><span class="identifier">async_connect</span><span class="special">()</span></code> operation, if the overlapped
I/O operation <code class="computeroutput"><span class="identifier">ConnectEx</span></code>
is unavailable. (On recent versions of Windows, <code class="computeroutput"><span class="identifier">ConnectEx</span></code>
is used and no additional thread is required.)
</li>
</ul></div>
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to emulate asynchronous host resolution. This thread is created
on the first call to either <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">async_resolve</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
For sockets, at most 64 buffers may be transferred in a single operation.
</li>
<li class="listitem">
For stream-oriented handles, only one buffer may be transferred in a
single operation.
</li>
</ul></div>
<h5>
<a name="asio.overview.implementation.h12"></a>
<span><a name="asio.overview.implementation.windows_runtime"></a></span><a class="link" href="implementation.html#asio.overview.implementation.windows_runtime">Windows
Runtime</a>
</h5>
<p>
Asio provides limited support for the Windows Runtime. It requires that the
language extensions be enabled. Due to the restricted facilities exposed
by the Windows Runtime API, the support comes with the following caveats:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
The core facilities such as the <code class="computeroutput"><span class="identifier">io_context</span></code>,
<code class="computeroutput"><span class="identifier">strand</span></code>, buffers, composed
operations, timers, etc., should all work as normal.
</li>
<li class="listitem">
For sockets, only client-side TCP is supported.
</li>
<li class="listitem">
Explicit binding of a client-side TCP socket is not supported.
</li>
<li class="listitem">
The <code class="computeroutput"><span class="identifier">cancel</span><span class="special">()</span></code>
function is not supported for sockets. Asynchronous operations may only
be cancelled by closing the socket.
</li>
<li class="listitem">
Operations that use <code class="computeroutput"><span class="identifier">null_buffers</span></code>
are not supported.
</li>
<li class="listitem">
Only <code class="computeroutput"><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">no_delay</span></code> and <code class="computeroutput"><span class="identifier">socket_base</span><span class="special">::</span><span class="identifier">keep_alive</span></code>
options are supported.
</li>
<li class="listitem">
Resolvers do not support service names, only numbers. I.e. you must use
"80" rather than "http".
</li>
<li class="listitem">
Most resolver query flags have no effect.
</li>
</ul></div>
<p>
Demultiplexing mechanism:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Uses the <code class="computeroutput"><span class="identifier">Windows</span><span class="special">::</span><span class="identifier">Networking</span><span class="special">::</span><span class="identifier">Sockets</span><span class="special">::</span><span class="identifier">StreamSocket</span></code> class to implement asynchronous
TCP socket operations.
</li></ul></div>
<p>
Threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Event completions are delivered to the Windows thread pool and posted
to the <code class="computeroutput"><span class="identifier">io_context</span></code> for
the handler to be executed.
</li>
<li class="listitem">
An additional thread per <code class="computeroutput"><span class="identifier">io_context</span></code>
is used to trigger timers. This thread is created on construction of
the first timer objects.
</li>
</ul></div>
<p>
Scatter-Gather:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
For sockets, at most one buffer may be transferred in a single operation.
</li></ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp2011/chrono.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="../using.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,77 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Asynchronous Model</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="basics.html" title="Basic Asio Anatomy">
<link rel="next" href="model/async_ops.html" title="Asynchronous Operations">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="basics.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="model/async_ops.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.model"></a><a class="link" href="model.html" title="Asynchronous Model">Asynchronous Model</a>
</h3></div></div></div>
<p>
This section presents a high-level overview of the asynchronous model at
the core of the Asio library. This model enshrines asynchronous operations
as the fundamental building block of asynchronous composition, but in a way
that decouples them from the composition mechanism. The asynchronous operations
in Asio support callbacks, futures (both eager and lazy), fibers, coroutines,
and approaches yet to be imagined. This allows the application programmer
to select an approach based on appropriate trade-offs.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a class="link" href="model/async_ops.html" title="Asynchronous Operations">Asynchronous Operations</a>
</li>
<li class="listitem">
<a class="link" href="model/async_agents.html" title="Asynchronous Agents">Asynchronous Agents</a>
</li>
<li class="listitem">
<a class="link" href="model/associators.html" title="Associated Characteristics and Associators">Associated Characteristics
and Associators</a>
</li>
<li class="listitem">
<a class="link" href="model/child_agents.html" title="Child Agents">Child Agents</a>
</li>
<li class="listitem">
<a class="link" href="model/executors.html" title="Executors">Executors</a>
</li>
<li class="listitem">
<a class="link" href="model/allocators.html" title="Allocators">Allocators</a>
</li>
<li class="listitem">
<a class="link" href="model/cancellation.html" title="Cancellation">Cancellation</a>
</li>
<li class="listitem">
<a class="link" href="model/completion_tokens.html" title="Completion Tokens">Completion Tokens</a>
</li>
<li class="listitem">
<a class="link" href="model/library_elements.html" title="Supporting Library Elements">Supporting Library
Elements</a>
</li>
<li class="listitem">
<a class="link" href="model/higher_levels.html" title="Higher Level Abstractions">Higher Level Abstractions</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="basics.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="model/async_ops.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,113 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Allocators</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="executors.html" title="Executors">
<link rel="next" href="cancellation.html" title="Cancellation">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="executors.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="cancellation.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.allocators"></a><a class="link" href="allocators.html" title="Allocators">Allocators</a>
</h4></div></div></div>
<p>
Every asynchronous agent has an associated <span class="emphasis"><em>allocator</em></span>.
An agent's allocator is an interface used by the agent's asynchronous operations
to obtain <span class="emphasis"><em>per-operation stable memory</em></span> resources (POSMs).
This name reflects the fact that the memory is per-operation because the
memory is only retained for the lifetime of that operation, and stable,
because the memory is guaranteed to be available at that location throughout
the operation.
</p>
<p>
Asynchronous operations may utilise POSMs in a number of different ways:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
The operation doesn't require any POSMs. For example, the operation
wraps an existing API that performs its own memory management, or is
copying the long lived state into existing memory like a circular buffer.
</li>
<li class="listitem">
The operation uses a single, fixed-size POSM for as long as the operation
is outstanding. For example, the operation stores some state in a linked
list.
</li>
<li class="listitem">
The operation uses a single, runtime-sized POSM. For example, the operation
stores a copy of a user-supplied buffer, or a runtime-sized array of
iovec structures.
</li>
<li class="listitem">
The operation uses multiple POSMs concurrently. For example, a fixed
size POSM for a linked list plus a runtime-sized POSM for a buffer.
</li>
<li class="listitem">
The operation uses multiple POSMs serially, which may vary in size.
</li>
</ul></div>
<p>
Associated allocators allow users to treat POSM optimisation as a cross-cutting
concern to the composition of asynchronous operations. Furthermore, using
allocators as the interface to obtain POSMs grant substantial flexibility
to both the implementers and users of asynchronous operations:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Users can ignore the allocator and accept whatever default strategy
is employed by the application.
</li>
<li class="listitem">
Implementers can ignore the allocator, especially if the operation
is not considered performance-sensitive.
</li>
<li class="listitem">
Users can co-locate POSMs for related asynchronous operations, for
better locality of reference.
</li>
<li class="listitem">
For compositions that involve serial POSMs of different sizes, memory
usage need only be as great as the currently extant POSM. For example,
consider a composition that contains a short-lived operation that uses
large POSMs (connection establishment and handshake) followed by a
long-lived operation that uses small POSMs (transferring data to and
from the peer).
</li>
</ul></div>
<p>
As noted previously, all resources must be released prior to calling the
completion handler. This enables memory to be recycled for subsequent asynchronous
operations within an agent. This allows applications with long-lived asynchronous
agents to have no hot-path memory allocations, even though the user code
is unaware of associated allocators.
</p>
<h6>
<a name="asio.overview.model.allocators.h0"></a>
<span><a name="asio.overview.model.allocators.see_also"></a></span><a class="link" href="allocators.html#asio.overview.model.allocators.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../core/allocation.html" title="Custom Memory Allocation">Custom Memory Allocation</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="executors.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="cancellation.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,150 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Associated Characteristics and Associators</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="async_agents.html" title="Asynchronous Agents">
<link rel="next" href="child_agents.html" title="Child Agents">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="async_agents.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="child_agents.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.associators"></a><a class="link" href="associators.html" title="Associated Characteristics and Associators">Associated Characteristics
and Associators</a>
</h4></div></div></div>
<p>
An asynchronous agent has <span class="emphasis"><em>associated characteristics</em></span>
that specify how asynchronous operations should behave when composed as
part of that agent, such as:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
An allocator, which determines how the agent's asynchronous operations
obtain memory resources.
</li>
<li class="listitem">
A cancellation slot, which determines how the agent's asynchronous
operations support cancellation.
</li>
<li class="listitem">
An executor, which determines how the agent's completion handlers will
be queued and run.
</li>
</ul></div>
<p>
When an asynchronous operation is run within an asynchronous agent, its
implementation may query these associated characteristics and use them
to satisfy the requirements or preferences they represent. The asynchronous
operation performs these queries by applying <span class="emphasis"><em>associator</em></span>
traits to the completion handler. Each characteristic has a corresponding
associator trait.
</p>
<p>
An associator trait may be specialised for concrete completion handler
types to:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
accept the default characteristic supplied by the asynchronous operation,
returning this default as-is
</li>
<li class="listitem">
return an unrelated implementation of the characteristic, or
</li>
<li class="listitem">
adapt the supplied default to introduce additional behaviour required
by the completion handler.
</li>
</ul></div>
<h6>
<a name="asio.overview.model.associators.h0"></a>
<span><a name="asio.overview.model.associators.specification_of_an_associator"></a></span><a class="link" href="associators.html#asio.overview.model.associators.specification_of_an_associator">Specification
of an Associator</a>
</h6>
<p>
Given an associator trait named<sup>[<a name="asio.overview.model.associators.f0" href="#ftn.asio.overview.model.associators.f0" class="footnote">2</a>]</sup> <code class="computeroutput"><span class="identifier">associated_R</span></code>,
having:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
a source value <code class="computeroutput"><span class="identifier">s</span></code> of
type <code class="computeroutput"><span class="identifier">S</span></code>, in this case
the completion handler and its type,
</li>
<li class="listitem">
a set of type requirements (or a concept) <code class="computeroutput"><span class="identifier">R</span></code>
that define the syntactic and semantic requirements of the associated
characteristic, and
</li>
<li class="listitem">
a candidate value <code class="computeroutput"><span class="identifier">c</span></code>
of type <code class="computeroutput"><span class="identifier">C</span></code> that meets
the type requirements <code class="computeroutput"><span class="identifier">R</span></code>,
which represents a default implementation of the associated characteristic,
supplied by the asynchronous operation
</li>
</ul></div>
<p>
the asynchronous operation uses the associator trait to compute:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
the type <code class="computeroutput"><span class="identifier">associated_R</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">type</span></code>,
and
</li>
<li class="listitem">
the value <code class="computeroutput"><span class="identifier">associated_R</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">c</span><span class="special">)</span></code>
</li>
</ul></div>
<p>
that meet the requirements defined in <code class="computeroutput"><span class="identifier">R</span></code>.
For convenience, these are also accessible via type alias <code class="computeroutput"><span class="identifier">associated_R_t</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;</span></code> and free function <code class="computeroutput"><span class="identifier">get_associated_R</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span>
<span class="identifier">c</span><span class="special">)</span></code>,
respectively.
</p>
<p>
The trait's primary template is specified such that:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
if <code class="computeroutput"><span class="identifier">S</span><span class="special">::</span><span class="identifier">R_type</span></code> is well-formed, defines a
nested type alias type as <code class="computeroutput"><span class="identifier">S</span><span class="special">::</span><span class="identifier">R_type</span></code>,
and a static member function get that returns <code class="computeroutput"><span class="identifier">s</span><span class="special">.</span><span class="identifier">get_R</span><span class="special">()</span></code>
</li>
<li class="listitem">
otherwise, if <code class="computeroutput"><span class="identifier">associator</span><span class="special">&lt;</span><span class="identifier">associated_R</span><span class="special">,</span> <span class="identifier">S</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">type</span></code>
is well-formed and denotes a type, inherits from <code class="computeroutput"><span class="identifier">associator</span><span class="special">&lt;</span><span class="identifier">associated_R</span><span class="special">,</span> <span class="identifier">S</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;</span></code>
</li>
<li class="listitem">
otherwise, defines a nested type alias type as <code class="computeroutput"><span class="identifier">C</span></code>,
and a static member function get that returns <code class="computeroutput"><span class="identifier">c</span></code>.
</li>
</ul></div>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.asio.overview.model.associators.f0" href="#asio.overview.model.associators.f0" class="para">2</a>] </sup>
The associator traits are named <a class="link" href="../../reference/associated_allocator.html" title="associated_allocator"><code class="computeroutput"><span class="identifier">associated_allocator</span></code></a>, <a class="link" href="../../reference/associated_executor.html" title="associated_executor"><code class="computeroutput"><span class="identifier">associated_executor</span></code></a>,
and <a class="link" href="../../reference/associated_cancellation_slot.html" title="associated_cancellation_slot"><code class="computeroutput"><span class="identifier">associated_cancellation_slot</span></code></a>.
</p></div>
</div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="async_agents.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="child_agents.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,69 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Asynchronous Agents</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="async_ops.html" title="Asynchronous Operations">
<link rel="next" href="associators.html" title="Associated Characteristics and Associators">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="async_ops.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="associators.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.async_agents"></a><a class="link" href="async_agents.html" title="Asynchronous Agents">Asynchronous Agents</a>
</h4></div></div></div>
<p>
<span class="inlinemediaobject"><img src="../../../async_agent_model.png" width="931"></span>
</p>
<p>
An <span class="emphasis"><em>asynchronous agent</em></span> is a sequential composition
of asynchronous operations. Every asynchronous operation is considered
to run as a part of an asynchronous agent, even if that agent contains
only that single operation. An asynchronous agent is an entity that may
perform work concurrently with other agents. Asynchronous agents are to
asynchronous operations as threads are to synchronous operations.
</p>
<p>
However, an asynchronous agent is a purely notional construct that allows
us to reason about the context for, and composition of, asynchronous operations
in a program. The name “asynchronous agent” does not appear in the
library, nor is it important which concrete mechanism<sup>[<a name="asio.overview.model.async_agents.f0" href="#ftn.asio.overview.model.async_agents.f0" class="footnote">1</a>]</sup> is used to compose the asynchronous operations in an agent.
</p>
<p>
We can visualise an asynchronous agent as follows:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../async_agent_chain.png" width="738"></span>
</p>
<p>
Asynchronous agents alternately wait for an asynchronous operation to complete,
and then run a completion handler for that operation. Within the context
of an agent, these completion handlers represent indivisible units of schedulable
work.
</p>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.asio.overview.model.async_agents.f0" href="#asio.overview.model.async_agents.f0" class="para">1</a>] </sup>
Such as chains of lambdas, coroutines, fibers, state machines, etc.
</p></div>
</div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="async_ops.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="associators.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,139 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Asynchronous Operations</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="../model.html" title="Asynchronous Model">
<link rel="next" href="async_agents.html" title="Asynchronous Agents">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../model.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="async_agents.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.async_ops"></a><a class="link" href="async_ops.html" title="Asynchronous Operations">Asynchronous Operations</a>
</h4></div></div></div>
<p>
<span class="inlinemediaobject"><img src="../../../async_op_model.png" width="421"></span>
</p>
<p>
An <span class="emphasis"><em>asynchronous operation</em></span> is the basic unit of composition
in the Asio asynchronous model. Asynchronous operations represent work
that is launched and performed in the background, while the user's code
that initiated the work can continue with other things.
</p>
<p>
Conceptually, the lifecycle of an asynchronous operation can be described
in terms of the following events and phases:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../async_op_phases.png" width="861"></span>
</p>
<p>
An <span class="emphasis"><em>initiating function</em></span> is a function which may be
called by the user to start an asynchronous operation.
</p>
<p>
A <span class="emphasis"><em>completion handler</em></span> is a user-provided, move-only
function object that will be invoked, at most once, with the result of
the asynchronous operation. The invocation of the completion handler tells
the user about something that has already happened: the operation completed,
and the side effects of the operation were established.
</p>
<p>
The initiating function and completion handler are incorporated into the
user's code as follows:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../async_op_init_complete.png" width="496"></span>
</p>
<p>
Synchronous operations, being embodied as single functions, have several
inherent semantic properties as a consequence. Asynchronous operations
adopt some of these semantic properties from their synchronous counterparts,
in order to facilitate flexible and efficient composition.
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Property of synchronous operations
</p>
</th>
<th>
<p>
Equivalent property of asynchronous operations
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
When a synchronous operation is generic (i.e. a template) the
return type is deterministically derived from the function and
its arguments.
</p>
</td>
<td>
<p>
When an asynchronous operation is generic, the completion handler's
arguments' types and order are deterministically derived from
the initiating function and its arguments.
</p>
</td>
</tr>
<tr>
<td>
<p>
If a synchronous operation requires a temporary resource (such
as memory, a file descriptor, or a thread), this resource is
released before returning from the function.
</p>
</td>
<td>
<p>
If an asynchronous operation requires a temporary resource (such
as memory, a file descriptor, or a thread), this resource is
released before calling the completion handler.
</p>
</td>
</tr>
</tbody>
</table></div>
<p>
The latter is an important property of asynchronous operations, in that
it allows a completion handler to initiate further asynchronous operations
without overlapping resource usage. Consider the trivial (and relatively
common) case of the same operation being repeated over and over in a chain:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../async_op_trivial_chain.png" width="375"></span>
</p>
<p>
By ensuring that resources are released before the completion handler runs,
we avoid doubling the peak resource usage of the chain of operations.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../model.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="async_agents.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,64 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Cancellation</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="allocators.html" title="Allocators">
<link rel="next" href="completion_tokens.html" title="Completion Tokens">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="allocators.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="completion_tokens.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.cancellation"></a><a class="link" href="cancellation.html" title="Cancellation">Cancellation</a>
</h4></div></div></div>
<p>
In Asio, many objects, such as sockets and timers, support object-wide
cancellation of outstanding asynchronous operations via their close or
cancel member functions. However, certain asynchronous operations also
support individual, targeted cancellation. This per-operation cancellation
is enabled by specifying that every asynchronous agent has an associated
<span class="emphasis"><em>cancellation slot</em></span>.
</p>
<p>
To support cancellation, an asynchronous operation installs a cancellation
handler into the agent's slot. The cancellation handler is a function object
that will be invoked when a cancellation signal is emitted by the user
into the slot. Since a cancellation slot is associated with a single agent,
the slot holds at most one handler at a time, and installing a new handler
will overwrite any previously installed handler. Thus, the same slot is
reused for subsequent asynchronous operations within the agent.
</p>
<p>
Cancellation is particularly useful when an asynchronous operation contains
multiple child agents. For example, one child agent may be complete and
the other is then cancelled, as its side effects are no longer required.
</p>
<h6>
<a name="asio.overview.model.cancellation.h0"></a>
<span><a name="asio.overview.model.cancellation.see_also"></a></span><a class="link" href="cancellation.html#asio.overview.model.cancellation.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../core/cancellation.html" title="Per-Operation Cancellation">Per-Operation Cancellation</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="allocators.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="completion_tokens.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,108 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Child Agents</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="associators.html" title="Associated Characteristics and Associators">
<link rel="next" href="executors.html" title="Executors">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="associators.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="executors.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.child_agents"></a><a class="link" href="child_agents.html" title="Child Agents">Child Agents</a>
</h4></div></div></div>
<p>
The asynchronous operations within an agent may themselves be implemented
in terms of child agents.<sup>[<a name="asio.overview.model.child_agents.f0" href="#ftn.asio.overview.model.child_agents.f0" class="footnote">3</a>]</sup> As far as the parent agent is concerned, it is waiting for
the completion of a single asynchronous operation. The asynchronous operations
that constitute the child agent run in sequence, and when the final completion
handler runs the parent agent is resumed.
</p>
<p>
<span class="inlinemediaobject"><img src="../../../async_child_agent_chain.png" width="802"></span>
</p>
<p>
As with individual asynchronous operations, the asynchronous operations
built on child agents must release their temporary resources prior to calling
the completion handler. We may also think of these child agents as resources
that end their lifetimes before the completion handler is invoked.
</p>
<p>
When an asynchronous operation creates a child agent, it may propagate<sup>[<a name="asio.overview.model.child_agents.f1" href="#ftn.asio.overview.model.child_agents.f1" class="footnote">4</a>]</sup> the associated characteristics of the parent agent to the child
agent. These associated characteristics may then be recursively propagated
through further layers of asynchronous operations and child agents. This
stacking of asynchronous operations replicates another property of synchronous
operations.
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Property of synchronous operations
</p>
</th>
<th>
<p>
Equivalent property of asynchronous operations
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<p>
Compositions of synchronous operations may be refactored to use
child functions that run on the same thread (i.e. are simply
called) without altering functionality.
</p>
</td>
<td>
<p>
Asynchronous agents may be refactored to use asynchronous operations
and child agents that share the associated characteristics of
the parent agent, without altering functionality.
</p>
</td>
</tr></tbody>
</table></div>
<p>
Finally, some asynchronous operations may be implemented in terms of multiple
child agents that run concurrently. In this case, the asynchronous operation
may choose to selectively propagate the associated characteristics of the
parent agent.
</p>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.asio.overview.model.child_agents.f0" href="#asio.overview.model.child_agents.f0" class="para">3</a>] </sup>
In Asio these asynchronous operations are referred to as <span class="emphasis"><em>composed
operations</em></span>.
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.asio.overview.model.child_agents.f1" href="#asio.overview.model.child_agents.f1" class="para">4</a>] </sup>
Typically, by specialising the associator trait and forwarding to the
outer completion handler.
</p></div>
</div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="associators.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="executors.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,325 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Completion Tokens</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="cancellation.html" title="Cancellation">
<link rel="next" href="library_elements.html" title="Supporting Library Elements">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cancellation.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="library_elements.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.completion_tokens"></a><a class="link" href="completion_tokens.html" title="Completion Tokens">Completion Tokens</a>
</h4></div></div></div>
<p>
<span class="inlinemediaobject"><img src="../../../completion_token_model.png" width="436"></span>
</p>
<p>
A key goal of Asio's asynchronous model is to support multiple composition
mechanisms. This is achieved via a <span class="emphasis"><em>completion token</em></span>,
which the user passes to an asynchronous operation's initiating function
to customise the API surface of the library. By convention, the completion
token is the final argument to an asynchronous operation's initiating function.
</p>
<p>
For example, if the user passes a lambda (or other function object) as
the completion token, the asynchronous operation behaves as previously
described: the operation begins, and when the operation completes the result
is passed to the lambda.
</p>
<pre class="programlisting"><span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">}</span>
<span class="special">);</span>
</pre>
<p>
When the user passes the <a class="link" href="../../reference/use_future.html" title="use_future">use_future</a>
completion token, the operation behaves as though implemented in terms
of a <code class="computeroutput"><span class="identifier">promise</span></code> and <code class="computeroutput"><span class="identifier">future</span></code> pair. The initiating function
does not just launch the operation, but also returns a future that may
be used to await the result.
</p>
<pre class="programlisting"><span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">f</span> <span class="special">=</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">use_future</span>
<span class="special">);</span>
<span class="comment">// ...</span>
<span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
</pre>
<p>
Similarly, when the user passes the <a class="link" href="../../reference/use_awaitable.html" title="use_awaitable">use_awaitable</a>
completion token, the initiating function behaves as though it is an <code class="computeroutput"><span class="identifier">awaitable</span></code>-based coroutine <sup>[<a name="asio.overview.model.completion_tokens.f0" href="#ftn.asio.overview.model.completion_tokens.f0" class="footnote">6</a>]</sup>. However, in this case the initiating function does not launch
the asynchronous operation directly. It only returns the <code class="computeroutput"><span class="identifier">awaitable</span></code>, which in turn launches the
operation when it is co_await-ed.
</p>
<pre class="programlisting"><span class="identifier">awaitable</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">use_awaitable</span>
<span class="special">);</span>
<span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<p>
Finally, the <a class="link" href="../../reference/yield_context.html" title="yield_context">yield_context</a>
completion token causes the initiating function to behave as a synchronous
operation within the context of a stackful coroutine. It not only begins
the asynchronous operation, but blocks the stackful coroutine until it
is complete. From the point of the stackful coroutine, it is a synchronous
operation.
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">yield_context</span> <span class="identifier">yield</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">yield</span><span class="special">);</span>
<span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<p>
All of these uses are supported by a single implementation of the <code class="computeroutput"><span class="identifier">async_read_some</span></code> initiating function.
</p>
<p>
To achieve this, an asynchronous operation must first specify a <span class="emphasis"><em>completion
signature</em></span> (or, possibly, signatures) that describes the arguments
that will be passed to its completion handler.
</p>
<p>
Then, the operation's initiating function takes the completion signature,
completion token, and its internal implementation and passes them to the
<span class="emphasis"><em>async_result</em></span> trait. The <code class="computeroutput"><span class="identifier">async_result</span></code>
trait is a customisation point that combines these to first produce a concrete
completion handler, and then launch the operation.
</p>
<p>
<span class="inlinemediaobject"><img src="../../../completion_token_transform.png" width="856"></span>
</p>
<p>
To see this in practice, let's use a detached thread to adapt a synchronous
operation into an asynchronous one:<sup>[<a name="asio.overview.model.completion_tokens.f1" href="#ftn.asio.overview.model.completion_tokens.f1" class="footnote">7</a>]</sup>
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span>
<span class="identifier">completion_token_for</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">)&gt;</span> <a class="co" name="asio.overview.model.completion_tokens.c0" href="completion_tokens.html#asio.overview.model.completion_tokens.c1"><img src="../../../1.png" alt="1" border="0"></a>
<span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">s</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">mutable_buffer</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">,</span>
<span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="identifier">init</span> <span class="special">=</span> <span class="special">[](</span> <a class="co" name="asio.overview.model.completion_tokens.c2" href="completion_tokens.html#asio.overview.model.completion_tokens.c3"><img src="../../../2.png" alt="2" border="0"></a>
<span class="keyword">auto</span> <span class="identifier">completion_handler</span><span class="special">,</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">mutable_buffer</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span> <a class="co" name="asio.overview.model.completion_tokens.c4" href="completion_tokens.html#asio.overview.model.completion_tokens.c5"><img src="../../../3.png" alt="3" border="0"></a>
<span class="special">[](</span>
<span class="keyword">auto</span> <span class="identifier">completion_handler</span><span class="special">,</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">mutable_buffer</span><span class="special">&amp;</span> <span class="identifier">b</span>
<span class="special">)</span>
<span class="special">{</span>
<span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">;</span>
<span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">s</span><span class="special">-&gt;</span><span class="identifier">read_some</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">completion_handler</span><span class="special">)(</span><span class="identifier">ec</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span> <a class="co" name="asio.overview.model.completion_tokens.c6" href="completion_tokens.html#asio.overview.model.completion_tokens.c7"><img src="../../../4.png" alt="4" border="0"></a>
<span class="special">},</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">completion_handler</span><span class="special">),</span>
<span class="identifier">s</span><span class="special">,</span>
<span class="identifier">b</span>
<span class="special">).</span><span class="identifier">detach</span><span class="special">();</span>
<span class="special">};</span>
<span class="keyword">return</span> <span class="identifier">async_result</span><span class="special">&lt;</span> <a class="co" name="asio.overview.model.completion_tokens.c8" href="completion_tokens.html#asio.overview.model.completion_tokens.c9"><img src="../../../5.png" alt="5" border="0"></a>
<span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span>
<span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">)</span>
<span class="special">&gt;::</span><span class="identifier">initiate</span><span class="special">(</span>
<span class="identifier">init</span><span class="special">,</span> <a class="co" name="asio.overview.model.completion_tokens.c10" href="completion_tokens.html#asio.overview.model.completion_tokens.c11"><img src="../../../6.png" alt="6" border="0"></a>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">),</span> <a class="co" name="asio.overview.model.completion_tokens.c12" href="completion_tokens.html#asio.overview.model.completion_tokens.c13"><img src="../../../7.png" alt="7" border="0"></a>
<span class="special">&amp;</span><span class="identifier">s</span><span class="special">,</span> <a class="co" name="asio.overview.model.completion_tokens.c14" href="completion_tokens.html#asio.overview.model.completion_tokens.c15"><img src="../../../8.png" alt="8" border="0"></a>
<span class="identifier">b</span>
<span class="special">);</span>
<span class="special">}</span>
</pre>
<div class="calloutlist"><table border="0" summary="Callout list">
<tr>
<td width="5%" valign="top" align="left"><p><a name="asio.overview.model.completion_tokens.c1"></a><a href="#asio.overview.model.completion_tokens.c0"><img src="../../../1.png" alt="1" border="0"></a> </p></td>
<td valign="top" align="left"><p>
The <code class="computeroutput"><span class="identifier">completion_token_for</span></code>
concept checks whether the user-supplied completion token will satisfy
the specified completion signature. For older versions of C++, simply
use <code class="computeroutput"><span class="keyword">typename</span></code> here instead.
</p></td>
</tr>
<tr>
<td width="5%" valign="top" align="left"><p><a name="asio.overview.model.completion_tokens.c3"></a><a href="#asio.overview.model.completion_tokens.c2"><img src="../../../2.png" alt="2" border="0"></a> </p></td>
<td valign="top" align="left"><p>
Define a function object that contains the code to launch the asynchronous
operation. This is passed the concrete completion handler, followed
by any additional arguments that were passed through the <code class="computeroutput"><span class="identifier">async_result</span></code> trait.
</p></td>
</tr>
<tr>
<td width="5%" valign="top" align="left"><p><a name="asio.overview.model.completion_tokens.c5"></a><a href="#asio.overview.model.completion_tokens.c4"><img src="../../../3.png" alt="3" border="0"></a> </p></td>
<td valign="top" align="left"><p>
The body of the function object spawns a new thread to perform the
operation.
</p></td>
</tr>
<tr>
<td width="5%" valign="top" align="left"><p><a name="asio.overview.model.completion_tokens.c7"></a><a href="#asio.overview.model.completion_tokens.c6"><img src="../../../4.png" alt="4" border="0"></a> </p></td>
<td valign="top" align="left"><p>
Once the operation completes, the completion handler is passed the
result.
</p></td>
</tr>
<tr>
<td width="5%" valign="top" align="left"><p><a name="asio.overview.model.completion_tokens.c9"></a><a href="#asio.overview.model.completion_tokens.c8"><img src="../../../5.png" alt="5" border="0"></a> </p></td>
<td valign="top" align="left"><p>
The <code class="computeroutput"><span class="identifier">async_result</span></code> trait
is passed the (decayed) completion token type, and the completion signatures
of the asynchronous operation.
</p></td>
</tr>
<tr>
<td width="5%" valign="top" align="left"><p><a name="asio.overview.model.completion_tokens.c11"></a><a href="#asio.overview.model.completion_tokens.c10"><img src="../../../6.png" alt="6" border="0"></a> </p></td>
<td valign="top" align="left"><p>
Call the traits <code class="computeroutput"><span class="identifier">initiate</span></code>
member function, first passing the function object that launches the
operation.
</p></td>
</tr>
<tr>
<td width="5%" valign="top" align="left"><p><a name="asio.overview.model.completion_tokens.c13"></a><a href="#asio.overview.model.completion_tokens.c12"><img src="../../../7.png" alt="7" border="0"></a> </p></td>
<td valign="top" align="left"><p>
Next comes the forwarded completion token. The trait implementation
will convert this into a concrete completion handler.
</p></td>
</tr>
<tr>
<td width="5%" valign="top" align="left"><p><a name="asio.overview.model.completion_tokens.c15"></a><a href="#asio.overview.model.completion_tokens.c14"><img src="../../../8.png" alt="8" border="0"></a> </p></td>
<td valign="top" align="left"><p>
Finally, pass any additional arguments for the function object. Assume
that these may be decay-copied and moved by the trait implementation.
</p></td>
</tr>
</table></div>
<p>
In practice we should call the <a class="link" href="../../reference/async_initiate.html" title="async_initiate">async_initiate</a>
helper function, rather than use the <code class="computeroutput"><span class="identifier">async_result</span></code>
trait directly. The <code class="computeroutput"><span class="identifier">async_initiate</span></code>
function automatically performs the necessary decay and forward of the
completion token, and also enables backwards compatibility with legacy
completion token implementations.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span>
<span class="identifier">completion_token_for</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">)&gt;</span>
<span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_read_some</span><span class="special">(</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">s</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">mutable_buffer</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">,</span>
<span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="identifier">init</span> <span class="special">=</span> <span class="comment">/* ... as above ... */</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">async_initiate</span><span class="special">&lt;</span>
<span class="identifier">CompletionToken</span><span class="special">,</span>
<span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">)</span>
<span class="special">&gt;(</span><span class="identifier">init</span><span class="special">,</span> <span class="identifier">token</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
We can think of the completion token as a kind of proto completion handler.
In the case where we pass a function object (like a lambda) as the completion
token, it already satisfies the completion handler requirements. The async_result
primary template handles this case by trivially forwarding the arguments
through:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">,</span> <span class="identifier">completion_signature</span><span class="special">...</span> <span class="identifier">Signatures</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">async_result</span>
<span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span>
<span class="keyword">class</span> <span class="identifier">Initiation</span><span class="special">,</span>
<span class="identifier">completion_handler_for</span><span class="special">&lt;</span><span class="identifier">Signatures</span><span class="special">...&gt;</span> <span class="identifier">CompletionHandler</span><span class="special">,</span>
<span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
<span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">initiate</span><span class="special">(</span>
<span class="identifier">Initiation</span><span class="special">&amp;&amp;</span> <span class="identifier">initiation</span><span class="special">,</span>
<span class="identifier">CompletionHandler</span><span class="special">&amp;&amp;</span> <span class="identifier">completion_handler</span><span class="special">,</span>
<span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Initiation</span><span class="special">&gt;(</span><span class="identifier">initiation</span><span class="special">)(</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionHandler</span><span class="special">&gt;(</span><span class="identifier">completion_handler</span><span class="special">),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Args</span><span class="special">&gt;(</span><span class="identifier">args</span><span class="special">)...);</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
We can see here that this default implementation avoids copies of all arguments,
thus ensuring that eager initiation is as efficient as possible.
</p>
<p>
On the other hand, a lazy completion token (such as <code class="computeroutput"><span class="identifier">use_awaitable</span></code>
above) may capture these arguments for deferred launching of the operation.
For example, a specialisation for a trivial <a class="link" href="../../reference/deferred.html" title="deferred">deferred</a>
token (that simply packages the operation for later) might look something
like this:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">completion_signature</span><span class="special">...</span> <span class="identifier">Signatures</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">deferred_t</span><span class="special">,</span> <span class="identifier">Signatures</span><span class="special">...&gt;</span>
<span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Initiation</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
<span class="keyword">static</span> <span class="keyword">auto</span> <span class="identifier">initiate</span><span class="special">(</span><span class="identifier">Initiation</span> <span class="identifier">initiation</span><span class="special">,</span> <span class="identifier">deferred_t</span><span class="special">,</span> <span class="identifier">Args</span><span class="special">...</span> <span class="identifier">args</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="special">[</span>
<span class="identifier">initiation</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">initiation</span><span class="special">),</span>
<span class="identifier">arg_pack</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">args</span><span class="special">)...)</span>
<span class="special">](</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span> <span class="keyword">mutable</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">apply</span><span class="special">(</span>
<span class="special">[&amp;](</span><span class="keyword">auto</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">token</span><span class="special">)&gt;,</span> <span class="identifier">Signatures</span><span class="special">...&gt;::</span><span class="identifier">initiate</span><span class="special">(</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">initiation</span><span class="special">),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">token</span><span class="special">)&gt;(</span><span class="identifier">token</span><span class="special">),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">args</span><span class="special">)&gt;(</span><span class="identifier">args</span><span class="special">)...</span>
<span class="special">);</span>
<span class="special">},</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">arg_pack</span><span class="special">)</span>
<span class="special">);</span>
<span class="special">};</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.asio.overview.model.completion_tokens.f0" href="#asio.overview.model.completion_tokens.f0" class="para">6</a>] </sup>
The <a class="link" href="../../reference/awaitable.html" title="awaitable">awaitable</a> class template
is included with the Asio library as a return type for C++20 coroutines.
These coroutines can be trivially implemented in terms of other <code class="computeroutput"><span class="identifier">awaitable</span></code>-based coroutines.
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.asio.overview.model.completion_tokens.f1" href="#asio.overview.model.completion_tokens.f1" class="para">7</a>] </sup>
For illustrative purposes only. Not recommended for real world use!
</p></div>
</div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cancellation.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="library_elements.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,104 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Executors</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="child_agents.html" title="Child Agents">
<link rel="next" href="allocators.html" title="Allocators">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="child_agents.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="allocators.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.executors"></a><a class="link" href="executors.html" title="Executors">Executors</a>
</h4></div></div></div>
<p>
Every asynchronous agent has an associated <span class="emphasis"><em>executor</em></span>.
An agent's executor determines how the agent's completion handlers are
queued and ultimately run.
</p>
<p>
Example uses of executors include:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Coordinating a group of asynchronous agents that operate on shared
data structures, ensuring that the agents' completion handlers never
run concurrently<sup>[<a name="asio.overview.model.executors.f0" href="#ftn.asio.overview.model.executors.f0" class="footnote">5</a>]</sup>.
</li>
<li class="listitem">
Ensuring that agents are run on specified execution resource (e.g.
a CPU) that is proximal to data or an event source (e.g. a NIC).
</li>
<li class="listitem">
Denoting a group of related agents, and so enabling dynamic thread
pools to make smarter scheduling decisions (such as moving the agents
between execution resources as a unit).
</li>
<li class="listitem">
Queuing all completion handlers to run on a GUI application thread,
so that they may safely update user interface elements.
</li>
<li class="listitem">
Returning an asynchronous operation's default executor as-is, to run
completion handlers as close as possible to the event that triggered
the operation's completion.
</li>
<li class="listitem">
Adapting an asynchronous operation's default executor, to run code
before and after every completion handler, such as logging, user authorisation,
or exception handling.
</li>
<li class="listitem">
Specifying a priority for an asynchronous agent and its completion
handlers.
</li>
</ul></div>
<p>
The asynchronous operations within an asynchronous agent use the agent's
associated executor to:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Track the existence of the work that the asynchronous operation represents,
while the operation is outstanding.
</li>
<li class="listitem">
Enqueue the completion handler for execution on completion of an operation.
</li>
<li class="listitem">
Ensure that completion handlers do not run re-entrantly, if doing so
might lead to inadvertent recursion and stack overflow.
</li>
</ul></div>
<p>
Thus, an asynchronous agent's associated executor represents a policy of
how, where, and when the agent should run, specified as a cross-cutting
concern to the code that makes up the agent.
</p>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.asio.overview.model.executors.f0" href="#asio.overview.model.executors.f0" class="para">5</a>] </sup>
In Asio, this kind of executor is called a <a class="link" href="../core/strands.html" title="Strands: Use Threads Without Explicit Locking">strand</a>.
</p></div>
</div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="child_agents.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="allocators.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,71 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Higher Level Abstractions</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="library_elements.html" title="Supporting Library Elements">
<link rel="next" href="../core.html" title="Core Concepts and Functionality">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="library_elements.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../core.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.higher_levels"></a><a class="link" href="higher_levels.html" title="Higher Level Abstractions">Higher Level Abstractions</a>
</h4></div></div></div>
<p>
<span class="inlinemediaobject"><img src="../../../higher_level_model.png" width="940"></span>
</p>
<p>
The asynchronous model presented in this section provides a basis for defining
higher level abstractions. Asio builds on this core model to provide additional
facilities, such as:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
I/O objects such as <a class="link" href="../networking.html" title="Networking">sockets</a>
and <a class="link" href="../timers.html" title="Timers">timers</a> that expose
asynchronous operations on top of this model.
</li>
<li class="listitem">
Concrete executors, such as the <a class="link" href="../../reference/io_context.html" title="io_context">io_context</a>
executor, <a class="link" href="../../reference/thread_pool.html" title="thread_pool">thread_pool</a>
executor, and the <a class="link" href="../../reference/strand.html" title="strand">strand</a>
adapter which guarantees non-concurrent execution of completion handlers.
</li>
<li class="listitem">
Completion tokens that facilitate different composition mechanisms,
such as <a class="link" href="../composition/cpp20_coroutines.html" title="C++20 Coroutines Support">C++
coroutines</a>, <a class="link" href="../composition/spawn.html" title="Stackful Coroutines">stackful
coroutines</a>, <a class="link" href="../composition/futures.html" title="Futures">futures</a>,
and <a class="link" href="../../reference/deferred.html" title="deferred">deferred operations</a>.
</li>
<li class="listitem">
High level support for C++ coroutines that combines support executors
and cancellation slots to allow for <a class="link" href="../composition/cpp20_coroutines.html#asio.overview.composition.cpp20_coroutines.co_ordinating_parallel_coroutines">easy
coordination of concurrent asynchronous agents</a>.
</li>
</ul></div>
<p>
To allow users to more easily write their own asynchronous operations that
adhere to this model, Asio also provides the helper function <a class="link" href="../../reference/async_compose.html" title="async_compose">async_compose</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="library_elements.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../core.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,185 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Supporting Library Elements</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../model.html" title="Asynchronous Model">
<link rel="prev" href="completion_tokens.html" title="Completion Tokens">
<link rel="next" href="higher_levels.html" title="Higher Level Abstractions">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="completion_tokens.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="higher_levels.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.model.library_elements"></a><a class="link" href="library_elements.html" title="Supporting Library Elements">Supporting Library
Elements</a>
</h4></div></div></div>
<p>
The Asio asynchronous model is enabled by the library elements listed in
the table below.
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Library Element
</p>
</th>
<th>
<p>
Description
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">completion_signature</span></code>
concept
</p>
</td>
<td>
<p>
Defines valid completion signature forms.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">completion_handler_for</span></code>
concept
</p>
</td>
<td>
<p>
Determines whether a completion handler is callable with a given
set of completion signatures.
</p>
</td>
</tr>
<tr>
<td>
<p>
<a class="link" href="../../reference/async_result.html" title="async_result">async_result</a>
trait
</p>
</td>
<td>
<p>
Converts a completion signature and completion token into a concrete
completion handler, and launches the operation.
</p>
</td>
</tr>
<tr>
<td>
<p>
<a class="link" href="../../reference/async_initiate.html" title="async_initiate">async_initiate</a>
function
</p>
</td>
<td>
<p>
Helper function to simplify use of the <code class="computeroutput"><span class="identifier">async_result</span></code>
trait.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">completion_token_for</span></code>
concept
</p>
</td>
<td>
<p>
Determines whether a completion token produces a completion handler
for a given set of completion signatures.
</p>
</td>
</tr>
<tr>
<td>
<p>
<a class="link" href="../../reference/associator.html" title="associator">associator</a> trait
</p>
</td>
<td>
<p>
Automatically propagates all associators through layers of abstraction.
</p>
</td>
</tr>
<tr>
<td>
<p>
<a class="link" href="../../reference/associated_executor.html" title="associated_executor">associated_executor</a>
trait, <code class="computeroutput"><span class="identifier">associated_executor_t</span></code>
type alias, and <a class="link" href="../../reference/get_associated_executor.html" title="get_associated_executor">get_associated_executor</a>
function
</p>
</td>
<td>
<p>
Defines an asynchronous agents associated executor.
</p>
</td>
</tr>
<tr>
<td>
<p>
<a class="link" href="../../reference/associated_allocator.html" title="associated_allocator">associated_allocator</a>
trait, <code class="computeroutput"><span class="identifier">associated_allocator_t</span></code>
type alias, and <a class="link" href="../../reference/get_associated_allocator.html" title="get_associated_allocator">get_associated_allocator</a>
function
</p>
</td>
<td>
<p>
Defines an asynchronous agents associated allocator.
</p>
</td>
</tr>
<tr>
<td>
<p>
<a class="link" href="../../reference/associated_cancellation_slot.html" title="associated_cancellation_slot">associated_cancellation_slot</a>
trait, <code class="computeroutput"><span class="identifier">associated_cancellation_slot_t</span></code>
type alias, and <a class="link" href="../../reference/get_associated_cancellation_slot.html" title="get_associated_cancellation_slot">get_associated_cancellation_slot</a>
function
</p>
</td>
<td>
<p>
Defines an asynchronous agents associated cancellation slot.
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="completion_tokens.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../model.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="higher_levels.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,50 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Networking</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="composition/immediate_completion.html" title="Customising Immediate Completion">
<link rel="next" href="networking/protocols.html" title="TCP, UDP and ICMP">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="composition/immediate_completion.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="networking/protocols.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.networking"></a><a class="link" href="networking.html" title="Networking">Networking</a>
</h3></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a class="link" href="networking/protocols.html" title="TCP, UDP and ICMP">TCP, UDP and ICMP</a>
</li>
<li class="listitem">
<a class="link" href="networking/other_protocols.html" title="Support for Other Protocols">Support for
Other Protocols</a>
</li>
<li class="listitem">
<a class="link" href="networking/iostreams.html" title="Socket Iostreams">Socket Iostreams</a>
</li>
<li class="listitem">
<a class="link" href="networking/bsd_sockets.html" title="The BSD Socket API and Asio">The BSD Socket API
and Asio</a>
</li>
</ul></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="composition/immediate_completion.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="networking/protocols.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,554 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The BSD Socket API and Asio</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../networking.html" title="Networking">
<link rel="prev" href="iostreams.html" title="Socket Iostreams">
<link rel="next" href="../timers.html" title="Timers">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="iostreams.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../networking.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../timers.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.networking.bsd_sockets"></a><a class="link" href="bsd_sockets.html" title="The BSD Socket API and Asio">The BSD Socket
API and Asio</a>
</h4></div></div></div>
<p>
The Asio library includes a low-level socket interface based on the BSD
socket API, which is widely implemented and supported by extensive literature.
It is also used as the basis for networking APIs in other languages, like
Java. This low-level interface is designed to support the development of
efficient and scalable applications. For example, it permits programmers
to exert finer control over the number of system calls, avoid redundant
data copying, minimise the use of resources like threads, and so on.
</p>
<p>
Unsafe and error prone aspects of the BSD socket API are not included.
For example, the use of <code class="computeroutput"><span class="keyword">int</span></code>
to represent all sockets lacks type safety. The socket representation in
Asio uses a distinct type for each protocol, e.g. for TCP one would use
<code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span></code>, and for UDP one uses <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">socket</span></code>.
</p>
<p>
The following table shows the mapping between the BSD socket API and Asio:
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
BSD Socket API Elements
</p>
</th>
<th>
<p>
Equivalents in Asio
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
socket descriptor - <code class="computeroutput"><span class="keyword">int</span></code>
(POSIX) or <code class="computeroutput"><span class="identifier">SOCKET</span></code>
(Windows)
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/ip__tcp/socket.html" title="ip::tcp::socket">ip::tcp::socket</a>,
<a class="link" href="../../reference/ip__tcp/acceptor.html" title="ip::tcp::acceptor">ip::tcp::acceptor</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/ip__udp/socket.html" title="ip::udp::socket">ip::udp::socket</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket.html" title="basic_socket">basic_socket</a>,
<a class="link" href="../../reference/basic_stream_socket.html" title="basic_stream_socket">basic_stream_socket</a>,
<a class="link" href="../../reference/basic_datagram_socket.html" title="basic_datagram_socket">basic_datagram_socket</a>,
<a class="link" href="../../reference/basic_raw_socket.html" title="basic_raw_socket">basic_raw_socket</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">in_addr</span></code>, <code class="computeroutput"><span class="identifier">in6_addr</span></code>
</p>
</td>
<td>
<p>
<a class="link" href="../../reference/ip__address.html" title="ip::address">ip::address</a>,
<a class="link" href="../../reference/ip__address.html" title="ip::address">ip::address_v4</a>,
<a class="link" href="../../reference/ip__address.html" title="ip::address">ip::address_v6</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">sockaddr_in</span></code>,
<code class="computeroutput"><span class="identifier">sockaddr_in6</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/ip__tcp/endpoint.html" title="ip::tcp::endpoint">ip::tcp::endpoint</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/ip__udp/endpoint.html" title="ip::udp::endpoint">ip::udp::endpoint</a>
</p>
<p>
<a class="link" href="../../reference/ip__basic_endpoint.html" title="ip::basic_endpoint">ip::basic_endpoint</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">accept</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket_acceptor/accept.html" title="basic_socket_acceptor::accept">ip::tcp::acceptor::accept()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket_acceptor/accept.html" title="basic_socket_acceptor::accept">basic_socket_acceptor::accept()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">bind</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/bind.html" title="basic_socket::bind">ip::tcp::acceptor::bind()</a>,
<a class="link" href="../../reference/basic_socket/bind.html" title="basic_socket::bind">ip::tcp::socket::bind()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/bind.html" title="basic_socket::bind">ip::udp::socket::bind()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/bind.html" title="basic_socket::bind">basic_socket::bind()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/close.html" title="basic_socket::close">ip::tcp::acceptor::close()</a>,
<a class="link" href="../../reference/basic_socket/close.html" title="basic_socket::close">ip::tcp::socket::close()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/close.html" title="basic_socket::close">ip::udp::socket::close()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/close.html" title="basic_socket::close">basic_socket::close()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">connect</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/connect.html" title="basic_socket::connect">ip::tcp::socket::connect()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/connect.html" title="basic_socket::connect">ip::udp::socket::connect()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/connect.html" title="basic_socket::connect">basic_socket::connect()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">getaddrinfo</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">gethostbyaddr</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">gethostbyname</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">getnameinfo</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">getservbyname</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">getservbyport</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/ip__basic_resolver/resolve.html" title="ip::basic_resolver::resolve">ip::tcp::resolver::resolve()</a>,
<a class="link" href="../../reference/ip__basic_resolver/async_resolve.html" title="ip::basic_resolver::async_resolve">ip::tcp::resolver::async_resolve()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/ip__basic_resolver/resolve.html" title="ip::basic_resolver::resolve">ip::udp::resolver::resolve()</a>,
<a class="link" href="../../reference/ip__basic_resolver/async_resolve.html" title="ip::basic_resolver::async_resolve">ip::udp::resolver::async_resolve()</a>
</p>
<p>
<a class="link" href="../../reference/ip__basic_resolver/resolve.html" title="ip::basic_resolver::resolve">ip::basic_resolver::resolve()</a>,
<a class="link" href="../../reference/ip__basic_resolver/async_resolve.html" title="ip::basic_resolver::async_resolve">ip::basic_resolver::async_resolve()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">gethostname</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
<a class="link" href="../../reference/ip__host_name.html" title="ip::host_name">ip::host_name()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">getpeername</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/remote_endpoint.html" title="basic_socket::remote_endpoint">ip::tcp::socket::remote_endpoint()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/remote_endpoint.html" title="basic_socket::remote_endpoint">ip::udp::socket::remote_endpoint()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/remote_endpoint.html" title="basic_socket::remote_endpoint">basic_socket::remote_endpoint()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">getsockname</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/local_endpoint.html" title="basic_socket::local_endpoint">ip::tcp::acceptor::local_endpoint()</a>,
<a class="link" href="../../reference/basic_socket/local_endpoint.html" title="basic_socket::local_endpoint">ip::tcp::socket::local_endpoint()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/local_endpoint.html" title="basic_socket::local_endpoint">ip::udp::socket::local_endpoint()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/local_endpoint.html" title="basic_socket::local_endpoint">basic_socket::local_endpoint()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">getsockopt</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/get_option.html" title="basic_socket::get_option">ip::tcp::acceptor::get_option()</a>,
<a class="link" href="../../reference/basic_socket/get_option.html" title="basic_socket::get_option">ip::tcp::socket::get_option()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/get_option.html" title="basic_socket::get_option">ip::udp::socket::get_option()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/get_option.html" title="basic_socket::get_option">basic_socket::get_option()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">inet_addr</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">inet_aton</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">inet_pton</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
<a class="link" href="../../reference/ip__address/from_string.html" title="ip::address::from_string">ip::address::from_string()</a>,
<a class="link" href="../../reference/ip__address/from_string.html" title="ip::address::from_string">ip::address_v4::from_string()</a>,
<a class="link" href="../../reference/ip__address/from_string.html" title="ip::address::from_string">ip_address_v6::from_string()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">inet_ntoa</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">inet_ntop</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
<a class="link" href="../../reference/ip__address/to_string.html" title="ip::address::to_string">ip::address::to_string()</a>,
<a class="link" href="../../reference/ip__address/to_string.html" title="ip::address::to_string">ip::address_v4::to_string()</a>,
<a class="link" href="../../reference/ip__address/to_string.html" title="ip::address::to_string">ip_address_v6::to_string()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">ioctl</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/io_control.html" title="basic_socket::io_control">ip::tcp::socket::io_control()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/io_control.html" title="basic_socket::io_control">ip::udp::socket::io_control()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/io_control.html" title="basic_socket::io_control">basic_socket::io_control()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">listen</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket_acceptor/listen.html" title="basic_socket_acceptor::listen">ip::tcp::acceptor::listen()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket_acceptor/listen.html" title="basic_socket_acceptor::listen">basic_socket_acceptor::listen()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">poll</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">select</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">pselect</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
<a class="link" href="../../reference/io_context/run.html" title="io_context::run">io_context::run()</a>,
<a class="link" href="../../reference/io_context/run_one.html" title="io_context::run_one">io_context::run_one()</a>,
<a class="link" href="../../reference/io_context/poll.html" title="io_context::poll">io_context::poll()</a>,
<a class="link" href="../../reference/io_context/poll_one.html" title="io_context::poll_one">io_context::poll_one()</a>
</p>
<p>
Note: in conjunction with asynchronous operations.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">readv</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">recv</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">read</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_stream_socket/read_some.html" title="basic_stream_socket::read_some">ip::tcp::socket::read_some()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_read_some.html" title="basic_stream_socket::async_read_some">ip::tcp::socket::async_read_some()</a>,
<a class="link" href="../../reference/basic_stream_socket/receive.html" title="basic_stream_socket::receive">ip::tcp::socket::receive()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_receive.html" title="basic_stream_socket::async_receive">ip::tcp::socket::async_receive()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_datagram_socket/receive.html" title="basic_datagram_socket::receive">ip::udp::socket::receive()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_receive.html" title="basic_datagram_socket::async_receive">ip::udp::socket::async_receive()</a>
</p>
<p>
<a class="link" href="../../reference/basic_stream_socket/read_some.html" title="basic_stream_socket::read_some">basic_stream_socket::read_some()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_read_some.html" title="basic_stream_socket::async_read_some">basic_stream_socket::async_read_some()</a>,
<a class="link" href="../../reference/basic_stream_socket/receive.html" title="basic_stream_socket::receive">basic_stream_socket::receive()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_receive.html" title="basic_stream_socket::async_receive">basic_stream_socket::async_receive()</a>,
<a class="link" href="../../reference/basic_datagram_socket/receive.html" title="basic_datagram_socket::receive">basic_datagram_socket::receive()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_receive.html" title="basic_datagram_socket::async_receive">basic_datagram_socket::async_receive()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">recvfrom</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For UDP: <a class="link" href="../../reference/basic_datagram_socket/receive_from.html" title="basic_datagram_socket::receive_from">ip::udp::socket::receive_from()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_receive_from.html" title="basic_datagram_socket::async_receive_from">ip::udp::socket::async_receive_from()</a>
</p>
<p>
<a class="link" href="../../reference/basic_datagram_socket/receive_from.html" title="basic_datagram_socket::receive_from">basic_datagram_socket::receive_from()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_receive_from.html" title="basic_datagram_socket::async_receive_from">basic_datagram_socket::async_receive_from()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">send</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">write</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">writev</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_stream_socket/write_some.html" title="basic_stream_socket::write_some">ip::tcp::socket::write_some()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_write_some.html" title="basic_stream_socket::async_write_some">ip::tcp::socket::async_write_some()</a>,
<a class="link" href="../../reference/basic_stream_socket/send.html" title="basic_stream_socket::send">ip::tcp::socket::send()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_send.html" title="basic_stream_socket::async_send">ip::tcp::socket::async_send()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_datagram_socket/send.html" title="basic_datagram_socket::send">ip::udp::socket::send()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_send.html" title="basic_datagram_socket::async_send">ip::udp::socket::async_send()</a>
</p>
<p>
<a class="link" href="../../reference/basic_stream_socket/write_some.html" title="basic_stream_socket::write_some">basic_stream_socket::write_some()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_write_some.html" title="basic_stream_socket::async_write_some">basic_stream_socket::async_write_some()</a>,
<a class="link" href="../../reference/basic_stream_socket/send.html" title="basic_stream_socket::send">basic_stream_socket::send()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_send.html" title="basic_stream_socket::async_send">basic_stream_socket::async_send()</a>,
<a class="link" href="../../reference/basic_datagram_socket/send.html" title="basic_datagram_socket::send">basic_datagram_socket::send()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_send.html" title="basic_datagram_socket::async_send">basic_datagram_socket::async_send()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">sendto</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For UDP: <a class="link" href="../../reference/basic_datagram_socket/send_to.html" title="basic_datagram_socket::send_to">ip::udp::socket::send_to()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_send_to.html" title="basic_datagram_socket::async_send_to">ip::udp::socket::async_send_to()</a>
</p>
<p>
<a class="link" href="../../reference/basic_datagram_socket/send_to.html" title="basic_datagram_socket::send_to">basic_datagram_socket::send_to()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_send_to.html" title="basic_datagram_socket::async_send_to">basic_datagram_socket::async_send_to()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">setsockopt</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/set_option.html" title="basic_socket::set_option">ip::tcp::acceptor::set_option()</a>,
<a class="link" href="../../reference/basic_socket/set_option.html" title="basic_socket::set_option">ip::tcp::socket::set_option()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/set_option.html" title="basic_socket::set_option">ip::udp::socket::set_option()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/set_option.html" title="basic_socket::set_option">basic_socket::set_option()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">shutdown</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/shutdown.html" title="basic_socket::shutdown">ip::tcp::socket::shutdown()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/shutdown.html" title="basic_socket::shutdown">ip::udp::socket::shutdown()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/shutdown.html" title="basic_socket::shutdown">basic_socket::shutdown()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">sockatmark</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/at_mark.html" title="basic_socket::at_mark">ip::tcp::socket::at_mark()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/at_mark.html" title="basic_socket::at_mark">basic_socket::at_mark()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">socket</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
For TCP: <a class="link" href="../../reference/basic_socket/open.html" title="basic_socket::open">ip::tcp::acceptor::open()</a>,
<a class="link" href="../../reference/basic_socket/open.html" title="basic_socket::open">ip::tcp::socket::open()</a>
</p>
<p>
For UDP: <a class="link" href="../../reference/basic_socket/open.html" title="basic_socket::open">ip::udp::socket::open()</a>
</p>
<p>
<a class="link" href="../../reference/basic_socket/open.html" title="basic_socket::open">basic_socket::open()</a>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">socketpair</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
<a class="link" href="../../reference/local__connect_pair.html" title="local::connect_pair">local::connect_pair()</a>
</p>
<p>
Note: POSIX operating systems only.
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="iostreams.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../networking.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../timers.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,110 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Socket Iostreams</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../networking.html" title="Networking">
<link rel="prev" href="other_protocols.html" title="Support for Other Protocols">
<link rel="next" href="bsd_sockets.html" title="The BSD Socket API and Asio">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="other_protocols.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../networking.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="bsd_sockets.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.networking.iostreams"></a><a class="link" href="iostreams.html" title="Socket Iostreams">Socket Iostreams</a>
</h4></div></div></div>
<p>
Asio includes classes that implement iostreams on top of sockets. These
hide away the complexities associated with endpoint resolution, protocol
independence, etc. To create a connection one might simply write:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">iostream</span> <span class="identifier">stream</span><span class="special">(</span><span class="string">"www.boost.org"</span><span class="special">,</span> <span class="string">"http"</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">stream</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// Can't connect.</span>
<span class="special">}</span>
</pre>
<p>
The iostream class can also be used in conjunction with an acceptor to
create simple servers. For example:
</p>
<pre class="programlisting"><span class="identifier">io_context</span> <span class="identifier">ioc</span><span class="special">;</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">endpoint</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">v4</span><span class="special">(),</span> <span class="number">80</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">acceptor</span> <span class="identifier">acceptor</span><span class="special">(</span><span class="identifier">ios</span><span class="special">,</span> <span class="identifier">endpoint</span><span class="special">);</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">iostream</span> <span class="identifier">stream</span><span class="special">;</span>
<span class="identifier">acceptor</span><span class="special">.</span><span class="identifier">accept</span><span class="special">(</span><span class="identifier">stream</span><span class="special">.</span><span class="identifier">socket</span><span class="special">());</span>
<span class="special">...</span>
<span class="special">}</span>
</pre>
<p>
Timeouts may be set by calling <code class="computeroutput"><span class="identifier">expires_at</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">expires_from_now</span><span class="special">()</span></code> to establish a deadline. Any socket operations
that occur past the deadline will put the iostream into a "bad"
state.
</p>
<p>
For example, a simple client program like this:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">iostream</span> <span class="identifier">stream</span><span class="special">;</span>
<span class="identifier">stream</span><span class="special">.</span><span class="identifier">expires_from_now</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">60</span><span class="special">));</span>
<span class="identifier">stream</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="string">"www.boost.org"</span><span class="special">,</span> <span class="string">"http"</span><span class="special">);</span>
<span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="string">"GET /LICENSE_1_0.txt HTTP/1.0\r\n"</span><span class="special">;</span>
<span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="string">"Host: www.boost.org\r\n"</span><span class="special">;</span>
<span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="string">"Accept: */*\r\n"</span><span class="special">;</span>
<span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="string">"Connection: close\r\n\r\n"</span><span class="special">;</span>
<span class="identifier">stream</span><span class="special">.</span><span class="identifier">flush</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">rdbuf</span><span class="special">();</span>
</pre>
<p>
will fail if all the socket operations combined take longer than 60 seconds.
</p>
<p>
If an error does occur, the iostream's <code class="computeroutput"><span class="identifier">error</span><span class="special">()</span></code> member function may be used to retrieve
the error code from the most recent system call:
</p>
<pre class="programlisting"><span class="keyword">if</span> <span class="special">(!</span><span class="identifier">stream</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Error: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">error</span><span class="special">().</span><span class="identifier">message</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<h6>
<a name="asio.overview.networking.iostreams.h0"></a>
<span><a name="asio.overview.networking.iostreams.see_also"></a></span><a class="link" href="iostreams.html#asio.overview.networking.iostreams.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/ip__tcp/iostream.html" title="ip::tcp::iostream">ip::tcp::iostream</a>,
<a class="link" href="../../reference/basic_socket_iostream.html" title="basic_socket_iostream">basic_socket_iostream</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.iostreams">iostreams examples</a>.
</p>
<h6>
<a name="asio.overview.networking.iostreams.h1"></a>
<span><a name="asio.overview.networking.iostreams.notes"></a></span><a class="link" href="iostreams.html#asio.overview.networking.iostreams.notes">Notes</a>
</h6>
<p>
These iostream templates only support <code class="computeroutput"><span class="keyword">char</span></code>,
not <code class="computeroutput"><span class="keyword">wchar_t</span></code>, and do not perform
any code conversion.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="other_protocols.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../networking.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="bsd_sockets.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,147 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Support for Other Protocols</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../networking.html" title="Networking">
<link rel="prev" href="protocols.html" title="TCP, UDP and ICMP">
<link rel="next" href="iostreams.html" title="Socket Iostreams">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="protocols.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../networking.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="iostreams.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.networking.other_protocols"></a><a class="link" href="other_protocols.html" title="Support for Other Protocols">Support for
Other Protocols</a>
</h4></div></div></div>
<p>
Support for other socket protocols (such as Bluetooth or IRCOMM sockets)
can be added by implementing the <a class="link" href="../../reference/Protocol.html" title="Protocol requirements">protocol
type requirements</a>. However, in many cases these protocols may also
be used with Asio's generic protocol support. For this, Asio provides the
following four classes:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a class="link" href="../../reference/generic__datagram_protocol.html" title="generic::datagram_protocol"><code class="computeroutput"><span class="identifier">generic</span><span class="special">::</span><span class="identifier">datagram_protocol</span></code></a>
</li>
<li class="listitem">
<a class="link" href="../../reference/generic__raw_protocol.html" title="generic::raw_protocol"><code class="computeroutput"><span class="identifier">generic</span><span class="special">::</span><span class="identifier">raw_protocol</span></code></a>
</li>
<li class="listitem">
<a class="link" href="../../reference/generic__seq_packet_protocol.html" title="generic::seq_packet_protocol"><code class="computeroutput"><span class="identifier">generic</span><span class="special">::</span><span class="identifier">seq_packet_protocol</span></code></a>
</li>
<li class="listitem">
<a class="link" href="../../reference/generic__stream_protocol.html" title="generic::stream_protocol"><code class="computeroutput"><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span></code></a>
</li>
</ul></div>
<p>
These classes implement the <a class="link" href="../../reference/Protocol.html" title="Protocol requirements">protocol
type requirements</a>, but allow the user to specify the address family
(e.g. <code class="computeroutput"><span class="identifier">AF_INET</span></code>) and protocol
type (e.g. <code class="computeroutput"><span class="identifier">IPPROTO_TCP</span></code>)
at runtime. For example:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">my_socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">open</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">(</span><span class="identifier">AF_INET</span><span class="special">,</span> <span class="identifier">IPPROTO_TCP</span><span class="special">));</span>
<span class="special">...</span>
</pre>
<p>
An endpoint class template, <a class="link" href="../../reference/generic__basic_endpoint.html" title="generic::basic_endpoint"><code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">generic</span><span class="special">::</span><span class="identifier">basic_endpoint</span></code></a>, is included to
support these protocol classes. This endpoint can hold any other endpoint
type, provided its native representation fits into a <code class="computeroutput"><span class="identifier">sockaddr_storage</span></code>
object. This class will also convert from other types that implement the
<a class="link" href="../../reference/Endpoint.html" title="Endpoint requirements">endpoint</a> type requirements:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">my_endpoint1</span> <span class="special">=</span> <span class="special">...;</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">my_endpoint2</span><span class="special">(</span><span class="identifier">my_endpoint1</span><span class="special">);</span>
</pre>
<p>
The conversion is implicit, so as to support the following use cases:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">my_socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">my_endpoint</span> <span class="special">=</span> <span class="special">...;</span>
<span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">my_endpoint</span><span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.networking.other_protocols.h0"></a>
<span><a name="asio.overview.networking.other_protocols.c__11_move_construction"></a></span><a class="link" href="other_protocols.html#asio.overview.networking.other_protocols.c__11_move_construction">C++11
Move Construction</a>
</h6>
<p>
When using C++11, it is possible to perform move construction from a socket
(or acceptor) object to convert to the more generic protocol's socket (or
acceptor) type. If the protocol conversion is valid:
</p>
<pre class="programlisting"><span class="identifier">Protocol1</span> <span class="identifier">p1</span> <span class="special">=</span> <span class="special">...;</span>
<span class="identifier">Protocol2</span> <span class="identifier">p2</span><span class="special">(</span><span class="identifier">p1</span><span class="special">);</span>
</pre>
<p>
then the corresponding socket conversion is allowed:
</p>
<pre class="programlisting"><span class="identifier">Protocol1</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">my_socket1</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">Protocol2</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">my_socket2</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">my_socket1</span><span class="special">));</span>
</pre>
<p>
For example, one possible conversion is from a TCP socket to a generic
stream-oriented socket:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">my_socket1</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">my_socket2</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">my_socket1</span><span class="special">));</span>
</pre>
<p>
These conversions are also available for move-assignment.
</p>
<p>
These conversions are not limited to the above generic protocol classes.
User-defined protocols may take advantage of this feature by similarly
ensuring the conversion from <code class="computeroutput"><span class="identifier">Protocol1</span></code>
to <code class="computeroutput"><span class="identifier">Protocol2</span></code> is valid,
as above.
</p>
<h6>
<a name="asio.overview.networking.other_protocols.h1"></a>
<span><a name="asio.overview.networking.other_protocols.accepting_generic_sockets"></a></span><a class="link" href="other_protocols.html#asio.overview.networking.other_protocols.accepting_generic_sockets">Accepting
Generic Sockets</a>
</h6>
<p>
As a convenience, a socket acceptor's <code class="computeroutput"><span class="identifier">accept</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">async_accept</span><span class="special">()</span></code> functions can directly accept into a
different protocol's socket type, provided the corresponding protocol conversion
is valid. For example, the following is supported because the protocol
<code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span></code> is convertible to <code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span></code>:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">acceptor</span> <span class="identifier">my_acceptor</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">my_socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">my_acceptor</span><span class="special">.</span><span class="identifier">accept</span><span class="special">(</span><span class="identifier">my_socket</span><span class="special">);</span>
</pre>
<h6>
<a name="asio.overview.networking.other_protocols.h2"></a>
<span><a name="asio.overview.networking.other_protocols.see_also"></a></span><a class="link" href="other_protocols.html#asio.overview.networking.other_protocols.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/generic__datagram_protocol.html" title="generic::datagram_protocol"><code class="computeroutput"><span class="identifier">generic</span><span class="special">::</span><span class="identifier">datagram_protocol</span></code></a>, <a class="link" href="../../reference/generic__raw_protocol.html" title="generic::raw_protocol"><code class="computeroutput"><span class="identifier">generic</span><span class="special">::</span><span class="identifier">raw_protocol</span></code></a>, <a class="link" href="../../reference/generic__seq_packet_protocol.html" title="generic::seq_packet_protocol"><code class="computeroutput"><span class="identifier">generic</span><span class="special">::</span><span class="identifier">seq_packet_protocol</span></code></a>, <a class="link" href="../../reference/generic__stream_protocol.html" title="generic::stream_protocol"><code class="computeroutput"><span class="identifier">generic</span><span class="special">::</span><span class="identifier">stream_protocol</span></code></a>, <a class="link" href="../../reference/Protocol.html" title="Protocol requirements">protocol
type requirements</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="protocols.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../networking.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="iostreams.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,201 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>TCP, UDP and ICMP</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../networking.html" title="Networking">
<link rel="prev" href="../networking.html" title="Networking">
<link rel="next" href="other_protocols.html" title="Support for Other Protocols">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../networking.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../networking.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="other_protocols.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.networking.protocols"></a><a class="link" href="protocols.html" title="TCP, UDP and ICMP">TCP, UDP and ICMP</a>
</h4></div></div></div>
<p>
Asio provides off-the-shelf support for the internet protocols TCP, UDP
and ICMP.
</p>
<h6>
<a name="asio.overview.networking.protocols.h0"></a>
<span><a name="asio.overview.networking.protocols.tcp_clients"></a></span><a class="link" href="protocols.html#asio.overview.networking.protocols.tcp_clients">TCP
Clients</a>
</h6>
<p>
Hostname resolution is performed using a resolver, where host and service
names are looked up and converted into one or more endpoints:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span> <span class="identifier">resolver</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">query</span> <span class="identifier">query</span><span class="special">(</span><span class="string">"www.boost.org"</span><span class="special">,</span> <span class="string">"http"</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">resolver</span><span class="special">.</span><span class="identifier">resolve</span><span class="special">(</span><span class="identifier">query</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">end</span><span class="special">;</span> <span class="comment">// End marker.</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">iter</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">endpoint</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">iter</span><span class="special">++;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">endpoint</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
The list of endpoints obtained above could contain both IPv4 and IPv6 endpoints,
so a program should try each of them until it finds one that works. This
keeps the client program independent of a specific IP version.
</p>
<p>
To simplify the development of protocol-independent programs, TCP clients
may establish connections using the free functions <a class="link" href="../../reference/connect.html" title="connect">connect()</a>
and <a class="link" href="../../reference/async_connect.html" title="async_connect">async_connect()</a>.
These operations try each endpoint in a list until the socket is successfully
connected. For example, a single call:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">resolver</span><span class="special">.</span><span class="identifier">resolve</span><span class="special">(</span><span class="identifier">query</span><span class="special">));</span>
</pre>
<p>
will synchronously try all endpoints until one is successfully connected.
Similarly, an asynchronous connect may be performed by writing:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_connect</span><span class="special">(</span><span class="identifier">socket_</span><span class="special">,</span> <span class="identifier">iter</span><span class="special">,</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">client</span><span class="special">::</span><span class="identifier">handle_connect</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">placeholders</span><span class="special">::</span><span class="identifier">error</span><span class="special">));</span>
<span class="comment">// ...</span>
<span class="keyword">void</span> <span class="identifier">handle_connect</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">error_code</span><span class="special">&amp;</span> <span class="identifier">error</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">error</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// Start read or write operations.</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="comment">// Handle error.</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
When a specific endpoint is available, a socket can be created and connected:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">endpoint</span><span class="special">);</span>
</pre>
<p>
Data may be read from or written to a connected TCP socket using the <a class="link" href="../../reference/basic_stream_socket/receive.html" title="basic_stream_socket::receive">receive()</a>,
<a class="link" href="../../reference/basic_stream_socket/async_receive.html" title="basic_stream_socket::async_receive">async_receive()</a>,
<a class="link" href="../../reference/basic_stream_socket/send.html" title="basic_stream_socket::send">send()</a> or
<a class="link" href="../../reference/basic_stream_socket/async_send.html" title="basic_stream_socket::async_send">async_send()</a>
member functions. However, as these could result in <a class="link" href="../core/streams.html" title="Streams, Short Reads and Short Writes">short
writes or reads</a>, an application will typically use the following
operations instead: <a class="link" href="../../reference/read.html" title="read">read()</a>,
<a class="link" href="../../reference/async_read.html" title="async_read">async_read()</a>, <a class="link" href="../../reference/write.html" title="write">write()</a>
and <a class="link" href="../../reference/async_write.html" title="async_write">async_write()</a>.
</p>
<h6>
<a name="asio.overview.networking.protocols.h1"></a>
<span><a name="asio.overview.networking.protocols.tcp_servers"></a></span><a class="link" href="protocols.html#asio.overview.networking.protocols.tcp_servers">TCP
Servers</a>
</h6>
<p>
A program uses an acceptor to accept incoming TCP connections:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">acceptor</span> <span class="identifier">acceptor</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="identifier">my_endpoint</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">acceptor</span><span class="special">.</span><span class="identifier">accept</span><span class="special">(</span><span class="identifier">socket</span><span class="special">);</span>
</pre>
<p>
After a socket has been successfully accepted, it may be read from or written
to as illustrated for TCP clients above.
</p>
<h6>
<a name="asio.overview.networking.protocols.h2"></a>
<span><a name="asio.overview.networking.protocols.udp"></a></span><a class="link" href="protocols.html#asio.overview.networking.protocols.udp">UDP</a>
</h6>
<p>
UDP hostname resolution is also performed using a resolver:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span> <span class="identifier">resolver</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">query</span> <span class="identifier">query</span><span class="special">(</span><span class="string">"localhost"</span><span class="special">,</span> <span class="string">"daytime"</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">resolver</span><span class="special">.</span><span class="identifier">resolve</span><span class="special">(</span><span class="identifier">query</span><span class="special">);</span>
<span class="special">...</span>
</pre>
<p>
A UDP socket is typically bound to a local endpoint. The following code
will create an IP version 4 UDP socket and bind it to the "any"
address on port <code class="computeroutput"><span class="number">12345</span></code>:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">endpoint</span><span class="special">(</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">v4</span><span class="special">(),</span> <span class="number">12345</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">udp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="identifier">endpoint</span><span class="special">);</span>
</pre>
<p>
Data may be read from or written to an unconnected UDP socket using the
<a class="link" href="../../reference/basic_datagram_socket/receive_from.html" title="basic_datagram_socket::receive_from">receive_from()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_receive_from.html" title="basic_datagram_socket::async_receive_from">async_receive_from()</a>,
<a class="link" href="../../reference/basic_datagram_socket/send_to.html" title="basic_datagram_socket::send_to">send_to()</a>
or <a class="link" href="../../reference/basic_datagram_socket/async_send_to.html" title="basic_datagram_socket::async_send_to">async_send_to()</a>
member functions. For a connected UDP socket, use the <a class="link" href="../../reference/basic_datagram_socket/receive.html" title="basic_datagram_socket::receive">receive()</a>,
<a class="link" href="../../reference/basic_datagram_socket/async_receive.html" title="basic_datagram_socket::async_receive">async_receive()</a>,
<a class="link" href="../../reference/basic_datagram_socket/send.html" title="basic_datagram_socket::send">send()</a>
or <a class="link" href="../../reference/basic_datagram_socket/async_send.html" title="basic_datagram_socket::async_send">async_send()</a>
member functions.
</p>
<h6>
<a name="asio.overview.networking.protocols.h3"></a>
<span><a name="asio.overview.networking.protocols.icmp"></a></span><a class="link" href="protocols.html#asio.overview.networking.protocols.icmp">ICMP</a>
</h6>
<p>
As with TCP and UDP, ICMP hostname resolution is performed using a resolver:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">icmp</span><span class="special">::</span><span class="identifier">resolver</span> <span class="identifier">resolver</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">icmp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">query</span> <span class="identifier">query</span><span class="special">(</span><span class="string">"localhost"</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">icmp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">resolver</span><span class="special">.</span><span class="identifier">resolve</span><span class="special">(</span><span class="identifier">query</span><span class="special">);</span>
<span class="special">...</span>
</pre>
<p>
An ICMP socket may be bound to a local endpoint. The following code will
create an IP version 6 ICMP socket and bind it to the "any" address:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">icmp</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">endpoint</span><span class="special">(</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">icmp</span><span class="special">::</span><span class="identifier">v6</span><span class="special">(),</span> <span class="number">0</span><span class="special">);</span>
<span class="identifier">ip</span><span class="special">::</span><span class="identifier">icmp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="identifier">endpoint</span><span class="special">);</span>
</pre>
<p>
The port number is not used for ICMP.
</p>
<p>
Data may be read from or written to an unconnected ICMP socket using the
<a class="link" href="../../reference/basic_raw_socket/receive_from.html" title="basic_raw_socket::receive_from">receive_from()</a>,
<a class="link" href="../../reference/basic_raw_socket/async_receive_from.html" title="basic_raw_socket::async_receive_from">async_receive_from()</a>,
<a class="link" href="../../reference/basic_raw_socket/send_to.html" title="basic_raw_socket::send_to">send_to()</a>
or <a class="link" href="../../reference/basic_raw_socket/async_send_to.html" title="basic_raw_socket::async_send_to">async_send_to()</a>
member functions.
</p>
<h6>
<a name="asio.overview.networking.protocols.h4"></a>
<span><a name="asio.overview.networking.protocols.see_also"></a></span><a class="link" href="protocols.html#asio.overview.networking.protocols.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/ip__tcp.html" title="ip::tcp">ip::tcp</a>, <a class="link" href="../../reference/ip__udp.html" title="ip::udp">ip::udp</a>,
<a class="link" href="../../reference/ip__icmp.html" title="ip::icmp">ip::icmp</a>, <a class="link" href="../../tutorial/tutdaytime1.html" title="Daytime.1 - A synchronous TCP daytime client">daytime
protocol tutorials</a>, <a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.icmp">ICMP
ping example</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../networking.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../networking.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="other_protocols.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,66 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Pipes</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="files.html" title="Files">
<link rel="next" href="serial_ports.html" title="Serial Ports">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="files.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="serial_ports.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.pipes"></a><a class="link" href="pipes.html" title="Pipes">Pipes</a>
</h3></div></div></div>
<p>
Asio provides support for portable anonymous pipes on POSIX and Windows (when
I/O completion ports are available). For example, to create and use a connected
pair of pipe objects:
</p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">readable_pipe</span> <span class="identifier">read_end</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">writable_pipe</span> <span class="identifier">write_end</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">connect_pipe</span><span class="special">(</span><span class="identifier">read_end</span><span class="special">,</span> <span class="identifier">write_end</span><span class="special">);</span>
<span class="identifier">write_end</span><span class="special">.</span><span class="identifier">async_write_some</span><span class="special">(</span><span class="identifier">my_write_buffer</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">});</span>
<span class="identifier">read_end</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_read_buffer</span><span class="special">,</span>
<span class="special">[](</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ...</span>
<span class="special">});</span>
</pre>
<h5>
<a name="asio.overview.pipes.h0"></a>
<span><a name="asio.overview.pipes.see_also"></a></span><a class="link" href="pipes.html#asio.overview.pipes.see_also">See
Also</a>
</h5>
<p>
<a class="link" href="../reference/basic_readable_pipe.html" title="basic_readable_pipe">basic_readable_pipe</a>,
<a class="link" href="../reference/basic_writable_pipe.html" title="basic_writable_pipe">basic_writable_pipe</a>,
<a class="link" href="../reference/connect_pipe.html" title="connect_pipe">connect_pipe</a>, <a class="link" href="../reference/readable_pipe.html" title="readable_pipe">readable_pipe</a>,
<a class="link" href="../reference/writable_pipe.html" title="writable_pipe">writable_pipe</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="files.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="serial_ports.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,44 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>POSIX-Specific Functionality</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="channels.html" title="Channels">
<link rel="next" href="posix/local.html" title="UNIX Domain Sockets">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="channels.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="posix/local.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.posix"></a><a class="link" href="posix.html" title="POSIX-Specific Functionality">POSIX-Specific Functionality</a>
</h3></div></div></div>
<p>
<a class="link" href="posix/local.html" title="UNIX Domain Sockets">UNIX Domain Sockets</a>
</p>
<p>
<a class="link" href="posix/stream_descriptor.html" title="Stream-Oriented File Descriptors">Stream-Oriented File
Descriptors</a>
</p>
<p>
<a class="link" href="posix/fork.html" title="Fork">Fork</a>
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="channels.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="posix/local.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,74 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Fork</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../posix.html" title="POSIX-Specific Functionality">
<link rel="prev" href="stream_descriptor.html" title="Stream-Oriented File Descriptors">
<link rel="next" href="../windows.html" title="Windows-Specific Functionality">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stream_descriptor.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../posix.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../windows.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.posix.fork"></a><a class="link" href="fork.html" title="Fork">Fork</a>
</h4></div></div></div>
<p>
Asio supports programs that utilise the <code class="computeroutput"><span class="identifier">fork</span><span class="special">()</span></code> system call. Provided the program calls
<code class="computeroutput"><span class="identifier">io_context</span><span class="special">.</span><span class="identifier">notify_fork</span><span class="special">()</span></code>
at the appropriate times, Asio will recreate any internal file descriptors
(such as the "self-pipe trick" descriptor used for waking up
a reactor). The notification is usually performed as follows:
</p>
<pre class="programlisting"><span class="identifier">io_context_</span><span class="special">.</span><span class="identifier">notify_fork</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">fork_prepare</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">fork</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">io_context_</span><span class="special">.</span><span class="identifier">notify_fork</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">fork_child</span><span class="special">);</span>
<span class="special">...</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="identifier">io_context_</span><span class="special">.</span><span class="identifier">notify_fork</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">fork_parent</span><span class="special">);</span>
<span class="special">...</span>
<span class="special">}</span>
</pre>
<p>
User-defined services can also be made fork-aware by overriding the <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">service</span><span class="special">::</span><span class="identifier">notify_fork</span><span class="special">()</span></code>
virtual function.
</p>
<p>
Note that any file descriptors accessible via Asio's public API (e.g. the
descriptors underlying <code class="computeroutput"><span class="identifier">basic_socket</span><span class="special">&lt;&gt;</span></code>, <code class="computeroutput"><span class="identifier">posix</span><span class="special">::</span><span class="identifier">stream_descriptor</span></code>,
etc.) are not altered during a fork. It is the program's responsibility
to manage these as required.
</p>
<h6>
<a name="asio.overview.posix.fork.h0"></a>
<span><a name="asio.overview.posix.fork.see_also"></a></span><a class="link" href="fork.html#asio.overview.posix.fork.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/io_context/notify_fork.html" title="io_context::notify_fork">io_context::notify_fork()</a>,
<a class="link" href="../../reference/io_context/fork_event.html" title="io_context::fork_event">io_context::fork_event</a>,
<a class="link" href="../../reference/execution_context__service/notify_fork.html" title="execution_context::service::notify_fork">io_context::service::notify_fork()</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.fork">Fork examples</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stream_descriptor.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../posix.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../windows.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,101 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>UNIX Domain Sockets</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../posix.html" title="POSIX-Specific Functionality">
<link rel="prev" href="../posix.html" title="POSIX-Specific Functionality">
<link rel="next" href="stream_descriptor.html" title="Stream-Oriented File Descriptors">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../posix.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../posix.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="stream_descriptor.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.posix.local"></a><a class="link" href="local.html" title="UNIX Domain Sockets">UNIX Domain Sockets</a>
</h4></div></div></div>
<p>
Asio provides basic support for UNIX domain sockets (also known as local
sockets). The simplest use involves creating a pair of connected sockets.
The following code:
</p>
<pre class="programlisting"><span class="identifier">local</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket1</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">local</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket2</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">local</span><span class="special">::</span><span class="identifier">connect_pair</span><span class="special">(</span><span class="identifier">socket1</span><span class="special">,</span> <span class="identifier">socket2</span><span class="special">);</span>
</pre>
<p>
will create a pair of stream-oriented sockets. To do the same for datagram-oriented
sockets, use:
</p>
<pre class="programlisting"><span class="identifier">local</span><span class="special">::</span><span class="identifier">datagram_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket1</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">local</span><span class="special">::</span><span class="identifier">datagram_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket2</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">local</span><span class="special">::</span><span class="identifier">connect_pair</span><span class="special">(</span><span class="identifier">socket1</span><span class="special">,</span> <span class="identifier">socket2</span><span class="special">);</span>
</pre>
<p>
A UNIX domain socket server may be created by binding an acceptor to an
endpoint, in much the same way as one does for a TCP server:
</p>
<pre class="programlisting"><span class="special">::</span><span class="identifier">unlink</span><span class="special">(</span><span class="string">"/tmp/foobar"</span><span class="special">);</span> <span class="comment">// Remove previous binding.</span>
<span class="identifier">local</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">ep</span><span class="special">(</span><span class="string">"/tmp/foobar"</span><span class="special">);</span>
<span class="identifier">local</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">acceptor</span> <span class="identifier">acceptor</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="identifier">ep</span><span class="special">);</span>
<span class="identifier">local</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">acceptor</span><span class="special">.</span><span class="identifier">accept</span><span class="special">(</span><span class="identifier">socket</span><span class="special">);</span>
</pre>
<p>
A client that connects to this server might look like:
</p>
<pre class="programlisting"><span class="identifier">local</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">endpoint</span> <span class="identifier">ep</span><span class="special">(</span><span class="string">"/tmp/foobar"</span><span class="special">);</span>
<span class="identifier">local</span><span class="special">::</span><span class="identifier">stream_protocol</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">ep</span><span class="special">);</span>
</pre>
<p>
Transmission of file descriptors or credentials across UNIX domain sockets
is not directly supported within Asio, but may be achieved by accessing
the socket's underlying descriptor using the <a class="link" href="../../reference/basic_socket/native_handle.html" title="basic_socket::native_handle">native_handle()</a>
member function.
</p>
<h6>
<a name="asio.overview.posix.local.h0"></a>
<span><a name="asio.overview.posix.local.see_also"></a></span><a class="link" href="local.html#asio.overview.posix.local.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/local__connect_pair.html" title="local::connect_pair">local::connect_pair</a>,
<a class="link" href="../../reference/local__datagram_protocol.html" title="local::datagram_protocol">local::datagram_protocol</a>,
<a class="link" href="../../reference/local__datagram_protocol/endpoint.html" title="local::datagram_protocol::endpoint">local::datagram_protocol::endpoint</a>,
<a class="link" href="../../reference/local__datagram_protocol/socket.html" title="local::datagram_protocol::socket">local::datagram_protocol::socket</a>,
<a class="link" href="../../reference/local__stream_protocol.html" title="local::stream_protocol">local::stream_protocol</a>,
<a class="link" href="../../reference/local__stream_protocol/acceptor.html" title="local::stream_protocol::acceptor">local::stream_protocol::acceptor</a>,
<a class="link" href="../../reference/local__stream_protocol/endpoint.html" title="local::stream_protocol::endpoint">local::stream_protocol::endpoint</a>,
<a class="link" href="../../reference/local__stream_protocol/iostream.html" title="local::stream_protocol::iostream">local::stream_protocol::iostream</a>,
<a class="link" href="../../reference/local__stream_protocol/socket.html" title="local::stream_protocol::socket">local::stream_protocol::socket</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.unix_domain_sockets">UNIX domain
sockets examples</a>.
</p>
<h6>
<a name="asio.overview.posix.local.h1"></a>
<span><a name="asio.overview.posix.local.notes"></a></span><a class="link" href="local.html#asio.overview.posix.local.notes">Notes</a>
</h6>
<p>
UNIX domain sockets are only available at compile time if supported by
the target operating system. A program may test for the macro <code class="computeroutput"><span class="identifier">ASIO_HAS_LOCAL_SOCKETS</span></code> to determine whether
they are supported.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../posix.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../posix.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="stream_descriptor.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,83 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Stream-Oriented File Descriptors</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../posix.html" title="POSIX-Specific Functionality">
<link rel="prev" href="local.html" title="UNIX Domain Sockets">
<link rel="next" href="fork.html" title="Fork">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="local.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../posix.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="fork.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.posix.stream_descriptor"></a><a class="link" href="stream_descriptor.html" title="Stream-Oriented File Descriptors">Stream-Oriented
File Descriptors</a>
</h4></div></div></div>
<p>
Asio includes classes added to permit synchronous and asynchronous read
and write operations to be performed on POSIX file descriptors, such as
pipes, standard input and output, and various devices.
</p>
<p>
These classes also provide limited support for regular files. This support
assumes that the underlying read and write operations provided by the operating
system never fail with <code class="computeroutput"><span class="identifier">EAGAIN</span></code>
or <code class="computeroutput"><span class="identifier">EWOULDBLOCK</span></code>. (This assumption
normally holds for buffered file I/O.) Synchronous and asynchronous read
and write operations on file descriptors will succeed but the I/O will
always be performed immediately. Wait operations, and operations involving
<code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">null_buffers</span></code>, are not portably supported.
</p>
<p>
For example, to perform read and write operations on standard input and
output, the following objects may be created:
</p>
<pre class="programlisting"><span class="identifier">posix</span><span class="special">::</span><span class="identifier">stream_descriptor</span> <span class="identifier">in</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="special">::</span><span class="identifier">dup</span><span class="special">(</span><span class="identifier">STDIN_FILENO</span><span class="special">));</span>
<span class="identifier">posix</span><span class="special">::</span><span class="identifier">stream_descriptor</span> <span class="identifier">out</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="special">::</span><span class="identifier">dup</span><span class="special">(</span><span class="identifier">STDOUT_FILENO</span><span class="special">));</span>
</pre>
<p>
These are then used as synchronous or asynchronous read and write streams.
This means the objects can be used with any of the <a class="link" href="../../reference/read.html" title="read">read()</a>,
<a class="link" href="../../reference/async_read.html" title="async_read">async_read()</a>, <a class="link" href="../../reference/write.html" title="write">write()</a>,
<a class="link" href="../../reference/async_write.html" title="async_write">async_write()</a>, <a class="link" href="../../reference/read_until.html" title="read_until">read_until()</a> or <a class="link" href="../../reference/async_read_until.html" title="async_read_until">async_read_until()</a>
free functions.
</p>
<h6>
<a name="asio.overview.posix.stream_descriptor.h0"></a>
<span><a name="asio.overview.posix.stream_descriptor.see_also"></a></span><a class="link" href="stream_descriptor.html#asio.overview.posix.stream_descriptor.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/posix__stream_descriptor.html" title="posix::stream_descriptor">posix::stream_descriptor</a>,
<a class="link" href="../../examples/cpp03_examples.html#asio.examples.cpp03_examples.chat">Chat example (C++03)</a>,
<a class="link" href="../../examples/cpp11_examples.html#asio.examples.cpp11_examples.chat">Chat example (C++11)</a>.
</p>
<h6>
<a name="asio.overview.posix.stream_descriptor.h1"></a>
<span><a name="asio.overview.posix.stream_descriptor.notes"></a></span><a class="link" href="stream_descriptor.html#asio.overview.posix.stream_descriptor.notes">Notes</a>
</h6>
<p>
POSIX stream descriptors are only available at compile time if supported
by the target operating system. A program may test for the macro <code class="computeroutput"><span class="identifier">ASIO_HAS_POSIX_STREAM_DESCRIPTOR</span></code> to determine
whether they are supported.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="local.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../posix.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="fork.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,94 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Rationale</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="../overview.html" title="Overview">
<link rel="next" href="basics.html" title="Basic Asio Anatomy">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../overview.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="basics.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.rationale"></a><a class="link" href="rationale.html" title="Rationale">Rationale</a>
</h3></div></div></div>
<p>
Most programs interact with the outside world in some way, whether it be
via a file, a network, a serial cable, or the console. Sometimes, as is the
case with networking, individual I/O operations can take a long time to complete.
This poses particular challenges to application development.
</p>
<p>
Asio provides the tools to manage these long running operations, without
requiring programs to use concurrency models based on threads and explicit
locking.
</p>
<p>
The Asio library is intended for programmers using C++ for systems programming,
where access to operating system functionality such as networking is often
required. In particular, Asio addresses the following goals:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<span class="bold"><strong>Portability.</strong></span> The library should support
a range of commonly used operating systems, and provide consistent behaviour
across these operating systems.
</li>
<li class="listitem">
<span class="bold"><strong>Scalability.</strong></span> The library should facilitate
the development of network applications that scale to thousands of concurrent
connections. The library implementation for each operating system should
use the mechanism that best enables this scalability.
</li>
<li class="listitem">
<span class="bold"><strong>Efficiency.</strong></span> The library should support
techniques such as scatter-gather I/O, and allow programs to minimise
data copying.
</li>
<li class="listitem">
<span class="bold"><strong>Model concepts from established APIs, such as BSD
sockets.</strong></span> The BSD socket API is widely implemented and understood,
and is covered in much literature. Other programming languages often
use a similar interface for networking APIs. As far as is reasonable,
Asio should leverage existing practice.
</li>
<li class="listitem">
<span class="bold"><strong>Ease of use.</strong></span> The library should provide
a lower entry barrier for new users by taking a toolkit, rather than
framework, approach. That is, it should try to minimise the up-front
investment in time to just learning a few basic rules and guidelines.
After that, a library user should only need to understand the specific
functions that are being used.
</li>
<li class="listitem">
<span class="bold"><strong>Basis for further abstraction.</strong></span> The library
should permit the development of other libraries that provide higher
levels of abstraction. For example, implementations of commonly used
protocols such as HTTP.
</li>
</ul></div>
<p>
Although Asio started life focused primarily on networking, its concepts
of asynchronous I/O have been extended to include other operating system
resources such as serial ports, file descriptors, and so on.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../overview.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="basics.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,81 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Serial Ports</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="pipes.html" title="Pipes">
<link rel="next" href="signals.html" title="Signal Handling">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="pipes.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="signals.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.serial_ports"></a><a class="link" href="serial_ports.html" title="Serial Ports">Serial Ports</a>
</h3></div></div></div>
<p>
Asio includes classes for creating and manipulating serial ports in a portable
manner. For example, a serial port may be opened using:
</p>
<pre class="programlisting"><span class="identifier">serial_port</span> <span class="identifier">port</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="identifier">name</span><span class="special">);</span>
</pre>
<p>
where name is something like <code class="computeroutput"><span class="string">"COM1"</span></code>
on Windows, and <code class="computeroutput"><span class="string">"/dev/ttyS0"</span></code>
on POSIX platforms.
</p>
<p>
Once opened, the serial port may be used as a <a class="link" href="core/streams.html" title="Streams, Short Reads and Short Writes">stream</a>.
This means the objects can be used with any of the <a class="link" href="../reference/read.html" title="read">read()</a>,
<a class="link" href="../reference/async_read.html" title="async_read">async_read()</a>, <a class="link" href="../reference/write.html" title="write">write()</a>,
<a class="link" href="../reference/async_write.html" title="async_write">async_write()</a>, <a class="link" href="../reference/read_until.html" title="read_until">read_until()</a>
or <a class="link" href="../reference/async_read_until.html" title="async_read_until">async_read_until()</a>
free functions.
</p>
<p>
The serial port implementation also includes option classes for configuring
the port's baud rate, flow control type, parity, stop bits and character
size.
</p>
<h5>
<a name="asio.overview.serial_ports.h0"></a>
<span><a name="asio.overview.serial_ports.see_also"></a></span><a class="link" href="serial_ports.html#asio.overview.serial_ports.see_also">See
Also</a>
</h5>
<p>
<a class="link" href="../reference/serial_port.html" title="serial_port">serial_port</a>, <a class="link" href="../reference/serial_port_base.html" title="serial_port_base">serial_port_base</a>,
<a class="link" href="../reference/serial_port_base__baud_rate.html" title="serial_port_base::baud_rate">serial_port_base::baud_rate</a>,
<a class="link" href="../reference/serial_port_base__flow_control.html" title="serial_port_base::flow_control">serial_port_base::flow_control</a>,
<a class="link" href="../reference/serial_port_base__parity.html" title="serial_port_base::parity">serial_port_base::parity</a>,
<a class="link" href="../reference/serial_port_base__stop_bits.html" title="serial_port_base::stop_bits">serial_port_base::stop_bits</a>,
<a class="link" href="../reference/serial_port_base__character_size.html" title="serial_port_base::character_size">serial_port_base::character_size</a>.
</p>
<h5>
<a name="asio.overview.serial_ports.h1"></a>
<span><a name="asio.overview.serial_ports.notes"></a></span><a class="link" href="serial_ports.html#asio.overview.serial_ports.notes">Notes</a>
</h5>
<p>
Serial ports are available on all POSIX platforms. For Windows, serial ports
are only available at compile time when the I/O completion port backend is
used (which is the default). A program may test for the macro <code class="computeroutput"><span class="identifier">ASIO_HAS_SERIAL_PORT</span></code> to determine whether
they are supported.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="pipes.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="signals.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,73 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Signal Handling</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="serial_ports.html" title="Serial Ports">
<link rel="next" href="channels.html" title="Channels">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="serial_ports.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="channels.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.signals"></a><a class="link" href="signals.html" title="Signal Handling">Signal Handling</a>
</h3></div></div></div>
<p>
Asio supports signal handling using a class called <a class="link" href="../reference/signal_set.html" title="signal_set">signal_set</a>.
Programs may add one or more signals to the set, and then perform an <code class="computeroutput"><span class="identifier">async_wait</span><span class="special">()</span></code>
operation. The specified handler will be called when one of the signals occurs.
The same signal number may be registered with multiple <a class="link" href="../reference/signal_set.html" title="signal_set">signal_set</a>
objects, however the signal number must be used only with Asio.
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span>
<span class="keyword">const</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">&amp;</span> <span class="identifier">error</span><span class="special">,</span>
<span class="keyword">int</span> <span class="identifier">signal_number</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">error</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// A signal occurred.</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="comment">// Construct a signal set registered for process termination.</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">signal_set</span> <span class="identifier">signals</span><span class="special">(</span><span class="identifier">io_context</span><span class="special">,</span> <span class="identifier">SIGINT</span><span class="special">,</span> <span class="identifier">SIGTERM</span><span class="special">);</span>
<span class="comment">// Start an asynchronous wait for one of the signals to occur.</span>
<span class="identifier">signals</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">handler</span><span class="special">);</span>
</pre>
<p>
Signal handling also works on Windows, as the Microsoft Visual C++ runtime
library maps console events like Ctrl+C to the equivalent signal.
</p>
<h5>
<a name="asio.overview.signals.h0"></a>
<span><a name="asio.overview.signals.see_also"></a></span><a class="link" href="signals.html#asio.overview.signals.see_also">See
Also</a>
</h5>
<p>
<a class="link" href="../reference/signal_set.html" title="signal_set">signal_set</a>, <a class="link" href="../examples/cpp03_examples.html#asio.examples.cpp03_examples.http_server">HTTP
server example (C++03)</a>, <a class="link" href="../examples/cpp11_examples.html#asio.examples.cpp11_examples.http_server">HTTP
server example (C++11)</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="serial_ports.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="channels.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,185 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SSL</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="windows/object_handle.html" title="Object HANDLEs">
<link rel="next" href="cpp2011.html" title="C++ 2011 Support">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="windows/object_handle.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp2011.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.ssl"></a><a class="link" href="ssl.html" title="SSL">SSL</a>
</h3></div></div></div>
<p>
Asio contains classes and class templates for basic SSL support. These classes
allow encrypted communication to be layered on top of an existing stream,
such as a TCP socket.
</p>
<p>
Before creating an encrypted stream, an application must construct an SSL
context object. This object is used to set SSL options such as verification
mode, certificate files, and so on. As an illustration, client-side initialisation
may look something like:
</p>
<pre class="programlisting"><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">context</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">sslv23</span><span class="special">);</span>
<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">set_verify_mode</span><span class="special">(</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">verify_peer</span><span class="special">);</span>
<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">load_verify_file</span><span class="special">(</span><span class="string">"ca.pem"</span><span class="special">);</span>
</pre>
<p>
To use SSL with a TCP socket, one may write:
</p>
<pre class="programlisting"><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span> <span class="identifier">ssl_sock</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span>
</pre>
<p>
To perform socket-specific operations, such as establishing an outbound connection
or accepting an incoming one, the underlying socket must first be obtained
using the <code class="computeroutput"><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span></code> template's <a class="link" href="../reference/ssl__stream/lowest_layer.html" title="ssl::stream::lowest_layer"><code class="computeroutput"><span class="identifier">lowest_layer</span><span class="special">()</span></code></a>
member function:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">::</span><span class="identifier">lowest_layer_type</span><span class="special">&amp;</span> <span class="identifier">sock</span> <span class="special">=</span> <span class="identifier">ssl_sock</span><span class="special">.</span><span class="identifier">lowest_layer</span><span class="special">();</span>
<span class="identifier">sock</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">my_endpoint</span><span class="special">);</span>
</pre>
<p>
In some use cases the underlying stream object will need to have a longer
lifetime than the SSL stream, in which case the template parameter should
be a reference to the stream type:
</p>
<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">sock</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;&gt;</span> <span class="identifier">ssl_sock</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span>
</pre>
<p>
SSL handshaking must be performed prior to transmitting or receiving data
over an encrypted connection. This is accomplished using the <code class="computeroutput"><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span></code>
template's <a class="link" href="../reference/ssl__stream/handshake.html" title="ssl::stream::handshake">handshake()</a>
or <a class="link" href="../reference/ssl__stream/async_handshake.html" title="ssl::stream::async_handshake">async_handshake()</a>
member functions.
</p>
<p>
Once connected, SSL stream objects are used as synchronous or asynchronous
read and write streams. This means the objects can be used with any of the
<a class="link" href="../reference/read.html" title="read">read()</a>, <a class="link" href="../reference/async_read.html" title="async_read">async_read()</a>,
<a class="link" href="../reference/write.html" title="write">write()</a>, <a class="link" href="../reference/async_write.html" title="async_write">async_write()</a>,
<a class="link" href="../reference/read_until.html" title="read_until">read_until()</a> or <a class="link" href="../reference/async_read_until.html" title="async_read_until">async_read_until()</a>
free functions.
</p>
<h5>
<a name="asio.overview.ssl.h0"></a>
<span><a name="asio.overview.ssl.certificate_verification"></a></span><a class="link" href="ssl.html#asio.overview.ssl.certificate_verification">Certificate
Verification</a>
</h5>
<p>
Asio provides various methods for configuring the way SSL certificates are
verified:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<a class="link" href="../reference/ssl__context/set_default_verify_paths.html" title="ssl::context::set_default_verify_paths">ssl::context::set_default_verify_paths()</a>
</li>
<li class="listitem">
<a class="link" href="../reference/ssl__context/set_verify_mode.html" title="ssl::context::set_verify_mode">ssl::context::set_verify_mode()</a>
</li>
<li class="listitem">
<a class="link" href="../reference/ssl__context/set_verify_callback.html" title="ssl::context::set_verify_callback">ssl::context::set_verify_callback()</a>
</li>
<li class="listitem">
<a class="link" href="../reference/ssl__context/load_verify_file.html" title="ssl::context::load_verify_file">ssl::context::load_verify_file()</a>
</li>
<li class="listitem">
<a class="link" href="../reference/ssl__stream/set_verify_mode.html" title="ssl::stream::set_verify_mode">ssl::stream::set_verify_mode()</a>
</li>
<li class="listitem">
<a class="link" href="../reference/ssl__stream/set_verify_callback.html" title="ssl::stream::set_verify_callback">ssl::stream::set_verify_callback()</a>
</li>
</ul></div>
<p>
To simplify use cases where certificates are verified according to the rules
in RFC 6125 (identity verification in the context of Transport Layer Security),
Asio provides a reusable verification callback as a function object:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a class="link" href="../reference/ssl__host_name_verification.html" title="ssl::host_name_verification">ssl::host_name_verification</a>
</li></ul></div>
<p>
The following example shows verification of a remote host's certificate according
to the rules used by HTTPS:
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">;</span>
<span class="keyword">namespace</span> <span class="identifier">ssl</span> <span class="special">=</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">ssl</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span> <span class="identifier">ssl_socket</span><span class="special">;</span>
<span class="comment">// Create a context that uses the default paths for</span>
<span class="comment">// finding CA certificates.</span>
<span class="identifier">ssl</span><span class="special">::</span><span class="identifier">context</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">sslv23</span><span class="special">);</span>
<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">set_default_verify_paths</span><span class="special">();</span>
<span class="comment">// Open a socket and connect it to the remote host.</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span> <span class="identifier">io_context</span><span class="special">;</span>
<span class="identifier">ssl_socket</span> <span class="identifier">sock</span><span class="special">(</span><span class="identifier">io_context</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span> <span class="identifier">resolver</span><span class="special">(</span><span class="identifier">io_context</span><span class="special">);</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span><span class="special">::</span><span class="identifier">query</span> <span class="identifier">query</span><span class="special">(</span><span class="string">"host.name"</span><span class="special">,</span> <span class="string">"https"</span><span class="special">);</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">sock</span><span class="special">.</span><span class="identifier">lowest_layer</span><span class="special">(),</span> <span class="identifier">resolver</span><span class="special">.</span><span class="identifier">resolve</span><span class="special">(</span><span class="identifier">query</span><span class="special">));</span>
<span class="identifier">sock</span><span class="special">.</span><span class="identifier">lowest_layer</span><span class="special">().</span><span class="identifier">set_option</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">no_delay</span><span class="special">(</span><span class="keyword">true</span><span class="special">));</span>
<span class="comment">// Perform SSL handshake and verify the remote host's</span>
<span class="comment">// certificate.</span>
<span class="identifier">sock</span><span class="special">.</span><span class="identifier">set_verify_mode</span><span class="special">(</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">verify_peer</span><span class="special">);</span>
<span class="identifier">sock</span><span class="special">.</span><span class="identifier">set_verify_callback</span><span class="special">(</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">host_name_verification</span><span class="special">(</span><span class="string">"host.name"</span><span class="special">));</span>
<span class="identifier">sock</span><span class="special">.</span><span class="identifier">handshake</span><span class="special">(</span><span class="identifier">ssl_socket</span><span class="special">::</span><span class="identifier">client</span><span class="special">);</span>
<span class="comment">// ... read and write as normal ...</span>
</pre>
<h5>
<a name="asio.overview.ssl.h1"></a>
<span><a name="asio.overview.ssl.ssl_and_threads"></a></span><a class="link" href="ssl.html#asio.overview.ssl.ssl_and_threads">SSL
and Threads</a>
</h5>
<p>
SSL stream objects perform no locking of their own. Therefore, it is essential
that all asynchronous SSL operations are performed in an implicit or explicit
<a class="link" href="core/strands.html" title="Strands: Use Threads Without Explicit Locking">strand</a>. Note that this
means that no synchronisation is required (and so no locking overhead is
incurred) in single threaded programs.
</p>
<h5>
<a name="asio.overview.ssl.h2"></a>
<span><a name="asio.overview.ssl.see_also"></a></span><a class="link" href="ssl.html#asio.overview.ssl.see_also">See
Also</a>
</h5>
<p>
<a class="link" href="../reference/ssl__context.html" title="ssl::context">ssl::context</a>, <a class="link" href="../reference/ssl__host_name_verification.html" title="ssl::host_name_verification">ssl::host_name_verification</a>,
<a class="link" href="../reference/ssl__stream.html" title="ssl::stream">ssl::stream</a>, <a class="link" href="../examples/cpp03_examples.html#asio.examples.cpp03_examples.ssl">SSL
example (C++03)</a>, <a class="link" href="../examples/cpp11_examples.html#asio.examples.cpp11_examples.ssl">SSL
example (C++11)</a>.
</p>
<h5>
<a name="asio.overview.ssl.h3"></a>
<span><a name="asio.overview.ssl.notes"></a></span><a class="link" href="ssl.html#asio.overview.ssl.notes">Notes</a>
</h5>
<p>
<a href="http://www.openssl.org" target="_top">OpenSSL</a> is required to make use
of Asio's SSL support. When an application needs to use OpenSSL functionality
that is not wrapped by Asio, the underlying OpenSSL types may be obtained
by calling <a class="link" href="../reference/ssl__context/native_handle.html" title="ssl::context::native_handle"><code class="computeroutput"><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">native_handle</span><span class="special">()</span></code></a> or <a class="link" href="../reference/ssl__stream/native_handle.html" title="ssl::stream::native_handle"><code class="computeroutput"><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span><span class="special">::</span><span class="identifier">native_handle</span><span class="special">()</span></code></a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="windows/object_handle.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="cpp2011.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,86 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Timers</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="networking/bsd_sockets.html" title="The BSD Socket API and Asio">
<link rel="next" href="files.html" title="Files">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="networking/bsd_sockets.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="files.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.timers"></a><a class="link" href="timers.html" title="Timers">Timers</a>
</h3></div></div></div>
<p>
Long running I/O operations will often have a deadline by which they must
have completed. These deadlines may be expressed as absolute times, but are
often calculated relative to the current time.
</p>
<p>
As a simple example, to perform a synchronous wait operation on a timer using
a relative time one may write:
</p>
<pre class="programlisting"><span class="identifier">io_context</span> <span class="identifier">i</span><span class="special">;</span>
<span class="special">...</span>
<span class="identifier">steady_timer</span> <span class="identifier">t</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">t</span><span class="special">.</span><span class="identifier">expires_after</span><span class="special">(</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">5</span><span class="special">));</span>
<span class="identifier">t</span><span class="special">.</span><span class="identifier">wait</span><span class="special">();</span>
</pre>
<p>
More commonly, a program will perform an asynchronous wait operation on a
timer:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
<span class="special">...</span>
<span class="identifier">io_context</span> <span class="identifier">i</span><span class="special">;</span>
<span class="special">...</span>
<span class="identifier">steady_timer</span> <span class="identifier">t</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">t</span><span class="special">.</span><span class="identifier">expires_after</span><span class="special">(</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">milliseconds</span><span class="special">(</span><span class="number">400</span><span class="special">));</span>
<span class="identifier">t</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">handler</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">i</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
</pre>
<p>
The deadline associated with a timer may also be obtained as an absolute
time:
</p>
<pre class="programlisting"><span class="identifier">steady_timer</span><span class="special">::</span><span class="identifier">time_point</span> <span class="identifier">time_of_expiry</span> <span class="special">=</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">expiry</span><span class="special">();</span>
</pre>
<p>
which allows composition of timers:
</p>
<pre class="programlisting"><span class="identifier">steady_timer</span> <span class="identifier">t2</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">t2</span><span class="special">.</span><span class="identifier">expires_at</span><span class="special">(</span><span class="identifier">t</span><span class="special">.</span><span class="identifier">expiry</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">30</span><span class="special">));</span>
</pre>
<h5>
<a name="asio.overview.timers.h0"></a>
<span><a name="asio.overview.timers.see_also"></a></span><a class="link" href="timers.html#asio.overview.timers.see_also">See
Also</a>
</h5>
<p>
<a class="link" href="../reference/basic_waitable_timer.html" title="basic_waitable_timer">basic_waitable_timer</a>,
<a class="link" href="../reference/steady_timer.html" title="steady_timer">steady_timer</a>, <a class="link" href="../reference/system_timer.html" title="system_timer">system_timer</a>,
<a class="link" href="../reference/high_resolution_timer.html" title="high_resolution_timer">high_resolution_timer</a>,
<a class="link" href="../tutorial/tuttimer1.html" title="Timer.1 - Using a timer synchronously">timer tutorials</a>.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="networking/bsd_sockets.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="files.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,44 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Windows-Specific Functionality</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../overview.html" title="Overview">
<link rel="prev" href="posix/fork.html" title="Fork">
<link rel="next" href="windows/stream_handle.html" title="Stream-Oriented HANDLEs">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="posix/fork.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="windows/stream_handle.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.overview.windows"></a><a class="link" href="windows.html" title="Windows-Specific Functionality">Windows-Specific Functionality</a>
</h3></div></div></div>
<p>
<a class="link" href="windows/stream_handle.html" title="Stream-Oriented HANDLEs">Stream-Oriented HANDLEs</a>
</p>
<p>
<a class="link" href="windows/random_access_handle.html" title="Random-Access HANDLEs">Random-Access
HANDLEs</a>
</p>
<p>
<a class="link" href="windows/object_handle.html" title="Object HANDLEs">Object HANDLEs</a>
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="posix/fork.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../overview.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="windows/stream_handle.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,94 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Object HANDLEs</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../windows.html" title="Windows-Specific Functionality">
<link rel="prev" href="random_access_handle.html" title="Random-Access HANDLEs">
<link rel="next" href="../ssl.html" title="SSL">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="random_access_handle.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../windows.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../ssl.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.windows.object_handle"></a><a class="link" href="object_handle.html" title="Object HANDLEs">Object HANDLEs</a>
</h4></div></div></div>
<p>
Asio provides Windows-specific classes that permit asynchronous wait operations
to be performed on HANDLEs to kernel objects of the following types:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Change notification
</li>
<li class="listitem">
Console input
</li>
<li class="listitem">
Event
</li>
<li class="listitem">
Memory resource notification
</li>
<li class="listitem">
Process
</li>
<li class="listitem">
Semaphore
</li>
<li class="listitem">
Thread
</li>
<li class="listitem">
Waitable timer
</li>
</ul></div>
<p>
For example, to perform asynchronous operations on an event, the following
object may be created:
</p>
<pre class="programlisting"><span class="identifier">HANDLE</span> <span class="identifier">handle</span> <span class="special">=</span> <span class="special">::</span><span class="identifier">CreateEvent</span><span class="special">(...);</span>
<span class="identifier">windows</span><span class="special">::</span><span class="identifier">object_handle</span> <span class="identifier">file</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="identifier">handle</span><span class="special">);</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">async_wait</span><span class="special">()</span></code>
member functions may then be used to wait until the kernel object is signalled.
</p>
<h6>
<a name="asio.overview.windows.object_handle.h0"></a>
<span><a name="asio.overview.windows.object_handle.see_also"></a></span><a class="link" href="object_handle.html#asio.overview.windows.object_handle.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/windows__object_handle.html" title="windows::object_handle">windows::object_handle</a>.
</p>
<h6>
<a name="asio.overview.windows.object_handle.h1"></a>
<span><a name="asio.overview.windows.object_handle.notes"></a></span><a class="link" href="object_handle.html#asio.overview.windows.object_handle.notes">Notes</a>
</h6>
<p>
Windows object <code class="computeroutput"><span class="identifier">HANDLE</span></code>s
are only available at compile time when targeting Windows. Programs may
test for the macro <code class="computeroutput"><span class="identifier">ASIO_HAS_WINDOWS_OBJECT_HANDLE</span></code>
to determine whether they are supported.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="random_access_handle.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../windows.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="../ssl.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,76 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Random-Access HANDLEs</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../windows.html" title="Windows-Specific Functionality">
<link rel="prev" href="stream_handle.html" title="Stream-Oriented HANDLEs">
<link rel="next" href="object_handle.html" title="Object HANDLEs">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stream_handle.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../windows.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="object_handle.html"><img src="../../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="asio.overview.windows.random_access_handle"></a><a class="link" href="random_access_handle.html" title="Random-Access HANDLEs">Random-Access
HANDLEs</a>
</h4></div></div></div>
<p>
Asio provides Windows-specific classes that permit asynchronous read and
write operations to be performed on HANDLEs that refer to regular files.
</p>
<p>
For example, to perform asynchronous operations on a file the following
object may be created:
</p>
<pre class="programlisting"><span class="identifier">HANDLE</span> <span class="identifier">handle</span> <span class="special">=</span> <span class="special">::</span><span class="identifier">CreateFile</span><span class="special">(...);</span>
<span class="identifier">windows</span><span class="special">::</span><span class="identifier">random_access_handle</span> <span class="identifier">file</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">,</span> <span class="identifier">handle</span><span class="special">);</span>
</pre>
<p>
Data may be read from or written to the handle using one of the <code class="computeroutput"><span class="identifier">read_some_at</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">async_read_some_at</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">write_some_at</span><span class="special">()</span></code>
or <code class="computeroutput"><span class="identifier">async_write_some_at</span><span class="special">()</span></code> member functions. However, like the equivalent
functions (<code class="computeroutput"><span class="identifier">read_some</span><span class="special">()</span></code>,
etc.) on streams, these functions are only required to transfer one or
more bytes in a single operation. Therefore free functions called <a class="link" href="../../reference/read_at.html" title="read_at">read_at()</a>, <a class="link" href="../../reference/async_read_at.html" title="async_read_at">async_read_at()</a>,
<a class="link" href="../../reference/write_at.html" title="write_at">write_at()</a> and <a class="link" href="../../reference/async_write_at.html" title="async_write_at">async_write_at()</a>
have been created to repeatedly call the corresponding <code class="literal"><span class="bold"><strong>*</strong></span>_some_at()</code> function until all data has
been transferred.
</p>
<h6>
<a name="asio.overview.windows.random_access_handle.h0"></a>
<span><a name="asio.overview.windows.random_access_handle.see_also"></a></span><a class="link" href="random_access_handle.html#asio.overview.windows.random_access_handle.see_also">See Also</a>
</h6>
<p>
<a class="link" href="../../reference/windows__random_access_handle.html" title="windows::random_access_handle">windows::random_access_handle</a>.
</p>
<h6>
<a name="asio.overview.windows.random_access_handle.h1"></a>
<span><a name="asio.overview.windows.random_access_handle.notes"></a></span><a class="link" href="random_access_handle.html#asio.overview.windows.random_access_handle.notes">Notes</a>
</h6>
<p>
Windows random-access <code class="computeroutput"><span class="identifier">HANDLE</span></code>s
are only available at compile time when targeting Windows and only when
the I/O completion port backend is used (which is the default). A program
may test for the macro <code class="computeroutput"><span class="identifier">ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE</span></code>
to determine whether they are supported.
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 Christopher M. Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stream_handle.html"><img src="../../../prev.png" alt="Prev"></a><a accesskey="u" href="../windows.html"><img src="../../../up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../home.png" alt="Home"></a><a accesskey="n" href="object_handle.html"><img src="../../../next.png" alt="Next"></a>
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More