@ -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. |
# Ignore libtoolize-generated files. |
||||
*.m4 |
*.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; |
||||
|
} |