@ -0,0 +1,243 @@ |
|||
@ECHO OFF |
|||
|
|||
REM Command file for Sphinx documentation |
|||
|
|||
if "%SPHINXBUILD%" == "" ( |
|||
set SPHINXBUILD=sphinx-build |
|||
) |
|||
set BUILDDIR=build |
|||
set SRCDIR=src |
|||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SRCDIR% |
|||
set I18NSPHINXOPTS=%SPHINXOPTS% %SRCDIR% |
|||
if NOT "%PAPER%" == "" ( |
|||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% |
|||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% |
|||
) |
|||
|
|||
if "%1" == "" goto help |
|||
|
|||
if "%1" == "help" ( |
|||
:help |
|||
echo.Please use `make ^<target^>` where ^<target^> is one of |
|||
echo. html to make standalone HTML files |
|||
echo. dirhtml to make HTML files named index.html in directories |
|||
echo. singlehtml to make a single large HTML file |
|||
echo. pickle to make pickle files |
|||
echo. json to make JSON files |
|||
echo. htmlhelp to make HTML files and a HTML help project |
|||
echo. qthelp to make HTML files and a qthelp project |
|||
echo. devhelp to make HTML files and a Devhelp project |
|||
echo. epub to make an epub |
|||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter |
|||
echo. text to make text files |
|||
echo. man to make manual pages |
|||
echo. texinfo to make Texinfo files |
|||
echo. gettext to make PO message catalogs |
|||
echo. changes to make an overview over all changed/added/deprecated items |
|||
echo. xml to make Docutils-native XML files |
|||
echo. pseudoxml to make pseudoxml-XML files for display purposes |
|||
echo. linkcheck to check all external links for integrity |
|||
echo. doctest to run all doctests embedded in the documentation if enabled |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "clean" ( |
|||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i |
|||
del /q /s %BUILDDIR%\* |
|||
goto end |
|||
) |
|||
|
|||
|
|||
%SPHINXBUILD% 2> nul |
|||
if errorlevel 9009 ( |
|||
echo. |
|||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx |
|||
echo.installed, then set the SPHINXBUILD environment variable to point |
|||
echo.to the full path of the 'sphinx-build' executable. Alternatively you |
|||
echo.may add the Sphinx directory to PATH. |
|||
echo. |
|||
echo.If you don't have Sphinx installed, grab it from |
|||
echo.http://sphinx-doc.org/ |
|||
exit /b 1 |
|||
) |
|||
|
|||
if "%1" == "html" ( |
|||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The HTML pages are in %BUILDDIR%/html. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "dirhtml" ( |
|||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "singlehtml" ( |
|||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "pickle" ( |
|||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished; now you can process the pickle files. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "json" ( |
|||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished; now you can process the JSON files. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "htmlhelp" ( |
|||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished; now you can run HTML Help Workshop with the ^ |
|||
.hhp project file in %BUILDDIR%/htmlhelp. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "qthelp" ( |
|||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished; now you can run "qcollectiongenerator" with the ^ |
|||
.qhcp project file in %BUILDDIR%/qthelp, like this: |
|||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\libuv.qhcp |
|||
echo.To view the help file: |
|||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\libuv.ghc |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "devhelp" ( |
|||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "epub" ( |
|||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The epub file is in %BUILDDIR%/epub. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "latex" ( |
|||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "latexpdf" ( |
|||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex |
|||
cd %BUILDDIR%/latex |
|||
make all-pdf |
|||
cd %BUILDDIR%/.. |
|||
echo. |
|||
echo.Build finished; the PDF files are in %BUILDDIR%/latex. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "latexpdfja" ( |
|||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex |
|||
cd %BUILDDIR%/latex |
|||
make all-pdf-ja |
|||
cd %BUILDDIR%/.. |
|||
echo. |
|||
echo.Build finished; the PDF files are in %BUILDDIR%/latex. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "text" ( |
|||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The text files are in %BUILDDIR%/text. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "man" ( |
|||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The manual pages are in %BUILDDIR%/man. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "texinfo" ( |
|||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "gettext" ( |
|||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "changes" ( |
|||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.The overview file is in %BUILDDIR%/changes. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "linkcheck" ( |
|||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Link check complete; look for any errors in the above output ^ |
|||
or in %BUILDDIR%/linkcheck/output.txt. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "doctest" ( |
|||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Testing of doctests in the sources finished, look at the ^ |
|||
results in %BUILDDIR%/doctest/output.txt. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "xml" ( |
|||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The XML files are in %BUILDDIR%/xml. |
|||
goto end |
|||
) |
|||
|
|||
if "%1" == "pseudoxml" ( |
|||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml |
|||
if errorlevel 1 exit /b 1 |
|||
echo. |
|||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. |
|||
goto end |
|||
) |
|||
|
|||
:end |
@ -0,0 +1,56 @@ |
|||
|
|||
.. _async: |
|||
|
|||
:c:type:`uv_async_t` --- Async handle |
|||
===================================== |
|||
|
|||
Async handles allow the user to "wakeup" the event loop and get a callback |
|||
called from another thread. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_async_t |
|||
|
|||
Async handle type. |
|||
|
|||
.. c:type:: void (*uv_async_cb)(uv_async_t* handle) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_async_init`. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) |
|||
|
|||
Initialize the handle. A NULL callback is allowed. |
|||
|
|||
.. note:: |
|||
Unlike other handle initialization functions, it immediately starts the handle. |
|||
|
|||
.. c:function:: int uv_async_send(uv_async_t* async) |
|||
|
|||
Wakeup the event loop and call the async handle's callback. |
|||
|
|||
.. note:: |
|||
It's safe to call this function from any thread. The callback will be called on the |
|||
loop thread. |
|||
|
|||
.. warning:: |
|||
libuv will coalesce calls to :c:func:`uv_async_send`, that is, not every call to it will |
|||
yield an execution of the callback, the only guarantee is that it will be called at least |
|||
once. Thus, calling this function may not wakeup the event loop if it was already called |
|||
previously within a short period of time. |
|||
|
|||
.. seealso:: |
|||
The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,46 @@ |
|||
|
|||
.. _check: |
|||
|
|||
:c:type:`uv_check_t` --- Check handle |
|||
===================================== |
|||
|
|||
Check handles will run the given callback once per loop iteration, right |
|||
after polling for i/o. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_check_t |
|||
|
|||
Check handle type. |
|||
|
|||
.. c:type:: void (*uv_check_cb)(uv_check_t* handle) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_check_start`. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_check_init(uv_loop_t*, uv_check_t* check) |
|||
|
|||
Initialize the handle. |
|||
|
|||
.. c:function:: int uv_check_start(uv_check_t* check, uv_check_cb cb) |
|||
|
|||
Start the handle with the given callback. |
|||
|
|||
.. c:function:: int uv_check_stop(uv_check_t* check) |
|||
|
|||
Stop the handle, the callback will no longer be called. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,348 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# |
|||
# libuv API documentation documentation build configuration file, created by |
|||
# sphinx-quickstart on Sun Jul 27 11:47:51 2014. |
|||
# |
|||
# This file is execfile()d with the current directory set to its |
|||
# containing dir. |
|||
# |
|||
# Note that not all possible configuration values are present in this |
|||
# autogenerated file. |
|||
# |
|||
# All configuration values have a default; values that are commented out |
|||
# serve to show the default. |
|||
|
|||
import os |
|||
import re |
|||
import sys |
|||
|
|||
|
|||
def get_libuv_version(): |
|||
with open('../../include/uv-version.h') as f: |
|||
data = f.read() |
|||
try: |
|||
m = re.search(r"""^#define UV_VERSION_MAJOR (\d)$""", data, re.MULTILINE) |
|||
major = int(m.group(1)) |
|||
m = re.search(r"""^#define UV_VERSION_MINOR (\d)$""", data, re.MULTILINE) |
|||
minor = int(m.group(1)) |
|||
m = re.search(r"""^#define UV_VERSION_PATCH (\d)$""", data, re.MULTILINE) |
|||
patch = int(m.group(1)) |
|||
m = re.search(r"""^#define UV_VERSION_IS_RELEASE (\d)$""", data, re.MULTILINE) |
|||
is_release = int(m.group(1)) |
|||
m = re.search(r"""^#define UV_VERSION_SUFFIX \"(\w*)\"$""", data, re.MULTILINE) |
|||
suffix = m.group(1) |
|||
return '%d.%d.%d%s' % (major, minor, patch, '-%s' % suffix if not is_release else '') |
|||
except Exception: |
|||
return 'unknown' |
|||
|
|||
# If extensions (or modules to document with autodoc) are in another directory, |
|||
# add these directories to sys.path here. If the directory is relative to the |
|||
# documentation root, use os.path.abspath to make it absolute, like shown here. |
|||
#sys.path.insert(0, os.path.abspath('.')) |
|||
|
|||
# -- General configuration ------------------------------------------------ |
|||
|
|||
# If your documentation needs a minimal Sphinx version, state it here. |
|||
#needs_sphinx = '1.0' |
|||
|
|||
# Add any Sphinx extension module names here, as strings. They can be |
|||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom |
|||
# ones. |
|||
extensions = [] |
|||
|
|||
# Add any paths that contain templates here, relative to this directory. |
|||
templates_path = ['templates'] |
|||
|
|||
# The suffix of source filenames. |
|||
source_suffix = '.rst' |
|||
|
|||
# The encoding of source files. |
|||
#source_encoding = 'utf-8-sig' |
|||
|
|||
# The master toctree document. |
|||
master_doc = 'index' |
|||
|
|||
# General information about the project. |
|||
project = u'libuv API documentation' |
|||
copyright = u'libuv contributors' |
|||
|
|||
# The version info for the project you're documenting, acts as replacement for |
|||
# |version| and |release|, also used in various other places throughout the |
|||
# built documents. |
|||
# |
|||
# The short X.Y version. |
|||
version = get_libuv_version() |
|||
# The full version, including alpha/beta/rc tags. |
|||
release = version |
|||
|
|||
# The language for content autogenerated by Sphinx. Refer to documentation |
|||
# for a list of supported languages. |
|||
#language = None |
|||
|
|||
# There are two options for replacing |today|: either, you set today to some |
|||
# non-false value, then it is used: |
|||
#today = '' |
|||
# Else, today_fmt is used as the format for a strftime call. |
|||
#today_fmt = '%B %d, %Y' |
|||
|
|||
# List of patterns, relative to source directory, that match files and |
|||
# directories to ignore when looking for source files. |
|||
exclude_patterns = [] |
|||
|
|||
# The reST default role (used for this markup: `text`) to use for all |
|||
# documents. |
|||
#default_role = None |
|||
|
|||
# If true, '()' will be appended to :func: etc. cross-reference text. |
|||
#add_function_parentheses = True |
|||
|
|||
# If true, the current module name will be prepended to all description |
|||
# unit titles (such as .. function::). |
|||
#add_module_names = True |
|||
|
|||
# If true, sectionauthor and moduleauthor directives will be shown in the |
|||
# output. They are ignored by default. |
|||
#show_authors = False |
|||
|
|||
# The name of the Pygments (syntax highlighting) style to use. |
|||
pygments_style = 'sphinx' |
|||
|
|||
# A list of ignored prefixes for module index sorting. |
|||
#modindex_common_prefix = [] |
|||
|
|||
# If true, keep warnings as "system message" paragraphs in the built documents. |
|||
#keep_warnings = False |
|||
|
|||
|
|||
# -- Options for HTML output ---------------------------------------------- |
|||
|
|||
# The theme to use for HTML and HTML Help pages. See the documentation for |
|||
# a list of builtin themes. |
|||
html_theme = 'nature' |
|||
|
|||
# Theme options are theme-specific and customize the look and feel of a theme |
|||
# further. For a list of options available for each theme, see the |
|||
# documentation. |
|||
#html_theme_options = {} |
|||
|
|||
# Add any paths that contain custom themes here, relative to this directory. |
|||
#html_theme_path = [] |
|||
|
|||
# The name for this set of Sphinx documents. If None, it defaults to |
|||
# "<project> v<release> documentation". |
|||
html_title = 'libuv API documentation' |
|||
|
|||
# A shorter title for the navigation bar. Default is the same as html_title. |
|||
html_short_title = 'libuv %s API documentation' % version |
|||
|
|||
# The name of an image file (relative to this directory) to place at the top |
|||
# of the sidebar. |
|||
html_logo = 'static/logo.png' |
|||
|
|||
# The name of an image file (within the static path) to use as favicon of the |
|||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
|||
# pixels large. |
|||
html_favicon = 'static/favicon.ico' |
|||
|
|||
# Add any paths that contain custom static files (such as style sheets) here, |
|||
# relative to this directory. They are copied after the builtin static files, |
|||
# so a file named "default.css" will overwrite the builtin "default.css". |
|||
html_static_path = ['static'] |
|||
|
|||
# Add any extra paths that contain custom files (such as robots.txt or |
|||
# .htaccess) here, relative to this directory. These files are copied |
|||
# directly to the root of the documentation. |
|||
#html_extra_path = [] |
|||
|
|||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, |
|||
# using the given strftime format. |
|||
#html_last_updated_fmt = '%b %d, %Y' |
|||
|
|||
# If true, SmartyPants will be used to convert quotes and dashes to |
|||
# typographically correct entities. |
|||
#html_use_smartypants = True |
|||
|
|||
# Custom sidebar templates, maps document names to template names. |
|||
#html_sidebars = {} |
|||
|
|||
# Additional templates that should be rendered to pages, maps page names to |
|||
# template names. |
|||
#html_additional_pages = {} |
|||
|
|||
# If false, no module index is generated. |
|||
#html_domain_indices = True |
|||
|
|||
# If false, no index is generated. |
|||
#html_use_index = True |
|||
|
|||
# If true, the index is split into individual pages for each letter. |
|||
#html_split_index = False |
|||
|
|||
# If true, links to the reST sources are added to the pages. |
|||
#html_show_sourcelink = True |
|||
|
|||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. |
|||
#html_show_sphinx = True |
|||
|
|||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. |
|||
#html_show_copyright = True |
|||
|
|||
# If true, an OpenSearch description file will be output, and all pages will |
|||
# contain a <link> tag referring to it. The value of this option must be the |
|||
# base URL from which the finished HTML is served. |
|||
#html_use_opensearch = '' |
|||
|
|||
# This is the file name suffix for HTML files (e.g. ".xhtml"). |
|||
#html_file_suffix = None |
|||
|
|||
# Output file base name for HTML help builder. |
|||
htmlhelp_basename = 'libuv' |
|||
|
|||
|
|||
# -- Options for LaTeX output --------------------------------------------- |
|||
|
|||
latex_elements = { |
|||
# The paper size ('letterpaper' or 'a4paper'). |
|||
#'papersize': 'letterpaper', |
|||
|
|||
# The font size ('10pt', '11pt' or '12pt'). |
|||
#'pointsize': '10pt', |
|||
|
|||
# Additional stuff for the LaTeX preamble. |
|||
#'preamble': '', |
|||
} |
|||
|
|||
# Grouping the document tree into LaTeX files. List of tuples |
|||
# (source start file, target name, title, |
|||
# author, documentclass [howto, manual, or own class]). |
|||
latex_documents = [ |
|||
('index', 'libuv.tex', u'libuv API documentation', |
|||
u'libuv contributors', 'manual'), |
|||
] |
|||
|
|||
# The name of an image file (relative to this directory) to place at the top of |
|||
# the title page. |
|||
#latex_logo = None |
|||
|
|||
# For "manual" documents, if this is true, then toplevel headings are parts, |
|||
# not chapters. |
|||
#latex_use_parts = False |
|||
|
|||
# If true, show page references after internal links. |
|||
#latex_show_pagerefs = False |
|||
|
|||
# If true, show URL addresses after external links. |
|||
#latex_show_urls = False |
|||
|
|||
# Documents to append as an appendix to all manuals. |
|||
#latex_appendices = [] |
|||
|
|||
# If false, no module index is generated. |
|||
#latex_domain_indices = True |
|||
|
|||
|
|||
# -- Options for manual page output --------------------------------------- |
|||
|
|||
# One entry per manual page. List of tuples |
|||
# (source start file, name, description, authors, manual section). |
|||
man_pages = [ |
|||
('index', 'libuv', u'libuv API documentation', |
|||
[u'libuv contributors'], 1) |
|||
] |
|||
|
|||
# If true, show URL addresses after external links. |
|||
#man_show_urls = False |
|||
|
|||
|
|||
# -- Options for Texinfo output ------------------------------------------- |
|||
|
|||
# Grouping the document tree into Texinfo files. List of tuples |
|||
# (source start file, target name, title, author, |
|||
# dir menu entry, description, category) |
|||
texinfo_documents = [ |
|||
('index', 'libuv', u'libuv API documentation', |
|||
u'libuv contributors', 'libuv', 'Cross-platform asychronous I/O', |
|||
'Miscellaneous'), |
|||
] |
|||
|
|||
# Documents to append as an appendix to all manuals. |
|||
#texinfo_appendices = [] |
|||
|
|||
# If false, no module index is generated. |
|||
#texinfo_domain_indices = True |
|||
|
|||
# How to display URL addresses: 'footnote', 'no', or 'inline'. |
|||
#texinfo_show_urls = 'footnote' |
|||
|
|||
# If true, do not generate a @detailmenu in the "Top" node's menu. |
|||
#texinfo_no_detailmenu = False |
|||
|
|||
|
|||
# -- Options for Epub output ---------------------------------------------- |
|||
|
|||
# Bibliographic Dublin Core info. |
|||
epub_title = u'libuv API documentation' |
|||
epub_author = u'libuv contributors' |
|||
epub_publisher = u'libuv contributors' |
|||
epub_copyright = u'2014, libuv contributors' |
|||
|
|||
# The basename for the epub file. It defaults to the project name. |
|||
epub_basename = u'libuv' |
|||
|
|||
# The HTML theme for the epub output. Since the default themes are not optimized |
|||
# for small screen space, using the same theme for HTML and epub output is |
|||
# usually not wise. This defaults to 'epub', a theme designed to save visual |
|||
# space. |
|||
#epub_theme = 'epub' |
|||
|
|||
# The language of the text. It defaults to the language option |
|||
# or en if the language is not set. |
|||
#epub_language = '' |
|||
|
|||
# The scheme of the identifier. Typical schemes are ISBN or URL. |
|||
#epub_scheme = '' |
|||
|
|||
# The unique identifier of the text. This can be a ISBN number |
|||
# or the project homepage. |
|||
#epub_identifier = '' |
|||
|
|||
# A unique identification for the text. |
|||
#epub_uid = '' |
|||
|
|||
# A tuple containing the cover image and cover page html template filenames. |
|||
#epub_cover = () |
|||
|
|||
# A sequence of (type, uri, title) tuples for the guide element of content.opf. |
|||
#epub_guide = () |
|||
|
|||
# HTML files that should be inserted before the pages created by sphinx. |
|||
# The format is a list of tuples containing the path and title. |
|||
#epub_pre_files = [] |
|||
|
|||
# HTML files shat should be inserted after the pages created by sphinx. |
|||
# The format is a list of tuples containing the path and title. |
|||
#epub_post_files = [] |
|||
|
|||
# A list of files that should not be packed into the epub file. |
|||
epub_exclude_files = ['search.html'] |
|||
|
|||
# The depth of the table of contents in toc.ncx. |
|||
#epub_tocdepth = 3 |
|||
|
|||
# Allow duplicate toc entries. |
|||
#epub_tocdup = True |
|||
|
|||
# Choose between 'default' and 'includehidden'. |
|||
#epub_tocscope = 'default' |
|||
|
|||
# Fix unsupported image types using the PIL. |
|||
#epub_fix_images = False |
|||
|
|||
# Scale large images. |
|||
#epub_max_image_width = 0 |
|||
|
|||
# How to display URL addresses: 'footnote', 'no', or 'inline'. |
|||
#epub_show_urls = 'inline' |
|||
|
|||
# If false, no index is generated. |
|||
#epub_use_index = True |
@ -0,0 +1,137 @@ |
|||
|
|||
.. _design: |
|||
|
|||
Design overview |
|||
=============== |
|||
|
|||
libuv is cross-platform support library which was originally written for NodeJS. It's designed |
|||
around the event-driven asynchronous I/O model. |
|||
|
|||
The library provides much more than simply abstraction over different I/O polling mechanisms: |
|||
'handles' and 'streams' provde a high level abstraction for sockets and other entities; |
|||
cross-platform file I/O and threading functionality is also provided, amongst other things. |
|||
|
|||
Here is a diagram illustrating the different parts that compose libuv and what subsystem they |
|||
relate to: |
|||
|
|||
.. image:: static/architecture.png |
|||
:scale: 75% |
|||
:align: center |
|||
|
|||
|
|||
Handles and requests |
|||
^^^^^^^^^^^^^^^^^^^^ |
|||
|
|||
libuv provides users with 2 abstractions to work with, in combination with the event loop: |
|||
handles and requests. |
|||
|
|||
Handles represent long-lived objects capable of performing certain operations while active. Some |
|||
examples: a prepare handle gets its callback called once every loop iteration when active, and |
|||
a TCP server handle get its connection callback called every time there is a new connection. |
|||
|
|||
Requests represent (typically) short-lived operations. These operations can be performed over a |
|||
handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests |
|||
don't need a handle they run directly on the loop. |
|||
|
|||
|
|||
The I/O loop |
|||
^^^^^^^^^^^^ |
|||
|
|||
The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O |
|||
operations, and it's meant to be tied to a single thread. One can run multiple event loops |
|||
as long as each runs in a different thread. The libuv event loop (or any other API involving |
|||
the loop or handles, for that matter) **is not thread-safe** except stated otherwise. |
|||
|
|||
The event loop follows the rather usual single threaded asynchronous I/O approah: all (network) |
|||
I/O is performed on non-blocking sockets which are polled using the best mechanism available |
|||
on the given platform: epoll on Linux, kqueue on OSX and other BSDs, event ports on SunOS and IOCP |
|||
on Windows. As part of a loop iteration the loop will block waiting for I/O activity on sockets |
|||
which have been added to the poller and callbacks will be fired indicating socket conditions |
|||
(readable, writable hangup) so handles can read, write or perform the desired I/O operation. |
|||
|
|||
In order to better understand how the event loop operates, the following diagram illustrates all |
|||
stages of a loop iteration: |
|||
|
|||
.. image:: static/loop_iteration.png |
|||
:scale: 75% |
|||
:align: center |
|||
|
|||
|
|||
#. The loop concept of 'now' is updated. The event loop caches the current time at the start of |
|||
the event loop tick in order to reduce the number of time-related system calls. |
|||
|
|||
#. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So, |
|||
when is a loop considered to be *alive*? If a loop has active and ref'd handles, active |
|||
requests or closing handles it's considered to be *alive*. |
|||
|
|||
#. Due timers are run. All active timers scheduled for a time before the loop's concept of *now* |
|||
get their callbacks called. |
|||
|
|||
#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the |
|||
most part. There are cases, however, in which calling such a callback is deferred for the next |
|||
loop iteration. If the previous iteration deferred any I/O callback it will be run at this point. |
|||
|
|||
#. Idle handle callbacks are called. Despite the unfortunate name, idle handles are run on every |
|||
loop iteration, if they are active. |
|||
|
|||
#. Prepare handle callbacks are called. Prepare handles get their callbacks called right before |
|||
the loop will block for I/O. |
|||
|
|||
#. Poll timeout is calculated. Before blocking for I/O the loop calculates for how long it should |
|||
block. These are the rules when calculating the timeout: |
|||
|
|||
* If the loop was run with the ``UV_RUN_NOWAIT`` flag, the timeout is 0. |
|||
* If the loop is going to be stopped (:c:func:`uv_stop` was called), the timeout is 0. |
|||
* If there are no active handles or requests, the timeout is 0. |
|||
* If there are any idle handles active, the timeout is 0. |
|||
* If there are any handles pending to be closed, the timeout is 0. |
|||
* If none of the above cases was matched, the timeout of the closest timer is taken, or |
|||
if there are no active timers, infinity. |
|||
|
|||
#. The loop blocks for I/O. At this point the loop will block for I/O for the timeout calculated |
|||
on the previous step. All I/O related handles that were monitoring a given file descriptor |
|||
for a read or write operation get their callbacks called at this point. |
|||
|
|||
#. Check handle callbacks are called. Check handles get their callbacks called right after the |
|||
loop has blocked for I/O. Check handles are essentially the counterpart of prepare handles. |
|||
|
|||
#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will |
|||
get the close callback called. |
|||
|
|||
#. Special case in case the loop was run with ``UV_RUN_ONCE``, as it implies forward progress. |
|||
It's possible that no I/O callbacks were fired after blocking for I/O, but some time has passed |
|||
so there might be timers which are due, those timers get their callbacks called. |
|||
|
|||
#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the |
|||
iteration is ended and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT`` |
|||
it will contionue from the start if it's asill *alive*, otherwise it will also end. |
|||
|
|||
|
|||
.. important:: |
|||
libuv uses a thread pool to make asynchronous file I/O operations possible, but |
|||
network I/O is **always** performed in a single thread, each loop's thread. |
|||
|
|||
.. note:: |
|||
While the polling mechanism is different, libuv makes the execution model consistent |
|||
Unix systems and Windows. |
|||
|
|||
|
|||
File I/O |
|||
^^^^^^^^ |
|||
|
|||
Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on, |
|||
so the current approach is to run blocking file I/O operations in a thread pool. |
|||
|
|||
For a thorough explanation of the cross-platform file I/O landscape, checkout |
|||
`this post <http://blog.libtorrent.org/2012/10/asynchronous-disk-io/>`_. |
|||
|
|||
libuv currently uses a global thread pool on which all loops can queue work on. 3 types of |
|||
operations are currently run on this pool: |
|||
|
|||
* Filesystem operations |
|||
* DNS functions (getaddrinfo and getnameinfo) |
|||
* User specified code via :c:func:`uv_queue_work` |
|||
|
|||
.. warning:: |
|||
See the :c:ref:`threadpool` section for more details, but keep in mind the thread pool size |
|||
is quite limited. |
@ -0,0 +1,44 @@ |
|||
|
|||
.. _dll: |
|||
|
|||
Shared library handling |
|||
======================= |
|||
|
|||
libuv prodives cross platform utilities for loading shared libraries and |
|||
retrieving symbols from them, using the following API. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_lib_t |
|||
|
|||
Shared library data type. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_dlopen(const char* filename, uv_lib_t* lib) |
|||
|
|||
Opens a shared library. The filename is in utf-8. Returns 0 on success and |
|||
-1 on error. Call :c:func:`uv_dlerror` to get the error message. |
|||
|
|||
.. c:function:: void uv_dlclose(uv_lib_t* lib) |
|||
|
|||
Close the shared library. |
|||
|
|||
.. c:function:: uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) |
|||
|
|||
Retrieves a data pointer from a dynamic library. It is legal for a symbol |
|||
to map to NULL. Returns 0 on success and -1 if the symbol was not found. |
|||
|
|||
.. c:function:: const char* uv_dlerror(const uv_lib_t* lib) |
|||
|
|||
Returns the last uv_dlopen() or uv_dlsym() error message. |
@ -0,0 +1,83 @@ |
|||
|
|||
.. _dns: |
|||
|
|||
DNS utility functions |
|||
===================== |
|||
|
|||
libuv provides asynchronous variants of `getaddrinfo` and `getnameinfo`. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_getaddrinfo_t |
|||
|
|||
`getaddrinfo` request type. |
|||
|
|||
.. c:type:: void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, int status, struct addrinfo* res) |
|||
|
|||
Callback which will be called with the getaddrinfo request result once |
|||
complete. In case it was cancelled, `status` will have a value of |
|||
``UV_ECANCELED``. |
|||
|
|||
.. c:type:: uv_getnameinfo_t |
|||
|
|||
`getnameinfo` request type. |
|||
|
|||
.. c:type:: void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, int status, const char* hostname, const char* service) |
|||
|
|||
Callback which will be called with the getnameinfo request result once |
|||
complete. In case it was cancelled, `status` will have a value of |
|||
``UV_ECANCELED``. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: uv_loop_t* uv_getaddrinfo_t.loop |
|||
|
|||
Loop that started this getaddrinfo request and where completion will be |
|||
reported. Readonly. |
|||
|
|||
.. c:member:: uv_loop_t* uv_getnameinfo_t.loop |
|||
|
|||
Loop that started this getnameinfo request and where completion will be |
|||
reported. Readonly. |
|||
|
|||
.. seealso:: The :c:type:`uv_req_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints) |
|||
|
|||
Asynchronous ``getaddrinfo(3)``. |
|||
|
|||
Either node or service may be NULL but not both. |
|||
|
|||
`hints` is a pointer to a struct addrinfo with additional address type |
|||
constraints, or NULL. Consult `man -s 3 getaddrinfo` for more details. |
|||
|
|||
Returns 0 on success or an error code < 0 on failure. If successful, the |
|||
callback will get called sometime in the future with the lookup result, |
|||
which is either: |
|||
|
|||
* status == 0, the res argument points to a valid `struct addrinfo`, or |
|||
* status < 0, the res argument is NULL. See the UV_EAI_* constants. |
|||
|
|||
Call :c:func:`uv_freeaddrinfo` to free the addrinfo structure. |
|||
|
|||
.. c:function:: void uv_freeaddrinfo(struct addrinfo* ai) |
|||
|
|||
Free the struct addrinfo. Passing NULL is allowed and is a no-op. |
|||
|
|||
.. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags) |
|||
|
|||
Asynchronous ``getnameinfo(3)``. |
|||
|
|||
Returns 0 on success or an error code < 0 on failure. If successful, the |
|||
callback will get called sometime in the future with the lookup result. |
|||
Consult `man -s 3 getnameinfo` for more details. |
|||
|
|||
.. seealso:: The :c:type:`uv_req_t` API functions also apply. |
@ -0,0 +1,329 @@ |
|||
|
|||
.. _errors: |
|||
|
|||
Error handling |
|||
============== |
|||
|
|||
In libuv errors are negative numbered constants. As a rule of thumb, whenever |
|||
there is a status parameter, or an API functions returns an integer, a negative |
|||
number will imply an error. |
|||
|
|||
.. note:: |
|||
Implementation detail: on Unix error codes are the negated `errno` (or `-errno`), while on |
|||
Windows they are defined by libuv to arbitrary negative numbers. |
|||
|
|||
|
|||
Error constants |
|||
--------------- |
|||
|
|||
.. c:macro:: UV_E2BIG |
|||
|
|||
argument list too long |
|||
|
|||
.. c:macro:: UV_EACCES |
|||
|
|||
permission denied |
|||
|
|||
.. c:macro:: UV_EADDRINUSE |
|||
|
|||
address already in use |
|||
|
|||
.. c:macro:: UV_EADDRNOTAVAIL |
|||
|
|||
address not available |
|||
|
|||
.. c:macro:: UV_EAFNOSUPPORT |
|||
|
|||
address family not supported |
|||
|
|||
.. c:macro:: UV_EAGAIN |
|||
|
|||
resource temporarily unavailable |
|||
|
|||
.. c:macro:: UV_EAI_ADDRFAMILY |
|||
|
|||
address family not supported |
|||
|
|||
.. c:macro:: UV_EAI_AGAIN |
|||
|
|||
temporary failure |
|||
|
|||
.. c:macro:: UV_EAI_BADFLAGS |
|||
|
|||
bad ai_flags value |
|||
|
|||
.. c:macro:: UV_EAI_BADHINTS |
|||
|
|||
invalid value for hints |
|||
|
|||
.. c:macro:: UV_EAI_CANCELED |
|||
|
|||
request canceled |
|||
|
|||
.. c:macro:: UV_EAI_FAIL |
|||
|
|||
permanent failure |
|||
|
|||
.. c:macro:: UV_EAI_FAMILY |
|||
|
|||
ai_family not supported |
|||
|
|||
.. c:macro:: UV_EAI_MEMORY |
|||
|
|||
out of memory |
|||
|
|||
.. c:macro:: UV_EAI_NODATA |
|||
|
|||
no address |
|||
|
|||
.. c:macro:: UV_EAI_NONAME |
|||
|
|||
unknown node or service |
|||
|
|||
.. c:macro:: UV_EAI_OVERFLOW |
|||
|
|||
argument buffer overflow |
|||
|
|||
.. c:macro:: UV_EAI_PROTOCOL |
|||
|
|||
resolved protocol is unknown |
|||
|
|||
.. c:macro:: UV_EAI_SERVICE |
|||
|
|||
service not available for socket type |
|||
|
|||
.. c:macro:: UV_EAI_SOCKTYPE |
|||
|
|||
socket type not supported |
|||
|
|||
.. c:macro:: UV_EALREADY |
|||
|
|||
connection already in progress |
|||
|
|||
.. c:macro:: UV_EBADF |
|||
|
|||
bad file descriptor |
|||
|
|||
.. c:macro:: UV_EBUSY |
|||
|
|||
resource busy or locked |
|||
|
|||
.. c:macro:: UV_ECANCELED |
|||
|
|||
operation canceled |
|||
|
|||
.. c:macro:: UV_ECHARSET |
|||
|
|||
invalid Unicode character |
|||
|
|||
.. c:macro:: UV_ECONNABORTED |
|||
|
|||
software caused connection abort |
|||
|
|||
.. c:macro:: UV_ECONNREFUSED |
|||
|
|||
connection refused |
|||
|
|||
.. c:macro:: UV_ECONNRESET |
|||
|
|||
connection reset by peer |
|||
|
|||
.. c:macro:: UV_EDESTADDRREQ |
|||
|
|||
destination address required |
|||
|
|||
.. c:macro:: UV_EEXIST |
|||
|
|||
file already exists |
|||
|
|||
.. c:macro:: UV_EFAULT |
|||
|
|||
bad address in system call argument |
|||
|
|||
.. c:macro:: UV_EFBIG |
|||
|
|||
file too large |
|||
|
|||
.. c:macro:: UV_EHOSTUNREACH |
|||
|
|||
host is unreachable |
|||
|
|||
.. c:macro:: UV_EINTR |
|||
|
|||
interrupted system call |
|||
|
|||
.. c:macro:: UV_EINVAL |
|||
|
|||
invalid argument |
|||
|
|||
.. c:macro:: UV_EIO |
|||
|
|||
i/o error |
|||
|
|||
.. c:macro:: UV_EISCONN |
|||
|
|||
socket is already connected |
|||
|
|||
.. c:macro:: UV_EISDIR |
|||
|
|||
illegal operation on a directory |
|||
|
|||
.. c:macro:: UV_ELOOP |
|||
|
|||
too many symbolic links encountered |
|||
|
|||
.. c:macro:: UV_EMFILE |
|||
|
|||
too many open files |
|||
|
|||
.. c:macro:: UV_EMSGSIZE |
|||
|
|||
message too long |
|||
|
|||
.. c:macro:: UV_ENAMETOOLONG |
|||
|
|||
name too long |
|||
|
|||
.. c:macro:: UV_ENETDOWN |
|||
|
|||
network is down |
|||
|
|||
.. c:macro:: UV_ENETUNREACH |
|||
|
|||
network is unreachable |
|||
|
|||
.. c:macro:: UV_ENFILE |
|||
|
|||
file table overflow |
|||
|
|||
.. c:macro:: UV_ENOBUFS |
|||
|
|||
no buffer space available |
|||
|
|||
.. c:macro:: UV_ENODEV |
|||
|
|||
no such device |
|||
|
|||
.. c:macro:: UV_ENOENT |
|||
|
|||
no such file or directory |
|||
|
|||
.. c:macro:: UV_ENOMEM |
|||
|
|||
not enough memory |
|||
|
|||
.. c:macro:: UV_ENONET |
|||
|
|||
machine is not on the network |
|||
|
|||
.. c:macro:: UV_ENOPROTOOPT |
|||
|
|||
protocol not available |
|||
|
|||
.. c:macro:: UV_ENOSPC |
|||
|
|||
no space left on device |
|||
|
|||
.. c:macro:: UV_ENOSYS |
|||
|
|||
function not implemented |
|||
|
|||
.. c:macro:: UV_ENOTCONN |
|||
|
|||
socket is not connected |
|||
|
|||
.. c:macro:: UV_ENOTDIR |
|||
|
|||
not a directory |
|||
|
|||
.. c:macro:: UV_ENOTEMPTY |
|||
|
|||
directory not empty |
|||
|
|||
.. c:macro:: UV_ENOTSOCK |
|||
|
|||
socket operation on non-socket |
|||
|
|||
.. c:macro:: UV_ENOTSUP |
|||
|
|||
operation not supported on socket |
|||
|
|||
.. c:macro:: UV_EPERM |
|||
|
|||
operation not permitted |
|||
|
|||
.. c:macro:: UV_EPIPE |
|||
|
|||
broken pipe |
|||
|
|||
.. c:macro:: UV_EPROTO |
|||
|
|||
protocol error |
|||
|
|||
.. c:macro:: UV_EPROTONOSUPPORT |
|||
|
|||
protocol not supported |
|||
|
|||
.. c:macro:: UV_EPROTOTYPE |
|||
|
|||
protocol wrong type for socket |
|||
|
|||
.. c:macro:: UV_ERANGE |
|||
|
|||
result too large |
|||
|
|||
.. c:macro:: UV_EROFS |
|||
|
|||
read-only file system |
|||
|
|||
.. c:macro:: UV_ESHUTDOWN |
|||
|
|||
cannot send after transport endpoint shutdown |
|||
|
|||
.. c:macro:: UV_ESPIPE |
|||
|
|||
invalid seek |
|||
|
|||
.. c:macro:: UV_ESRCH |
|||
|
|||
no such process |
|||
|
|||
.. c:macro:: UV_ETIMEDOUT |
|||
|
|||
connection timed out |
|||
|
|||
.. c:macro:: UV_ETXTBSY |
|||
|
|||
text file is busy |
|||
|
|||
.. c:macro:: UV_EXDEV |
|||
|
|||
cross-device link not permitted |
|||
|
|||
.. c:macro:: UV_UNKNOWN |
|||
|
|||
unknown error |
|||
|
|||
.. c:macro:: UV_EOF |
|||
|
|||
end of file |
|||
|
|||
.. c:macro:: UV_ENXIO |
|||
|
|||
no such device or address |
|||
|
|||
.. c:macro:: UV_EMLINK |
|||
|
|||
too many links |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: const char* uv_strerror(int err) |
|||
|
|||
Returns the error message for the given error code. |
|||
|
|||
.. c:function:: const char* uv_err_name(int err) |
|||
|
|||
Returns the error name for the given error code. |
@ -0,0 +1,259 @@ |
|||
|
|||
.. _fs: |
|||
|
|||
Filesystem operations |
|||
===================== |
|||
|
|||
libuv provides a wide variety of cross-platform sync and async filesystem |
|||
operations. All functions defined in this document take a callback, which is |
|||
allowed to be NULL. If the callback is NULL the request is completed synchronously, |
|||
otherwise it will be performed asynchronously. |
|||
|
|||
All file operations are run on the threadpool, see :ref:`threadpool` for information |
|||
on the threadpool size. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_fs_t |
|||
|
|||
Filesystem request type. |
|||
|
|||
.. c:type:: uv_stat_t |
|||
|
|||
Portable equivalent of `struct stat`. |
|||
|
|||
:: |
|||
|
|||
typedef struct { |
|||
uint64_t st_dev; |
|||
uint64_t st_mode; |
|||
uint64_t st_nlink; |
|||
uint64_t st_uid; |
|||
uint64_t st_gid; |
|||
uint64_t st_rdev; |
|||
uint64_t st_ino; |
|||
uint64_t st_size; |
|||
uint64_t st_blksize; |
|||
uint64_t st_blocks; |
|||
uint64_t st_flags; |
|||
uint64_t st_gen; |
|||
uv_timespec_t st_atim; |
|||
uv_timespec_t st_mtim; |
|||
uv_timespec_t st_ctim; |
|||
uv_timespec_t st_birthtim; |
|||
} uv_stat_t; |
|||
|
|||
.. c:type:: uv_fs_type |
|||
|
|||
Filesystem request type. |
|||
|
|||
:: |
|||
|
|||
typedef enum { |
|||
UV_FS_UNKNOWN = -1, |
|||
UV_FS_CUSTOM, |
|||
UV_FS_OPEN, |
|||
UV_FS_CLOSE, |
|||
UV_FS_READ, |
|||
UV_FS_WRITE, |
|||
UV_FS_SENDFILE, |
|||
UV_FS_STAT, |
|||
UV_FS_LSTAT, |
|||
UV_FS_FSTAT, |
|||
UV_FS_FTRUNCATE, |
|||
UV_FS_UTIME, |
|||
UV_FS_FUTIME, |
|||
UV_FS_CHMOD, |
|||
UV_FS_FCHMOD, |
|||
UV_FS_FSYNC, |
|||
UV_FS_FDATASYNC, |
|||
UV_FS_UNLINK, |
|||
UV_FS_RMDIR, |
|||
UV_FS_MKDIR, |
|||
UV_FS_MKDTEMP, |
|||
UV_FS_RENAME, |
|||
UV_FS_READDIR, |
|||
UV_FS_LINK, |
|||
UV_FS_SYMLINK, |
|||
UV_FS_READLINK, |
|||
UV_FS_CHOWN, |
|||
UV_FS_FCHOWN |
|||
} uv_fs_type; |
|||
|
|||
.. c:type:: uv_dirent_t |
|||
|
|||
Cross platform (reduced) equivalent of ``struct dirent``. |
|||
Used in :c:func:`uv_fs_readdir_next`. |
|||
|
|||
:: |
|||
|
|||
typedef enum { |
|||
UV_DIRENT_UNKNOWN, |
|||
UV_DIRENT_FILE, |
|||
UV_DIRENT_DIR, |
|||
UV_DIRENT_LINK, |
|||
UV_DIRENT_FIFO, |
|||
UV_DIRENT_SOCKET, |
|||
UV_DIRENT_CHAR, |
|||
UV_DIRENT_BLOCK |
|||
} uv_dirent_type_t; |
|||
|
|||
typedef struct uv_dirent_s { |
|||
const char* name; |
|||
uv_dirent_type_t type; |
|||
} uv_dirent_t; |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: uv_loop_t* uv_fs_t.loop |
|||
|
|||
Loop that started this request and where completion will be reported. |
|||
Readonly. |
|||
|
|||
.. c:member:: uv_fs_type uv_fs_t.fs_type |
|||
|
|||
FS request type. |
|||
|
|||
.. c:member:: const char* uv_fs_t.path |
|||
|
|||
Path affecting the request. |
|||
|
|||
.. c:member:: ssize_t uv_fs_t.result |
|||
|
|||
Result of the request. < 0 means error, success otherwise. On requests such |
|||
as :c:func:`uv_fs_read` or :c:func:`uv_fs_write` it indicates the amount of |
|||
data that was read or written, respectively. |
|||
|
|||
.. c:member:: uv_stat_t uv_fs_t.statbuf |
|||
|
|||
Stores the result of :c:func:`uv_fs_stat` and other stat requests. |
|||
|
|||
.. c:member:: void* uv_fs_t.ptr |
|||
|
|||
Stores the result of :c:func:`uv_fs_readlink` and serves as an alias to |
|||
`statbuf`. |
|||
|
|||
.. seealso:: The :c:type:`uv_req_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: void uv_fs_req_cleanup(uv_fs_t* req) |
|||
|
|||
Cleanup request. Must be called after a request is finished to deallocate |
|||
any memory libuv might have allocated. |
|||
|
|||
.. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``close(2)``. |
|||
|
|||
.. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``open(2)``. |
|||
|
|||
.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``preadv(2)``. |
|||
|
|||
.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``unlink(2)``. |
|||
|
|||
.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``pwritev(2)``. |
|||
|
|||
.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``mkdir(2)``. |
|||
|
|||
.. note:: |
|||
`mode` is currently not implemented on Windows. |
|||
|
|||
.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``mkdtemp(3)``. |
|||
|
|||
.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``rmdir(2)``. |
|||
|
|||
.. c:function:: int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) |
|||
.. c:function:: int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent) |
|||
|
|||
Equivalent to ``readdir(2)``, with a slightly different API. Once the callback |
|||
for the request is called, the user can use :c:func:`uv_fs_readdir_next` to |
|||
get `ent` populated with the next directory entry data. When there are no |
|||
more entries ``UV_EOF`` will be returned. |
|||
|
|||
.. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) |
|||
.. c:function:: int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) |
|||
.. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``(f/l)stat(2)``. |
|||
|
|||
.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``rename(2)``. |
|||
|
|||
.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``fsync(2)``. |
|||
|
|||
.. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``fdatasync(2)``. |
|||
|
|||
.. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``ftruncate(2)``. |
|||
|
|||
.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) |
|||
|
|||
Limited equivalent to ``sendfile(2)``. |
|||
|
|||
.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) |
|||
.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``(f)chmod(2)``. |
|||
|
|||
.. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) |
|||
.. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``(f)utime(s)(2)``. |
|||
|
|||
.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``link(2)``. |
|||
|
|||
.. c:function:: int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``symlink(2)``. |
|||
|
|||
.. note:: |
|||
On Windows the `flags` parameter can be specified to control how the symlink will |
|||
be created: |
|||
|
|||
* ``UV_FS_SYMLINK_DIR``: indicates that `path` points to a directory. |
|||
|
|||
* ``UV_FS_SYMLINK_JUNCTION``: request that the symlink is created |
|||
using junktion points. |
|||
|
|||
.. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``readlink(2)``. |
|||
|
|||
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) |
|||
.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) |
|||
|
|||
Equivalent to ``(f)chown(2)``. |
|||
|
|||
.. note:: |
|||
These functions are not implemented on Windows. |
|||
|
|||
.. seealso:: The :c:type:`uv_req_t` API functions also apply. |
@ -0,0 +1,102 @@ |
|||
|
|||
.. _fs_event: |
|||
|
|||
:c:type:`uv_fs_event_t` --- FS Event handle |
|||
=========================================== |
|||
|
|||
FS Event handles allow the user to monitor a given path for changes, for example, |
|||
if the file was renamed or there was a generic change in it. This handle uses |
|||
the best backend for the job on each platform. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_fs_event_t |
|||
|
|||
FS Event handle type. |
|||
|
|||
.. c:type:: void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status) |
|||
|
|||
Callback passed to :c:func:`uv_fs_event_start` which will be called repeatedly |
|||
after the handle is started. If the handle was started with a directory the |
|||
`filename` parameter will be a relative path to a file contained in the directory. |
|||
The `events` parameter is an ORed mask of :c:type:`uv_fs_event` elements. |
|||
|
|||
.. c:type:: uv_fs_event |
|||
|
|||
Event types that :c:type:`uv_fs_event_t` handles monitor. |
|||
|
|||
:: |
|||
|
|||
enum uv_fs_event { |
|||
UV_RENAME = 1, |
|||
UV_CHANGE = 2 |
|||
}; |
|||
|
|||
.. c:type:: uv_fs_event_flags |
|||
|
|||
Flags that can be passed to :c:func:`uv_fs_event_start` to control its |
|||
behavior. |
|||
|
|||
:: |
|||
|
|||
enum uv_fs_event_flags { |
|||
/* |
|||
* By default, if the fs event watcher is given a directory name, we will |
|||
* watch for all events in that directory. This flags overrides this behavior |
|||
* and makes fs_event report only changes to the directory entry itself. This |
|||
* flag does not affect individual files watched. |
|||
* This flag is currently not implemented yet on any backend. |
|||
*/ |
|||
UV_FS_EVENT_WATCH_ENTRY = 1, |
|||
/* |
|||
* By default uv_fs_event will try to use a kernel interface such as inotify |
|||
* or kqueue to detect events. This may not work on remote filesystems such |
|||
* as NFS mounts. This flag makes fs_event fall back to calling stat() on a |
|||
* regular interval. |
|||
* This flag is currently not implemented yet on any backend. |
|||
*/ |
|||
UV_FS_EVENT_STAT = 2, |
|||
/* |
|||
* By default, event watcher, when watching directory, is not registering |
|||
* (is ignoring) changes in it's subdirectories. |
|||
* This flag will override this behaviour on platforms that support it. |
|||
*/ |
|||
UV_FS_EVENT_RECURSIVE = 4 |
|||
}; |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) |
|||
|
|||
Initialize the handle. |
|||
|
|||
.. c:function:: int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) |
|||
|
|||
Start the handle with the given callback, which will watch the specified |
|||
`path` for changes. `flags` can be an ORed mask of :c:type:`uv_fs_event_flags`. |
|||
|
|||
.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle) |
|||
|
|||
Stop the handle, the callback will no longer be called. |
|||
|
|||
.. c:function:: int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) |
|||
|
|||
Get the path being monitored by the handle. The buffer must be preallocated |
|||
by the user. Returns 0 on success or an error code < 0 in case of failure. |
|||
On sucess, `buf` will contain the path and `len` its length. If the buffer |
|||
is not big enough UV_ENOBUFS will be returned and len will be set to the |
|||
required size. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,65 @@ |
|||
|
|||
.. _fs_poll: |
|||
|
|||
:c:type:`uv_fs_poll_t` --- FS Poll handle |
|||
========================================= |
|||
|
|||
FS Poll handles allow the user to monitor a given path for changes. Unlike |
|||
:c:type:`uv_fs_event_t`, fs poll handles use `stat` to detect when a file has |
|||
changed so they can work on file systems where fs event handles can't. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_fs_poll_t |
|||
|
|||
FS Poll handle type. |
|||
|
|||
.. c:type:: void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr) |
|||
|
|||
Callback passed to :c:func:`uv_fs_poll_start` which will be called repeatedly |
|||
after the handle is started, when any change happens to the monitored path. |
|||
|
|||
The callback is invoked with `status < 0` if `path` does not exist |
|||
or is inaccessible. The watcher is *not* stopped but your callback is |
|||
not called again until something changes (e.g. when the file is created |
|||
or the error reason changes). |
|||
|
|||
When `status == 0`, the callback receives pointers to the old and new |
|||
:c:type:`uv_stat_t` structs. They are valid for the duration of the |
|||
callback only. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb poll_cb, const char* path, unsigned int interval) |
|||
|
|||
Check the file at `path` for changes every `interval` milliseconds. |
|||
|
|||
.. note:: |
|||
For maximum portability, use multi-second intervals. Sub-second intervals will not detect |
|||
all changes on many file systems. |
|||
|
|||
.. c:function:: int uv_fs_poll_stop(uv_fs_poll_t* handle) |
|||
|
|||
Stop the handle, the callback will no longer be called. |
|||
|
|||
.. c:function:: int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len) |
|||
|
|||
Get the path being monitored by the handle. The buffer must be preallocated |
|||
by the user. Returns 0 on success or an error code < 0 in case of failure. |
|||
On sucess, `buf` will contain the path and `len` its length. If the buffer |
|||
is not big enough UV_ENOBUFS will be returned and len will be set to the |
|||
required size. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,172 @@ |
|||
|
|||
.. _handle: |
|||
|
|||
:c:type:`uv_handle_t` --- Base handle |
|||
===================================== |
|||
|
|||
`uv_handle_t` is the base type for all libuv handle types. |
|||
|
|||
Strcutures are aligned so that any libuv handle can be cast to `uv_handle_t`. |
|||
All API functions defined here work with any handle type. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_handle_t |
|||
|
|||
The base libuv handle type. |
|||
|
|||
.. c:type:: uv_any_handle |
|||
|
|||
Union of all handle types. |
|||
|
|||
.. c:type:: void (*uv_close_cb)(uv_handle_t* handle) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_close`. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: uv_loop_t* uv_handle_t.loop |
|||
|
|||
Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly. |
|||
|
|||
.. c:member:: void* uv_handle_t.data |
|||
|
|||
Space for user-defined arbitrary data. libuv does not use this field. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_is_active(const uv_handle_t* handle) |
|||
|
|||
Returns non-zero if the handle is active, zero if it's inactive. What |
|||
"active" means depends on the type of handle: |
|||
|
|||
- A uv_async_t handle is always active and cannot be deactivated, except |
|||
by closing it with uv_close(). |
|||
|
|||
- A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that |
|||
deals with i/o - is active when it is doing something that involves i/o, |
|||
like reading, writing, connecting, accepting new connections, etc. |
|||
|
|||
- A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has |
|||
been started with a call to uv_check_start(), uv_idle_start(), etc. |
|||
|
|||
Rule of thumb: if a handle of type `uv_foo_t` has a `uv_foo_start()` |
|||
function, then it's active from the moment that function is called. |
|||
Likewise, `uv_foo_stop()` deactivates the handle again. |
|||
|
|||
.. c:function:: int uv_is_closing(const uv_handle_t* handle) |
|||
|
|||
Returns non-zero if the handle is closing or closed, zero otherwise. |
|||
|
|||
.. note:: |
|||
This function should only be used between the initialization of the handle and the |
|||
arrival of the close callback. |
|||
|
|||
.. c:function:: void uv_close(uv_handle_t* handle, uv_close_cb close_cb) |
|||
|
|||
Request handle to be closed. `close_cb` will be called asynchronously after |
|||
this call. This MUST be called on each handle before memory is released. |
|||
|
|||
Handles that wrap file descriptors are closed immediately but |
|||
`close_cb` will still be deferred to the next iteration of the event loop. |
|||
It gives you a chance to free up any resources associated with the handle. |
|||
|
|||
In-progress requests, like uv_connect_t or uv_write_t, are cancelled and |
|||
have their callbacks called asynchronously with status=UV_ECANCELED. |
|||
|
|||
.. c:function:: void uv_ref(uv_handle_t* handle) |
|||
|
|||
Reference the given handle. References are idempotent, that is, if a handle |
|||
is already referenced calling this function again will have no effect. |
|||
|
|||
See :ref:`refcount`. |
|||
|
|||
.. c:function:: void uv_unref(uv_handle_t* handle) |
|||
|
|||
Un-reference the given handle. References are idempotent, that is, if a handle |
|||
is not referenced calling this function again will have no effect. |
|||
|
|||
See :ref:`refcount`. |
|||
|
|||
.. c:function:: int uv_has_ref(const uv_handle_t* handle) |
|||
|
|||
Returns non-zero if the handle referenced, zero otherwise. |
|||
|
|||
See :ref:`refcount`. |
|||
|
|||
.. c:function:: size_t uv_handle_size(uv_handle_type type) |
|||
|
|||
Returns the size of the given handle type. Useful for FFI binding writers |
|||
who don't want to know the structure layout. |
|||
|
|||
|
|||
Miscellaneous API functions |
|||
--------------------------- |
|||
|
|||
The following API functions take a :c:type:`uv_handle_t` argument but they work |
|||
just for some handle types. |
|||
|
|||
.. c:function:: int uv_send_buffer_size(uv_handle_t* handle, int* value) |
|||
|
|||
Gets or sets the size of the send buffer that the operating |
|||
system uses for the socket. |
|||
|
|||
If `*value` == 0, it will return the current send buffer size, |
|||
otherwise it will use `*value` to set the new send buffer size. |
|||
|
|||
This function works for TCP, pipe and UDP handles on Unix and for TCP and |
|||
UDP handles on Windows. |
|||
|
|||
.. note:: |
|||
Linux will set double the size and return double the size of the original set value. |
|||
|
|||
.. c:function:: int uv_recv_buffer_size(uv_handle_t* handle, int* value) |
|||
|
|||
Gets or sets the size of the receive buffer that the operating |
|||
system uses for the socket. |
|||
|
|||
If `*value` == 0, it will return the current receive buffer size, |
|||
otherwise it will use `*value` to set the new receive buffer size. |
|||
|
|||
This function works for TCP, pipe and UDP handles on Unix and for TCP and |
|||
UDP handles on Windows. |
|||
|
|||
.. note:: |
|||
Linux will set double the size and return double the size of the original set value. |
|||
|
|||
.. c:function:: int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) |
|||
|
|||
Gets the platform dependent file descriptor equivalent. |
|||
|
|||
The following handles are supported: TCP, pipes, TTY, UDP and poll. Passing |
|||
any other handle type will fail with `UV_EINVAL`. |
|||
|
|||
If a handle doesn't have an attached file descriptor yet or the handle |
|||
itself has been closed, this function will return `UV_EBADF`. |
|||
|
|||
.. warning:: |
|||
Be very careful when using this function. libuv assumes it's in control of the file |
|||
descriptor so any change to it may lead to malfunction. |
|||
|
|||
|
|||
.. _refcount: |
|||
|
|||
Reference counting |
|||
------------------ |
|||
|
|||
The libuv event loop (if run in the default mode) will run until there are no |
|||
active `and` referenced handles left. The user can force the loop to exit early |
|||
by unreferencing handles which are active, for example by calling :c:func:`uv_unref` |
|||
after calling :c:func:`uv_timer_start`. |
|||
|
|||
A handle can be referenced or unreferenced, the refcounting scheme doesn't use |
|||
a counter, so both operations are idempotent. |
|||
|
|||
All handles are referenced when active by default, see :c:func:`uv_is_active` |
|||
for a more detailed explanation on what being `active` involves. |
@ -0,0 +1,54 @@ |
|||
|
|||
.. _idle: |
|||
|
|||
:c:type:`uv_idle_t` --- Idle handle |
|||
=================================== |
|||
|
|||
Idle handles will run the given callback once per loop iteration, right |
|||
before the :c:type:`uv_prepare_t` handles. |
|||
|
|||
.. note:: |
|||
The notable difference with prepare handles is that when there are active idle handles, |
|||
the loop will perform a zero timeout poll instead of blocking for i/o. |
|||
|
|||
.. warning:: |
|||
Despite the name, idle handles will get their callbacks called on every loop iteration, |
|||
not when the loop is actually "idle". |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_idle_t |
|||
|
|||
Idle handle type. |
|||
|
|||
.. c:type:: void (*uv_idle_cb)(uv_idle_t* handle) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_idle_start`. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_idle_init(uv_loop_t*, uv_idle_t* idle) |
|||
|
|||
Initialize the handle. |
|||
|
|||
.. c:function:: int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) |
|||
|
|||
Start the handle with the given callback. |
|||
|
|||
.. c:function:: int uv_idle_stop(uv_idle_t* idle) |
|||
|
|||
Stop the handle, the callback will no longer be called. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,84 @@ |
|||
|
|||
Welcome to the libuv API documentation |
|||
====================================== |
|||
|
|||
Overview |
|||
-------- |
|||
|
|||
libuv is a multi-platform support library with a focus on asynchronous I/O. It |
|||
was primarily developed for use by `Node.js`_, but it's also used by Mozilla's |
|||
`Rust language`_, `Luvit`_, `Julia`_, `pyuv`_, and `others`_. |
|||
|
|||
.. note:: |
|||
In case you find errors in this documentation you can help by sending |
|||
`pull requests <https://github.com/joyent/libuv>`_! |
|||
|
|||
.. _Node.js: http://nodejs.org |
|||
.. _Rust language: http://www.rust-lang.org |
|||
.. _Luvit: http://luvit.io |
|||
.. _Julia: http://julialang.org |
|||
.. _pyuv: https://github.com/saghul/pyuv |
|||
.. _others: https://github.com/joyent/libuv/wiki/Projects-that-use-libuv |
|||
|
|||
|
|||
Features |
|||
-------- |
|||
|
|||
* Full-featured event loop backed by epoll, kqueue, IOCP, event ports. |
|||
* Asynchronous TCP and UDP sockets |
|||
* Asynchronous DNS resolution |
|||
* Asynchronous file and file system operations |
|||
* File system events |
|||
* ANSI escape code controlled TTY |
|||
* IPC with socket sharing, using Unix domain sockets or named pipes (Windows) |
|||
* Child processes |
|||
* Thread pool |
|||
* Signal handling |
|||
* High resolution clock |
|||
* Threading and synchronization primitives |
|||
|
|||
|
|||
Downloads |
|||
--------- |
|||
|
|||
libuv can be downloaded from `here <http://dist.libuv.org/dist/>`_. |
|||
|
|||
|
|||
Installation |
|||
------------ |
|||
|
|||
Installation instructions can be found on `the README <https://github.com/joyent/libuv/blob/master/README.md>`_. |
|||
|
|||
|
|||
Documentation |
|||
------------- |
|||
|
|||
.. toctree:: |
|||
:maxdepth: 1 |
|||
|
|||
design |
|||
errors |
|||
loop |
|||
handle |
|||
request |
|||
timer |
|||
prepare |
|||
check |
|||
idle |
|||
async |
|||
poll |
|||
signal |
|||
process |
|||
stream |
|||
tcp |
|||
pipe |
|||
tty |
|||
udp |
|||
fs_event |
|||
fs_poll |
|||
fs |
|||
threadpool |
|||
dns |
|||
dll |
|||
threading |
|||
misc |
@ -0,0 +1,137 @@ |
|||
|
|||
.. _loop: |
|||
|
|||
:c:type:`uv_loop_t` --- Event loop |
|||
================================== |
|||
|
|||
The event loop is the central part of libuv's functionality. It takes care |
|||
of polling for i/o and scheduling callbacks to be run based on different sources |
|||
of events. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_loop_t |
|||
|
|||
Loop data type. |
|||
|
|||
.. c:type:: uv_run_mode |
|||
|
|||
Mode used to run the loop with :c:func:`uv_run`. |
|||
|
|||
:: |
|||
|
|||
typedef enum { |
|||
UV_RUN_DEFAULT = 0, |
|||
UV_RUN_ONCE, |
|||
UV_RUN_NOWAIT |
|||
} uv_run_mode; |
|||
|
|||
.. c:type:: void (*uv_walk_cb)(uv_handle_t* handle, void* arg) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_walk`. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: void* uv_loop_t.data |
|||
|
|||
Space for user-defined arbitrary data. libuv does not use this field. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_loop_init(uv_loop_t* loop) |
|||
|
|||
Initializes the given `uv_loop_t` structure. |
|||
|
|||
.. c:function:: int uv_loop_close(uv_loop_t* loop) |
|||
|
|||
Closes all internal loop resources. This function must only be called once |
|||
the loop has finished its execution or it will return UV_EBUSY. After this |
|||
function returns the user shall free the memory allocated for the loop. |
|||
|
|||
.. c:function:: uv_loop_t* uv_default_loop(void) |
|||
|
|||
Returns the initialized default loop. It may return NULL in case of |
|||
allocation failture. |
|||
|
|||
.. c:function:: int uv_run(uv_loop_t* loop, uv_run_mode mode) |
|||
|
|||
This function runs the event loop. It will act differently depending on the |
|||
specified mode: |
|||
|
|||
- UV_RUN_DEFAULT: Runs the event loop until there are no more active and |
|||
referenced handles or requests. Always returns zero. |
|||
- UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if |
|||
there are no pending callbacks. Returns zero when done (no active handles |
|||
or requests left), or non-zero if more callbacks are expected (meaning |
|||
you should run the event loop again sometime in the future). |
|||
- UV_RUN_NOWAIT: Poll for i/o once but don't block if there are no |
|||
pending callbacks. Returns zero if done (no active handles |
|||
or requests left), or non-zero if more callbacks are expected (meaning |
|||
you should run the event loop again sometime in the future). |
|||
|
|||
.. c:function:: int uv_loop_alive(const uv_loop_t* loop) |
|||
|
|||
Returns non-zero if there are active handles or request in the loop. |
|||
|
|||
.. c:function:: void uv_stop(uv_loop_t* loop) |
|||
|
|||
Stop the event loop, causing :c:func:`uv_run` to end as soon as |
|||
possible. This will happen not sooner than the next loop iteration. |
|||
If this function was called before blocking for i/o, the loop won't block |
|||
for i/o on this iteration. |
|||
|
|||
.. c:function:: size_t uv_loop_size(void) |
|||
|
|||
Returns the size of the `uv_loop_t` structure. Useful for FFI binding |
|||
writers who don't want to know the structure layout. |
|||
|
|||
.. c:function:: int uv_backend_fd(const uv_loop_t* loop) |
|||
|
|||
Get backend file descriptor. Only kqueue, epoll and event ports are |
|||
supported. |
|||
|
|||
This can be used in conjunction with `uv_run(loop, UV_RUN_NOWAIT)` to |
|||
poll in one thread and run the event loop's callbacks in another see |
|||
test/test-embed.c for an example. |
|||
|
|||
.. note:: |
|||
Embedding a kqueue fd in another kqueue pollset doesn't work on all platforms. It's not |
|||
an error to add the fd but it never generates events. |
|||
|
|||
.. c:function:: int uv_backend_timeout(const uv_loop_t* loop) |
|||
|
|||
Get the poll timeout. The return value is in milliseconds, or -1 for no |
|||
timeout. |
|||
|
|||
.. c:function:: uint64_t uv_now(const uv_loop_t* loop) |
|||
|
|||
Return the current timestamp in milliseconds. The timestamp is cached at |
|||
the start of the event loop tick, see :c:func:`uv_update_time` for details |
|||
and rationale. |
|||
|
|||
The timestamp increases monotonically from some arbitrary point in time. |
|||
Don't make assumptions about the starting point, you will only get |
|||
disappointed. |
|||
|
|||
.. note:: |
|||
Use :c:func:`uv_hrtime` if you need sub-millisecond granularity. |
|||
|
|||
.. c:function:: void uv_update_time(uv_loop_t* loop) |
|||
|
|||
Update the event loop's concept of "now". Libuv caches the current time |
|||
at the start of the event loop tick in order to reduce the number of |
|||
time-related system calls. |
|||
|
|||
You won't normally need to call this function unless you have callbacks |
|||
that block the event loop for longer periods of time, where "longer" is |
|||
somewhat subjective but probably on the order of a millisecond or more. |
|||
|
|||
.. c:function:: void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) |
|||
|
|||
Walk the list of handles: `walk_cb` will be executed with the given `arg`. |
@ -0,0 +1,228 @@ |
|||
|
|||
.. _misc: |
|||
|
|||
Miscelaneous utilities |
|||
====================== |
|||
|
|||
This section contains miscelaneous functions that don't really belong in any |
|||
other section. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_buf_t |
|||
|
|||
Buffer data type. |
|||
|
|||
.. c:type:: uv_file |
|||
|
|||
Cross platform representation of a file handle. |
|||
|
|||
.. c:type:: uv_os_sock_t |
|||
|
|||
Cross platform representation of a socket handle. |
|||
|
|||
.. c:type:: uv_os_fd_t |
|||
|
|||
Abstract representation of a file descriptor. On Unix systems this is a |
|||
`typedef` of `int` and on Windows fa `HANDLE`. |
|||
|
|||
.. c:type:: uv_rusage_t |
|||
|
|||
Data type for resource usage results. |
|||
|
|||
:: |
|||
|
|||
typedef struct { |
|||
uv_timeval_t ru_utime; /* user CPU time used */ |
|||
uv_timeval_t ru_stime; /* system CPU time used */ |
|||
uint64_t ru_maxrss; /* maximum resident set size */ |
|||
uint64_t ru_ixrss; /* integral shared memory size */ |
|||
uint64_t ru_idrss; /* integral unshared data size */ |
|||
uint64_t ru_isrss; /* integral unshared stack size */ |
|||
uint64_t ru_minflt; /* page reclaims (soft page faults) */ |
|||
uint64_t ru_majflt; /* page faults (hard page faults) */ |
|||
uint64_t ru_nswap; /* swaps */ |
|||
uint64_t ru_inblock; /* block input operations */ |
|||
uint64_t ru_oublock; /* block output operations */ |
|||
uint64_t ru_msgsnd; /* IPC messages sent */ |
|||
uint64_t ru_msgrcv; /* IPC messages received */ |
|||
uint64_t ru_nsignals; /* signals received */ |
|||
uint64_t ru_nvcsw; /* voluntary context switches */ |
|||
uint64_t ru_nivcsw; /* involuntary context switches */ |
|||
} uv_rusage_t; |
|||
|
|||
.. c:type:: uv_cpu_info_t |
|||
|
|||
Data type for CPU information. |
|||
|
|||
:: |
|||
|
|||
typedef struct uv_cpu_info_s { |
|||
char* model; |
|||
int speed; |
|||
struct uv_cpu_times_s { |
|||
uint64_t user; |
|||
uint64_t nice; |
|||
uint64_t sys; |
|||
uint64_t idle; |
|||
uint64_t irq; |
|||
} cpu_times; |
|||
} uv_cpu_info_t; |
|||
|
|||
.. c:type:: uv_interface_address_t |
|||
|
|||
Data type for interface addresses. |
|||
|
|||
:: |
|||
|
|||
typedef struct uv_interface_address_s { |
|||
char* name; |
|||
char phys_addr[6]; |
|||
int is_internal; |
|||
union { |
|||
struct sockaddr_in address4; |
|||
struct sockaddr_in6 address6; |
|||
} address; |
|||
union { |
|||
struct sockaddr_in netmask4; |
|||
struct sockaddr_in6 netmask6; |
|||
} netmask; |
|||
} uv_interface_address_t; |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: uv_handle_type uv_guess_handle(uv_file file) |
|||
|
|||
Used to detect what type of stream should be used with a given file |
|||
descriptor. Usually this will be used during initialization to guess the |
|||
type of the stdio streams. |
|||
|
|||
For ``isatty()`` functionality use this function and test for ``UV_TTY``. |
|||
|
|||
.. c:function:: unsigned int uv_version(void) |
|||
|
|||
Returns the libuv version packed into a single integer. 8 bits are used for |
|||
each component, with the patch number stored in the 8 least significant |
|||
bits. E.g. for libuv 1.2.3 this would return 0x010203. |
|||
|
|||
.. c:function:: const char* uv_version_string(void) |
|||
|
|||
Returns the libuv version number as a string. For non-release versions |
|||
"-pre" is appended, so the version number could be "1.2.3-pre". |
|||
|
|||
.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len) |
|||
|
|||
Constructor for :c:type:`uv_buf_t`. |
|||
|
|||
Due to platform differences the user cannot rely on the ordering of the |
|||
`base` and `len` members of the uv_buf_t struct. The user is responsible for |
|||
freeing `base` after the uv_buf_t is done. Return struct passed by value. |
|||
|
|||
.. c:function:: char** uv_setup_args(int argc, char** argv) |
|||
|
|||
Store the program arguments. Required for getting / setting the process title. |
|||
|
|||
.. c:function:: int uv_get_process_title(char* buffer, size_t size) |
|||
|
|||
Gets the title of the current process. |
|||
|
|||
.. c:function:: int uv_set_process_title(const char* title) |
|||
|
|||
Sets the current process title. |
|||
|
|||
.. c:function:: int uv_resident_set_memory(size_t* rss) |
|||
|
|||
Gets the resident set size (RSS) for the current process. |
|||
|
|||
.. c:function:: int uv_uptime(double* uptime) |
|||
|
|||
Gets the current system uptime. |
|||
|
|||
.. c:function:: int uv_getrusage(uv_rusage_t* rusage) |
|||
|
|||
Gets the resource usage measures for the current process. |
|||
|
|||
.. note:: |
|||
On Windows not all fields are set, the unsupported fields are filled with zeroes. |
|||
|
|||
.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) |
|||
|
|||
Gets information about the CPUs on the system. The `cpu_infos` array will |
|||
have `count` elements and needs to be freed with :c:func:`uv_free_cpu_info`. |
|||
|
|||
.. c:function:: void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) |
|||
|
|||
Frees the `cpu_infos` array previously allocated with :c:func:`uv_cpu_info`. |
|||
|
|||
.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count) |
|||
|
|||
Gets address information about the network interfaces on the system. An |
|||
array of `count` elements is allocated and returned in `addresses`. It must |
|||
be freed by the user, calling :c:func:`uv_free_interface_addresses`. |
|||
|
|||
.. c:function:: void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) |
|||
|
|||
Free an array of :c:type:`uv_interface_address_t` which was returned by |
|||
:c:func:`uv_interface_addresses`. |
|||
|
|||
.. c:function:: void uv_loadavg(double avg[3]) |
|||
|
|||
Gets the load average. See: http://en.wikipedia.org/wiki/Load_(computing) |
|||
|
|||
.. note:: |
|||
Returns [0,0,0] on Windows (i.e., it's not implemented). |
|||
|
|||
.. c:function:: int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) |
|||
|
|||
Convert a string containing an IPv4 addresses to a binary structure. |
|||
|
|||
.. c:function:: int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) |
|||
|
|||
Convert a string containing an IPv6 addresses to a binary structure. |
|||
|
|||
.. c:function:: int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) |
|||
|
|||
Convert a binary structure containing an IPv4 addres to a string. |
|||
|
|||
.. c:function:: int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) |
|||
|
|||
Convert a binary structure containing an IPv6 addres to a string. |
|||
|
|||
.. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size) |
|||
.. c:function:: int uv_inet_pton(int af, const char* src, void* dst) |
|||
|
|||
Cross-platform IPv6-capable implementation of the 'standard' ``inet_ntop()`` |
|||
and ``inet_pton()`` functions. On success they return 0. In case of error |
|||
the target `dst` pointer is unmodified. |
|||
|
|||
.. c:function:: int uv_exepath(char* buffer, size_t* size) |
|||
|
|||
Gets the executable path. |
|||
|
|||
.. c:function:: int uv_cwd(char* buffer, size_t* size) |
|||
|
|||
Gets the current working directory. |
|||
|
|||
.. c:function:: int uv_chdir(const char* dir) |
|||
|
|||
Changes the current working directory. |
|||
|
|||
.. uint64_t uv_get_free_memory(void) |
|||
.. c:function:: uint64_t uv_get_total_memory(void) |
|||
|
|||
Gets memory information (in bytes). |
|||
|
|||
.. c:function:: uint64_t uv_hrtime(void) |
|||
|
|||
Returns the current high-resolution real time. This is expressed in |
|||
nanoseconds. It is relative to an arbitrary time in the past. It is not |
|||
related to the time of day and therefore not subject to clock drift. The |
|||
primary use is for measuring performance between intervals. |
|||
|
|||
.. note:: |
|||
Not every platform can support nanosecond resolution; however, this value will always |
|||
be in nanoseconds. |
@ -0,0 +1,86 @@ |
|||
|
|||
.. _pipe: |
|||
|
|||
:c:type:`uv_pipe_t` --- Pipe handle |
|||
=================================== |
|||
|
|||
Pipe handles provide an abstraction over local domain sockets on Unix and named |
|||
pipes on Windows. |
|||
|
|||
:c:type:`uv_pipe_t` is a 'subclass' of :c:type:`uv_stream_t`. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_pipe_t |
|||
|
|||
Pipe handle type. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_stream_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc) |
|||
|
|||
Initialize a pipe handle. The `ipc` argument is a boolean to indicate if |
|||
this pipe will be used for handle passing between processes. |
|||
|
|||
.. c:function:: int uv_pipe_open(uv_pipe_t*, uv_file file) |
|||
|
|||
Open an existing file descriptor or HANDLE as a pipe. |
|||
|
|||
.. note:: |
|||
The user is responsible for setting the dile descriptor in non-blocking mode. |
|||
|
|||
.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name) |
|||
|
|||
Bind the pipe to a file path (Unix) or a name (Windows). |
|||
|
|||
.. note:: |
|||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between |
|||
92 and 108 bytes. |
|||
|
|||
.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb) |
|||
|
|||
Connect to the Unix domain socket or the named pipe. |
|||
|
|||
.. note:: |
|||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between |
|||
92 and 108 bytes. |
|||
|
|||
.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) |
|||
|
|||
Get the name of the Unix domain socket or the named pipe. |
|||
|
|||
A preallocated buffer must be provided. The len parameter holds the length |
|||
of the buffer and it's set to the number of bytes written to the buffer on |
|||
output. If the buffer is not big enough ``UV_ENOBUFS`` will be returned and |
|||
len will contain the required size. |
|||
|
|||
.. c:function:: void uv_pipe_pending_instances(uv_pipe_t* handle, int count) |
|||
|
|||
Set the number of pending pipe instance handles when the pipe server is |
|||
waiting for connections. |
|||
|
|||
.. note:: |
|||
This setting applies to Windows only. |
|||
|
|||
.. c:function:: int uv_pipe_pending_count(uv_pipe_t* handle) |
|||
.. c:function:: uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) |
|||
|
|||
Used to receive handles over IPC pipes. |
|||
|
|||
First - call :c:func:`uv_pipe_pending_count`, if it's > 0 then initialize |
|||
a handle of the given `type`, returned by :c:func:`uv_pipe_pending_type` |
|||
and call ``uv_accept(pipe, handle)``. |
|||
|
|||
.. seealso:: The :c:type:`uv_stream_t` API functions also apply. |
@ -0,0 +1,99 @@ |
|||
|
|||
.. _poll: |
|||
|
|||
:c:type:`uv_poll_t` --- Poll handle |
|||
=================================== |
|||
|
|||
Poll handles are used to watch file descriptors for readability and |
|||
writability, similar to the purpose of poll(2). |
|||
|
|||
The purpose of poll handles is to enable integrating external libraries that |
|||
rely on the event loop to signal it about the socket status changes, like |
|||
c-ares or libssh2. Using uv_poll_t for any other purpose is not recommended; |
|||
:c:type:`uv_tcp_t`, :c:type:`uv_udp_t`, etc. provide an implementation that is faster and |
|||
more scalable than what can be achieved with :c:type:`uv_poll_t`, especially on |
|||
Windows. |
|||
|
|||
It is possible that poll handles occasionally signal that a file descriptor is |
|||
readable or writable even when it isn't. The user should therefore always |
|||
be prepared to handle EAGAIN or equivalent when it attempts to read from or |
|||
write to the fd. |
|||
|
|||
It is not okay to have multiple active poll handles for the same socket, this |
|||
can cause libuv to busyloop or otherwise malfunction. |
|||
|
|||
The user should not close a file descriptor while it is being polled by an |
|||
active poll handle. This can cause the handle to report an error, |
|||
but it might also start polling another socket. However the fd can be safely |
|||
closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`. |
|||
|
|||
.. note:: |
|||
On windows only sockets can be polled with poll handles. On Unix any file |
|||
descriptor that would be accepted by poll(2) can be used. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_poll_t |
|||
|
|||
Poll handle type. |
|||
|
|||
.. c:type:: void (*uv_poll_cb)(uv_poll_t* handle, int status, int events) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_poll_start`. |
|||
|
|||
.. c:type:: uv_poll_event |
|||
|
|||
Poll event types |
|||
|
|||
:: |
|||
|
|||
enum uv_poll_event { |
|||
UV_READABLE = 1, |
|||
UV_WRITABLE = 2 |
|||
}; |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) |
|||
|
|||
Initialize the handle using a file descriptor. |
|||
|
|||
.. c:function:: int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket) |
|||
|
|||
Initialize the handle using a socket descriptor. On Unix this is identical |
|||
to :c:func:`uv_poll_init`. On windows it takes a SOCKET handle. |
|||
|
|||
.. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) |
|||
|
|||
Starts polling the file descriptor. `events` is a bitmask consisting made up |
|||
of UV_READABLE and UV_WRITABLE. As soon as an event is detected the callback |
|||
will be called with `status` set to 0, and the detected events set on the |
|||
`events` field. |
|||
|
|||
If an error happens while polling, `status` will be < 0 and corresponds |
|||
with one of the UV_E* error codes (see :ref:`errors`). The user should |
|||
not close the socket while the handle is active. If the user does that |
|||
anyway, the callback *may* be called reporting an error status, but this |
|||
is **not** guaranteed. |
|||
|
|||
.. note:: |
|||
Calling :c:func:`uv_poll_start` on a handle that is already active is fine. Doing so |
|||
will update the events mask that is being watched for. |
|||
|
|||
.. c:function:: int uv_poll_stop(uv_poll_t* poll) |
|||
|
|||
Stop polling the file descriptor, the callback will no longer be called. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,46 @@ |
|||
|
|||
.. _prepare: |
|||
|
|||
:c:type:`uv_prepare_t` --- Prepare handle |
|||
========================================= |
|||
|
|||
Prepare handles will run the given callback once per loop iteration, right |
|||
before polling for i/o. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_prepare_t |
|||
|
|||
Prepare handle type. |
|||
|
|||
.. c:type:: void (*uv_prepare_cb)(uv_prepare_t* handle) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_prepare_start`. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) |
|||
|
|||
Initialize the handle. |
|||
|
|||
.. c:function:: int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) |
|||
|
|||
Start the handle with the given callback. |
|||
|
|||
.. c:function:: int uv_prepare_stop(uv_prepare_t* prepare) |
|||
|
|||
Stop the handle, the callback will no longer be called. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,215 @@ |
|||
|
|||
.. _process: |
|||
|
|||
:c:type:`uv_process_t` --- Process handle |
|||
========================================= |
|||
|
|||
Process handles will spawn a new process and allow the user to control it and |
|||
establish communication channels with it using streams. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_process_t |
|||
|
|||
Process handle type. |
|||
|
|||
.. c:type:: uv_process_options_t |
|||
|
|||
Options for spawning the process (passed to :c:func:`uv_spawn`. |
|||
|
|||
:: |
|||
|
|||
typedef struct uv_process_options_s { |
|||
uv_exit_cb exit_cb; |
|||
const char* file; |
|||
char** args; |
|||
char** env; |
|||
const char* cwd; |
|||
unsigned int flags; |
|||
int stdio_count; |
|||
uv_stdio_container_t* stdio; |
|||
uv_uid_t uid; |
|||
uv_gid_t gid; |
|||
} uv_process_options_t; |
|||
|
|||
.. c:type:: void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal) |
|||
|
|||
Type definition for callback passed in :c:type:`uv_process_options_t` which |
|||
will indicate the exit status and the signal that caused the process to |
|||
terminate, if any. |
|||
|
|||
.. c:type:: uv_process_flags |
|||
|
|||
Flags to be set on the flags field of :c:type:`uv_process_options_t`. |
|||
|
|||
:: |
|||
|
|||
enum uv_process_flags { |
|||
/* |
|||
* Set the child process' user id. |
|||
*/ |
|||
UV_PROCESS_SETUID = (1 << 0), |
|||
/* |
|||
* Set the child process' group id. |
|||
*/ |
|||
UV_PROCESS_SETGID = (1 << 1), |
|||
/* |
|||
* Do not wrap any arguments in quotes, or perform any other escaping, when |
|||
* converting the argument list into a command line string. This option is |
|||
* only meaningful on Windows systems. On Unix it is silently ignored. |
|||
*/ |
|||
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2), |
|||
/* |
|||
* Spawn the child process in a detached state - this will make it a process |
|||
* group leader, and will effectively enable the child to keep running after |
|||
* the parent exits. Note that the child process will still keep the |
|||
* parent's event loop alive unless the parent process calls uv_unref() on |
|||
* the child's process handle. |
|||
*/ |
|||
UV_PROCESS_DETACHED = (1 << 3), |
|||
/* |
|||
* Hide the subprocess console window that would normally be created. This |
|||
* option is only meaningful on Windows systems. On Unix it is silently |
|||
* ignored. |
|||
*/ |
|||
UV_PROCESS_WINDOWS_HIDE = (1 << 4) |
|||
}; |
|||
|
|||
.. c:type:: uv_stdio_container_t |
|||
|
|||
Container for each stdio handle or fd passed to a child process. |
|||
|
|||
:: |
|||
|
|||
typedef struct uv_stdio_container_s { |
|||
uv_stdio_flags flags; |
|||
union { |
|||
uv_stream_t* stream; |
|||
int fd; |
|||
} data; |
|||
} uv_stdio_container_t; |
|||
|
|||
.. c:type:: uv_stdio_flags |
|||
|
|||
Flags specifying how a stdio should be transmitted to the child process. |
|||
|
|||
:: |
|||
|
|||
typedef enum { |
|||
UV_IGNORE = 0x00, |
|||
UV_CREATE_PIPE = 0x01, |
|||
UV_INHERIT_FD = 0x02, |
|||
UV_INHERIT_STREAM = 0x04, |
|||
/* |
|||
* When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE |
|||
* determine the direction of flow, from the child process' perspective. Both |
|||
* flags may be specified to create a duplex data stream. |
|||
*/ |
|||
UV_READABLE_PIPE = 0x10, |
|||
UV_WRITABLE_PIPE = 0x20 |
|||
} uv_stdio_flags; |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: uv_process_t.pid |
|||
|
|||
The PID of the spawned process. It's set after calling :c:func:`uv_spawn`. |
|||
|
|||
.. note:: |
|||
The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
.. c:member:: uv_process_options_t.exit_cb |
|||
|
|||
Callback called after the process exits. |
|||
|
|||
.. c:member:: uv_process_options_t.file |
|||
|
|||
Path pointing to the program to be executed. |
|||
|
|||
.. c:member:: uv_process_options_t.args |
|||
|
|||
Command line arguments. args[0] should be the path to the program. On |
|||
Windows this uses `CreateProcess` which concatenates the arguments into a |
|||
string this can cause some strange errors. See the |
|||
``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` flag on :c:type:`uv_process_flags`. |
|||
|
|||
.. c:member:: uv_process_options_t.env |
|||
|
|||
Environment for the new process. If NULL the parents environment is used. |
|||
|
|||
.. c:member:: uv_process_options_t.cwd |
|||
|
|||
Current working directory for the subprocess. |
|||
|
|||
.. c:member:: uv_process_options_t.flags |
|||
|
|||
Various flags that control how :c:func:`uv_spawn` behaves. See |
|||
:c:type:`uv_process_flags`. |
|||
|
|||
.. c:member:: uv_process_options_t.stdio_count |
|||
.. c:member:: uv_process_options_t.stdio |
|||
|
|||
The `stdio` field points to an array of :c:type:`uv_stdio_container_t` |
|||
structs that describe the file descriptors that will be made available to |
|||
the child process. The convention is that stdio[0] points to stdin, |
|||
fd 1 is used for stdout, and fd 2 is stderr. |
|||
|
|||
.. note:: |
|||
On Windows file descriptors greater than 2 are available to the child process only if |
|||
the child processes uses the MSVCRT runtime. |
|||
|
|||
.. c:member:: uv_process_options_t.uid |
|||
.. c:member:: uv_process_options_t.gid |
|||
|
|||
Libuv can change the child process' user/group id. This happens only when |
|||
the appropriate bits are set in the flags fields. |
|||
|
|||
.. note:: |
|||
This is not supported on Windows, :c:func:`uv_spawn` will fail and set the error |
|||
to ``UV_ENOTSUP``. |
|||
|
|||
.. c:member:: uv_stdio_container_t.flags |
|||
|
|||
Flags specifying how the stdio container should be passed to the child. See |
|||
:c:type:`uv_stdio_flags`. |
|||
|
|||
.. c:member:: uv_stdio_container_t.data |
|||
|
|||
Union containing either the stream or fd to be passed on to the child |
|||
process. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: void uv_disable_stdio_inheritance(void) |
|||
|
|||
Disables inheritance for file descriptors / handles that this process |
|||
inherited from its parent. The effect is that child processes spawned by |
|||
this process don't accidentally inherit these handles. |
|||
|
|||
It is recommended to call this function as early in your program as possible, |
|||
before the inherited file descriptors can be closed or duplicated. |
|||
|
|||
.. note:: |
|||
This function works on a best-effort basis: there is no guarantee that libuv can discover |
|||
all file descriptors that were inherited. In general it does a better job on Windows than |
|||
it does on Unix. |
|||
|
|||
.. c:function:: int uv_spawn(uv_loop_t* loop, uv_process_t* handle, const uv_process_options_t* options) |
|||
|
|||
Initializes the process handle and starts the process. If the process is |
|||
successfully spawned, this function will return 0. Otherwise, the |
|||
negative error code corresponding to the reason it couldn't spawn is |
|||
returned. |
|||
|
|||
Possible reasons for failing to spawn would include (but not be limited to) |
|||
the file to execute not existing, not having permissions to use the setuid or |
|||
setgid specified, or not having enough memory to allocate for the new |
|||
process. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,82 @@ |
|||
|
|||
.. _request: |
|||
|
|||
:c:type:`uv_req_t` --- Base request |
|||
=================================== |
|||
|
|||
`uv_req_t` is the base type for all libuv request types. |
|||
|
|||
Strcutures are aligned so that any libuv request can be cast to `uv_req_t`. |
|||
All API functions defined here work with any request type. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_req_t |
|||
|
|||
The base libuv request structure. |
|||
|
|||
.. c:type:: uv_any_req |
|||
|
|||
Union of all request types. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: void* uv_request_t.data |
|||
|
|||
Space for user-defined arbitrary data. libuv does not use this field. |
|||
|
|||
.. c:member:: uv_req_type uv_req_t.type |
|||
|
|||
Indicated the type of request. Readonly. |
|||
|
|||
:: |
|||
|
|||
typedef enum { |
|||
UV_UNKNOWN_REQ = 0, |
|||
UV_REQ, |
|||
UV_CONNECT, |
|||
UV_WRITE, |
|||
UV_SHUTDOWN, |
|||
UV_UDP_SEND, |
|||
UV_FS, |
|||
UV_WORK, |
|||
UV_GETADDRINFO, |
|||
UV_GETNAMEINFO, |
|||
UV_REQ_TYPE_PRIVATE, |
|||
UV_REQ_TYPE_MAX, |
|||
} uv_req_type; |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_cancel(uv_req_t* req) |
|||
|
|||
Cancel a pending request. Fails if the request is executing or has finished |
|||
executing. |
|||
|
|||
Returns 0 on success, or an error code < 0 on failure. |
|||
|
|||
Only cancellation of :c:type:`uv_fs_t`, :c:type:`uv_getaddrinfo_t`, |
|||
:c:type:`uv_getnameinfo_t` and :c:type:`uv_work_t` requests is |
|||
currently supported. |
|||
|
|||
Cancelled requests have their callbacks invoked some time in the future. |
|||
It's **not** safe to free the memory associated with the request until the |
|||
callback is called. |
|||
|
|||
Here is how cancellation is reported to the callback: |
|||
|
|||
* A :c:type:`uv_fs_t` request has its req->result field set to `UV_ECANCELED`. |
|||
|
|||
* A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t` or c:type:`uv_getnameinfo_t` |
|||
request has its callback invoked with status == `UV_ECANCELED`. |
|||
|
|||
.. c:function:: size_t uv_req_size(uv_req_type type) |
|||
|
|||
Returns the size of the given request type. Useful for FFI binding writers |
|||
who don't want to know the structure layout. |
@ -0,0 +1,77 @@ |
|||
|
|||
.. _signal: |
|||
|
|||
:c:type:`uv_signal_t` --- Signal handle |
|||
======================================= |
|||
|
|||
Signal handles implement Unix style signal handling on a per-event loop bases. |
|||
|
|||
Reception of some signals is emulated on Windows: |
|||
|
|||
* SIGINT is normally delivered when the user presses CTRL+C. However, like |
|||
on Unix, it is not generated when terminal raw mode is enabled. |
|||
|
|||
* SIGBREAK is delivered when the user pressed CTRL + BREAK. |
|||
|
|||
* SIGHUP is generated when the user closes the console window. On SIGHUP the |
|||
program is given approximately 10 seconds to perform cleanup. After that |
|||
Windows will unconditionally terminate it. |
|||
|
|||
* SIGWINCH is raised whenever libuv detects that the console has been |
|||
resized. SIGWINCH is emulated by libuv when the program uses a :c:type:`uv_tty_t` |
|||
handle to write to the console. SIGWINCH may not always be delivered in a |
|||
timely manner; libuv will only detect size changes when the cursor is |
|||
being moved. When a readable :c:type:`uv_tty_t` handle is used in raw mode, |
|||
resizing the console buffer will also trigger a SIGWINCH signal. |
|||
|
|||
Watchers for other signals can be successfully created, but these signals |
|||
are never received. These signals are: `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`, |
|||
`SIGTERM` and `SIGKILL.` |
|||
|
|||
Calls to raise() or abort() to programmatically raise a signal are |
|||
not detected by libuv; these will not trigger a signal watcher. |
|||
|
|||
.. note:: |
|||
On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to |
|||
manage threads. Installing watchers for those signals will lead to unpredictable behavior |
|||
and is strongly discouraged. Future versions of libuv may simply reject them. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_signal_t |
|||
|
|||
Signal handle type. |
|||
|
|||
.. c:type:: void (*uv_signal_cb)(uv_signal_t* handle, int signum) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_signal_start`. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: int uv_signal_t.signum |
|||
|
|||
Signal being monitored by this handle. Readonly. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_signal_init(uv_loop_t*, uv_signal_t* signal) |
|||
|
|||
Initialize the handle. |
|||
|
|||
.. c:function:: int uv_signal_start(uv_signal_t* signal, uv_signal_cb cb, int signum) |
|||
|
|||
Start the handle with the given callback, watching for the given signal. |
|||
|
|||
.. c:function:: int uv_signal_stop(uv_signal_t* signal) |
|||
|
|||
Stop the handle, the callback will no longer be called. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
After Width: | Height: | Size: 202 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<array> |
|||
<string>Template: White (2014-02-28 09:41)</string> |
|||
<string>M6.2.2-1878-1</string> |
|||
</array> |
|||
</plist> |
@ -0,0 +1 @@ |
|||
F69E9CD9-EEF1-4223-9DA4-A1EA7FE112BA |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 105 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 79 KiB |
@ -0,0 +1,189 @@ |
|||
|
|||
.. _stream: |
|||
|
|||
:c:type:`uv_stream_t` --- Stream handle |
|||
======================================= |
|||
|
|||
Stream handles provide an abstraction of a duplex communication channel. |
|||
:c:type:`uv_stream_t` is an abstract type, libuv provides 3 stream implementations |
|||
in the for of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_stream_t |
|||
|
|||
Stream handle type. |
|||
|
|||
.. c:type:: void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) |
|||
|
|||
Callback called when data was read on a stream. |
|||
|
|||
`nread` is > 0 if there is data available, 0 if libuv is done reading for |
|||
now, or < 0 on error. |
|||
|
|||
The callee is responsible for stopping closing the stream when an error happens |
|||
by calling :c:func:`uv_read_stop` or :c:func:`uv_close`. Trying to read |
|||
from the stream again is undefined. |
|||
|
|||
The callee is responsible for freeing the buffer, libuv does not reuse it. |
|||
The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on |
|||
error. |
|||
|
|||
.. c:type:: void (*uv_write_cb)(uv_write_t* req, int status) |
|||
|
|||
Callback called after data was written on a stream. `status` will be 0 in |
|||
case of success, < 0 otherwise. |
|||
|
|||
.. c:type:: void (*uv_connect_cb)(uv_connect_t* req, int status) |
|||
|
|||
Callback called after a connection started by :c:func:`uv_connect` is done. |
|||
`status` will be 0 in case of success, < 0 otherwise. |
|||
|
|||
.. c:type:: void (*uv_shutdown_cb)(uv_shutdown_t* req, int status) |
|||
|
|||
Callback called after s shutdown request has been completed. `status` will |
|||
be 0 in case of success, < 0 otherwise. |
|||
|
|||
.. c:type:: void (*uv_connection_cb)(uv_stream_t* server, int status) |
|||
|
|||
Callback called when a stream server has received an incoming connection. |
|||
The user can accept the connection by calling :c:func:`uv_accept`. |
|||
`status` will de 0 in case of success, < 0 otherwise. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: size_t uv_stream_t.write_queue_size |
|||
|
|||
Contains the amount of queued bytes waiting to be sent. Readonly. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) |
|||
|
|||
Shutdown the outgoing (write) side of a duplex stream. It waits for pending |
|||
write requests to complete. The `handle` should refer to a initialized stream. |
|||
`req` should be an uninitialized shutdown request struct. The `cb` is called |
|||
after shutdown is complete. |
|||
|
|||
.. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) |
|||
|
|||
Start listening for incoming connections. `backlog` indicates the number of |
|||
connections the kernel might queue, same as ``listen(2)``. When a new |
|||
incoming connection is received the :c:type:`uv_connection_cb` callback is |
|||
called. |
|||
|
|||
.. c:function:: int uv_accept(uv_stream_t* server, uv_stream_t* client) |
|||
|
|||
This call is used in conjunction with :c:func:`uv_listen` to accept incoming |
|||
connections. Call this function after receiving a :c:type:`uv_connection_cb` |
|||
to accept the connection. Before calling this function the client handle must |
|||
be initialized. < 0 return value indicates an error. |
|||
|
|||
When the :c:type:`uv_connection_cb` callback is called it is guaranteed that |
|||
this function will complete successfully the first time. If you attempt to use |
|||
it more than once, it may fail. It is suggested to only call this function once |
|||
per :c:type:`uv_connection_cb` call. |
|||
|
|||
.. note:: |
|||
`server` and `client` must be handles running on the same loop. |
|||
|
|||
.. c:function:: int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb) |
|||
|
|||
Read data from an incoming stream. The callback will be made several |
|||
times until there is no more data to read or :c:func:`uv_read_stop` is called. |
|||
When we've reached EOF `nread` will be set to ``UV_EOF``. |
|||
|
|||
When `nread` < 0, the `buf` parameter might not point to a valid buffer; |
|||
in that case `buf.len` and `buf.base` are both set to 0. |
|||
|
|||
.. note:: |
|||
`nread` might also be 0, which does *not* indicate an error or EOF, it happens when |
|||
libuv requested a buffer through the alloc callback but then decided that it didn't |
|||
need that buffer. |
|||
|
|||
.. c:function:: int uv_read_stop(uv_stream_t*) |
|||
|
|||
Stop reading data from the stream. The :c:type:`uv_read_cb` callback will |
|||
no longer be called. |
|||
|
|||
.. c:function:: int uv_write(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb) |
|||
|
|||
Write data to stream. Buffers are written in order. Example: |
|||
|
|||
:: |
|||
|
|||
uv_buf_t a[] = { |
|||
{ .base = "1", .len = 1 }, |
|||
{ .base = "2", .len = 1 } |
|||
}; |
|||
|
|||
uv_buf_t b[] = { |
|||
{ .base = "3", .len = 1 }, |
|||
{ .base = "4", .len = 1 } |
|||
}; |
|||
|
|||
uv_write_t req1; |
|||
uv_write_t req2; |
|||
|
|||
/* writes "1234" */ |
|||
uv_write(&req1, stream, a, 2); |
|||
uv_write(&req2, stream, b, 2); |
|||
|
|||
.. c:function:: int uv_write2(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, uv_write_cb cb) |
|||
|
|||
Extended write function for sending handles over a pipe. The pipe must be |
|||
initialized with `ipc` == 1. |
|||
|
|||
.. note:: |
|||
`send_handle` must be a TCP socket or pipe, which is a server or a connection (listening |
|||
or connected state). Bound sockets or pipes will be assumed to be servers. |
|||
|
|||
.. c:function:: int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs) |
|||
|
|||
Same as :c:func:`uv_write`, but won't queue a write request if it can't be |
|||
completed immediately. |
|||
|
|||
Will return either: |
|||
|
|||
* > 0: number of bytes written (can be less than the supplied buffer size). |
|||
* < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent |
|||
immediately). |
|||
|
|||
.. c:function:: int uv_is_readable(const uv_stream_t* handle) |
|||
|
|||
Returns 1 if the stream is readable, 0 otherwise. |
|||
|
|||
.. c:function:: int uv_is_writable(const uv_stream_t* handle) |
|||
|
|||
Returns 1 if the stream is writable, 0 otherwise. |
|||
|
|||
.. c:function:: int uv_stream_set_blocking(uv_stream_t* handle, int blocking) |
|||
|
|||
Enable or disable blocking mode for a stream. |
|||
|
|||
When blocking mode is enabled all writes complete synchronously. The |
|||
interface remains unchanged otherwise, e.g. completion or failure of the |
|||
operation will still be reported through a callback which is made |
|||
asychronously. |
|||
|
|||
.. warning:: |
|||
Relying too much on this API is not recommended. It is likely to change |
|||
significantly in the future. |
|||
|
|||
Currently this only works on Windows and only for |
|||
:c:type:`uv_pipe_t` handles. |
|||
|
|||
Also libuv currently makes no ordering guarantee when the blocking mode |
|||
is changed after write requests have already been submitted. Therefore it is |
|||
recommended to set the blocking mode immediately after opening or creating |
|||
the stream. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,97 @@ |
|||
|
|||
.. _tcp: |
|||
|
|||
:c:type:`uv_tcp_t` --- TCP handle |
|||
================================= |
|||
|
|||
TCP handles are used to represent both TCP streams and servers. |
|||
|
|||
:c:type:`uv_tcp_t` is a 'subclass' of :c:type:`uv_stream_t`. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_tcp_t |
|||
|
|||
TCP handle type. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_stream_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle) |
|||
|
|||
Initialize the handle. |
|||
|
|||
.. c:function:: int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) |
|||
|
|||
Open an existing file descriptor or SOCKET as a TCP handle. |
|||
|
|||
.. note:: |
|||
The user is responsible for setting the file descriptor in |
|||
non-blocking mode. |
|||
|
|||
.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable) |
|||
|
|||
Enable / disable Nagle's algorithm. |
|||
|
|||
.. c:function:: int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) |
|||
|
|||
Enable / disable TCP keep-alive. `delay` is the initial delay in seconds, |
|||
ignored when `enable` is zero. |
|||
|
|||
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) |
|||
|
|||
Enable / disable simultaneous asynchronous accept requests that are |
|||
queued by the operating system when listening for new TCP connections. |
|||
|
|||
This setting is used to tune a TCP server for the desired performance. |
|||
Having simultaneous accepts can significantly improve the rate of accepting |
|||
connections (which is why it is enabled by default) but may lead to uneven |
|||
load distribution in multi-process setups. |
|||
|
|||
.. c:function:: int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags) |
|||
|
|||
Bind the handle to an address and port. `addr` should point to an |
|||
initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``. |
|||
|
|||
When the port is already taken, you can expect to see an ``UV_EADDRINUSE`` |
|||
error from either :c:func:`uv_tcp_bind`, :c:func:`uv_listen` or |
|||
:c:func:`uv_tcp_connect`. That is, a successful call to this function does |
|||
not guarantee that the call to :c:func:`uv_listen` or :c:func:`uv_tcp_connect` |
|||
will succeed as well. |
|||
|
|||
`flags` con contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support |
|||
is disabled and only IPv6 is used. |
|||
|
|||
.. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen) |
|||
|
|||
Get the current address to which the handle is bound. `addr` must point to |
|||
a valid and big enough chunk of memory, ``struct sockaddr_storage`` is |
|||
recommended for IPv4 and IPv6 support. |
|||
|
|||
.. c:function:: int uv_tcp_getpeername(const uv_tcp_t* handle, struct sockaddr* name, int* namelen) |
|||
|
|||
Get the address of the peer connected to the handle. `addr` must point to |
|||
a valid and big enough chunk of memory, ``struct sockaddr_storage`` is |
|||
recommended for IPv4 and IPv6 support. |
|||
|
|||
.. c:function:: int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, const struct sockaddr* addr, uv_connect_cb cb) |
|||
|
|||
Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle |
|||
and an uninitialized :c:type:`uv_connect_t`. `addr` should point to an |
|||
initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``. |
|||
|
|||
The callback is made when the connection has been established or when a |
|||
connection error happened. |
|||
|
|||
.. seealso:: The :c:type:`uv_stream_t` API functions also apply. |
@ -0,0 +1,156 @@ |
|||
|
|||
.. _threading: |
|||
|
|||
Threading and synchronization utilities |
|||
======================================= |
|||
|
|||
libuv provides cross-platform implementations for multiple threading and |
|||
synchronization primitives. The API largely follows the pthreads API. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_thread_t |
|||
|
|||
Thread data type. |
|||
|
|||
.. c:type:: void (*uv_thread_cb)(void* arg) |
|||
|
|||
Callback that is invoked to initialize thread execution. `arg` is the same |
|||
value that was passed to :c:func:`uv_thread_create`. |
|||
|
|||
.. c:type:: uv_key_t |
|||
|
|||
Thread-local key data type. |
|||
|
|||
.. c:type:: uv_once_t |
|||
|
|||
Once-only initializer data type. |
|||
|
|||
.. c:type:: uv_mutex_t |
|||
|
|||
Mutex data type. |
|||
|
|||
.. c:type:: uv_rwlock_t |
|||
|
|||
Read-write lock data type. |
|||
|
|||
.. c:type:: uv_sem_t |
|||
|
|||
Semaphore data type. |
|||
|
|||
.. c:type:: uv_cond_t |
|||
|
|||
Condition data type. |
|||
|
|||
.. c:type:: uv_barrier_t |
|||
|
|||
Barrier data type. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
Threads |
|||
^^^^^^^ |
|||
|
|||
.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg) |
|||
.. c:function:: unsigned long uv_thread_self(void) |
|||
.. c:function:: int uv_thread_join(uv_thread_t *tid) |
|||
|
|||
Thread-local storage |
|||
^^^^^^^^^^^^^^^^^^^^ |
|||
|
|||
.. note:: |
|||
The total thread-local storage size may be limited. That is, it may not be possible to |
|||
create many TLS keys. |
|||
|
|||
.. c:function:: int uv_key_create(uv_key_t* key) |
|||
.. c:function:: void uv_key_delete(uv_key_t* key) |
|||
.. c:function:: void* uv_key_get(uv_key_t* key) |
|||
.. c:function:: void uv_key_set(uv_key_t* key, void* value) |
|||
|
|||
Once-only initialization |
|||
^^^^^^^^^^^^^^^^^^^^^^^^ |
|||
|
|||
Runs a function once and only once. Concurrent calls to :c:func:`uv_once` with the |
|||
same guard will block all callers except one (it's unspecified which one). |
|||
The guard should be initialized statically with the UV_ONCE_INIT macro. |
|||
|
|||
.. c:function:: void uv_once(uv_once_t* guard, void (*callback)(void)) |
|||
|
|||
Mutex locks |
|||
^^^^^^^^^^^ |
|||
|
|||
Functions return 0 on success or an error code < 0 (unless the |
|||
return type is void, of course). |
|||
|
|||
.. c:function:: int uv_mutex_init(uv_mutex_t* handle) |
|||
.. c:function:: void uv_mutex_destroy(uv_mutex_t* handle) |
|||
.. c:function:: void uv_mutex_lock(uv_mutex_t* handle) |
|||
.. c:function:: int uv_mutex_trylock(uv_mutex_t* handle) |
|||
.. c:function:: void uv_mutex_unlock(uv_mutex_t* handle) |
|||
|
|||
Read-write locks |
|||
^^^^^^^^^^^^^^^^ |
|||
|
|||
Functions return 0 on success or an error code < 0 (unless the |
|||
return type is void, of course). |
|||
|
|||
.. c:function:: int uv_rwlock_init(uv_rwlock_t* rwlock) |
|||
.. c:function:: void uv_rwlock_destroy(uv_rwlock_t* rwlock) |
|||
.. c:function:: void uv_rwlock_rdlock(uv_rwlock_t* rwlock) |
|||
.. c:function:: int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) |
|||
.. c:function:: void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) |
|||
.. c:function:: void uv_rwlock_wrlock(uv_rwlock_t* rwlock) |
|||
.. c:function:: int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) |
|||
.. c:function:: void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) |
|||
|
|||
Semaphores |
|||
^^^^^^^^^^ |
|||
|
|||
Functions return 0 on success or an error code < 0 (unless the |
|||
return type is void, of course). |
|||
|
|||
.. c:function:: int uv_sem_init(uv_sem_t* sem, unsigned int value) |
|||
.. c:function:: void uv_sem_destroy(uv_sem_t* sem) |
|||
.. c:function:: void uv_sem_post(uv_sem_t* sem) |
|||
.. c:function:: void uv_sem_wait(uv_sem_t* sem) |
|||
.. c:function:: int uv_sem_trywait(uv_sem_t* sem) |
|||
|
|||
Conditions |
|||
^^^^^^^^^^ |
|||
|
|||
Functions return 0 on success or an error code < 0 (unless the |
|||
return type is void, of course). |
|||
|
|||
.. note:: |
|||
Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait` and |
|||
:c:func:`uv_cond_timedwait`. |
|||
|
|||
.. c:function:: int uv_cond_init(uv_cond_t* cond) |
|||
.. c:function:: void uv_cond_destroy(uv_cond_t* cond) |
|||
.. c:function:: void uv_cond_signal(uv_cond_t* cond) |
|||
.. c:function:: void uv_cond_broadcast(uv_cond_t* cond) |
|||
.. c:function:: void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) |
|||
.. c:function:: int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) |
|||
|
|||
Barriers |
|||
^^^^^^^^ |
|||
|
|||
Functions return 0 on success or an error code < 0 (unless the |
|||
return type is void, of course). |
|||
|
|||
.. note:: |
|||
:c:func:`uv_barrier_wait` returns a value > 0 to an arbitrarily chosen "serializer" thread |
|||
to facilitate cleanup, i.e. |
|||
|
|||
:: |
|||
|
|||
if (uv_barrier_wait(&barrier) > 0) |
|||
uv_barrier_destroy(&barrier); |
|||
|
|||
.. c:function:: int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) |
|||
.. c:function:: void uv_barrier_destroy(uv_barrier_t* barrier) |
|||
.. c:function:: int uv_barrier_wait(uv_barrier_t* barrier) |
@ -0,0 +1,59 @@ |
|||
|
|||
.. _threadpool: |
|||
|
|||
Thread pool work scheduling |
|||
=========================== |
|||
|
|||
libuv provides a threadpool which can be used to run user code and get notified |
|||
in the loop thread. This thread pool is internally used to run al filesystem |
|||
operations, as well as getaddrinfo and getnameinfo requests. |
|||
|
|||
Its default size is 4, but it can be changed at startup time by setting the |
|||
``UV_THREADPOOL_SIZE`` environment variable to any value (the absolute maximum |
|||
is 128). |
|||
|
|||
The threadpool is global and shared across all event loops. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_work_t |
|||
|
|||
Work request type. |
|||
|
|||
.. c:type:: void (*uv_work_cb)(uv_work_t* req) |
|||
|
|||
Callback passed to :c:func:`uv_queue_work` which will be run on the thread |
|||
pool. |
|||
|
|||
.. c:type:: void (*uv_after_work_cb)(uv_work_t* req, int status) |
|||
|
|||
Callback passed to :c:func:`uv_queue_work` which will be called on the loop |
|||
thread after the work on the threadpool has been completed. If the work |
|||
was cancelled using :c:func:`uv_cancel` `status` will be ``UV_ECANCELED``. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: uv_loop_t* uv_work_t.loop |
|||
|
|||
Loop that started this request and where completion will be reported. |
|||
Readonly. |
|||
|
|||
.. seealso:: The :c:type:`uv_req_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb) |
|||
|
|||
Initializes a work request which will run the given `work_cb` in a thread |
|||
from the threadpool. Once `work_cb` is completed, `after_work_cb` will be |
|||
called on the loop thread. |
|||
|
|||
This request can be cancelled with :c:func:`uv_cancel`. |
|||
|
|||
.. seealso:: The :c:type:`uv_req_t` API functions also apply. |
@ -0,0 +1,68 @@ |
|||
|
|||
.. _timer: |
|||
|
|||
:c:type:`uv_timer_t` --- Timer handle |
|||
===================================== |
|||
|
|||
Timer handles are used to schedule callbacks to be called in the future. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_timer_t |
|||
|
|||
Timer handle type. |
|||
|
|||
.. c:type:: void (*uv_timer_cb)(uv_timer_t* handle) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_timer_start`. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) |
|||
|
|||
Initialize the handle. |
|||
|
|||
.. c:function:: int uv_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat) |
|||
|
|||
Start the timer. `timeout` and `repeat` are in milliseconds. |
|||
|
|||
If `timeout` is zero, the callback fires on the next event loop iteration. |
|||
If `repeat` is non-zero, the callback fires first after `timeout` |
|||
milliseconds and then repeatedly after `repeat` milliseconds. |
|||
|
|||
.. c:function:: int uv_timer_stop(uv_timer_t* handle) |
|||
|
|||
Stop the timer, the callback will not be called anymore. |
|||
|
|||
.. c:function:: int uv_timer_again(uv_timer_t* handle) |
|||
|
|||
Stop the timer, and if it is repeating restart it using the repeat value |
|||
as the timeout. If the timer has never been started before it returns |
|||
UV_EINVAL. |
|||
|
|||
.. c:function:: void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) |
|||
|
|||
Set the repeat value in milliseconds. |
|||
|
|||
.. note:: |
|||
If the repeat value is set from a timer callback it does not immediately take effect. |
|||
If the timer was non-repeating before, it will have been stopped. If it was repeating, |
|||
then the old repeat value will have been used to schedule the next timeout. |
|||
|
|||
.. c:function:: uint64_t uv_timer_get_repeat(const uv_timer_t* handle) |
|||
|
|||
Get the timer repeat value. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -0,0 +1,63 @@ |
|||
|
|||
.. _tty: |
|||
|
|||
:c:type:`uv_tty_t` --- TTY handle |
|||
================================= |
|||
|
|||
TTY handles represent a stream for the console. |
|||
|
|||
:c:type:`uv_tty_t` is a 'subclass' of :c:type:`uv_stream_t`. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_tty_t |
|||
|
|||
TTY handle type. |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
N/A |
|||
|
|||
.. seealso:: The :c:type:`uv_stream_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable) |
|||
|
|||
Initialize a new TTY stream with the given file descriptor. Usually the |
|||
file descriptor will be: |
|||
|
|||
* 0 = stdin |
|||
* 1 = stdout |
|||
* 2 = stderr |
|||
|
|||
`readable`, specifies if you plan on calling :c:func:`uv_read_start` with |
|||
this stream. stdin is readable, stdout is not. |
|||
|
|||
.. note:: |
|||
TTY streams which are not readable have blocking writes. |
|||
|
|||
.. c:function:: int uv_tty_set_mode(uv_tty_t*, int mode) |
|||
|
|||
Set the TTY mode. 0 for normal, 1 for raw. |
|||
|
|||
.. c:function:: int uv_tty_reset_mode(void) |
|||
|
|||
To be called when the program exits. Resets TTY settings to default |
|||
values for the next process to take over. |
|||
|
|||
This function is async signal-safe on Unix platforms but can fail with error |
|||
code ``UV_EBUSY`` if you call it when execution is inside |
|||
:c:func:`uv_tty_set_mode`. |
|||
|
|||
.. c:function:: int uv_tty_get_winsize(uv_tty_t*, int* width, int* height) |
|||
|
|||
Gets the current Window size. On success it returns 0. |
|||
|
|||
.. seealso:: The :c:type:`uv_stream_t` API functions also apply. |
@ -0,0 +1,280 @@ |
|||
|
|||
.. _udp: |
|||
|
|||
:c:type:`uv_udp_t` --- UDP handle |
|||
================================= |
|||
|
|||
UDP handles encapsulate UDP communication for both clients and servers. |
|||
|
|||
|
|||
Data types |
|||
---------- |
|||
|
|||
.. c:type:: uv_udp_t |
|||
|
|||
UDP handle type. |
|||
|
|||
.. c:type:: uv_udp_send_t |
|||
|
|||
UDP send request type. |
|||
|
|||
.. c:type:: uv_udp_flags |
|||
|
|||
Flags used in :c:func:`uv_udp_bind` and :c:type:`uv_udp_recv_cb`.. |
|||
|
|||
:: |
|||
|
|||
enum uv_udp_flags { |
|||
/* Disables dual stack mode. */ |
|||
UV_UDP_IPV6ONLY = 1, |
|||
/* |
|||
* Indicates message was truncated because read buffer was too small. The |
|||
* remainder was discarded by the OS. Used in uv_udp_recv_cb. |
|||
*/ |
|||
UV_UDP_PARTIAL = 2, |
|||
/* |
|||
* Indicates if SO_REUSEADDR will be set when binding the handle in |
|||
* uv_udp_bind. |
|||
* This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other |
|||
* Unix platforms, it sets the SO_REUSEADDR flag. What that means is that |
|||
* multiple threads or processes can bind to the same address without error |
|||
* (provided they all set the flag) but only the last one to bind will receive |
|||
* any traffic, in effect "stealing" the port from the previous listener. |
|||
*/ |
|||
UV_UDP_REUSEADDR = 4 |
|||
}; |
|||
|
|||
.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_udp_send`, which is |
|||
called after the data was sent. |
|||
|
|||
.. c:type:: void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) |
|||
|
|||
Type definition for callback passed to :c:func:`uv_udp_recv_start`, which |
|||
is called when the endpoint receives data. |
|||
|
|||
* `handle`: UDP handle |
|||
* `nread`: Number of bytes that have been received. |
|||
0 if there is no more data to read. You may discard or repurpose |
|||
the read buffer. Note that 0 may also mean that an empty datagram |
|||
was received (in this case `addr` is not NULL). < 0 if a transmission |
|||
error was detected. |
|||
* `buf`: :c:type:`uv_buf_t` with the received data. |
|||
* `addr`: ``struct sockaddr*`` containing the address of the sender. |
|||
Can be NULL. Valid for the duration of the callback only. |
|||
* `flags`: One or more or'ed UV_UDP_* constants. Right now only |
|||
``UV_UDP_PARTIAL`` is used. |
|||
|
|||
.. note:: |
|||
The receive callback will be called with `nread` == 0 and `addr` == NULL when there is |
|||
nothing to read, and with `nread` == 0 and `addr` != NULL when an empty UDP packet is |
|||
received. |
|||
|
|||
.. c:type:: uv_membership |
|||
|
|||
Membership type for a multicast address. |
|||
|
|||
:: |
|||
|
|||
typedef enum { |
|||
UV_LEAVE_GROUP = 0, |
|||
UV_JOIN_GROUP |
|||
} uv_membership; |
|||
|
|||
|
|||
Public members |
|||
^^^^^^^^^^^^^^ |
|||
|
|||
.. c:member:: size_t uv_udp_t.send_queue_size |
|||
|
|||
Number of bytes queued for sending. This field strictly shows how much |
|||
information is currently queued. |
|||
|
|||
.. c:member:: size_t uv_udp_t.send_queue_count |
|||
|
|||
Number of send requests currently in the queue awaiting to be processed. |
|||
|
|||
.. c:member:: uv_udp_t* uv_udp_send_t.handle |
|||
|
|||
UDP handle where this send request is taking place. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` members also apply. |
|||
|
|||
|
|||
API |
|||
--- |
|||
|
|||
.. c:function:: int uv_udp_init(uv_loop_t*, uv_udp_t* handle) |
|||
|
|||
Initialize a new UDP handle. The actual socket is created lazily. |
|||
Returns 0 on success. |
|||
|
|||
.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) |
|||
|
|||
Opens an existing file descriptor or Windows SOCKET as a UDP handle. |
|||
|
|||
Unix only: |
|||
The only requirement of the `sock` argument is that it follows the datagram |
|||
contract (works in unconnected mode, supports sendmsg()/recvmsg(), etc). |
|||
In other words, other datagram-type sockets like raw sockets or netlink |
|||
sockets can also be passed to this function. |
|||
|
|||
.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags) |
|||
|
|||
Bind the UDP handle to an IP address and port. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param addr: `struct sockaddr_in` or `struct sockaddr_in6` |
|||
with the address and port to bind to. |
|||
|
|||
:param flags: Indicate how the socket will be bound, |
|||
``UV_UDP_IPV6ONLY`` and ``UV_UDP_REUSEADDR`` are supported. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_getsockname(const uv_udp_t* handle, struct sockaddr* name, int* namelen) |
|||
|
|||
Get the local IP and port of the UDP handle. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init` and bound. |
|||
|
|||
:param name: Pointer to the structure to be filled with the address data. |
|||
In order to support IPv4 and IPv6 `struct sockaddr_storage` should be |
|||
used. |
|||
|
|||
:param namelen: On input it indicates the data of the `name` field. On |
|||
output it indicates how much of it was filled. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership) |
|||
|
|||
Set membership for a multicast address |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param multicast_addr: Multicast address to set membership for. |
|||
|
|||
:param interface_addr: Interface address. |
|||
|
|||
:param membership: Should be ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) |
|||
|
|||
Set IP multicast loop flag. Makes multicast packets loop back to |
|||
local sockets. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param on: 1 for on, 0 for off. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) |
|||
|
|||
Set the multicast ttl. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param ttl: 1 through 255. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) |
|||
|
|||
Set the multicast interface to send or receive data on. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param interface_addr: interface address. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_set_broadcast(uv_udp_t* handle, int on) |
|||
|
|||
Set broadcast on or off. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param on: 1 for on, 0 for off. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_set_ttl(uv_udp_t* handle, int ttl) |
|||
|
|||
Set the time to live. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param ttl: 1 through 255. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr, uv_udp_send_cb send_cb) |
|||
|
|||
Send data over the UDP socket. If the socket has not previously been bound |
|||
with :c:func:`uv_udp_bind` it will be bound to 0.0.0.0 |
|||
(the "all interfaces" IPv4 address) and a random port number. |
|||
|
|||
:param req: UDP request handle. Need not be initialized. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param bufs: List of buffers to send. |
|||
|
|||
:param nbufs: Number of buffers in `bufs`. |
|||
|
|||
:param addr: `struct sockaddr_in` or `struct sockaddr_in6` with the |
|||
address and port of the remote peer. |
|||
|
|||
:param send_cb: Callback to invoke when the data has been sent out. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_try_send(uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr) |
|||
|
|||
Same as :c:func:`uv_udp_send`, but won't queue a send request if it can't |
|||
be completed immediately. |
|||
|
|||
:returns: >= 0: number of bytes sent (it matches the given buffer size). |
|||
< 0: negative error code (``UV_EAGAIN`` is returned when the message |
|||
can't be sent immediately). |
|||
|
|||
.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb) |
|||
|
|||
Prepare for receiving data. If the socket has not previously been bound |
|||
with :c:func:`uv_udp_bind` it is bound to 0.0.0.0 (the "all interfaces" |
|||
IPv4 address) and a random port number. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:param alloc_cb: Callback to invoke when temporary storage is needed. |
|||
|
|||
:param recv_cb: Callback to invoke with received data. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle) |
|||
|
|||
Stop listening for incoming datagrams. |
|||
|
|||
:param handle: UDP handle. Should have been initialized with |
|||
:c:func:`uv_udp_init`. |
|||
|
|||
:returns: 0 on success, or an error code < 0 on failure. |
|||
|
|||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. |
@ -1,2 +1,5 @@ |
|||
# Ignore libtoolize-generated files. |
|||
*.m4 |
|||
!as_case.m4 |
|||
!dtrace.m4 |
|||
!libuv-check-flags.m4 |
@ -0,0 +1,21 @@ |
|||
# AS_CASE(WORD, [PATTERN1], [IF-MATCHED1]...[DEFAULT]) |
|||
# ---------------------------------------------------- |
|||
# Expand into |
|||
# | case WORD in |
|||
# | PATTERN1) IF-MATCHED1 ;; |
|||
# | ... |
|||
# | *) DEFAULT ;; |
|||
# | esac |
|||
m4_define([_AS_CASE], |
|||
[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], |
|||
[$#], 1, [ *) $1 ;;], |
|||
[$#], 2, [ $1) m4_default([$2], [:]) ;;], |
|||
[ $1) m4_default([$2], [:]) ;; |
|||
$0(m4_shiftn(2, $@))])dnl |
|||
]) |
|||
m4_defun([AS_CASE], |
|||
[m4_ifval([$2$3], |
|||
[case $1 in |
|||
_AS_CASE(m4_shift($@)) |
|||
esac])]) |
|||
|
@ -0,0 +1,66 @@ |
|||
dnl Copyright (C) 2009 Sun Microsystems |
|||
dnl This file is free software; Sun Microsystems |
|||
dnl gives unlimited permission to copy and/or distribute it, |
|||
dnl with or without modifications, as long as this notice is preserved. |
|||
|
|||
dnl --------------------------------------------------------------------------- |
|||
dnl Macro: PANDORA_ENABLE_DTRACE |
|||
dnl --------------------------------------------------------------------------- |
|||
AC_DEFUN([PANDORA_ENABLE_DTRACE],[ |
|||
AC_ARG_ENABLE([dtrace], |
|||
[AS_HELP_STRING([--disable-dtrace], |
|||
[enable DTrace USDT probes. @<:@default=yes@:>@])], |
|||
[ac_cv_enable_dtrace="$enableval"], |
|||
[ac_cv_enable_dtrace="yes"]) |
|||
|
|||
AS_IF([test "$ac_cv_enable_dtrace" = "yes"],[ |
|||
AC_CHECK_PROGS([DTRACE], [dtrace]) |
|||
AS_IF([test "x$ac_cv_prog_DTRACE" = "xdtrace"],[ |
|||
|
|||
AC_CACHE_CHECK([if dtrace works],[ac_cv_dtrace_works],[ |
|||
cat >conftest.d <<_ACEOF |
|||
provider Example { |
|||
probe increment(int); |
|||
}; |
|||
_ACEOF |
|||
$DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero |
|||
AS_IF([test $? -eq 0],[ac_cv_dtrace_works=yes], |
|||
[ac_cv_dtrace_works=no]) |
|||
rm -f conftest.h conftest.d |
|||
]) |
|||
AS_IF([test "x$ac_cv_dtrace_works" = "xyes"],[ |
|||
AC_DEFINE([HAVE_DTRACE], [1], [Enables DTRACE Support]) |
|||
AC_CACHE_CHECK([if dtrace should instrument object files], |
|||
[ac_cv_dtrace_needs_objects],[ |
|||
dnl DTrace on MacOSX does not use -G option |
|||
cat >conftest.d <<_ACEOF |
|||
provider Example { |
|||
probe increment(int); |
|||
}; |
|||
_ACEOF |
|||
cat > conftest.c <<_ACEOF |
|||
#include "conftest.h" |
|||
void foo() { |
|||
EXAMPLE_INCREMENT(1); |
|||
} |
|||
_ACEOF |
|||
$DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero |
|||
$CC -c -o conftest.o conftest.c |
|||
$DTRACE -G -o conftest.d.o -s conftest.d conftest.o 2>/dev/zero |
|||
AS_IF([test $? -eq 0],[ac_cv_dtrace_needs_objects=yes], |
|||
[ac_cv_dtrace_needs_objects=no]) |
|||
rm -f conftest.d.o conftest.d conftest.h conftest.o conftest.c |
|||
]) |
|||
]) |
|||
AC_SUBST(DTRACEFLAGS) dnl TODO: test for -G on OSX |
|||
ac_cv_have_dtrace=yes |
|||
])]) |
|||
|
|||
AM_CONDITIONAL([HAVE_DTRACE], [test "x$ac_cv_dtrace_works" = "xyes"]) |
|||
AM_CONDITIONAL([DTRACE_NEEDS_OBJECTS], |
|||
[test "x$ac_cv_dtrace_needs_objects" = "xyes"]) |
|||
|
|||
]) |
|||
dnl --------------------------------------------------------------------------- |
|||
dnl End Macro: PANDORA_ENABLE_DTRACE |
|||
dnl --------------------------------------------------------------------------- |
@ -0,0 +1,319 @@ |
|||
dnl Macros to check the presence of generic (non-typed) symbols. |
|||
dnl Copyright (c) 2006-2008 Diego Pettenà <flameeyes gmail com> |
|||
dnl Copyright (c) 2006-2008 xine project |
|||
dnl |
|||
dnl This program is free software; you can redistribute it and/or modify |
|||
dnl it under the terms of the GNU General Public License as published by |
|||
dnl the Free Software Foundation; either version 3, or (at your option) |
|||
dnl any later version. |
|||
dnl |
|||
dnl This program is distributed in the hope that it will be useful, |
|||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
dnl GNU General Public License for more details. |
|||
dnl |
|||
dnl You should have received a copy of the GNU General Public License |
|||
dnl along with this program; if not, write to the Free Software |
|||
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|||
dnl 02110-1301, USA. |
|||
dnl |
|||
dnl As a special exception, the copyright owners of the |
|||
dnl macro gives unlimited permission to copy, distribute and modify the |
|||
dnl configure scripts that are the output of Autoconf when processing the |
|||
dnl Macro. You need not follow the terms of the GNU General Public |
|||
dnl License when using or distributing such scripts, even though portions |
|||
dnl of the text of the Macro appear in them. The GNU General Public |
|||
dnl License (GPL) does govern all other use of the material that |
|||
dnl constitutes the Autoconf Macro. |
|||
dnl |
|||
dnl This special exception to the GPL applies to versions of the |
|||
dnl Autoconf Macro released by this project. When you make and |
|||
dnl distribute a modified version of the Autoconf Macro, you may extend |
|||
dnl this special exception to the GPL to apply to your modified version as |
|||
dnl well. |
|||
|
|||
dnl Check if the flag is supported by compiler |
|||
dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) |
|||
|
|||
AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ |
|||
AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), |
|||
[ac_save_CFLAGS="$CFLAGS" |
|||
CFLAGS="$CFLAGS $1" |
|||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])], |
|||
[eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], |
|||
[eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) |
|||
CFLAGS="$ac_save_CFLAGS" |
|||
]) |
|||
|
|||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], |
|||
[$2], [$3]) |
|||
]) |
|||
|
|||
dnl Check if the flag is supported by compiler (cacheable) |
|||
dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) |
|||
|
|||
AC_DEFUN([CC_CHECK_CFLAGS], [ |
|||
AC_CACHE_CHECK([if $CC supports $1 flag], |
|||
AS_TR_SH([cc_cv_cflags_$1]), |
|||
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! |
|||
) |
|||
|
|||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], |
|||
[$2], [$3]) |
|||
]) |
|||
|
|||
dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found]) |
|||
dnl Check for CFLAG and appends them to CFLAGS if supported |
|||
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [ |
|||
AC_CACHE_CHECK([if $CC supports $1 flag], |
|||
AS_TR_SH([cc_cv_cflags_$1]), |
|||
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! |
|||
) |
|||
|
|||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], |
|||
[CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3]) |
|||
]) |
|||
|
|||
dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not]) |
|||
AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [ |
|||
for flag in $1; do |
|||
CC_CHECK_CFLAG_APPEND($flag, [$2], [$3]) |
|||
done |
|||
]) |
|||
|
|||
dnl Check if the flag is supported by linker (cacheable) |
|||
dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) |
|||
|
|||
AC_DEFUN([CC_CHECK_LDFLAGS], [ |
|||
AC_CACHE_CHECK([if $CC supports $1 flag], |
|||
AS_TR_SH([cc_cv_ldflags_$1]), |
|||
[ac_save_LDFLAGS="$LDFLAGS" |
|||
LDFLAGS="$LDFLAGS $1" |
|||
AC_LANG_PUSH([C]) |
|||
AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])], |
|||
[eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], |
|||
[eval "AS_TR_SH([cc_cv_ldflags_$1])="]) |
|||
AC_LANG_POP([C]) |
|||
LDFLAGS="$ac_save_LDFLAGS" |
|||
]) |
|||
|
|||
AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], |
|||
[$2], [$3]) |
|||
]) |
|||
|
|||
dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for |
|||
dnl the current linker to avoid undefined references in a shared object. |
|||
AC_DEFUN([CC_NOUNDEFINED], [ |
|||
dnl We check $host for which systems to enable this for. |
|||
AC_REQUIRE([AC_CANONICAL_HOST]) |
|||
|
|||
case $host in |
|||
dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads |
|||
dnl are requested, as different implementations are present; to avoid problems |
|||
dnl use -Wl,-z,defs only for those platform not behaving this way. |
|||
*-freebsd* | *-openbsd*) ;; |
|||
*) |
|||
dnl First of all check for the --no-undefined variant of GNU ld. This allows |
|||
dnl for a much more readable commandline, so that people can understand what |
|||
dnl it does without going to look for what the heck -z defs does. |
|||
for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do |
|||
CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) |
|||
break |
|||
done |
|||
;; |
|||
esac |
|||
|
|||
AC_SUBST([LDFLAGS_NOUNDEFINED]) |
|||
]) |
|||
|
|||
dnl Check for a -Werror flag or equivalent. -Werror is the GCC |
|||
dnl and ICC flag that tells the compiler to treat all the warnings |
|||
dnl as fatal. We usually need this option to make sure that some |
|||
dnl constructs (like attributes) are not simply ignored. |
|||
dnl |
|||
dnl Other compilers don't support -Werror per se, but they support |
|||
dnl an equivalent flag: |
|||
dnl - Sun Studio compiler supports -errwarn=%all |
|||
AC_DEFUN([CC_CHECK_WERROR], [ |
|||
AC_CACHE_CHECK( |
|||
[for $CC way to treat warnings as errors], |
|||
[cc_cv_werror], |
|||
[CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], |
|||
[CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) |
|||
]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_CHECK_ATTRIBUTE], [ |
|||
AC_REQUIRE([CC_CHECK_WERROR]) |
|||
AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], |
|||
AS_TR_SH([cc_cv_attribute_$1]), |
|||
[ac_save_CFLAGS="$CFLAGS" |
|||
CFLAGS="$CFLAGS $cc_cv_werror" |
|||
AC_LANG_PUSH([C]) |
|||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], |
|||
[eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], |
|||
[eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) |
|||
AC_LANG_POP([C]) |
|||
CFLAGS="$ac_save_CFLAGS" |
|||
]) |
|||
|
|||
AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], |
|||
[AC_DEFINE( |
|||
AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, |
|||
[Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] |
|||
) |
|||
$4], |
|||
[$5]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[constructor],, |
|||
[void __attribute__((constructor)) ctor() { int a; }], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[format], [format(printf, n, n)], |
|||
[void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[format_arg], [format_arg(printf)], |
|||
[char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[visibility_$1], [visibility("$1")], |
|||
[void __attribute__((visibility("$1"))) $1_function() { }], |
|||
[$2], [$3]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[nonnull], [nonnull()], |
|||
[void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[unused], , |
|||
[void some_function(void *foo, __attribute__((unused)) void *bar);], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[sentinel], , |
|||
[void some_function(void *foo, ...) __attribute__((sentinel));], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[deprecated], , |
|||
[void some_function(void *foo, ...) __attribute__((deprecated));], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[alias], [weak, alias], |
|||
[void other_function(void *foo) { } |
|||
void some_function(void *foo) __attribute__((weak, alias("other_function")));], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[malloc], , |
|||
[void * __attribute__((malloc)) my_alloc(int n);], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_PACKED], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[packed], , |
|||
[struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_CONST], [ |
|||
CC_CHECK_ATTRIBUTE( |
|||
[const], , |
|||
[int __attribute__((const)) twopow(int n) { return 1 << n; } ], |
|||
[$1], [$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_FLAG_VISIBILITY], [ |
|||
AC_REQUIRE([CC_CHECK_WERROR]) |
|||
AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], |
|||
[cc_cv_flag_visibility], |
|||
[cc_flag_visibility_save_CFLAGS="$CFLAGS" |
|||
CFLAGS="$CFLAGS $cc_cv_werror" |
|||
CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], |
|||
cc_cv_flag_visibility='yes', |
|||
cc_cv_flag_visibility='no') |
|||
CFLAGS="$cc_flag_visibility_save_CFLAGS"]) |
|||
|
|||
AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], |
|||
[AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, |
|||
[Define this if the compiler supports the -fvisibility flag]) |
|||
$1], |
|||
[$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_FUNC_EXPECT], [ |
|||
AC_REQUIRE([CC_CHECK_WERROR]) |
|||
AC_CACHE_CHECK([if compiler has __builtin_expect function], |
|||
[cc_cv_func_expect], |
|||
[ac_save_CFLAGS="$CFLAGS" |
|||
CFLAGS="$CFLAGS $cc_cv_werror" |
|||
AC_LANG_PUSH([C]) |
|||
AC_COMPILE_IFELSE([AC_LANG_SOURCE( |
|||
[int some_function() { |
|||
int a = 3; |
|||
return (int)__builtin_expect(a, 3); |
|||
}])], |
|||
[cc_cv_func_expect=yes], |
|||
[cc_cv_func_expect=no]) |
|||
AC_LANG_POP([C]) |
|||
CFLAGS="$ac_save_CFLAGS" |
|||
]) |
|||
|
|||
AS_IF([test "x$cc_cv_func_expect" = "xyes"], |
|||
[AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, |
|||
[Define this if the compiler supports __builtin_expect() function]) |
|||
$1], |
|||
[$2]) |
|||
]) |
|||
|
|||
AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ |
|||
AC_REQUIRE([CC_CHECK_WERROR]) |
|||
AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], |
|||
[cc_cv_attribute_aligned], |
|||
[ac_save_CFLAGS="$CFLAGS" |
|||
CFLAGS="$CFLAGS $cc_cv_werror" |
|||
AC_LANG_PUSH([C]) |
|||
for cc_attribute_align_try in 64 32 16 8 4 2; do |
|||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([ |
|||
int main() { |
|||
static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; |
|||
return c; |
|||
}])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) |
|||
done |
|||
AC_LANG_POP([C]) |
|||
CFLAGS="$ac_save_CFLAGS" |
|||
]) |
|||
|
|||
if test "x$cc_cv_attribute_aligned" != "x"; then |
|||
AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], |
|||
[Define the highest alignment supported]) |
|||
fi |
|||
]) |
@ -0,0 +1,59 @@ |
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to |
|||
* deal in the Software without restriction, including without limitation the |
|||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|||
* sell copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in |
|||
* all copies or substantial portions of the Software. |
|||
* |
|||
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
|||
* IN THE SOFTWARE. |
|||
*/ |
|||
|
|||
#include "uv.h" |
|||
#include "task.h" |
|||
|
|||
|
|||
static int timer_cb_called; |
|||
|
|||
|
|||
static void timer_cb(uv_timer_t* timer) { |
|||
timer_cb_called++; |
|||
uv_close((uv_handle_t*) timer, NULL); |
|||
} |
|||
|
|||
|
|||
TEST_IMPL(default_loop_close) { |
|||
uv_loop_t* loop; |
|||
uv_timer_t timer_handle; |
|||
|
|||
loop = uv_default_loop(); |
|||
ASSERT(loop != NULL); |
|||
|
|||
ASSERT(0 == uv_timer_init(loop, &timer_handle)); |
|||
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); |
|||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); |
|||
ASSERT(1 == timer_cb_called); |
|||
ASSERT(0 == uv_loop_close(loop)); |
|||
|
|||
loop = uv_default_loop(); |
|||
ASSERT(loop != NULL); |
|||
|
|||
ASSERT(0 == uv_timer_init(loop, &timer_handle)); |
|||
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); |
|||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); |
|||
ASSERT(2 == timer_cb_called); |
|||
ASSERT(0 == uv_loop_close(loop)); |
|||
|
|||
MAKE_VALGRIND_HAPPY(); |
|||
return 0; |
|||
} |
@ -0,0 +1,120 @@ |
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to |
|||
* deal in the Software without restriction, including without limitation the |
|||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|||
* sell copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in |
|||
* all copies or substantial portions of the Software. |
|||
* |
|||
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
|||
* IN THE SOFTWARE. |
|||
*/ |
|||
|
|||
#include "uv.h" |
|||
#include "task.h" |
|||
|
|||
|
|||
static int get_tty_fd(void) { |
|||
/* Make sure we have an FD that refers to a tty */ |
|||
#ifdef _WIN32 |
|||
HANDLE handle; |
|||
handle = CreateFileA("conout$", |
|||
GENERIC_READ | GENERIC_WRITE, |
|||
FILE_SHARE_READ | FILE_SHARE_WRITE, |
|||
NULL, |
|||
OPEN_EXISTING, |
|||
FILE_ATTRIBUTE_NORMAL, |
|||
NULL); |
|||
if (handle == INVALID_HANDLE_VALUE) |
|||
return -1; |
|||
return _open_osfhandle((intptr_t) handle, 0); |
|||
#else /* unix */ |
|||
return open("/dev/tty", O_RDONLY, 0); |
|||
#endif |
|||
} |
|||
|
|||
|
|||
TEST_IMPL(handle_fileno) { |
|||
int r; |
|||
int tty_fd; |
|||
struct sockaddr_in addr; |
|||
uv_os_fd_t fd; |
|||
uv_tcp_t tcp; |
|||
uv_udp_t udp; |
|||
uv_pipe_t pipe; |
|||
uv_tty_t tty; |
|||
uv_idle_t idle; |
|||
uv_loop_t* loop; |
|||
|
|||
loop = uv_default_loop(); |
|||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); |
|||
|
|||
r = uv_idle_init(loop, &idle); |
|||
ASSERT(r == 0); |
|||
r = uv_fileno((uv_handle_t*) &idle, &fd); |
|||
ASSERT(r == UV_EINVAL); |
|||
uv_close((uv_handle_t*) &idle, NULL); |
|||
|
|||
r = uv_tcp_init(loop, &tcp); |
|||
ASSERT(r == 0); |
|||
r = uv_fileno((uv_handle_t*) &tcp, &fd); |
|||
ASSERT(r == UV_EBADF); |
|||
r = uv_tcp_bind(&tcp, (const struct sockaddr*) &addr, 0); |
|||
ASSERT(r == 0); |
|||
r = uv_fileno((uv_handle_t*) &tcp, &fd); |
|||
ASSERT(r == 0); |
|||
uv_close((uv_handle_t*) &tcp, NULL); |
|||
r = uv_fileno((uv_handle_t*) &tcp, &fd); |
|||
ASSERT(r == UV_EBADF); |
|||
|
|||
r = uv_udp_init(loop, &udp); |
|||
ASSERT(r == 0); |
|||
r = uv_fileno((uv_handle_t*) &udp, &fd); |
|||
ASSERT(r == UV_EBADF); |
|||
r = uv_udp_bind(&udp, (const struct sockaddr*) &addr, 0); |
|||
ASSERT(r == 0); |
|||
r = uv_fileno((uv_handle_t*) &udp, &fd); |
|||
ASSERT(r == 0); |
|||
uv_close((uv_handle_t*) &udp, NULL); |
|||
r = uv_fileno((uv_handle_t*) &udp, &fd); |
|||
ASSERT(r == UV_EBADF); |
|||
|
|||
r = uv_pipe_init(loop, &pipe, 0); |
|||
ASSERT(r == 0); |
|||
r = uv_fileno((uv_handle_t*) &pipe, &fd); |
|||
ASSERT(r == UV_EBADF); |
|||
r = uv_pipe_bind(&pipe, TEST_PIPENAME); |
|||
ASSERT(r == 0); |
|||
r = uv_fileno((uv_handle_t*) &pipe, &fd); |
|||
ASSERT(r == 0); |
|||
uv_close((uv_handle_t*) &pipe, NULL); |
|||
r = uv_fileno((uv_handle_t*) &pipe, &fd); |
|||
ASSERT(r == UV_EBADF); |
|||
|
|||
tty_fd = get_tty_fd(); |
|||
if (tty_fd < 0) { |
|||
LOGF("Cannot open a TTY fd"); |
|||
} else { |
|||
r = uv_tty_init(loop, &tty, tty_fd, 0); |
|||
ASSERT(r == 0); |
|||
r = uv_fileno((uv_handle_t*) &tty, &fd); |
|||
ASSERT(r == 0); |
|||
uv_close((uv_handle_t*) &tty, NULL); |
|||
r = uv_fileno((uv_handle_t*) &tty, &fd); |
|||
ASSERT(r == UV_EBADF); |
|||
} |
|||
|
|||
uv_run(loop, UV_RUN_DEFAULT); |
|||
|
|||
MAKE_VALGRIND_HAPPY(); |
|||
return 0; |
|||
} |
@ -0,0 +1,103 @@ |
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to |
|||
* deal in the Software without restriction, including without limitation the |
|||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|||
* sell copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in |
|||
* all copies or substantial portions of the Software. |
|||
* |
|||
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
|||
* IN THE SOFTWARE. |
|||
*/ |
|||
|
|||
#ifndef _WIN32 |
|||
|
|||
#include <stdlib.h> |
|||
#include <unistd.h> |
|||
#include <sys/wait.h> |
|||
#include <sys/types.h> |
|||
|
|||
#include "uv.h" |
|||
#include "task.h" |
|||
|
|||
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf) |
|||
{ |
|||
static char buffer[1024]; |
|||
|
|||
buf->base = buffer; |
|||
buf->len = sizeof(buffer); |
|||
} |
|||
|
|||
void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf) |
|||
{ |
|||
if (nread < 0) { |
|||
uv_close((uv_handle_t*)stream, NULL); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
* This test is a reproduction of joyent/libuv#1419 . |
|||
*/ |
|||
TEST_IMPL(pipe_close_stdout_read_stdin) { |
|||
int r = -1; |
|||
int pid; |
|||
int fd[2]; |
|||
int status; |
|||
|
|||
pipe(fd); |
|||
|
|||
if ((pid = fork()) == 0) { |
|||
/*
|
|||
* Make the read side of the pipe our stdin. |
|||
* The write side will be closed by the parent process. |
|||
*/ |
|||
close(fd[1]); |
|||
close(0); |
|||
dup(fd[0]); |
|||
|
|||
/* Create a stream that reads from the pipe. */ |
|||
uv_pipe_t stdin_pipe; |
|||
|
|||
r = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)&stdin_pipe, 0); |
|||
ASSERT(r == 0); |
|||
|
|||
r = uv_pipe_open((uv_pipe_t *)&stdin_pipe, 0); |
|||
ASSERT(r == 0); |
|||
|
|||
r = uv_read_start((uv_stream_t *)&stdin_pipe, alloc_buffer, read_stdin); |
|||
ASSERT(r == 0); |
|||
|
|||
/*
|
|||
* Because the other end of the pipe was closed, there should |
|||
* be no event left to process after one run of the event loop. |
|||
* Otherwise, it means that events were not processed correctly. |
|||
*/ |
|||
ASSERT(uv_run(uv_default_loop(), UV_RUN_NOWAIT) == 0); |
|||
} else { |
|||
/*
|
|||
* Close both ends of the pipe so that the child |
|||
* get a POLLHUP event when it tries to read from |
|||
* the other end. |
|||
*/ |
|||
close(fd[1]); |
|||
close(fd[0]); |
|||
|
|||
waitpid(pid, &status, 0); |
|||
ASSERT(WIFEXITED(status) && WEXITSTATUS(status) == 0); |
|||
} |
|||
|
|||
MAKE_VALGRIND_HAPPY(); |
|||
return 0; |
|||
} |
|||
|
|||
#endif /* ifndef _WIN32 */ |
@ -0,0 +1,77 @@ |
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to |
|||
* deal in the Software without restriction, including without limitation the |
|||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|||
* sell copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in |
|||
* all copies or substantial portions of the Software. |
|||
* |
|||
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
|||
* IN THE SOFTWARE. |
|||
*/ |
|||
|
|||
#include "uv.h" |
|||
#include "task.h" |
|||
|
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
|
|||
static uv_udp_t udp; |
|||
static uv_tcp_t tcp; |
|||
static int close_cb_called; |
|||
|
|||
|
|||
static void close_cb(uv_handle_t* handle) { |
|||
close_cb_called++; |
|||
} |
|||
|
|||
|
|||
static void check_buffer_size(uv_handle_t* handle) { |
|||
int value; |
|||
|
|||
value = 0; |
|||
ASSERT(0 == uv_recv_buffer_size(handle, &value)); |
|||
ASSERT(value > 0); |
|||
|
|||
value = 10000; |
|||
ASSERT(0 == uv_recv_buffer_size(handle, &value)); |
|||
|
|||
value = 0; |
|||
ASSERT(0 == uv_recv_buffer_size(handle, &value)); |
|||
/* linux sets double the value */ |
|||
ASSERT(value == 10000 || value == 20000); |
|||
} |
|||
|
|||
|
|||
TEST_IMPL(socket_buffer_size) { |
|||
struct sockaddr_in addr; |
|||
|
|||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); |
|||
|
|||
ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp)); |
|||
ASSERT(0 == uv_tcp_bind(&tcp, (struct sockaddr*) &addr, 0)); |
|||
check_buffer_size((uv_handle_t*) &tcp); |
|||
uv_close((uv_handle_t*) &tcp, close_cb); |
|||
|
|||
ASSERT(0 == uv_udp_init(uv_default_loop(), &udp)); |
|||
ASSERT(0 == uv_udp_bind(&udp, (struct sockaddr*) &addr, 0)); |
|||
check_buffer_size((uv_handle_t*) &udp); |
|||
uv_close((uv_handle_t*) &udp, close_cb); |
|||
|
|||
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); |
|||
|
|||
ASSERT(close_cb_called == 2); |
|||
|
|||
MAKE_VALGRIND_HAPPY(); |
|||
return 0; |
|||
} |