Update to libuv commit 3ca382.

This patch changes libuv's gyp build system to
make it's own makefiles. To generate them for rust,
run these commands. They requires python 2.x to
work:

$ mkdir -p src/rt/libuv/build
$ svn co http://gyp.googlecode.com/svn src/rt/libuv/build/gyp
$ ./etc/src/gyp_uv
This commit is contained in:
Erick Tryzelaar 2011-09-23 16:13:14 -07:00
parent d8f6e9f237
commit 5f066e06b9
213 changed files with 30554 additions and 7209 deletions

2
.gitignore vendored
View File

@ -52,7 +52,7 @@ rustc
TAGS TAGS
version.ml version.ml
version.texi version.texi
Makefile ./Makefile
config.mk config.mk
/rt/ /rt/
/rustllvm/ /rustllvm/

4
configure vendored
View File

@ -406,8 +406,4 @@ done
copy ${CFG_SRC_DIR}Makefile.in ./Makefile copy ${CFG_SRC_DIR}Makefile.in ./Makefile
copy ${CFG_SRC_DIR}src/rt/libuv/Makefile rt/libuv/Makefile
copy ${CFG_SRC_DIR}src/rt/libuv/config-unix.mk rt/libuv/config-unix.mk
copy ${CFG_SRC_DIR}src/rt/libuv/config-mingw.mk rt/libuv/config-mingw.mk
step_msg "complete" step_msg "complete"

View File

@ -54,3 +54,4 @@ clean:
aux cp fn ky log pdf html pg toc tp vr cps, \ aux cp fn ky log pdf html pg toc tp vr cps, \
$(wildcard doc/*.$(ext))) $(wildcard doc/*.$(ext)))
$(Q)rm -Rf doc/version.texi $(Q)rm -Rf doc/version.texi
$(Q)rm -rf rt/libuv

359
mk/libuv/mac/Makefile Normal file
View File

@ -0,0 +1,359 @@
# We borrow heavily from the kernel build setup, though we are simpler since
# we don't have Kconfig tweaking settings on us.
# The implicit make rules have it looking for RCS files, among other things.
# We instead explicitly write all the rules we care about.
# It's even quicker (saves ~200ms) to pass -r on the command line.
MAKEFLAGS=-r
# The source directory tree.
srcdir := ../../..
# The name of the builddir.
builddir_name ?= out
# The V=1 flag on command line makes us verbosely print command lines.
ifdef V
quiet=
else
quiet=quiet_
endif
# Specify BUILDTYPE=Release on the command line for a release build.
BUILDTYPE ?= Default
# Directory all our build output goes into.
# Note that this must be two directories beneath src/ for unit tests to pass,
# as they reach into the src/ directory for data with relative paths.
builddir ?= $(builddir_name)/$(BUILDTYPE)
abs_builddir := $(abspath $(builddir))
depsdir := $(builddir)/.deps
# Object output directory.
obj := $(builddir)/obj
abs_obj := $(abspath $(obj))
# We build up a list of every single one of the targets so we can slurp in the
# generated dependency rule Makefiles in one pass.
all_deps :=
# C++ apps need to be linked with g++. Not sure what's appropriate.
#
# Note, the flock is used to seralize linking. Linking is a memory-intensive
# process so running parallel links can often lead to thrashing. To disable
# the serialization, override FLOCK via an envrionment variable as follows:
#
# export FLOCK=
#
# This will allow make to invoke N linker processes as specified in -jN.
FLOCK ?= ./gyp-mac-tool flock $(builddir)/linker.lock
LINK ?= $(FLOCK) $(CXX)
CC.target ?= $(CC)
CFLAGS.target ?= $(CFLAGS)
CXX.target ?= $(CXX)
CXXFLAGS.target ?= $(CXXFLAGS)
LINK.target ?= $(LINK)
LDFLAGS.target ?= $(LDFLAGS)
AR.target ?= $(AR)
ARFLAGS.target ?= crs
# N.B.: the logic of which commands to run should match the computation done
# in gyp's make.py where ARFLAGS.host etc. is computed.
# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
# to replicate this environment fallback in make as well.
CC.host ?= gcc
CFLAGS.host ?=
CXX.host ?= g++
CXXFLAGS.host ?=
LINK.host ?= g++
LDFLAGS.host ?=
AR.host ?= ar
ARFLAGS.host := crs
# Define a dir function that can handle spaces.
# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions
# "leading spaces cannot appear in the text of the first argument as written.
# These characters can be put into the argument value by variable substitution."
empty :=
space := $(empty) $(empty)
# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces
replace_spaces = $(subst $(space),?,$1)
unreplace_spaces = $(subst ?,$(space),$1)
dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1)))
# Flags to make gcc output dependency info. Note that you need to be
# careful here to use the flags that ccache and distcc can understand.
# We write to a dep file on the side first and then rename at the end
# so we can't end up with a broken dep file.
depfile = $(depsdir)/$(call replace_spaces,$@).d
DEPFLAGS = -MMD -MF $(depfile).raw
# We have to fixup the deps output in a few ways.
# (1) the file output should mention the proper .o file.
# ccache or distcc lose the path to the target, so we convert a rule of
# the form:
# foobar.o: DEP1 DEP2
# into
# path/to/foobar.o: DEP1 DEP2
# (2) we want missing files not to cause us to fail to build.
# We want to rewrite
# foobar.o: DEP1 DEP2 \
# DEP3
# to
# DEP1:
# DEP2:
# DEP3:
# so if the files are missing, they're just considered phony rules.
# We have to do some pretty insane escaping to get those backslashes
# and dollar signs past make, the shell, and sed at the same time.
# Doesn't work with spaces, but that's fine: .d files have spaces in
# their names replaced with other characters.
define fixup_dep
# The depfile may not exist if the input file didn't have any #includes.
touch $(depfile).raw
# Fixup path as in (1).
sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
# Add extra rules as in (2).
# We remove slashes and replace spaces with new lines;
# remove blank lines;
# delete the first line and append a colon to the remaining lines.
sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
grep -v '^$$' |\
sed -e 1d -e 's|$$|:|' \
>> $(depfile)
rm $(depfile).raw
endef
# Command definitions:
# - cmd_foo is the actual command to run;
# - quiet_cmd_foo is the brief-output summary of the command.
quiet_cmd_cc = CC($(TOOLSET)) $@
cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $<
quiet_cmd_cxx = CXX($(TOOLSET)) $@
cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
quiet_cmd_objc = CXX($(TOOLSET)) $@
cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $<
quiet_cmd_objcxx = CXX($(TOOLSET)) $@
cmd_objcxx = $(CXX.$(TOOLSET)) $(GYP_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $<
# Commands for precompiled header files.
quiet_cmd_pch_c = CXX($(TOOLSET)) $@
cmd_pch_c = $(CC.$(TOOLSET)) $(GYP_PCH_CFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
quiet_cmd_pch_cc = CXX($(TOOLSET)) $@
cmd_pch_cc = $(CC.$(TOOLSET)) $(GYP_PCH_CCFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
quiet_cmd_pch_m = CXX($(TOOLSET)) $@
cmd_pch_m = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $<
quiet_cmd_pch_mm = CXX($(TOOLSET)) $@
cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $<
# gyp-mac-tool is written next to the root Makefile by gyp.
# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd
# already.
quiet_cmd_mac_tool = MACTOOL $(4) $<
cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@"
quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@
cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4)
quiet_cmd_touch = TOUCH $@
cmd_touch = touch $@
quiet_cmd_copy = COPY $@
# send stderr to /dev/null to ignore messages when linking directories.
cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@")
quiet_cmd_alink = LIBTOOL-STATIC $@
cmd_alink = rm -f $@ && libtool -static -o $@ $(filter %.o,$^)
quiet_cmd_link = LINK($(TOOLSET)) $@
cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
# TODO(thakis): Find out and document the difference between shared_library and
# loadable_module on mac.
quiet_cmd_solink = SOLINK($(TOOLSET)) $@
cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
# TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass
# -bundle -single_module here (for osmesa.so).
quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS)
# Define an escape_quotes function to escape single quotes.
# This allows us to handle quotes properly as long as we always use
# use single quotes and escape_quotes.
escape_quotes = $(subst ','\'',$(1))
# This comment is here just to include a ' to unconfuse syntax highlighting.
# Define an escape_vars function to escape '$' variable syntax.
# This allows us to read/write command lines with shell variables (e.g.
# $LD_LIBRARY_PATH), without triggering make substitution.
escape_vars = $(subst $$,$$$$,$(1))
# Helper that expands to a shell command to echo a string exactly as it is in
# make. This uses printf instead of echo because printf's behaviour with respect
# to escape sequences is more portable than echo's across different shells
# (e.g., dash, bash).
exact_echo = printf '%s\n' '$(call escape_quotes,$(1))'
# Helper to compare the command we're about to run against the command
# we logged the last time we ran the command. Produces an empty
# string (false) when the commands match.
# Tricky point: Make has no string-equality test function.
# The kernel uses the following, but it seems like it would have false
# positives, where one string reordered its arguments.
# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
# $(filter-out $(cmd_$@), $(cmd_$(1))))
# We instead substitute each for the empty string into the other, and
# say they're equal if both substitutions produce the empty string.
# .d files contain ? instead of spaces, take that into account.
command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
$(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1))))
# Helper that is non-empty when a prerequisite changes.
# Normally make does this implicitly, but we force rules to always run
# so we can check their command lines.
# $? -- new prerequisites
# $| -- order-only dependencies
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
# do_cmd: run a command via the above cmd_foo names, if necessary.
# Should always run for a given target to handle command-line changes.
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
# Third argument, if non-zero, makes it do POSTBUILDS processing.
# Note: We intentionally do NOT call dirx for depfile, since it contains ? for
# spaces already and dirx strips the ? characters.
define do_cmd
$(if $(or $(command_changed),$(prereq_changed)),
@$(call exact_echo, $($(quiet)cmd_$(1)))
@mkdir -p "$(call dirx,$@)" "$(dir $(depfile))"
$(if $(findstring flock,$(word 2,$(cmd_$1))),
@$(cmd_$(1))
@echo " $(quiet_cmd_$(1)): Finished",
@$(cmd_$(1))
)
@$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
@$(if $(2),$(fixup_dep))
$(if $(and $(3), $(POSTBUILDS)),
@for p in $(POSTBUILDS); do eval $$p; done
)
)
endef
# Declare "all" target first so it is the default, even though we don't have the
# deps yet.
.PHONY: all
all:
# Use FORCE_DO_CMD to force a target to run. Should be coupled with
# do_cmd.
.PHONY: FORCE_DO_CMD
FORCE_DO_CMD:
TOOLSET := target
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.m FORCE_DO_CMD
@$(call do_cmd,objc,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.mm FORCE_DO_CMD
@$(call do_cmd,objcxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.m FORCE_DO_CMD
@$(call do_cmd,objc,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.mm FORCE_DO_CMD
@$(call do_cmd,objcxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.m FORCE_DO_CMD
@$(call do_cmd,objc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.mm FORCE_DO_CMD
@$(call do_cmd,objcxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/run-benchmarks.target.mk)))),)
include src/rt/libuv/run-benchmarks.target.mk
endif
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/run-tests.target.mk)))),)
include src/rt/libuv/run-tests.target.mk
endif
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/uv.target.mk)))),)
include src/rt/libuv/uv.target.mk
endif
quiet_cmd_regen_makefile = ACTION Regenerating $@
cmd_regen_makefile = ./src/rt/libuv/build/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." "--depth=." "--generator-output=mk/libuv/mac" "-Dlibrary=static_library" "-Dtarget_arch=ia32" "-DOS=mac" src/rt/libuv/uv.gyp
#Makefile: $(srcdir)/src/rt/libuv/uv.gyp
# $(call do_cmd,regen_makefile)
# "all" is a concatenation of the "all" targets from all the included
# sub-makefiles. This is just here to clarify.
all:
# Add in dependency-tracking rules. $(all_deps) is the list of every single
# target in our tree. Only consider the ones with .d (dependency) info:
d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
ifneq ($(d_files),)
# Rather than include each individual .d file, concatenate them into a
# single file which make is able to load faster. We split this into
# commands that take 1000 files at a time to avoid overflowing the
# command line.
$(shell cat $(wordlist 1,1000,$(d_files)) > $(depsdir)/all.deps)
ifneq ($(word 1001,$(d_files)),)
$(error Found unprocessed dependency files (gyp didn't generate enough rules!))
endif
# make looks for ways to re-generate included makefiles, but in our case, we
# don't have a direct way. Explicitly telling make that it has nothing to do
# for them makes it go faster.
$(depsdir)/all.deps: ;
include $(depsdir)/all.deps
endif

188
mk/libuv/mac/gyp-mac-tool Executable file
View File

@ -0,0 +1,188 @@
#!/usr/bin/python
# Generated by gyp. Do not edit.
# Copyright (c) 2011 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Utility functions to perform Xcode-style build steps.
These functions are executed via gyp-mac-tool when using the Makefile generator.
"""
import os
import fcntl
import plistlib
import shutil
import string
import subprocess
import sys
def main(args):
executor = MacTool()
executor.Dispatch(args)
class MacTool(object):
"""This class performs all the Mac tooling steps. The methods can either be
executed directly, or dispatched from an argument list."""
def Dispatch(self, args):
"""Dispatches a string command to a method."""
if len(args) < 1:
raise Exception("Not enough arguments")
method = "Exec%s" % self._CommandifyName(args[0])
getattr(self, method)(*args[1:])
def _CommandifyName(self, name_string):
"""Transforms a tool name like copy-info-plist to CopyInfoPlist"""
return name_string.title().replace('-', '')
def ExecFlock(self, lockfile, *cmd_list):
"""Emulates the most basic behavior of Linux's flock(1)."""
# Rely on exception handling to report errors.
fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666)
fcntl.flock(fd, fcntl.LOCK_EX)
return subprocess.call(cmd_list)
def ExecCopyInfoPlist(self, source, dest):
"""Copies the |source| Info.plist to the destination directory |dest|."""
# Read the source Info.plist into memory.
fd = open(source, 'r')
lines = fd.read()
fd.close()
# Go through all the environment variables and replace them as variables in
# the file.
for key in os.environ:
if key.startswith('_'):
continue
evar = '${%s}' % key
lines = string.replace(lines, evar, os.environ[key])
# Write out the file with variables replaced.
fd = open(dest, 'w')
fd.write(lines)
fd.close()
# Now write out PkgInfo file now that the Info.plist file has been
# "compiled".
self._WritePkgInfo(dest)
def _WritePkgInfo(self, info_plist):
"""This writes the PkgInfo file from the data stored in Info.plist."""
plist = plistlib.readPlist(info_plist)
if not plist:
return
# The format of PkgInfo is eight characters, representing the bundle type
# and bundle signature, each four characters. If either is missing, four
# '?' characters are used instead.
package_type = plist['CFBundlePackageType']
if len(package_type) != 4:
package_type = '?' * 4
signature_code = plist['CFBundleSignature']
if len(signature_code) != 4:
signature_code = '?' * 4
dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo')
fp = open(dest, 'w')
fp.write('%s%s' % (package_type, signature_code))
fp.close()
def ExecPackageFramework(self, framework, version):
"""Takes a path to Something.framework and the Current version of that and
sets up all the symlinks."""
# Find the name of the binary based on the part before the ".framework".
binary = os.path.basename(framework).split('.')[0]
CURRENT = 'Current'
RESOURCES = 'Resources'
VERSIONS = 'Versions'
if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)):
# Binary-less frameworks don't seem to contain symlinks (see e.g.
# chromium's out/Debug/org.chromium.Chromium.manifest/ bundle).
return
# Move into the framework directory to set the symlinks correctly.
pwd = os.getcwd()
os.chdir(framework)
# Set up the Current version.
self._Relink(version, os.path.join(VERSIONS, CURRENT))
# Set up the root symlinks.
self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary)
self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES)
# Back to where we were before!
os.chdir(pwd)
def _Relink(self, dest, link):
"""Creates a symlink to |dest| named |link|. If |link| already exists,
it is overwritten."""
if os.path.lexists(link):
os.remove(link)
os.symlink(dest, link)
def ExecCopyBundleResource(self, source, dest):
"""Copies a resource file to the bundle/Resources directory, performing any
necessary compilation on each resource."""
extension = os.path.splitext(source)[1].lower()
if os.path.isdir(source):
# Copy tree.
if os.path.exists(dest):
shutil.rmtree(dest)
shutil.copytree(source, dest)
elif extension == '.xib':
self._CopyXIBFile(source, dest)
elif extension == '.strings':
self._CopyStringsFile(source, dest)
# TODO: Given that files with arbitrary extensions can be copied to the
# bundle, we will want to get rid of this whitelist eventually.
elif extension in [
'.icns', '.manifest', '.pak', '.pdf', '.png', '.sb', '.sh',
'.ttf', '.sdef']:
shutil.copyfile(source, dest)
else:
raise NotImplementedError(
"Don't know how to copy bundle resources of type %s while copying "
"%s to %s)" % (extension, source, dest))
def _CopyXIBFile(self, source, dest):
"""Compiles a XIB file with ibtool into a binary plist in the bundle."""
args = ['/Developer/usr/bin/ibtool', '--errors', '--warnings',
'--notices', '--output-format', 'human-readable-text', '--compile',
dest, source]
subprocess.call(args)
def _CopyStringsFile(self, source, dest):
"""Copies a .strings file using iconv to reconvert the input into UTF-16."""
input_code = self._DetectInputEncoding(source) or "UTF-8"
fp = open(dest, 'w')
args = ['/usr/bin/iconv', '--from-code', input_code, '--to-code',
'UTF-16', source]
subprocess.call(args, stdout=fp)
fp.close()
def _DetectInputEncoding(self, file_name):
"""Reads the first few bytes from file_name and tries to guess the text
encoding. Returns None as a guess if it can't detect it."""
fp = open(file_name, 'rb')
try:
header = fp.read(3)
except e:
fp.close()
return None
fp.close()
if header.startswith("\xFE\xFF"):
return "UTF-16BE"
elif header.startswith("\xFF\xFE"):
return "UTF-16LE"
elif header.startswith("\xEF\xBB\xBF"):
return "UTF-8"
else:
return None
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -0,0 +1,91 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := run-benchmarks
DEFS_Default := '-D_GNU_SOURCE'
# Flags passed to all source files.
CFLAGS_Default := -fasm-blocks \
-mpascal-strings \
-gdwarf-2 \
-arch i386
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
# Flags passed to only ObjC files.
CFLAGS_OBJC_Default :=
# Flags passed to only ObjC++ files.
CFLAGS_OBJCC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ares.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ping-pongs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pound.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pump.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-sizes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-udp-packet-storm.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/dns-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-benchmarks.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-unix.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# Make sure our dependencies are built before any of us.
$(OBJS): | $(builddir)/libuv.a
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE))
$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default := -arch i386 \
-L$(builddir)
LIBS := -framework Carbon \
-framework CoreServices
$(builddir)/run-benchmarks: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(builddir)/run-benchmarks: LIBS := $(LIBS)
$(builddir)/run-benchmarks: LD_INPUTS := $(OBJS) $(builddir)/libuv.a
$(builddir)/run-benchmarks: TOOLSET := $(TOOLSET)
$(builddir)/run-benchmarks: $(OBJS) $(builddir)/libuv.a FORCE_DO_CMD
$(call do_cmd,link)
all_deps += $(builddir)/run-benchmarks
# Add target alias
.PHONY: run-benchmarks
run-benchmarks: $(builddir)/run-benchmarks
# Add executable to "all" target.
.PHONY: all
all: $(builddir)/run-benchmarks

View File

@ -0,0 +1,114 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := run-tests
DEFS_Default := '-D_GNU_SOURCE'
# Flags passed to all source files.
CFLAGS_Default := -fasm-blocks \
-mpascal-strings \
-gdwarf-2 \
-arch i386
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
# Flags passed to only ObjC files.
CFLAGS_OBJC_Default :=
# Flags passed to only ObjC++ files.
CFLAGS_OBJCC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-tests.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-async.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-callback-stack.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-connection-fail.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-delayed-accept.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fail-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs-event.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-currentexe.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getsockname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-hrtime.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-close.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tty.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-dgram-too-big.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-ipv6.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-send-and-recv.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-unix.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# Make sure our dependencies are built before any of us.
$(OBJS): | $(builddir)/libuv.a
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE))
$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default := -arch i386 \
-L$(builddir)
LIBS := -framework Carbon \
-framework CoreServices
$(builddir)/run-tests: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(builddir)/run-tests: LIBS := $(LIBS)
$(builddir)/run-tests: LD_INPUTS := $(OBJS) $(builddir)/libuv.a
$(builddir)/run-tests: TOOLSET := $(TOOLSET)
$(builddir)/run-tests: $(OBJS) $(builddir)/libuv.a FORCE_DO_CMD
$(call do_cmd,link)
all_deps += $(builddir)/run-tests
# Add target alias
.PHONY: run-tests
run-tests: $(builddir)/run-tests
# Add executable to "all" target.
.PHONY: all
all: $(builddir)/run-tests

View File

@ -0,0 +1,6 @@
# This file is generated by gyp; do not edit.
export builddir_name ?= mk/libuv/mac/./src/rt/libuv/out
.PHONY: all
all:
$(MAKE) -C ../../.. uv run-tests run-benchmarks

View File

@ -0,0 +1,141 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := uv
DEFS_Default := '-DHAVE_CONFIG_H' \
'-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-D_GNU_SOURCE' \
'-DEIO_STACKSIZE=262144' \
'-DEV_CONFIG_H="config_darwin.h"' \
'-DEIO_CONFIG_H="config_darwin.h"'
# Flags passed to all source files.
CFLAGS_Default := -fasm-blocks \
-mpascal-strings \
-gdwarf-2 \
-arch i386
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
# Flags passed to only ObjC files.
CFLAGS_OBJC_Default :=
# Flags passed to only ObjC++ files.
CFLAGS_OBJCC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include \
-I$(srcdir)/src/rt/libuv/include/uv-private \
-I$(srcdir)/src/rt/libuv/src \
-I$(srcdir)/src/rt/libuv/src/unix/ev \
-I$(srcdir)/src/rt/libuv/src/ares/config_darwin
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_cancel.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_data.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_destroy.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_name.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_fds.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyaddr.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getnameinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getopt.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getsock.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_init.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_library_init.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_llist.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_mkquery.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_nowarn.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_options.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_aaaa_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_mx_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ns_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ptr_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_srv_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_txt_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_query.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_search.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_send.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strcasecmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strdup.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strerror.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_timeout.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_version.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_writev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/bitncmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_net_pton.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_ntop.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/core.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/uv-eio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/udp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/tcp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/pipe.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/tty.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/stream.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/cares.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/error.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/eio/eio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/ev/ev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/darwin.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE))
$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default := -arch i386 \
-L$(builddir)
LIBS := -lm
$(builddir)/libuv.a: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(builddir)/libuv.a: LIBS := $(LIBS)
$(builddir)/libuv.a: TOOLSET := $(TOOLSET)
$(builddir)/libuv.a: $(OBJS) FORCE_DO_CMD
$(call do_cmd,alink)
all_deps += $(builddir)/libuv.a
# Add target alias
.PHONY: uv
uv: $(builddir)/libuv.a
# Add target alias to "all" target.
.PHONY: all
all: uv

337
mk/libuv/unix/Makefile Normal file
View File

@ -0,0 +1,337 @@
# We borrow heavily from the kernel build setup, though we are simpler since
# we don't have Kconfig tweaking settings on us.
# The implicit make rules have it looking for RCS files, among other things.
# We instead explicitly write all the rules we care about.
# It's even quicker (saves ~200ms) to pass -r on the command line.
MAKEFLAGS=-r
# The source directory tree.
srcdir := ../../..
# The name of the builddir.
builddir_name ?= out
# The V=1 flag on command line makes us verbosely print command lines.
ifdef V
quiet=
else
quiet=quiet_
endif
# Specify BUILDTYPE=Release on the command line for a release build.
BUILDTYPE ?= Default
# Directory all our build output goes into.
# Note that this must be two directories beneath src/ for unit tests to pass,
# as they reach into the src/ directory for data with relative paths.
builddir ?= $(builddir_name)/$(BUILDTYPE)
abs_builddir := $(abspath $(builddir))
depsdir := $(builddir)/.deps
# Object output directory.
obj := $(builddir)/obj
abs_obj := $(abspath $(obj))
# We build up a list of every single one of the targets so we can slurp in the
# generated dependency rule Makefiles in one pass.
all_deps :=
# C++ apps need to be linked with g++. Not sure what's appropriate.
#
# Note, the flock is used to seralize linking. Linking is a memory-intensive
# process so running parallel links can often lead to thrashing. To disable
# the serialization, override FLOCK via an envrionment variable as follows:
#
# export FLOCK=
#
# This will allow make to invoke N linker processes as specified in -jN.
FLOCK ?= flock $(builddir)/linker.lock
LINK ?= $(FLOCK) $(CXX)
CC.target ?= $(CC)
CFLAGS.target ?= $(CFLAGS)
CXX.target ?= $(CXX)
CXXFLAGS.target ?= $(CXXFLAGS)
LINK.target ?= $(LINK)
LDFLAGS.target ?= $(LDFLAGS)
AR.target ?= $(AR)
ARFLAGS.target ?= crsT
# N.B.: the logic of which commands to run should match the computation done
# in gyp's make.py where ARFLAGS.host etc. is computed.
# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
# to replicate this environment fallback in make as well.
CC.host ?= gcc
CFLAGS.host ?=
CXX.host ?= g++
CXXFLAGS.host ?=
LINK.host ?= g++
LDFLAGS.host ?=
AR.host ?= ar
ARFLAGS.host := crsT
# Define a dir function that can handle spaces.
# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions
# "leading spaces cannot appear in the text of the first argument as written.
# These characters can be put into the argument value by variable substitution."
empty :=
space := $(empty) $(empty)
# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces
replace_spaces = $(subst $(space),?,$1)
unreplace_spaces = $(subst ?,$(space),$1)
dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1)))
# Flags to make gcc output dependency info. Note that you need to be
# careful here to use the flags that ccache and distcc can understand.
# We write to a dep file on the side first and then rename at the end
# so we can't end up with a broken dep file.
depfile = $(depsdir)/$(call replace_spaces,$@).d
DEPFLAGS = -MMD -MF $(depfile).raw
# We have to fixup the deps output in a few ways.
# (1) the file output should mention the proper .o file.
# ccache or distcc lose the path to the target, so we convert a rule of
# the form:
# foobar.o: DEP1 DEP2
# into
# path/to/foobar.o: DEP1 DEP2
# (2) we want missing files not to cause us to fail to build.
# We want to rewrite
# foobar.o: DEP1 DEP2 \
# DEP3
# to
# DEP1:
# DEP2:
# DEP3:
# so if the files are missing, they're just considered phony rules.
# We have to do some pretty insane escaping to get those backslashes
# and dollar signs past make, the shell, and sed at the same time.
# Doesn't work with spaces, but that's fine: .d files have spaces in
# their names replaced with other characters.
define fixup_dep
# The depfile may not exist if the input file didn't have any #includes.
touch $(depfile).raw
# Fixup path as in (1).
sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
# Add extra rules as in (2).
# We remove slashes and replace spaces with new lines;
# remove blank lines;
# delete the first line and append a colon to the remaining lines.
sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
grep -v '^$$' |\
sed -e 1d -e 's|$$|:|' \
>> $(depfile)
rm $(depfile).raw
endef
# Command definitions:
# - cmd_foo is the actual command to run;
# - quiet_cmd_foo is the brief-output summary of the command.
quiet_cmd_cc = CC($(TOOLSET)) $@
cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $<
quiet_cmd_cxx = CXX($(TOOLSET)) $@
cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
quiet_cmd_touch = TOUCH $@
cmd_touch = touch $@
quiet_cmd_copy = COPY $@
# send stderr to /dev/null to ignore messages when linking directories.
cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@")
quiet_cmd_alink = AR($(TOOLSET)) $@
cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) $(ARFLAGS.$(TOOLSET)) $@ $(filter %.o,$^)
# Due to circular dependencies between libraries :(, we wrap the
# special "figure out circular dependencies" flags around the entire
# input list during linking.
quiet_cmd_link = LINK($(TOOLSET)) $@
cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS)
# We support two kinds of shared objects (.so):
# 1) shared_library, which is just bundling together many dependent libraries
# into a link line.
# 2) loadable_module, which is generating a module intended for dlopen().
#
# They differ only slightly:
# In the former case, we want to package all dependent code into the .so.
# In the latter case, we want to package just the API exposed by the
# outermost module.
# This means shared_library uses --whole-archive, while loadable_module doesn't.
# (Note that --whole-archive is incompatible with the --start-group used in
# normal linking.)
# Other shared-object link notes:
# - Set SONAME to the library filename so our binaries don't reference
# the local, absolute paths used on the link command-line.
quiet_cmd_solink = SOLINK($(TOOLSET)) $@
cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS)
quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
# Define an escape_quotes function to escape single quotes.
# This allows us to handle quotes properly as long as we always use
# use single quotes and escape_quotes.
escape_quotes = $(subst ','\'',$(1))
# This comment is here just to include a ' to unconfuse syntax highlighting.
# Define an escape_vars function to escape '$' variable syntax.
# This allows us to read/write command lines with shell variables (e.g.
# $LD_LIBRARY_PATH), without triggering make substitution.
escape_vars = $(subst $$,$$$$,$(1))
# Helper that expands to a shell command to echo a string exactly as it is in
# make. This uses printf instead of echo because printf's behaviour with respect
# to escape sequences is more portable than echo's across different shells
# (e.g., dash, bash).
exact_echo = printf '%s\n' '$(call escape_quotes,$(1))'
# Helper to compare the command we're about to run against the command
# we logged the last time we ran the command. Produces an empty
# string (false) when the commands match.
# Tricky point: Make has no string-equality test function.
# The kernel uses the following, but it seems like it would have false
# positives, where one string reordered its arguments.
# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
# $(filter-out $(cmd_$@), $(cmd_$(1))))
# We instead substitute each for the empty string into the other, and
# say they're equal if both substitutions produce the empty string.
# .d files contain ? instead of spaces, take that into account.
command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
$(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1))))
# Helper that is non-empty when a prerequisite changes.
# Normally make does this implicitly, but we force rules to always run
# so we can check their command lines.
# $? -- new prerequisites
# $| -- order-only dependencies
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
# do_cmd: run a command via the above cmd_foo names, if necessary.
# Should always run for a given target to handle command-line changes.
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
# Third argument, if non-zero, makes it do POSTBUILDS processing.
# Note: We intentionally do NOT call dirx for depfile, since it contains ? for
# spaces already and dirx strips the ? characters.
define do_cmd
$(if $(or $(command_changed),$(prereq_changed)),
@$(call exact_echo, $($(quiet)cmd_$(1)))
@mkdir -p "$(call dirx,$@)" "$(dir $(depfile))"
$(if $(findstring flock,$(word 1,$(cmd_$1))),
@$(cmd_$(1))
@echo " $(quiet_cmd_$(1)): Finished",
@$(cmd_$(1))
)
@$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
@$(if $(2),$(fixup_dep))
$(if $(and $(3), $(POSTBUILDS)),
@for p in $(POSTBUILDS); do eval $$p; done
)
)
endef
# Declare "all" target first so it is the default, even though we don't have the
# deps yet.
.PHONY: all
all:
# Use FORCE_DO_CMD to force a target to run. Should be coupled with
# do_cmd.
.PHONY: FORCE_DO_CMD
FORCE_DO_CMD:
TOOLSET := target
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/run-benchmarks.target.mk)))),)
include src/rt/libuv/run-benchmarks.target.mk
endif
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/run-tests.target.mk)))),)
include src/rt/libuv/run-tests.target.mk
endif
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/uv.target.mk)))),)
include src/rt/libuv/uv.target.mk
endif
quiet_cmd_regen_makefile = ACTION Regenerating $@
cmd_regen_makefile = ./src/rt/libuv/build/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." "--depth=." "--generator-output=mk/libuv/unix" "-Dlibrary=static_library" "-Dtarget_arch=ia32" "-DOS=linux" src/rt/libuv/uv.gyp
#Makefile: $(srcdir)/src/rt/libuv/uv.gyp
# $(call do_cmd,regen_makefile)
# "all" is a concatenation of the "all" targets from all the included
# sub-makefiles. This is just here to clarify.
all:
# Add in dependency-tracking rules. $(all_deps) is the list of every single
# target in our tree. Only consider the ones with .d (dependency) info:
d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
ifneq ($(d_files),)
# Rather than include each individual .d file, concatenate them into a
# single file which make is able to load faster. We split this into
# commands that take 1000 files at a time to avoid overflowing the
# command line.
$(shell cat $(wordlist 1,1000,$(d_files)) > $(depsdir)/all.deps)
ifneq ($(word 1001,$(d_files)),)
$(error Found unprocessed dependency files (gyp didn't generate enough rules!))
endif
# make looks for ways to re-generate included makefiles, but in our case, we
# don't have a direct way. Explicitly telling make that it has nothing to do
# for them makes it go faster.
$(depsdir)/all.deps: ;
include $(depsdir)/all.deps
endif

View File

@ -0,0 +1,78 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := run-benchmarks
DEFS_Default := '-D_GNU_SOURCE'
# Flags passed to all source files.
CFLAGS_Default :=
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ares.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ping-pongs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pound.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pump.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-sizes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-udp-packet-storm.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/dns-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-benchmarks.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-unix.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# Make sure our dependencies are built before any of us.
$(OBJS): | $(obj).target/src/rt/libuv/libuv.a
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default := -pthread
LIBS := -lrt
$(builddir)/run-benchmarks: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(builddir)/run-benchmarks: LIBS := $(LIBS)
$(builddir)/run-benchmarks: LD_INPUTS := $(OBJS) $(obj).target/src/rt/libuv/libuv.a
$(builddir)/run-benchmarks: TOOLSET := $(TOOLSET)
$(builddir)/run-benchmarks: $(OBJS) $(obj).target/src/rt/libuv/libuv.a FORCE_DO_CMD
$(call do_cmd,link)
all_deps += $(builddir)/run-benchmarks
# Add target alias
.PHONY: run-benchmarks
run-benchmarks: $(builddir)/run-benchmarks
# Add executable to "all" target.
.PHONY: all
all: $(builddir)/run-benchmarks

View File

@ -0,0 +1,101 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := run-tests
DEFS_Default := '-D_GNU_SOURCE'
# Flags passed to all source files.
CFLAGS_Default :=
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-tests.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-async.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-callback-stack.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-connection-fail.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-delayed-accept.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fail-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs-event.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-currentexe.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getsockname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-hrtime.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-close.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tty.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-dgram-too-big.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-ipv6.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-send-and-recv.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-unix.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# Make sure our dependencies are built before any of us.
$(OBJS): | $(obj).target/src/rt/libuv/libuv.a
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default := -pthread
LIBS := -lrt
$(builddir)/run-tests: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(builddir)/run-tests: LIBS := $(LIBS)
$(builddir)/run-tests: LD_INPUTS := $(OBJS) $(obj).target/src/rt/libuv/libuv.a
$(builddir)/run-tests: TOOLSET := $(TOOLSET)
$(builddir)/run-tests: $(OBJS) $(obj).target/src/rt/libuv/libuv.a FORCE_DO_CMD
$(call do_cmd,link)
all_deps += $(builddir)/run-tests
# Add target alias
.PHONY: run-tests
run-tests: $(builddir)/run-tests
# Add executable to "all" target.
.PHONY: all
all: $(builddir)/run-tests

View File

@ -0,0 +1,6 @@
# This file is generated by gyp; do not edit.
export builddir_name ?= mk/libuv/unix/./src/rt/libuv/out
.PHONY: all
all:
$(MAKE) -C ../../.. uv run-tests run-benchmarks

View File

@ -0,0 +1,134 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := uv
DEFS_Default := '-DHAVE_CONFIG_H' \
'-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-D_GNU_SOURCE' \
'-DEIO_STACKSIZE=262144' \
'-DEV_CONFIG_H="config_linux.h"' \
'-DEIO_CONFIG_H="config_linux.h"'
# Flags passed to all source files.
CFLAGS_Default := -g \
--std=gnu89 \
-pedantic \
-Wall \
-Wextra \
-Wno-unused-parameter
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include \
-I$(srcdir)/src/rt/libuv/include/uv-private \
-I$(srcdir)/src/rt/libuv/src \
-I$(srcdir)/src/rt/libuv/src/unix/ev \
-I$(srcdir)/src/rt/libuv/src/ares/config_linux
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_cancel.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_data.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_destroy.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_name.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_fds.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyaddr.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getnameinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getopt.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getsock.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_init.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_library_init.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_llist.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_mkquery.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_nowarn.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_options.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_aaaa_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_mx_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ns_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ptr_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_srv_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_txt_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_query.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_search.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_send.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strcasecmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strdup.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strerror.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_timeout.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_version.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_writev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/bitncmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_net_pton.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_ntop.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/core.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/uv-eio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/udp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/tcp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/pipe.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/tty.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/stream.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/cares.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/error.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/eio/eio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/ev/ev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/linux.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default :=
LIBS := -lm
$(obj).target/src/rt/libuv/libuv.a: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(obj).target/src/rt/libuv/libuv.a: LIBS := $(LIBS)
$(obj).target/src/rt/libuv/libuv.a: TOOLSET := $(TOOLSET)
$(obj).target/src/rt/libuv/libuv.a: $(OBJS) FORCE_DO_CMD
$(call do_cmd,alink)
all_deps += $(obj).target/src/rt/libuv/libuv.a
# Add target alias
.PHONY: uv
uv: $(obj).target/src/rt/libuv/libuv.a
# Add target alias to "all" target.
.PHONY: all
all: uv

337
mk/libuv/win/Makefile Normal file
View File

@ -0,0 +1,337 @@
# We borrow heavily from the kernel build setup, though we are simpler since
# we don't have Kconfig tweaking settings on us.
# The implicit make rules have it looking for RCS files, among other things.
# We instead explicitly write all the rules we care about.
# It's even quicker (saves ~200ms) to pass -r on the command line.
MAKEFLAGS=-r
# The source directory tree.
srcdir := ../../..
# The name of the builddir.
builddir_name ?= out
# The V=1 flag on command line makes us verbosely print command lines.
ifdef V
quiet=
else
quiet=quiet_
endif
# Specify BUILDTYPE=Release on the command line for a release build.
BUILDTYPE ?= Default
# Directory all our build output goes into.
# Note that this must be two directories beneath src/ for unit tests to pass,
# as they reach into the src/ directory for data with relative paths.
builddir ?= $(builddir_name)/$(BUILDTYPE)
abs_builddir := $(abspath $(builddir))
depsdir := $(builddir)/.deps
# Object output directory.
obj := $(builddir)/obj
abs_obj := $(abspath $(obj))
# We build up a list of every single one of the targets so we can slurp in the
# generated dependency rule Makefiles in one pass.
all_deps :=
# C++ apps need to be linked with g++. Not sure what's appropriate.
#
# Note, the flock is used to seralize linking. Linking is a memory-intensive
# process so running parallel links can often lead to thrashing. To disable
# the serialization, override FLOCK via an envrionment variable as follows:
#
# export FLOCK=
#
# This will allow make to invoke N linker processes as specified in -jN.
FLOCK ?= flock $(builddir)/linker.lock
LINK ?= $(FLOCK) $(CXX)
CC.target ?= $(CC)
CFLAGS.target ?= $(CFLAGS)
CXX.target ?= $(CXX)
CXXFLAGS.target ?= $(CXXFLAGS)
LINK.target ?= $(LINK)
LDFLAGS.target ?= $(LDFLAGS)
AR.target ?= $(AR)
ARFLAGS.target ?= crsT
# N.B.: the logic of which commands to run should match the computation done
# in gyp's make.py where ARFLAGS.host etc. is computed.
# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
# to replicate this environment fallback in make as well.
CC.host ?= gcc
CFLAGS.host ?=
CXX.host ?= g++
CXXFLAGS.host ?=
LINK.host ?= g++
LDFLAGS.host ?=
AR.host ?= ar
ARFLAGS.host := crsT
# Define a dir function that can handle spaces.
# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions
# "leading spaces cannot appear in the text of the first argument as written.
# These characters can be put into the argument value by variable substitution."
empty :=
space := $(empty) $(empty)
# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces
replace_spaces = $(subst $(space),?,$1)
unreplace_spaces = $(subst ?,$(space),$1)
dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1)))
# Flags to make gcc output dependency info. Note that you need to be
# careful here to use the flags that ccache and distcc can understand.
# We write to a dep file on the side first and then rename at the end
# so we can't end up with a broken dep file.
depfile = $(depsdir)/$(call replace_spaces,$@).d
DEPFLAGS = -MMD -MF $(depfile).raw
# We have to fixup the deps output in a few ways.
# (1) the file output should mention the proper .o file.
# ccache or distcc lose the path to the target, so we convert a rule of
# the form:
# foobar.o: DEP1 DEP2
# into
# path/to/foobar.o: DEP1 DEP2
# (2) we want missing files not to cause us to fail to build.
# We want to rewrite
# foobar.o: DEP1 DEP2 \
# DEP3
# to
# DEP1:
# DEP2:
# DEP3:
# so if the files are missing, they're just considered phony rules.
# We have to do some pretty insane escaping to get those backslashes
# and dollar signs past make, the shell, and sed at the same time.
# Doesn't work with spaces, but that's fine: .d files have spaces in
# their names replaced with other characters.
define fixup_dep
# The depfile may not exist if the input file didn't have any #includes.
touch $(depfile).raw
# Fixup path as in (1).
sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
# Add extra rules as in (2).
# We remove slashes and replace spaces with new lines;
# remove blank lines;
# delete the first line and append a colon to the remaining lines.
sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
grep -v '^$$' |\
sed -e 1d -e 's|$$|:|' \
>> $(depfile)
rm $(depfile).raw
endef
# Command definitions:
# - cmd_foo is the actual command to run;
# - quiet_cmd_foo is the brief-output summary of the command.
quiet_cmd_cc = CC($(TOOLSET)) $@
cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $<
quiet_cmd_cxx = CXX($(TOOLSET)) $@
cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
quiet_cmd_touch = TOUCH $@
cmd_touch = touch $@
quiet_cmd_copy = COPY $@
# send stderr to /dev/null to ignore messages when linking directories.
cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@")
quiet_cmd_alink = AR($(TOOLSET)) $@
cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) $(ARFLAGS.$(TOOLSET)) $@ $(filter %.o,$^)
# Due to circular dependencies between libraries :(, we wrap the
# special "figure out circular dependencies" flags around the entire
# input list during linking.
quiet_cmd_link = LINK($(TOOLSET)) $@
cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS)
# We support two kinds of shared objects (.so):
# 1) shared_library, which is just bundling together many dependent libraries
# into a link line.
# 2) loadable_module, which is generating a module intended for dlopen().
#
# They differ only slightly:
# In the former case, we want to package all dependent code into the .so.
# In the latter case, we want to package just the API exposed by the
# outermost module.
# This means shared_library uses --whole-archive, while loadable_module doesn't.
# (Note that --whole-archive is incompatible with the --start-group used in
# normal linking.)
# Other shared-object link notes:
# - Set SONAME to the library filename so our binaries don't reference
# the local, absolute paths used on the link command-line.
quiet_cmd_solink = SOLINK($(TOOLSET)) $@
cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS)
quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
# Define an escape_quotes function to escape single quotes.
# This allows us to handle quotes properly as long as we always use
# use single quotes and escape_quotes.
escape_quotes = $(subst ','\'',$(1))
# This comment is here just to include a ' to unconfuse syntax highlighting.
# Define an escape_vars function to escape '$' variable syntax.
# This allows us to read/write command lines with shell variables (e.g.
# $LD_LIBRARY_PATH), without triggering make substitution.
escape_vars = $(subst $$,$$$$,$(1))
# Helper that expands to a shell command to echo a string exactly as it is in
# make. This uses printf instead of echo because printf's behaviour with respect
# to escape sequences is more portable than echo's across different shells
# (e.g., dash, bash).
exact_echo = printf '%s\n' '$(call escape_quotes,$(1))'
# Helper to compare the command we're about to run against the command
# we logged the last time we ran the command. Produces an empty
# string (false) when the commands match.
# Tricky point: Make has no string-equality test function.
# The kernel uses the following, but it seems like it would have false
# positives, where one string reordered its arguments.
# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
# $(filter-out $(cmd_$@), $(cmd_$(1))))
# We instead substitute each for the empty string into the other, and
# say they're equal if both substitutions produce the empty string.
# .d files contain ? instead of spaces, take that into account.
command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
$(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1))))
# Helper that is non-empty when a prerequisite changes.
# Normally make does this implicitly, but we force rules to always run
# so we can check their command lines.
# $? -- new prerequisites
# $| -- order-only dependencies
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
# do_cmd: run a command via the above cmd_foo names, if necessary.
# Should always run for a given target to handle command-line changes.
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
# Third argument, if non-zero, makes it do POSTBUILDS processing.
# Note: We intentionally do NOT call dirx for depfile, since it contains ? for
# spaces already and dirx strips the ? characters.
define do_cmd
$(if $(or $(command_changed),$(prereq_changed)),
@$(call exact_echo, $($(quiet)cmd_$(1)))
@mkdir -p "$(call dirx,$@)" "$(dir $(depfile))"
$(if $(findstring flock,$(word 1,$(cmd_$1))),
@$(cmd_$(1))
@echo " $(quiet_cmd_$(1)): Finished",
@$(cmd_$(1))
)
@$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
@$(if $(2),$(fixup_dep))
$(if $(and $(3), $(POSTBUILDS)),
@for p in $(POSTBUILDS); do eval $$p; done
)
)
endef
# Declare "all" target first so it is the default, even though we don't have the
# deps yet.
.PHONY: all
all:
# Use FORCE_DO_CMD to force a target to run. Should be coupled with
# do_cmd.
.PHONY: FORCE_DO_CMD
FORCE_DO_CMD:
TOOLSET := target
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD
@$(call do_cmd,cc,1)
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/run-benchmarks.target.mk)))),)
include src/rt/libuv/run-benchmarks.target.mk
endif
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/run-tests.target.mk)))),)
include src/rt/libuv/run-tests.target.mk
endif
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
$(findstring $(join ^,$(prefix)),\
$(join ^,src/rt/libuv/uv.target.mk)))),)
include src/rt/libuv/uv.target.mk
endif
quiet_cmd_regen_makefile = ACTION Regenerating $@
cmd_regen_makefile = ./src/rt/libuv/build/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." "--depth=." "--generator-output=mk/libuv/win" "-Dlibrary=static_library" "-Dtarget_arch=ia32" "-DOS=win" src/rt/libuv/uv.gyp
#Makefile: $(srcdir)/src/rt/libuv/uv.gyp
# $(call do_cmd,regen_makefile)
# "all" is a concatenation of the "all" targets from all the included
# sub-makefiles. This is just here to clarify.
all:
# Add in dependency-tracking rules. $(all_deps) is the list of every single
# target in our tree. Only consider the ones with .d (dependency) info:
d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
ifneq ($(d_files),)
# Rather than include each individual .d file, concatenate them into a
# single file which make is able to load faster. We split this into
# commands that take 1000 files at a time to avoid overflowing the
# command line.
$(shell cat $(wordlist 1,1000,$(d_files)) > $(depsdir)/all.deps)
ifneq ($(word 1001,$(d_files)),)
$(error Found unprocessed dependency files (gyp didn't generate enough rules!))
endif
# make looks for ways to re-generate included makefiles, but in our case, we
# don't have a direct way. Explicitly telling make that it has nothing to do
# for them makes it go faster.
$(depsdir)/all.deps: ;
include $(depsdir)/all.deps
endif

View File

@ -0,0 +1,79 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := run-benchmarks
DEFS_Default :=
# Flags passed to all source files.
CFLAGS_Default :=
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ares.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ping-pongs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pound.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pump.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-sizes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-udp-packet-storm.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/dns-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-benchmarks.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-win.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# Make sure our dependencies are built before any of us.
$(OBJS): | $(obj).target/src/rt/libuv/libuv.a
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default :=
LIBS := ws2_32.lib \
-lws2_32.lib
$(builddir)/run-benchmarks: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(builddir)/run-benchmarks: LIBS := $(LIBS)
$(builddir)/run-benchmarks: LD_INPUTS := $(OBJS) $(obj).target/src/rt/libuv/libuv.a
$(builddir)/run-benchmarks: TOOLSET := $(TOOLSET)
$(builddir)/run-benchmarks: $(OBJS) $(obj).target/src/rt/libuv/libuv.a FORCE_DO_CMD
$(call do_cmd,link)
all_deps += $(builddir)/run-benchmarks
# Add target alias
.PHONY: run-benchmarks
run-benchmarks: $(builddir)/run-benchmarks
# Add executable to "all" target.
.PHONY: all
all: $(builddir)/run-benchmarks

View File

@ -0,0 +1,102 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := run-tests
DEFS_Default :=
# Flags passed to all source files.
CFLAGS_Default :=
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-tests.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-async.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-callback-stack.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-connection-fail.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-delayed-accept.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fail-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs-event.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-currentexe.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getsockname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-hrtime.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-close.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tty.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-dgram-too-big.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-ipv6.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-send-and-recv.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-win.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# Make sure our dependencies are built before any of us.
$(OBJS): | $(obj).target/src/rt/libuv/libuv.a
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default :=
LIBS := ws2_32.lib \
-lws2_32.lib
$(builddir)/run-tests: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(builddir)/run-tests: LIBS := $(LIBS)
$(builddir)/run-tests: LD_INPUTS := $(OBJS) $(obj).target/src/rt/libuv/libuv.a
$(builddir)/run-tests: TOOLSET := $(TOOLSET)
$(builddir)/run-tests: $(OBJS) $(obj).target/src/rt/libuv/libuv.a FORCE_DO_CMD
$(call do_cmd,link)
all_deps += $(builddir)/run-tests
# Add target alias
.PHONY: run-tests
run-tests: $(builddir)/run-tests
# Add executable to "all" target.
.PHONY: all
all: $(builddir)/run-tests

View File

@ -0,0 +1,6 @@
# This file is generated by gyp; do not edit.
export builddir_name ?= mk/libuv/win/./src/rt/libuv/out
.PHONY: all
all:
$(MAKE) -C ../../.. uv run-tests run-benchmarks

View File

@ -0,0 +1,135 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := uv
DEFS_Default := '-DHAVE_CONFIG_H' \
'-D_WIN32_WINNT=0x0502' \
'-DEIO_STACKSIZE=262144' \
'-D_GNU_SOURCE'
# Flags passed to all source files.
CFLAGS_Default :=
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include \
-I$(srcdir)/src/rt/libuv/include/uv-private \
-I$(srcdir)/src/rt/libuv/src \
-I$(srcdir)/src/rt/libuv/src/ares/config_win32
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_cancel.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_data.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_destroy.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_name.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_fds.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyaddr.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getnameinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getopt.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getsock.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_init.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_library_init.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_llist.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_mkquery.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_nowarn.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_options.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_aaaa_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_mx_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ns_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ptr_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_srv_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_txt_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_query.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_search.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_send.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strcasecmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strdup.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strerror.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_timeout.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_version.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_writev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/bitncmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_net_pton.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_ntop.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/windows_port.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/async.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/cares.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/core.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/error.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/fs-event.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/handle.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/loop-watcher.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/pipe.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/req.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/stdio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/stream.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/tcp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/tty.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/threadpool.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/threads.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/timer.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/udp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/util.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/winapi.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/winsock.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
@$(call do_cmd,cc,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default :=
LIBS :=
$(obj).target/src/rt/libuv/libuv.a: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(obj).target/src/rt/libuv/libuv.a: LIBS := $(LIBS)
$(obj).target/src/rt/libuv/libuv.a: TOOLSET := $(TOOLSET)
$(obj).target/src/rt/libuv/libuv.a: $(OBJS) FORCE_DO_CMD
$(call do_cmd,alink)
all_deps += $(obj).target/src/rt/libuv/libuv.a
# Add target alias
.PHONY: uv
uv: $(obj).target/src/rt/libuv/libuv.a
# Add target alias to "all" target.
.PHONY: all
all: uv

View File

@ -50,7 +50,7 @@ ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
CFG_LIB_NAME=lib$(1).dylib CFG_LIB_NAME=lib$(1).dylib
CFG_UNIXY := 1 CFG_UNIXY := 1
CFG_LDENV := DYLD_LIBRARY_PATH CFG_LDENV := DYLD_LIBRARY_PATH
CFG_GCCISH_LINK_FLAGS += -dynamiclib -lpthread CFG_GCCISH_LINK_FLAGS += -dynamiclib -lpthread -framework CoreServices
CFG_GCCISH_DEF_FLAG := -Wl,-exported_symbols_list, CFG_GCCISH_DEF_FLAG := -Wl,-exported_symbols_list,
# Darwin has a very blurry notion of "64 bit", and claims it's running # Darwin has a very blurry notion of "64 bit", and claims it's running
# "on an i386" when the whole userspace is 64-bit and the compiler # "on an i386" when the whole userspace is 64-bit and the compiler

View File

@ -68,11 +68,22 @@ RUNTIME_HDR := rt/globals.h \
rt/test/rust_test_util.h \ rt/test/rust_test_util.h \
rt/arch/i386/context.h \ rt/arch/i386/context.h \
ifeq ($(CFG_WINDOWSY), 1)
LIBUV_OSTYPE := win
LIBUV_LIB := rt/libuv/Default/obj.target/src/rt/libuv/libuv.a
else ifeq ($(CFG_OSTYPE), apple-darwin)
LIBUV_OSTYPE := mac
LIBUV_LIB := rt/libuv/Default/libuv.a
else
LIBUV_OSTYPE := unix
LIBUV_LIB := rt/libuv/Default/obj.target/src/rt/libuv/libuv.a
endif
RUNTIME_DEF := rt/rustrt$(CFG_DEF_SUFFIX) RUNTIME_DEF := rt/rustrt$(CFG_DEF_SUFFIX)
RUNTIME_INCS := -I $(S)src/rt/isaac -I $(S)src/rt/uthash \ RUNTIME_INCS := -I $(S)src/rt/isaac -I $(S)src/rt/uthash \
-I $(S)src/rt/arch/i386 -I $(S)src/rt/libuv/include -I $(S)src/rt/arch/i386 -I $(S)src/rt/libuv/include
RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o) $(RUNTIME_LL:.ll=.o) $(RUNTIME_S:.S=.o) RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o) $(RUNTIME_LL:.ll=.o) $(RUNTIME_S:.S=.o)
RUNTIME_LIBS := rt/libuv/uv.a RUNTIME_LIBS := $(LIBUV_LIB)
rt/%.o: rt/%.cpp $(MKFILES) rt/%.o: rt/%.cpp $(MKFILES)
@$(call E, compile: $@) @$(call E, compile: $@)
@ -105,12 +116,18 @@ rt/$(CFG_RUNTIME): $(RUNTIME_OBJS) $(MKFILES) $(RUNTIME_HDR) $(RUNTIME_DEF) $(RU
# FIXME: For some reason libuv's makefiles can't figure out the correct definition # FIXME: For some reason libuv's makefiles can't figure out the correct definition
# of CC on the mingw I'm using, so we are explicitly using gcc. Also, we # of CC on the mingw I'm using, so we are explicitly using gcc. Also, we
# have to list environment variables first on windows... mysterious # have to list environment variables first on windows... mysterious
rt/libuv/uv.a: $(wildcard \ $(LIBUV_LIB): $(wildcard \
$(S)src/rt/libuv/* \ $(S)src/rt/libuv/* \
$(S)src/rt/libuv/*/* \ $(S)src/rt/libuv/*/* \
$(S)src/rt/libuv/*/*/* \ $(S)src/rt/libuv/*/*/* \
$(S)src/rt/libuv/*/*/*/*) $(S)src/rt/libuv/*/*/*/*)
$(Q)CFLAGS=\"-m32\" LDFLAGS=\"-m32\" CC=$(CC) $(MAKE) -C rt/libuv $(Q)$(MAKE) -C $(S)mk/libuv/$(LIBUV_OSTYPE) \
CFLAGS="-m32" LDFLAGS="-m32" \
CC="$(CFG_GCCISH_CROSS)$(CC)" \
CXX="$(CFG_GCCISH_CROSS)$(CXX)" \
AR="$(CFG_GCCISH_CROSS)$(AR)" \
builddir_name="$(CFG_BUILD_DIR)/rt/libuv" \
V=$(VERBOSE) FLOCK= uv
# These could go in rt.mk or rustllvm.mk, they're needed for both. # These could go in rt.mk or rustllvm.mk, they're needed for both.

36
src/etc/gyp-uv Executable file
View File

@ -0,0 +1,36 @@
#!/bin/sh
set -e
cd `dirname $0`
cd ../..
args="--depth . -Dlibrary=static_library -Dtarget_arch=ia32"
./src/rt/libuv/build/gyp/gyp src/rt/libuv/uv.gyp $args \
-f make-mac \
--generator-output mk/libuv/mac \
-DOS=mac
./src/rt/libuv/build/gyp/gyp src/rt/libuv/uv.gyp $args \
-f make-linux \
--generator-output mk/libuv/unix \
-DOS=linux
./src/rt/libuv/build/gyp/gyp src/rt/libuv/uv.gyp $args \
-f make-linux \
--generator-output mk/libuv/win \
-DOS=win
# Comment out the gyp auto regeneration
for os in mac unix win; do
sed -i ".save" \
-e 's/^\(Makefile: $(srcdir)\/src\/rt\/libuv\/uv\.gyp\)/#\1/' \
mk/libuv/$os/Makefile
sed -i ".save" \
-e 's/^\( $(call do_cmd,regen_makefile)\)/#\1/' \
mk/libuv/$os/Makefile
rm mk/libuv/$os/Makefile.save
done

View File

@ -7,37 +7,23 @@
*.orig *.orig
*.sdf *.sdf
*.suo *.suo
/out/
/build/gyp
/test/run-tests
/test/run-tests.exe
/test/run-tests.dSYM
/test/run-benchmarks
/test/run-benchmarks.exe
/test/run-benchmarks.dSYM
*.sln
*.vcproj
*.vcxproj
*.vcxproj.filters *.vcxproj.filters
*.vcxproj.user *.vcxproj.user
ev/.deps/ _UpgradeReport_Files/
ev/.libs/ UpgradeLog*.XML
ev/Makefile Debug
ev/config.h Release
ev/config.log ipch
ev/config.status
ev/libtool
ev/stamp-h1
ev/autom4te.cache
/msvs/ipch/
/build/
test/run-tests
test/run-benchmarks
test/run-tests.exe
test/run-benchmarks.exe
test/run-benchmarks.dSYM/
test/run-tests.dSYM/
c-ares/.deps/
c-ares/.libs/
c-ares/Makefile
c-ares/acountry
c-ares/adig
c-ares/ahost
c-ares/ares_config.h
c-ares/config.log
c-ares/config.status
c-ares/libcares.pc
c-ares/libtool
c-ares/stamp-h1
c-ares/stamp-h2

8
src/rt/libuv/.mailmap Normal file
View File

@ -0,0 +1,8 @@
# update AUTHORS with:
# git log --all --reverse --format='%aN <%aE>' | perl -ne 'BEGIN{print "# Authors ordered by first contribution.\n"} print unless $h{$_}; $h{$_} = 1' > AUTHORS
<rm@joyent.com> <rm@fingolfin.org>
<ryan@joyent.com> <ry@tinyclouds.org>
<bertbelder@gmail.com> <info@2bs.nl>
<alan@prettyrobots.com> <alan@blogometer.com>
San-Tai Hsu <vanilla@fatpipi.com>
Isaac Z. Schlueter <i@izs.me>

View File

@ -3,9 +3,24 @@ Ryan Dahl <ryan@joyent.com>
Bert Belder <bertbelder@gmail.com> Bert Belder <bertbelder@gmail.com>
Josh Roesslein <jroesslein@gmail.com> Josh Roesslein <jroesslein@gmail.com>
Alan Gutierrez <alan@prettyrobots.com> Alan Gutierrez <alan@prettyrobots.com>
Joshua Peek <josh@joshpeek.com>
Igor Zinkovsky <igorzi@microsoft.com> Igor Zinkovsky <igorzi@microsoft.com>
Vanilla Hsu <vanilla@fatpipi.com> San-Tai Hsu <vanilla@fatpipi.com>
Ben Noordhuis <info@bnoordhuis.nl> Ben Noordhuis <info@bnoordhuis.nl>
Henry Rawas <henryr@schakra.com> Henry Rawas <henryr@schakra.com>
Robert Mustacchi <rm@joyent.com> Robert Mustacchi <rm@joyent.com>
Matt Stevens <matt@alloysoft.com> Matt Stevens <matt@alloysoft.com>
Paul Querna <pquerna@apache.org>
Shigeki Ohtsu <ohtsu@iij.ad.jp>
Tom Hughes <tom.hughes@palm.com>
Peter Bright <drpizza@quiscalusmexicanus.org>
Jeroen Janssen <jeroen.janssen@gmail.com>
Andrea Lattuada <ndr.lattuada@gmail.com>
Augusto Henrique Hentz <ahhentz@gmail.com>
Clifford Heath <clifford.heath@gmail.com>
Jorge Chamorro Bieling <jorge@jorgechamorro.com>
Luis Lavena <luislavena@gmail.com>
Matthew Sporleder <msporleder@gmail.com>
Erick Tryzelaar <erick.tryzelaar@gmail.com>
Isaac Z. Schlueter <i@izs.me>
Pieter Noordhuis <pcnoordhuis@gmail.com>

View File

@ -1,5 +0,0 @@
This subtree is pulled from:
ee599ec1141cc48f895de1f9d148033babdf9c2a
When pulling in a new version of libuv, please update this file to ensure that
everyone correctly rebuilds libuv.

View File

@ -18,30 +18,13 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE. # IN THE SOFTWARE.
include ../../config.mk
CFLAGS=-m32
LDFLAGS=-m32
CC=gcc
S:=$(shell cd ../../; cd $(CFG_SRC_DIR)src/rt/libuv; pwd)
ifdef VERBOSE
Q :=
EE =
else
Q := @
EE = echo $(1)
endif
VPATH:=$(S)
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
ifdef MSVC ifdef MSVC
uname_S := MINGW uname_S := MINGW
endif endif
CPPFLAGS += -I$(S)/include CPPFLAGS += -Iinclude -Iinclude/uv-private
CARES_OBJS = CARES_OBJS =
CARES_OBJS += src/ares/ares__close_sockets.o CARES_OBJS += src/ares/ares__close_sockets.o
@ -94,8 +77,43 @@ else
include config-unix.mk include config-unix.mk
endif endif
all: uv.a TESTS=test/echo-server.c test/test-*.c
BENCHMARKS=test/echo-server.c test/dns-server.c test/benchmark-*.c
all: uv.a test/run-tests$(E) test/run-benchmarks$(E)
$(CARES_OBJS): %.o: %.c $(CARES_OBJS): %.o: %.c
@$(call EE, compile: $@) $(CC) -o $*.o -c $(CFLAGS) $(CPPFLAGS) $< -DHAVE_CONFIG_H
$(Q)$(CC) -o $*.o -c $(CFLAGS) $(CPPFLAGS) $< -DHAVE_CONFIG_H
test/run-tests$(E): test/*.h test/run-tests.c $(RUNNER_SRC) test/runner-unix.c $(TESTS) uv.a
$(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o test/run-tests test/run-tests.c \
test/runner.c $(RUNNER_SRC) $(TESTS) uv.a $(RUNNER_LIBS) $(RUNNER_LINKFLAGS)
test/run-benchmarks$(E): test/*.h test/run-benchmarks.c test/runner.c $(RUNNER_SRC) $(BENCHMARKS) uv.a
$(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o test/run-benchmarks test/run-benchmarks.c \
test/runner.c $(RUNNER_SRC) $(BENCHMARKS) uv.a $(RUNNER_LIBS) $(RUNNER_LINKFLAGS)
test/echo.o: test/echo.c test/echo.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c test/echo.c -o test/echo.o
.PHONY: clean clean-platform distclean distclean-platform test bench
test: test/run-tests$(E)
test/run-tests
#test-%: test/run-tests$(E)
# test/run-tests $(@:test-%=%)
bench: test/run-benchmarks$(E)
test/run-benchmarks
#bench-%: test/run-benchmarks$(E)
# test/run-benchmarks $(@:bench-%=%)
clean: clean-platform
$(RM) -f src/*.o *.a test/run-tests$(E) test/run-benchmarks$(E)
distclean: distclean-platform
$(RM) -f src/*.o *.a test/run-tests$(E) test/run-benchmarks$(E)

View File

@ -1,16 +0,0 @@
This is the new networking layer for Node. Its purpose is to abstract
IOCP on windows and libev on Unix systems. We intend to eventually contain
all platform differences in this library.
http://nodejs.org/
(This was previously called liboio)
Supported Platforms:
Microsoft Windows operating systems since Windows XP sp2. It can be built
with either Visual Studio or MinGW.
Linux 2.6 and MacOS using the GCC toolchain.
Solaris 121 and later using GCC toolchain.

92
src/rt/libuv/README.md Normal file
View File

@ -0,0 +1,92 @@
# libuv
libuv is a new platform layer for Node. Its purpose is to abstract IOCP on
windows and libev on Unix systems. We intend to eventually contain all
platform differences in this library.
http://nodejs.org/
## Features
Implemented:
* Non-blocking TCP sockets
* Non-blocking named pipes
* UDP
* Timers
* Child process spawning
* Asynchronous DNS via c-ares or `uv_getaddrinfo`.
* Asynchronous file system APIs `uv_fs_*`
* High resolution time `uv_hrtime`
* Current executable path look up `uv_exepath`
* Thread pool scheduling `uv_queue_work`
In-progress:
* File system events (Currently supports inotify, `ReadDirectoryChangesW`
and will support kqueue and event ports in the near future.)
`uv_fs_event_t`
* VT100 TTY `uv_tty_t`
* Socket sharing between processes `uv_ipc_t`
## Documentation
See `include/uv.h`.
## Build Instructions
For GCC (including MinGW) there are two methods building: via normal
makefiles or via GYP. GYP is a meta-build system which can generate MSVS,
Makefile, and XCode backends. It is best used for integration into other
projects. The old (more stable) system is using Makefiles.
To build via Makefile simply execute:
make
To build with Visual Studio run the vcbuilds.bat file which will
checkout the GYP code into build/gyp and generate the uv.sln and
related files.
Windows users can also build from cmd-line using msbuild. This is
done by running vcbuild.bat from Visual Studio command prompt.
To have GYP generate build script for another system you will need to
checkout GYP into the project tree manually:
svn co http://gyp.googlecode.com/svn/trunk build/gyp
Unix users run
./gyp_uv -f make
make
Macintosh users run
./gyp_uv -f xcode
xcodebuild -project uv.xcodeproj -configuration Release -target All
## Supported Platforms
Microsoft Windows operating systems since Windows XP SP2. It can be built
with either Visual Studio or MinGW.
Linux 2.6 using the GCC toolchain.
MacOS using the GCC or XCode toolchain.
Solaris 121 and later using GCC toolchain.

164
src/rt/libuv/common.gypi Normal file
View File

@ -0,0 +1,164 @@
{
'variables': {
'visibility%': 'hidden', # V8's visibility setting
'target_arch%': 'ia32', # set v8's target architecture
'host_arch%': 'ia32', # set v8's host architecture
'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
'component%': 'static_library', # NB. these names match with what V8 expects
'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
},
'target_defaults': {
'default_configuration': 'Debug',
'configurations': {
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
'cflags': [ '-g', '-O0' ],
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
['library=="static_library"', {
'RuntimeLibrary': 1, # static debug
}, {
'RuntimeLibrary': 3, # DLL debug
}],
],
'Optimization': 0, # /Od, no optimization
'MinimalRebuild': 'true',
'OmitFramePointers': 'false',
'BasicRuntimeChecks': 3, # /RTC1
},
'VCLinkerTool': {
'LinkIncremental': 2, # enable incremental linking
},
},
},
'Release': {
'defines': [ 'NDEBUG' ],
'cflags': [ '-O3', '-fomit-frame-pointer', '-fdata-sections', '-ffunction-sections' ],
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
['library=="static_library"', {
'RuntimeLibrary': 0, # static release
}, {
'RuntimeLibrary': 2, # debug release
}],
],
'Optimization': 3, # /Ox, full optimization
'FavorSizeOrSpeed': 1, # /Ot, favour speed over size
'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible
'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG
'OmitFramePointers': 'true',
'EnableFunctionLevelLinking': 'true',
'EnableIntrinsicFunctions': 'true',
'AdditionalOptions': [
'/MP', # compile across multiple CPUs
],
},
'VCLibrarianTool': {
'AdditionalOptions': [
'/LTCG', # link time code generation
],
},
'VCLinkerTool': {
'LinkTimeCodeGeneration': 1, # link-time code generation
'OptimizeReferences': 2, # /OPT:REF
'EnableCOMDATFolding': 2, # /OPT:ICF
'LinkIncremental': 1, # disable incremental linking
},
},
}
},
'msvs_settings': {
'VCCLCompilerTool': {
'StringPooling': 'true', # pool string literals
'DebugInformationFormat': 3, # Generate a PDB
'WarningLevel': 3,
'BufferSecurityCheck': 'true',
'ExceptionHandling': 1, # /EHsc
'SuppressStartupBanner': 'true',
'WarnAsError': 'false',
},
'VCLibrarianTool': {
},
'VCLinkerTool': {
'GenerateDebugInformation': 'true',
'RandomizedBaseAddress': 2, # enable ASLR
'DataExecutionPrevention': 2, # enable DEP
'AllowIsolation': 'true',
'SuppressStartupBanner': 'true',
'target_conditions': [
['_type=="executable"', {
'SubSystem': 1, # console executable
}],
],
},
},
'conditions': [
['OS == "win"', {
'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin
'defines': [
'WIN32',
# we don't really want VC++ warning us about
# how dangerous C functions are...
'_CRT_SECURE_NO_DEPRECATE',
# ... or that C implementations shouldn't use
# POSIX names
'_CRT_NONSTDC_NO_DEPRECATE',
],
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
'cflags': [ '-Wall', '-pthread', ],
'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
'ldflags': [ '-pthread', ],
'conditions': [
[ 'host_arch != target_arch and target_arch=="ia32"', {
'cflags': [ '-m32' ],
'ldflags': [ '-m32' ],
}],
[ 'OS=="linux"', {
'cflags': [ '-ansi' ],
}],
[ 'visibility=="hidden"', {
'cflags': [ '-fvisibility=hidden' ],
}],
],
}],
['OS=="mac"', {
'xcode_settings': {
'ALWAYS_SEARCH_USER_PATHS': 'NO',
'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
# (Equivalent to -fPIC)
'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
# GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
'GCC_VERSION': '4.2',
'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
'MACOSX_DEPLOYMENT_TARGET': '10.4', # -mmacosx-version-min=10.4
'PREBINDING': 'NO', # No -Wl,-prebind
'USE_HEADERMAP': 'NO',
'OTHER_CFLAGS': [
'-fno-strict-aliasing',
],
'WARNING_CFLAGS': [
'-Wall',
'-Wendif-labels',
'-W',
'-Wno-unused-parameter',
],
},
'target_conditions': [
['_type!="static_library"', {
'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
}],
],
}],
],
},
}

View File

@ -20,37 +20,41 @@
# Use make -f Makefile.gcc PREFIX=i686-w64-mingw32- # Use make -f Makefile.gcc PREFIX=i686-w64-mingw32-
# for cross compilation # for cross compilation
CC ?= $(PREFIX)gcc CC = $(PREFIX)gcc
AR ?= $(PREFIX)ar AR = $(PREFIX)ar
E=.exe E=.exe
CFLAGS+=$(CPPFLAGS) -g --std=gnu89 -D_WIN32_WINNT=0x0501 -I$(S)/src/ares/config_win32 CFLAGS=$(CPPFLAGS) -g --std=gnu89 -D_WIN32_WINNT=0x0501 -Isrc/ares/config_win32
LINKFLAGS=-lm LINKFLAGS=-lm
CARES_OBJS += src/ares/windows_port.o CARES_OBJS += src/ares/windows_port.o
WIN_SRCS=$(wildcard src/win/*.c)
WIN_OBJS=$(WIN_SRCS:.c=.o)
uv.a: src/uv-win.o src/uv-common.o src/uv-eio.o src/eio/eio.o $(CARES_OBJS) RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE # Need _GNU_SOURCE for strdup?
@$(call EE, ar: $@) RUNNER_LINKFLAGS=$(LINKFLAGS)
$(Q)$(AR) rcs uv.a $^ RUNNER_LIBS=-lws2_32
RUNNER_SRC=test/runner-win.c
src/uv-win.o: src/uv-win.c include/uv.h include/uv-win.h uv.a: $(WIN_OBJS) src/uv-common.o $(CARES_OBJS)
@$(call EE, compile: $@) $(AR) rcs uv.a src/win/*.o src/uv-common.o $(CARES_OBJS)
$(Q)$(CC) $(CFLAGS) -c $< -o $@
src/uv-common.o: src/uv-common.c include/uv.h include/uv-win.h src/win/%.o: src/win/%.c src/win/internal.h
@$(call EE, compile: $@) $(CC) $(CFLAGS) -o $@ -c $<
$(Q)$(CC) $(CFLAGS) -c $< -o $@
src/uv-common.o: src/uv-common.c include/uv.h include/uv-private/uv-win.h
$(CC) $(CFLAGS) -c src/uv-common.c -o src/uv-common.o
EIO_CPPFLAGS += $(CPPFLAGS) EIO_CPPFLAGS += $(CPPFLAGS)
EIO_CPPFLAGS += -DEIO_CONFIG_H=\"$(EIO_CONFIG)\"
EIO_CPPFLAGS += -DEIO_STACKSIZE=65536 EIO_CPPFLAGS += -DEIO_STACKSIZE=65536
EIO_CPPFLAGS += -D_GNU_SOURCE EIO_CPPFLAGS += -D_GNU_SOURCE
src/eio/eio.o: src/eio/eio.c clean-platform:
@$(call EE, compile: $@) -rm -f src/ares/*.o
$(Q)$(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c $< -o $@ -rm -f src/eio/*.o
-rm -f src/win/*.o
src/uv-eio.o: src/uv-eio.c
@$(call EE, compile: $@)
$(Q)$(CC) $(CPPFLAGS) -I$(S)src/eio/ $(CFLAGS) -c $< -o $@
distclean-platform:
-rm -f src/ares/*.o
-rm -f src/eio/*.o
-rm -f src/win/*.o

View File

@ -18,95 +18,127 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE. # IN THE SOFTWARE.
CC ?= $(PREFIX)gcc CC = $(PREFIX)gcc
AR ?= $(PREFIX)ar AR = $(PREFIX)ar
E= E=
CSTDFLAG=--std=c89 -pedantic CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter
CFLAGS+=-g CFLAGS += -g
CPPFLAGS += -I$(S)/src/ev CPPFLAGS += -Isrc/unix/ev
LINKFLAGS=-lm LINKFLAGS=-lm
CPPFLAGS += -D_LARGEFILE_SOURCE CPPFLAGS += -D_LARGEFILE_SOURCE
CPPFLAGS += -D_FILE_OFFSET_BITS=64 CPPFLAGS += -D_FILE_OFFSET_BITS=64
OBJS += src/unix/core.o
OBJS += src/unix/fs.o
OBJS += src/unix/cares.o
OBJS += src/unix/udp.o
OBJS += src/unix/error.o
OBJS += src/unix/process.o
OBJS += src/unix/tcp.o
OBJS += src/unix/pipe.o
OBJS += src/unix/tty.o
OBJS += src/unix/stream.o
ifeq (SunOS,$(uname_S)) ifeq (SunOS,$(uname_S))
EV_CONFIG=config_sunos.h EV_CONFIG=config_sunos.h
EIO_CONFIG=config_sunos.h EIO_CONFIG=config_sunos.h
CPPFLAGS += -I$(S)/src/ares/config_sunos CPPFLAGS += -Isrc/ares/config_sunos -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
LINKFLAGS+=-lsocket -lnsl LINKFLAGS+=-lsocket -lnsl
UV_OS_FILE=uv-sunos.c OBJS += src/unix/sunos.o
endif endif
ifeq (Darwin,$(uname_S)) ifeq (Darwin,$(uname_S))
EV_CONFIG=config_darwin.h EV_CONFIG=config_darwin.h
EIO_CONFIG=config_darwin.h EIO_CONFIG=config_darwin.h
CPPFLAGS += -I$(S)/src/ares/config_darwin CPPFLAGS += -Isrc/ares/config_darwin
LINKFLAGS+=-framework CoreServices LINKFLAGS+=-framework CoreServices
UV_OS_FILE=uv-darwin.c OBJS += src/unix/darwin.o
endif endif
ifeq (Linux,$(uname_S)) ifeq (Linux,$(uname_S))
EV_CONFIG=config_linux.h EV_CONFIG=config_linux.h
EIO_CONFIG=config_linux.h EIO_CONFIG=config_linux.h
CSTDFLAG += -D_XOPEN_SOURCE=600 CSTDFLAG += -D_GNU_SOURCE
CPPFLAGS += -I$(S)/src/ares/config_linux CPPFLAGS += -Isrc/ares/config_linux
LINKFLAGS+=-lrt LINKFLAGS+=-lrt
UV_OS_FILE=uv-linux.c OBJS += src/unix/linux.o
endif endif
ifeq (FreeBSD,$(uname_S)) ifeq (FreeBSD,$(uname_S))
EV_CONFIG=config_freebsd.h EV_CONFIG=config_freebsd.h
EIO_CONFIG=config_freebsd.h EIO_CONFIG=config_freebsd.h
CPPFLAGS += -I$(S)/src/ares/config_freebsd CPPFLAGS += -Isrc/ares/config_freebsd
LINKFLAGS+= LINKFLAGS+=
UV_OS_FILE=uv-freebsd.c OBJS += src/unix/freebsd.o
endif
ifeq (NetBSD,$(uname_S))
EV_CONFIG=config_netbsd.h
EIO_CONFIG=config_netbsd.h
CPPFLAGS += -Isrc/ares/config_netbsd
LINKFLAGS+=
OBJS += src/unix/netbsd.o
endif endif
ifneq (,$(findstring CYGWIN,$(uname_S))) ifneq (,$(findstring CYGWIN,$(uname_S)))
EV_CONFIG=config_cygwin.h EV_CONFIG=config_cygwin.h
EIO_CONFIG=config_cygwin.h EIO_CONFIG=config_cygwin.h
CPPFLAGS += -I$(S)/src/ares/config_cygwin # We drop the --std=c89, it hides CLOCK_MONOTONIC on cygwin
CSTDFLAG = -D_GNU_SOURCE
CPPFLAGS += -Isrc/ares/config_cygwin
LINKFLAGS+= LINKFLAGS+=
UV_OS_FILE=uv-cygwin.c OBJS += src/unix/cygwin.o
endif endif
# Need _GNU_SOURCE for strdup? # Need _GNU_SOURCE for strdup?
RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE
RUNNER_LINKFLAGS=$(LINKFLAGS)
ifeq (SunOS,$(uname_S))
RUNNER_LINKFLAGS += -pthreads
else
RUNNER_LINKFLAGS += -pthread
endif
RUNNER_LINKFLAGS=$(LINKFLAGS) -pthread
RUNNER_LIBS= RUNNER_LIBS=
RUNNER_SRC=test/runner-unix.c RUNNER_SRC=test/runner-unix.c
uv.a: src/uv-unix.o src/uv-common.o src/uv-platform.o src/ev/ev.o src/uv-eio.o src/eio/eio.o $(CARES_OBJS) uv.a: $(OBJS) src/uv-common.o src/unix/ev/ev.o src/unix/uv-eio.o src/unix/eio/eio.o $(CARES_OBJS)
@$(call EE, ar: $@) $(AR) rcs uv.a $(OBJS) src/uv-common.o src/unix/uv-eio.o src/unix/ev/ev.o src/unix/eio/eio.o $(CARES_OBJS)
$(Q)$(AR) rcs uv.a $^
src/uv-platform.o: src/$(UV_OS_FILE) include/uv.h include/uv-unix.h src/unix/%.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
@$(call EE, compile: $@) $(CC) $(CSTDFLAG) $(CPPFLAGS) -Isrc $(CFLAGS) -c $< -o $@
$(Q)$(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
src/uv-unix.o: src/uv-unix.c include/uv.h include/uv-unix.h src/uv-common.o: src/uv-common.c include/uv.h include/uv-private/uv-unix.h
@$(call EE, compile: $@) $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/uv-common.c -o src/uv-common.o
$(Q)$(CC) $(CSTDFLAG) $(CPPFLAGS) -I$(S)/eio $(CFLAGS) -c $< -o $@
src/uv-common.o: src/uv-common.c include/uv.h include/uv-unix.h src/unix/ev/ev.o: src/unix/ev/ev.c
@$(call EE, compile: $@) $(CC) $(CPPFLAGS) $(CFLAGS) -c src/unix/ev/ev.c -o src/unix/ev/ev.o -DEV_CONFIG_H=\"$(EV_CONFIG)\"
$(Q)$(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
src/ev/ev.o: src/ev/ev.c
@$(call EE, compile: $@)
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ -DEV_CONFIG_H=\"$(EV_CONFIG)\"
EIO_CPPFLAGS += $(CPPFLAGS) EIO_CPPFLAGS += $(CPPFLAGS)
EIO_CPPFLAGS += -DEIO_CONFIG_H=\"$(EIO_CONFIG)\" EIO_CPPFLAGS += -DEIO_CONFIG_H=\"$(EIO_CONFIG)\"
EIO_CPPFLAGS += -DEIO_STACKSIZE=65536 EIO_CPPFLAGS += -DEIO_STACKSIZE=262144
EIO_CPPFLAGS += -D_GNU_SOURCE EIO_CPPFLAGS += -D_GNU_SOURCE
src/eio/eio.o: src/eio/eio.c src/unix/eio/eio.o: src/unix/eio/eio.c
@$(call EE, compile: $@) $(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c src/unix/eio/eio.c -o src/unix/eio/eio.o
$(Q)$(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c $< -o $@
src/uv-eio.o: src/uv-eio.c src/unix/uv-eio.o: src/unix/uv-eio.c
@$(call EE, compile: $@) $(CC) $(CPPFLAGS) -Isrc/unix/eio/ $(CSTDFLAG) $(CFLAGS) -c src/unix/uv-eio.c -o src/unix/uv-eio.o
$(Q)$(CC) $(CPPFLAGS) -I$(S)/src/eio/ $(CSTDFLAG) $(CFLAGS) -c $< -o $@
clean-platform:
-rm -f src/ares/*.o
-rm -f src/unix/ev/*.o
-rm -f src/unix/eio/*.o
-rm -f src/unix/*.o
-rm -rf test/run-tests.dSYM run-benchmarks.dSYM
distclean-platform:
-rm -f src/ares/*.o
-rm -f src/unix/ev/*.o
-rm -f src/unix/*.o
-rm -f src/unix/eio/*.o
-rm -rf test/run-tests.dSYM run-benchmarks.dSYM

View File

@ -1,159 +0,0 @@
Warning: this is not actual API but desired API.
# `uv_handle_t`
This is the abstract base class of all types of handles. All handles have in
common:
* When handles are initialized, the reference count to the event loop is
increased by one.
* The user owns the `uv_handle_t` memory and is in charge of freeing it.
* In order to free resources associated with a handle, one must `uv_close()`
and wait for the `uv_close_cb` callback. After the close callback has been
made, the user is allowed to the `uv_handle_t` object.
* The `uv_close_cb` is always made directly off the event loop. That is, it
is not called from `uv_close()`.
# `uv_tcp_server_t`
A TCP server class that is a subclass of `uv_handle_t`. This can be bound to
an address and begin accepting new TCP sockets.
int uv_bind4(uv_tcp_server_t* tcp_server, struct sockaddr_in* address);
int uv_bind6(uv_tcp_server_t* tcp_server, struct sockaddr_in6* address);
Binds the TCP server to an address. The `address` can be created with
`uv_ip4_addr()`. Call this before `uv_listen()`
Returns zero on success, -1 on failure. Errors in order of least-seriousness:
* `UV_EADDRINUSE` There is already another socket bound to the specified
address.
* `UV_EADDRNOTAVAIL` The `address` parameter is an IP address that is not
* `UV_EINVAL` The server is already bound to an address.
* `UV_EFAULT` Memory of `address` parameter is unintelligible.
int uv_listen(uv_tcp_server_t*, int backlog, uv_connection_cb cb);
Begins listening for connections. The accept callback is level-triggered.
int uv_accept(uv_tcp_server_t* server,
uv_tcp_t* client);
Accepts a connection. This should be called after the accept callback is
made. The `client` parameter should be uninitialized memory; `uv_accept` is
used instead of `uv_tcp_init` for server-side `uv_tcp_t` initialization.
Return value 0 indicates success, -1 failure. Possible errors:
* `UV_EAGAIN` There are no connections. Wait for the `uv_connection_cb` callback
to be called again.
* `UV_EFAULT` The memory of either `server` is unintelligible.
# `uv_stream_t`
An abstract subclass of `uv_handle_t`. Streams represent something that
reads and/or writes data. Streams can be half or full-duplex. TCP sockets
are streams, files are streams with offsets.
int uv_read_start(uv_stream_t* stream,
uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
Starts the stream reading continuously. The `alloc_cb` is used to allow the
user to implement various means of supplying the stream with buffers to
fill. The `read_cb` returns buffers to the user filled with data.
Sometimes the buffers returned to the user do not contain data. This does
not indicate EOF as in other systems. EOF is made via the `uv_eof_cb` which
can be set like this `uv_set_eof_cb(stream, eof_cb);`
int uv_read_stop(uv_stream_t* stream);
Stops reading from the stream.
int uv_write_req_init(uv_write_req_t*,
uv_stream_t*,
uv_buf_t bufs[],
int butcnf);
Initiates a write request on a stream.
int uv_shutdown_req_init(uv_shutdown_req_t*, uv_stream_t*)
Initiates a shutdown of outgoing data once the write queue drains.
# `uv_tcp_t`
The TCP handle class represents one endpoint of a duplex TCP stream.
`uv_tcp_t` is a subclass of `uv_stream_t`. A TCP handle can represent a
client side connection (one that has been used with uv_connect_req_init`)
or a server-side connection (one that was initialized with `uv_accept`)
int uv_connect_req_init(uv_connect_req_t* req,
uv_tcp_t* socket,
struct sockaddr* addr);
Initiates a request to open a connection.
# `uv_req_t`
Abstract class represents an asynchronous request. This is a subclass of `uv_handle_t`.
# `uv_connect_req_t`
Subclass of `uv_req_t`. Represents a request for a TCP connection. Operates
on `uv_tcp_t` handles. Like other types of requests the `close_cb` indicates
completion of the request.
int uv_connect_req_init(uv_connect_req_t* req,
uv_tcp_t* socket,
struct sockaddr* addr);
Initializes the connection request. Returning 0 indicates success, -1 if
there was an error. The following values can be retrieved from
`uv_last_error` in the case of an error:
* ???
# `uv_shutdown_req_t`
Subclass of `uv_req_t`. Represents an ongoing shutdown request. Once the
write queue of the parent `uv_stream_t` is drained, the outbound data
channel is shutdown. Once a shutdown request is initiated on a stream, the
stream will allow no more writes.
int uv_shutdown_req_init(uv_shutdown_req_t*,
uv_stream_t* parent);
Initializes the shutdown request.
# `uv_write_req_t`
int uv_write_req_init(uv_write_req_t*,
uv_stream_t*,
uv_buf_t bufs[],
int butcnf);
Initiates a write request on a stream.

60
src/rt/libuv/gyp_uv Executable file
View File

@ -0,0 +1,60 @@
#!/usr/bin/env python
import glob
import os
import shlex
import sys
script_dir = os.path.dirname(__file__)
uv_root = os.path.normpath(script_dir)
sys.path.insert(0, os.path.join(uv_root, 'build', 'gyp', 'pylib'))
import gyp
# Directory within which we want all generated files (including Makefiles)
# to be written.
output_dir = os.path.join(os.path.abspath(uv_root), 'out')
def run_gyp(args):
rc = gyp.main(args)
if rc != 0:
print 'Error running GYP'
sys.exit(rc)
if __name__ == '__main__':
args = sys.argv[1:]
# GYP bug.
# On msvs it will crash if it gets an absolute path.
# On Mac/make it will crash if it doesn't get an absolute path.
if sys.platform == 'win32':
args.append(os.path.join(uv_root, 'uv.gyp'))
common_fn = os.path.join(uv_root, 'common.gypi')
options_fn = os.path.join(uv_root, 'options.gypi')
else:
args.append(os.path.join(os.path.abspath(uv_root), 'uv.gyp'))
common_fn = os.path.join(os.path.abspath(uv_root), 'common.gypi')
options_fn = os.path.join(os.path.abspath(uv_root), 'options.gypi')
if os.path.exists(common_fn):
args.extend(['-I', common_fn])
if os.path.exists(options_fn):
args.extend(['-I', options_fn])
args.append('--depth=' + uv_root)
# There's a bug with windows which doesn't allow this feature.
if sys.platform != 'win32':
# Tell gyp to write the Makefiles into output_dir
args.extend(['--generator-output', output_dir])
# Tell make to write its output into the same dir
args.extend(['-Goutput_dir=' + output_dir])
args.append('-Dtarget_arch=ia32')
args.append('-Dcomponent=static_library')
args.append('-Dlibrary=static_library')
gyp_args = list(args)
print gyp_args
run_gyp(gyp_args)

View File

@ -1,7 +1,7 @@
/* /*
* libeio API header * libeio API header
* *
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libeio@schmorp.de> * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libeio@schmorp.de>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modifica- * Redistribution and use in source and binary forms, with or without modifica-
@ -45,17 +45,9 @@ extern "C" {
#endif #endif
#include <stddef.h> #include <stddef.h>
#include <signal.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef __OpenBSD__
# include <inttypes.h>
#endif
#ifdef _WIN32
# define uid_t int
# define gid_t int
#endif
typedef struct eio_req eio_req; typedef struct eio_req eio_req;
typedef struct eio_dirent eio_dirent; typedef struct eio_dirent eio_dirent;
@ -68,11 +60,34 @@ typedef int (*eio_cb)(eio_req *req);
#ifndef EIO_STRUCT_STAT #ifndef EIO_STRUCT_STAT
# ifdef _WIN32 # ifdef _WIN32
# define EIO_STRUCT_STAT struct _stati64 # define EIO_STRUCT_STAT struct _stati64
# define EIO_STRUCT_STATI64
# else # else
# define EIO_STRUCT_STAT struct stat # define EIO_STRUCT_STAT struct stat
# endif # endif
#endif #endif
#ifdef _WIN32
typedef int eio_uid_t;
typedef int eio_gid_t;
typedef int eio_mode_t;
#ifdef __MINGW32__ /* no intptr_t */
typedef ssize_t eio_ssize_t;
#else
typedef intptr_t eio_ssize_t; /* or SSIZE_T */
#endif
#if __GNUC__
typedef long long eio_ino_t;
#else
typedef __int64 eio_ino_t; /* unsigned not supported by msvc */
#endif
#else
typedef uid_t eio_uid_t;
typedef gid_t eio_gid_t;
typedef ssize_t eio_ssize_t;
typedef ino_t eio_ino_t;
typedef mode_t eio_mode_t;
#endif
#ifndef EIO_STRUCT_STATVFS #ifndef EIO_STRUCT_STATVFS
# define EIO_STRUCT_STATVFS struct statvfs # define EIO_STRUCT_STATVFS struct statvfs
#endif #endif
@ -119,7 +134,7 @@ struct eio_dirent
unsigned short namelen; /* size of filename without trailing 0 */ unsigned short namelen; /* size of filename without trailing 0 */
unsigned char type; /* one of EIO_DT_* */ unsigned char type; /* one of EIO_DT_* */
signed char score; /* internal use */ signed char score; /* internal use */
ino_t inode; /* the inode number, if available, otherwise unspecified */ eio_ino_t inode; /* the inode number, if available, otherwise unspecified */
}; };
/* eio_msync flags */ /* eio_msync flags */
@ -131,14 +146,12 @@ enum
}; };
/* eio_mtouch flags */ /* eio_mtouch flags */
enum enum
{ {
EIO_MT_MODIFY = 1 EIO_MT_MODIFY = 1
}; };
/* eio_sync_file_range flags */ /* eio_sync_file_range flags */
enum enum
{ {
EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1, EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1,
@ -146,10 +159,16 @@ enum
EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4 EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4
}; };
typedef double eio_tstamp; /* feel free to use double in your code directly */ /* eio_fallocate flags */
enum
{
EIO_FALLOC_FL_KEEP_SIZE = 1 /* MUST match the value in linux/falloc.h */
};
/* timestamps and differences - feel free to use double in your code directly */
typedef double eio_tstamp;
/* the eio request structure */ /* the eio request structure */
enum enum
{ {
EIO_CUSTOM, EIO_CUSTOM,
@ -162,12 +181,12 @@ enum
EIO_UTIME, EIO_FUTIME, EIO_UTIME, EIO_FUTIME,
EIO_CHMOD, EIO_FCHMOD, EIO_CHMOD, EIO_FCHMOD,
EIO_CHOWN, EIO_FCHOWN, EIO_CHOWN, EIO_FCHOWN,
EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC, EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC, EIO_SYNCFS,
EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE, EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE, EIO_FALLOCATE,
EIO_MLOCK, EIO_MLOCKALL, EIO_MLOCK, EIO_MLOCKALL,
EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME, EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME,
EIO_MKNOD, EIO_READDIR, EIO_MKNOD, EIO_READDIR,
EIO_LINK, EIO_SYMLINK, EIO_READLINK, EIO_LINK, EIO_SYMLINK, EIO_READLINK, EIO_REALPATH,
EIO_GROUP, EIO_NOP, EIO_GROUP, EIO_NOP,
EIO_BUSY EIO_BUSY
}; };
@ -194,9 +213,9 @@ struct eio_req
{ {
eio_req volatile *next; /* private ETP */ eio_req volatile *next; /* private ETP */
ssize_t result; /* result of syscall, e.g. result = read (... */ eio_ssize_t result; /* result of syscall, e.g. result = read (... */
off_t offs; /* read, write, truncate, readahead, sync_file_range: file offset */ off_t offs; /* read, write, truncate, readahead, sync_file_range, fallocate: file offset, mknod: dev_t */
size_t size; /* read, write, readahead, sendfile, msync, mlock, sync_file_range: length */ size_t size; /* read, write, readahead, sendfile, msync, mlock, sync_file_range, fallocate: length */
void *ptr1; /* all applicable requests: pathname, old name; readdir: optional eio_dirents */ void *ptr1; /* all applicable requests: pathname, old name; readdir: optional eio_dirents */
void *ptr2; /* all applicable requests: new name or memory buffer; readdir: name strings */ void *ptr2; /* all applicable requests: new name or memory buffer; readdir: name strings */
eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */ eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */
@ -204,16 +223,22 @@ struct eio_req
int type; /* EIO_xxx constant ETP */ int type; /* EIO_xxx constant ETP */
int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */ int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range: flags */ long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range, fallocate: flags */
long int3; /* chown, fchown: gid; mknod: dev_t */ long int3; /* chown, fchown: gid */
int errorno; /* errno value on syscall return */ int errorno; /* errno value on syscall return */
#if __i386 || __amd64
unsigned char cancelled;
#else
sig_atomic_t cancelled;
#endif
unsigned char flags; /* private */ unsigned char flags; /* private */
signed char pri; /* the priority */ signed char pri; /* the priority */
void *data; void *data;
eio_cb finish; eio_cb finish;
void (*destroy)(eio_req *req); /* called when requets no longer needed */ void (*destroy)(eio_req *req); /* called when request no longer needed */
void (*feed)(eio_req *req); /* only used for group requests */ void (*feed)(eio_req *req); /* only used for group requests */
EIO_REQ_MEMBERS EIO_REQ_MEMBERS
@ -223,10 +248,9 @@ struct eio_req
/* _private_ request flags */ /* _private_ request flags */
enum { enum {
EIO_FLAG_CANCELLED = 0x01, /* request was cancelled */ EIO_FLAG_PTR1_FREE = 0x01, /* need to free(ptr1) */
EIO_FLAG_PTR1_FREE = 0x02, /* need to free(ptr1) */ EIO_FLAG_PTR2_FREE = 0x02, /* need to free(ptr2) */
EIO_FLAG_PTR2_FREE = 0x04, /* need to free(ptr2) */ EIO_FLAG_GROUPADD = 0x04 /* some request was added to the group */
EIO_FLAG_GROUPADD = 0x08 /* some request was added to the group */
}; };
/* undocumented/unsupported/private helper */ /* undocumented/unsupported/private helper */
@ -254,14 +278,15 @@ void eio_set_max_poll_reqs (unsigned int nreqs);
void eio_set_min_parallel (unsigned int nthreads); void eio_set_min_parallel (unsigned int nthreads);
void eio_set_max_parallel (unsigned int nthreads); void eio_set_max_parallel (unsigned int nthreads);
void eio_set_max_idle (unsigned int nthreads); void eio_set_max_idle (unsigned int nthreads);
void eio_set_idle_timeout (unsigned int seconds);
unsigned int eio_nreqs (void); /* number of requests in-flight */ unsigned int eio_nreqs (void); /* number of requests in-flight */
unsigned int eio_nready (void); /* number of not-yet handled requests */ unsigned int eio_nready (void); /* number of not-yet handled requests */
unsigned int eio_npending (void); /* numbe rof finished but unhandled requests */ unsigned int eio_npending (void); /* number of finished but unhandled requests */
unsigned int eio_nthreads (void); /* number of worker threads in use currently */ unsigned int eio_nthreads (void); /* number of worker threads in use currently */
/*****************************************************************************/ /*****************************************************************************/
/* convinience wrappers */ /* convenience wrappers */
#ifndef EIO_NO_WRAPPERS #ifndef EIO_NO_WRAPPERS
eio_req *eio_nop (int pri, eio_cb cb, void *data); /* does nothing except go through the whole process */ eio_req *eio_nop (int pri, eio_cb cb, void *data); /* does nothing except go through the whole process */
@ -269,11 +294,13 @@ eio_req *eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data); /* ti
eio_req *eio_sync (int pri, eio_cb cb, void *data); eio_req *eio_sync (int pri, eio_cb cb, void *data);
eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data); eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data); eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data); eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data); eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data); eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data);
eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data); eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data);
eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data); eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data);
eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data);
eio_req *eio_close (int fd, int pri, eio_cb cb, void *data); eio_req *eio_close (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data); eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data);
eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data); eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
@ -282,28 +309,29 @@ eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data); /* stat buffer=
eio_req *eio_fstatvfs (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */ eio_req *eio_fstatvfs (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
eio_req *eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data); eio_req *eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data); eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data);
eio_req *eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data); eio_req *eio_fchmod (int fd, eio_mode_t mode, int pri, eio_cb cb, void *data);
eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data); eio_req *eio_fchown (int fd, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data);
eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data); eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data);
eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data); eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data);
eio_req *eio_open (const char *path, int flags, mode_t mode, int pri, eio_cb cb, void *data); eio_req *eio_open (const char *path, int flags, eio_mode_t mode, int pri, eio_cb cb, void *data);
eio_req *eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data); eio_req *eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data); eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data);
eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data); eio_req *eio_chown (const char *path, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data);
eio_req *eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data); eio_req *eio_chmod (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data);
eio_req *eio_mkdir (const char *path, mode_t mode, int pri, eio_cb cb, void *data); eio_req *eio_mkdir (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data);
eio_req *eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */ eio_req *eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data); eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data);
eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data); eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data);
eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */ eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
eio_req *eio_realpath (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */ eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */ eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
eio_req *eio_statvfs (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */ eio_req *eio_statvfs (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data); eio_req *eio_mknod (const char *path, eio_mode_t mode, dev_t dev, int pri, eio_cb cb, void *data);
eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data); eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data); eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data); eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
eio_req *eio_custom (eio_cb execute, int pri, eio_cb cb, void *data); eio_req *eio_custom (void (*execute)(eio_req *), int pri, eio_cb cb, void *data);
#endif #endif
/*****************************************************************************/ /*****************************************************************************/
@ -319,7 +347,7 @@ void eio_grp_cancel (eio_req *grp); /* cancels all sub requests but not the g
/* request api */ /* request api */
/* true if the request was cancelled, useful in the invoke callback */ /* true if the request was cancelled, useful in the invoke callback */
#define EIO_CANCELLED(req) ((req)->flags & EIO_FLAG_CANCELLED) #define EIO_CANCELLED(req) ((req)->cancelled)
#define EIO_RESULT(req) ((req)->result) #define EIO_RESULT(req) ((req)->result)
/* returns a pointer to the result buffer allocated by eio */ /* returns a pointer to the result buffer allocated by eio */
@ -332,21 +360,13 @@ void eio_grp_cancel (eio_req *grp); /* cancels all sub requests but not the g
void eio_submit (eio_req *req); void eio_submit (eio_req *req);
/* cancel a request as soon fast as possible, if possible */ /* cancel a request as soon fast as possible, if possible */
void eio_cancel (eio_req *req); void eio_cancel (eio_req *req);
/* destroy a request that has never been submitted */
void eio_destroy (eio_req *req);
/*****************************************************************************/ /*****************************************************************************/
/* convinience functions */ /* convenience functions */
ssize_t eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count); eio_ssize_t eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count);
eio_ssize_t eio__pread (int fd, void *buf, size_t count, off_t offset);
/*****************************************************************************/ eio_ssize_t eio__pwrite (int fd, void *buf, size_t count, off_t offset);
/* export these so node_file can use these function instead of pread/write */
#if !HAVE_PREADWRITE
ssize_t eio__pread (int fd, void *buf, size_t count, off_t offset);
ssize_t eio__pwrite (int fd, void *buf, size_t count, off_t offset);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -48,6 +48,12 @@
EV_CPP(extern "C" {) EV_CPP(extern "C" {)
#ifdef __GNUC__
# define EV_MAYBE_UNUSED __attribute__ ((unused))
#else
# define EV_MAYBE_UNUSED
#endif
/*****************************************************************************/ /*****************************************************************************/
/* pre-4.0 compatibility */ /* pre-4.0 compatibility */
@ -539,7 +545,7 @@ void ev_set_syserr_cb (void (*cb)(const char *msg));
struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)); struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
EV_INLINE struct ev_loop * EV_INLINE struct ev_loop *
ev_default_loop_uc_ (void) EV_MAYBE_UNUSED ev_default_loop_uc_ (void)
{ {
extern struct ev_loop *ev_default_loop_ptr; extern struct ev_loop *ev_default_loop_ptr;
@ -547,7 +553,7 @@ ev_default_loop_uc_ (void)
} }
EV_INLINE int EV_INLINE int
ev_is_default_loop (EV_P) EV_MAYBE_UNUSED ev_is_default_loop (EV_P)
{ {
return EV_A == EV_DEFAULT_UC; return EV_A == EV_DEFAULT_UC;
} }
@ -807,14 +813,14 @@ void ev_async_send (EV_P_ ev_async *w);
#define EVUNLOOP_ONE EVBREAK_ONE #define EVUNLOOP_ONE EVBREAK_ONE
#define EVUNLOOP_ALL EVBREAK_ALL #define EVUNLOOP_ALL EVBREAK_ALL
#if EV_PROTOTYPES #if EV_PROTOTYPES
EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); } EV_INLINE void EV_MAYBE_UNUSED ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); }
EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); } EV_INLINE void EV_MAYBE_UNUSED ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); }
EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); } EV_INLINE void EV_MAYBE_UNUSED ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); }
EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); } EV_INLINE void EV_MAYBE_UNUSED ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); }
#if EV_FEATURE_API #if EV_FEATURE_API
EV_INLINE unsigned int ev_loop_count (EV_P) { return ev_iteration (EV_A); } EV_INLINE unsigned int EV_MAYBE_UNUSED ev_loop_count (EV_P) { return ev_iteration (EV_A); }
EV_INLINE unsigned int ev_loop_depth (EV_P) { return ev_depth (EV_A); } EV_INLINE unsigned int EV_MAYBE_UNUSED ev_loop_depth (EV_P) { return ev_depth (EV_A); }
EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); } EV_INLINE void EV_MAYBE_UNUSED ev_loop_verify (EV_P) { ev_verify (EV_A); }
#endif #endif
#endif #endif
#else #else

View File

@ -1,4 +1,5 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to * of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the * deal in the Software without restriction, including without limitation the
@ -18,32 +19,11 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
#include "uv.h" #ifndef UV_LINUX_H
#define UV_LINUX_H
#define UV_FS_EVENT_PRIVATE_FIELDS \
ev_io read_watcher; \
uv_fs_event_cb cb; \
int uv_exepath(char* buffer, size_t* size) { #endif /* UV_LINUX_H */
uint32_t usize;
int result;
char* path;
char* fullpath;
if (!buffer || !size) {
return -1;
}
int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
size_t cb = *size;
if (sysctl(mib, 4, buffer, &cb, NULL, 0) < 0) {
*size = 0;
return -1;
}
*size = strlen(buffer);
return 0;
}

View File

@ -25,6 +25,11 @@
#include "ngx-queue.h" #include "ngx-queue.h"
#include "ev.h" #include "ev.h"
#include "eio.h"
#if defined(__linux__)
#include "uv-private/uv-linux.h"
#endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -39,16 +44,52 @@ typedef struct {
size_t len; size_t len;
} uv_buf_t; } uv_buf_t;
typedef int uv_file;
/* Stub. Remove it once all platforms support the file watcher API. */
#ifndef UV_FS_EVENT_PRIVATE_FIELDS
#define UV_FS_EVENT_PRIVATE_FIELDS /* empty */
#endif
#define UV_LOOP_PRIVATE_FIELDS \
ares_channel channel; \
/* \
* While the channel is active this timer is called once per second to be \
* sure that we're always calling ares_process. See the warning above the \
* definition of ares_timeout(). \
*/ \
ev_timer timer; \
struct ev_loop* ev;
#define UV_REQ_BUFSML_SIZE (4) #define UV_REQ_BUFSML_SIZE (4)
#define UV_REQ_PRIVATE_FIELDS \ #define UV_REQ_PRIVATE_FIELDS /* empty */
int write_index; \
ev_timer timer; \ #define UV_WRITE_PRIVATE_FIELDS \
ngx_queue_t queue; \ ngx_queue_t queue; \
int write_index; \
uv_buf_t* bufs; \ uv_buf_t* bufs; \
int bufcnt; \ int bufcnt; \
int error; \
uv_buf_t bufsml[UV_REQ_BUFSML_SIZE]; uv_buf_t bufsml[UV_REQ_BUFSML_SIZE];
#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
#define UV_CONNECT_PRIVATE_FIELDS \
ngx_queue_t queue;
#define UV_UDP_SEND_PRIVATE_FIELDS \
ngx_queue_t queue; \
struct sockaddr_storage addr; \
socklen_t addrlen; \
uv_buf_t* bufs; \
int bufcnt; \
ssize_t status; \
uv_udp_send_cb send_cb; \
uv_buf_t bufsml[UV_REQ_BUFSML_SIZE]; \
#define UV_PRIVATE_REQ_TYPES /* empty */
/* TODO: union or classes please! */ /* TODO: union or classes please! */
#define UV_HANDLE_PRIVATE_FIELDS \ #define UV_HANDLE_PRIVATE_FIELDS \
@ -59,20 +100,35 @@ typedef struct {
#define UV_STREAM_PRIVATE_FIELDS \ #define UV_STREAM_PRIVATE_FIELDS \
uv_read_cb read_cb; \ uv_read_cb read_cb; \
uv_alloc_cb alloc_cb; uv_alloc_cb alloc_cb; \
uv_connect_t *connect_req; \
uv_shutdown_t *shutdown_req; \
/* UV_TCP */
#define UV_TCP_PRIVATE_FIELDS \
int delayed_error; \
uv_connection_cb connection_cb; \
int accepted_fd; \
uv_req_t *connect_req; \
uv_req_t *shutdown_req; \
ev_io read_watcher; \ ev_io read_watcher; \
ev_io write_watcher; \ ev_io write_watcher; \
ngx_queue_t write_queue; \ ngx_queue_t write_queue; \
ngx_queue_t write_completed_queue; ngx_queue_t write_completed_queue; \
int delayed_error; \
uv_connection_cb connection_cb; \
int accepted_fd;
/* UV_TCP */
#define UV_TCP_PRIVATE_FIELDS
/* UV_UDP */
#define UV_UDP_PRIVATE_FIELDS \
uv_alloc_cb alloc_cb; \
uv_udp_recv_cb recv_cb; \
ev_io read_watcher; \
ev_io write_watcher; \
ngx_queue_t write_queue; \
ngx_queue_t write_completed_queue; \
/* UV_NAMED_PIPE */
#define UV_PIPE_PRIVATE_FIELDS \
const char* pipe_fname; /* strdup'ed */
/* UV_PREPARE */ \ /* UV_PREPARE */ \
@ -117,4 +173,16 @@ typedef struct {
struct addrinfo* res; \ struct addrinfo* res; \
int retcode; int retcode;
#define UV_PROCESS_PRIVATE_FIELDS \
ev_child child_watcher;
#define UV_FS_PRIVATE_FIELDS \
struct stat statbuf; \
eio_req* eio;
#define UV_WORK_PRIVATE_FIELDS \
eio_req* eio;
#define UV_TTY_PRIVATE_FIELDS /* empty */
#endif /* UV_UNIX_H */ #endif /* UV_UNIX_H */

View File

@ -0,0 +1,281 @@
/* 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_WINNT
# define _WIN32_WINNT 0x0502
#endif
#include <stdint.h>
#include <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <sys/stat.h>
#include "tree.h"
#define MAX_PIPENAME_LEN 256
/**
* It should be possible to cast uv_buf_t[] to WSABUF[]
* see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx
*/
typedef struct uv_buf_t {
ULONG len;
char* base;
} uv_buf_t;
typedef int uv_file;
RB_HEAD(uv_timer_tree_s, uv_timer_s);
#define UV_LOOP_PRIVATE_FIELDS \
/* The loop's I/O completion port */ \
HANDLE iocp; \
/* Reference count that keeps the event loop alive */ \
int refs; \
/* The current time according to the event loop. in msecs. */ \
int64_t time; \
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
/* is empty, tail_ is NULL. If there is only one item, */ \
/* tail_->next_req == tail_ */ \
uv_req_t* pending_reqs_tail; \
/* Head of a single-linked list of closed handles */ \
uv_handle_t* endgame_handles; \
/* The head of the timers tree */ \
struct uv_timer_tree_s timers; \
/* Lists of active loop (prepare / check / idle) watchers */ \
uv_prepare_t* prepare_handles; \
uv_check_t* check_handles; \
uv_idle_t* idle_handles; \
/* This pointer will refer to the prepare/check/idle handle whose */ \
/* callback is scheduled to be called next. This is needed to allow */ \
/* safe removal from one of the lists above while that list being */ \
/* iterated over. */ \
uv_prepare_t* next_prepare_handle; \
uv_check_t* next_check_handle; \
uv_idle_t* next_idle_handle; \
ares_channel ares_chan; \
int ares_active_sockets; \
uv_timer_t ares_polling_timer; \
/* Last error code */ \
uv_err_t last_error;
#define UV_REQ_TYPE_PRIVATE \
/* TODO: remove the req suffix */ \
UV_ARES_EVENT_REQ, \
UV_ARES_CLEANUP_REQ, \
UV_GETADDRINFO_REQ, \
UV_PROCESS_EXIT, \
UV_PROCESS_CLOSE, \
UV_UDP_RECV, \
UV_FS_EVENT_REQ
#define UV_REQ_PRIVATE_FIELDS \
union { \
/* Used by I/O operations */ \
struct { \
OVERLAPPED overlapped; \
size_t queued_bytes; \
}; \
}; \
struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \
/* empty */
#define UV_CONNECT_PRIVATE_FIELDS \
/* empty */
#define UV_SHUTDOWN_PRIVATE_FIELDS \
/* empty */
#define UV_UDP_SEND_PRIVATE_FIELDS \
/* empty */
#define UV_PRIVATE_REQ_TYPES \
typedef struct uv_pipe_accept_s { \
UV_REQ_FIELDS \
HANDLE pipeHandle; \
struct uv_pipe_accept_s* next_pending; \
} uv_pipe_accept_t; \
typedef struct uv_tcp_accept_s { \
UV_REQ_FIELDS \
SOCKET accept_socket; \
char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
struct uv_tcp_accept_s* next_pending; \
} uv_tcp_accept_t;
#define uv_stream_connection_fields \
unsigned int write_reqs_pending; \
uv_shutdown_t* shutdown_req;
#define uv_stream_server_fields \
uv_connection_cb connection_cb;
#define UV_STREAM_PRIVATE_FIELDS \
unsigned int reqs_pending; \
uv_alloc_cb alloc_cb; \
uv_read_cb read_cb; \
uv_req_t read_req; \
union { \
struct { uv_stream_connection_fields }; \
struct { uv_stream_server_fields }; \
};
#define uv_tcp_server_fields \
uv_tcp_accept_t* accept_reqs; \
uv_tcp_accept_t* pending_accepts;
#define uv_tcp_connection_fields \
uv_buf_t read_buffer;
#define UV_TCP_PRIVATE_FIELDS \
SOCKET socket; \
uv_err_t bind_error; \
union { \
struct { uv_tcp_server_fields }; \
struct { uv_tcp_connection_fields }; \
};
#define UV_UDP_PRIVATE_FIELDS \
SOCKET socket; \
unsigned int reqs_pending; \
uv_req_t recv_req; \
uv_buf_t recv_buffer; \
struct sockaddr_storage recv_from; \
int recv_from_len; \
uv_udp_recv_cb recv_cb; \
uv_alloc_cb alloc_cb;
#define uv_pipe_server_fields \
uv_pipe_accept_t accept_reqs[4]; \
uv_pipe_accept_t* pending_accepts;
#define uv_pipe_connection_fields \
uv_timer_t* eof_timer;
#define UV_PIPE_PRIVATE_FIELDS \
HANDLE handle; \
wchar_t* name; \
union { \
struct { uv_pipe_server_fields }; \
struct { uv_pipe_connection_fields }; \
};
#define UV_TIMER_PRIVATE_FIELDS \
RB_ENTRY(uv_timer_s) tree_entry; \
int64_t due; \
int64_t repeat; \
uv_timer_cb timer_cb;
#define UV_ASYNC_PRIVATE_FIELDS \
struct uv_req_s async_req; \
uv_async_cb async_cb; \
/* char to avoid alignment issues */ \
char volatile async_sent;
#define UV_PREPARE_PRIVATE_FIELDS \
uv_prepare_t* prepare_prev; \
uv_prepare_t* prepare_next; \
uv_prepare_cb prepare_cb;
#define UV_CHECK_PRIVATE_FIELDS \
uv_check_t* check_prev; \
uv_check_t* check_next; \
uv_check_cb check_cb;
#define UV_IDLE_PRIVATE_FIELDS \
uv_idle_t* idle_prev; \
uv_idle_t* idle_next; \
uv_idle_cb idle_cb;
#define UV_HANDLE_PRIVATE_FIELDS \
uv_handle_t* endgame_next; \
unsigned int flags;
#define UV_ARES_TASK_PRIVATE_FIELDS \
struct uv_req_s ares_req; \
SOCKET sock; \
HANDLE h_wait; \
WSAEVENT h_event; \
HANDLE h_close_event;
#define UV_GETADDRINFO_PRIVATE_FIELDS \
struct uv_req_s getadddrinfo_req; \
uv_getaddrinfo_cb getaddrinfo_cb; \
void* alloc; \
wchar_t* node; \
wchar_t* service; \
struct addrinfoW* hints; \
struct addrinfoW* res; \
int retcode;
#define UV_PROCESS_PRIVATE_FIELDS \
struct uv_process_exit_s { \
UV_REQ_FIELDS \
} exit_req; \
struct uv_process_close_s { \
UV_REQ_FIELDS \
} close_req; \
HANDLE child_stdio[3]; \
int exit_signal; \
DWORD spawn_errno; \
HANDLE wait_handle; \
HANDLE process_handle; \
HANDLE close_handle;
#define UV_FS_PRIVATE_FIELDS \
int flags; \
int last_error; \
struct _stati64 stat; \
void* arg0; \
union { \
struct { \
void* arg1; \
void* arg2; \
void* arg3; \
}; \
struct { \
ssize_t arg4; \
ssize_t arg5; \
}; \
};
#define UV_WORK_PRIVATE_FIELDS \
#define UV_FS_EVENT_PRIVATE_FIELDS \
struct uv_fs_event_req_s { \
UV_REQ_FIELDS \
} req; \
HANDLE dir_handle; \
int req_pending; \
uv_fs_event_cb cb; \
wchar_t* filew; \
int is_path_dir; \
char* buffer;
#define UV_TTY_PRIVATE_FIELDS /* empty */
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
size_t utf16Size);

View File

@ -1,130 +0,0 @@
/* 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_WINNT
# define _WIN32_WINNT 0x0501
#endif
#include <stdint.h>
#include <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <windows.h>
#include "tree.h"
/**
* It should be possible to cast uv_buf_t[] to WSABUF[]
* see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx
*/
typedef struct uv_buf_t {
ULONG len;
char* base;
} uv_buf_t;
#define UV_REQ_PRIVATE_FIELDS \
union { \
/* Used by I/O operations */ \
struct { \
OVERLAPPED overlapped; \
size_t queued_bytes; \
}; \
}; \
int flags; \
uv_err_t error; \
struct uv_req_s* next_req;
#define UV_STREAM_PRIVATE_FIELDS \
uv_alloc_cb alloc_cb; \
uv_read_cb read_cb; \
struct uv_req_s read_req; \
#define uv_tcp_connection_fields \
unsigned int write_reqs_pending; \
uv_req_t* shutdown_req;
#define uv_tcp_server_fields \
uv_connection_cb connection_cb; \
SOCKET accept_socket; \
struct uv_req_s accept_req; \
char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32];
#define UV_TCP_PRIVATE_FIELDS \
unsigned int reqs_pending; \
union { \
SOCKET socket; \
HANDLE handle; \
}; \
union { \
struct { uv_tcp_connection_fields }; \
struct { uv_tcp_server_fields }; \
};
#define UV_TIMER_PRIVATE_FIELDS \
RB_ENTRY(uv_timer_s) tree_entry; \
int64_t due; \
int64_t repeat; \
uv_timer_cb timer_cb;
#define UV_ASYNC_PRIVATE_FIELDS \
struct uv_req_s async_req; \
/* char to avoid alignment issues */ \
char volatile async_sent;
#define UV_PREPARE_PRIVATE_FIELDS \
uv_prepare_t* prepare_prev; \
uv_prepare_t* prepare_next; \
uv_prepare_cb prepare_cb;
#define UV_CHECK_PRIVATE_FIELDS \
uv_check_t* check_prev; \
uv_check_t* check_next; \
uv_check_cb check_cb;
#define UV_IDLE_PRIVATE_FIELDS \
uv_idle_t* idle_prev; \
uv_idle_t* idle_next; \
uv_idle_cb idle_cb;
#define UV_HANDLE_PRIVATE_FIELDS \
uv_handle_t* endgame_next; \
unsigned int flags; \
uv_err_t error;
#define UV_ARES_TASK_PRIVATE_FIELDS \
struct uv_req_s ares_req; \
SOCKET sock; \
HANDLE h_wait; \
WSAEVENT h_event; \
HANDLE h_close_event;
#define UV_GETADDRINFO_PRIVATE_FIELDS \
struct uv_req_s getadddrinfo_req; \
uv_getaddrinfo_cb getaddrinfo_cb; \
void* alloc; \
wchar_t* node; \
wchar_t* service; \
struct addrinfoW* hints; \
struct addrinfoW* res; \
int retcode;
int uv_utf16_to_utf8(wchar_t* utf16Buffer, size_t utf16Size, char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer, size_t utf16Size);

File diff suppressed because it is too large Load Diff

View File

@ -1,179 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\ares\ares__close_sockets.c" />
<ClCompile Include="..\src\ares\ares__get_hostent.c" />
<ClCompile Include="..\src\ares\ares__read_line.c" />
<ClCompile Include="..\src\ares\ares__timeval.c" />
<ClCompile Include="..\src\ares\ares_cancel.c" />
<ClCompile Include="..\src\ares\ares_data.c" />
<ClCompile Include="..\src\ares\ares_destroy.c" />
<ClCompile Include="..\src\ares\ares_expand_name.c" />
<ClCompile Include="..\src\ares\ares_expand_string.c" />
<ClCompile Include="..\src\ares\ares_fds.c" />
<ClCompile Include="..\src\ares\ares_free_hostent.c" />
<ClCompile Include="..\src\ares\ares_free_string.c" />
<ClCompile Include="..\src\ares\ares_gethostbyaddr.c" />
<ClCompile Include="..\src\ares\ares_gethostbyname.c" />
<ClCompile Include="..\src\ares\ares_getnameinfo.c" />
<ClCompile Include="..\src\ares\ares_getsock.c" />
<ClCompile Include="..\src\ares\ares_init.c" />
<ClCompile Include="..\src\ares\ares_library_init.c" />
<ClCompile Include="..\src\ares\ares_llist.c" />
<ClCompile Include="..\src\ares\ares_mkquery.c" />
<ClCompile Include="..\src\ares\ares_nowarn.c" />
<ClCompile Include="..\src\ares\ares_options.c" />
<ClCompile Include="..\src\ares\ares_parse_a_reply.c" />
<ClCompile Include="..\src\ares\ares_parse_aaaa_reply.c" />
<ClCompile Include="..\src\ares\ares_parse_mx_reply.c" />
<ClCompile Include="..\src\ares\ares_parse_ns_reply.c" />
<ClCompile Include="..\src\ares\ares_parse_ptr_reply.c" />
<ClCompile Include="..\src\ares\ares_parse_srv_reply.c" />
<ClCompile Include="..\src\ares\ares_parse_txt_reply.c" />
<ClCompile Include="..\src\ares\ares_process.c" />
<ClCompile Include="..\src\ares\ares_query.c" />
<ClCompile Include="..\src\ares\ares_search.c" />
<ClCompile Include="..\src\ares\ares_send.c" />
<ClCompile Include="..\src\ares\ares_strcasecmp.c" />
<ClCompile Include="..\src\ares\ares_strdup.c" />
<ClCompile Include="..\src\ares\ares_strerror.c" />
<ClCompile Include="..\src\ares\ares_timeout.c" />
<ClCompile Include="..\src\ares\ares_version.c" />
<ClCompile Include="..\src\ares\ares_writev.c" />
<ClCompile Include="..\src\ares\bitncmp.c" />
<ClCompile Include="..\src\ares\inet_net_pton.c" />
<ClCompile Include="..\src\ares\inet_ntop.c" />
<ClCompile Include="..\src\ares\windows_port.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\ares.h" />
<ClInclude Include="..\include\ares_version.h" />
<ClInclude Include="..\src\ares\ares_data.h" />
<ClInclude Include="..\src\ares\ares_dns.h" />
<ClInclude Include="..\src\ares\ares_iphlpapi.h" />
<ClInclude Include="..\src\ares\ares_ipv6.h" />
<ClInclude Include="..\src\ares\ares_library_init.h" />
<ClInclude Include="..\src\ares\ares_llist.h" />
<ClInclude Include="..\src\ares\ares_nowarn.h" />
<ClInclude Include="..\src\ares\ares_private.h" />
<ClInclude Include="..\src\ares\ares_rules.h" />
<ClInclude Include="..\src\ares\ares_setup.h" />
<ClInclude Include="..\src\ares\ares_strcasecmp.h" />
<ClInclude Include="..\src\ares\ares_strdup.h" />
<ClInclude Include="..\src\ares\ares_version.h" />
<ClInclude Include="..\src\ares\ares_writev.h" />
<ClInclude Include="..\src\ares\bitncmp.h" />
<ClInclude Include="..\src\ares\config_win32\ares_config.h" />
<ClInclude Include="..\src\ares\inet_net_pton.h" />
<ClInclude Include="..\src\ares\inet_ntop.h" />
<ClInclude Include="..\src\ares\nameser.h" />
<ClInclude Include="..\src\ares\setup_once.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,167 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\test\benchmark-ares.c" />
<ClCompile Include="..\test\benchmark-getaddrinfo.c" />
<ClCompile Include="..\test\benchmark-ping-pongs.c" />
<ClCompile Include="..\test\benchmark-pump.c" />
<ClCompile Include="..\test\benchmark-sizes.c" />
<ClCompile Include="..\test\dns-server.c" />
<ClCompile Include="..\test\echo-server.c" />
<ClCompile Include="..\test\run-benchmarks.c" />
<ClCompile Include="..\test\runner-win.c" />
<ClCompile Include="..\test\runner.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\test\benchmark-list.h" />
<ClInclude Include="..\test\runner-win.h" />
<ClInclude Include="..\test\runner.h" />
<ClInclude Include="..\test\task.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="libuv.vcxproj">
<Project>{301fe650-cd34-14e5-6b63-42e383fa02bc}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,180 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\test\echo-server.c" />
<ClCompile Include="..\test\test-async.c" />
<ClCompile Include="..\test\test-bind6-error.c" />
<ClCompile Include="..\test\test-delayed-accept.c" />
<ClCompile Include="..\test\test-callback-stack.c" />
<ClCompile Include="..\test\test-connection-fail.c" />
<ClCompile Include="..\test\test-get-currentexe.c" />
<ClCompile Include="..\test\test-fail-always.c" />
<ClCompile Include="..\test\test-gethostbyname.c" />
<ClCompile Include="..\test\test-getaddrinfo.c" />
<ClCompile Include="..\test\test-hrtime.c" />
<ClCompile Include="..\test\test-loop-handles.c" />
<ClCompile Include="..\test\test-pass-always.c" />
<ClCompile Include="..\test\test-ping-pong.c" />
<ClCompile Include="..\test\runner-win.c" />
<ClCompile Include="..\test\runner.c" />
<ClCompile Include="..\test\test-bind-error.c" />
<ClCompile Include="..\test\test-shutdown-eof.c" />
<ClCompile Include="..\test\test-tcp-writealot.c" />
<ClCompile Include="..\test\test-timer-again.c" />
<ClCompile Include="..\test\test-timer.c" />
<ClCompile Include="..\test\run-tests.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\test\test-list.h" />
<ClInclude Include="..\test\runner-win.h" />
<ClInclude Include="..\test\runner.h" />
<ClInclude Include="..\test\task.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="libuv.vcxproj">
<Project>{301fe650-cd34-14e5-6b63-42e383fa02bc}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,56 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libuv", "libuv.vcxproj", "{301FE650-CD34-14E5-6B63-42E383FA02BC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libuv-test", "libuv-test.vcxproj", "{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libuv-benchmark", "libuv-benchmark.vcxproj", "{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "c-ares", "c-ares.vcxproj", "{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Debug|Win32.ActiveCfg = Debug|Win32
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Debug|Win32.Build.0 = Debug|Win32
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Debug|x64.ActiveCfg = Debug|x64
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Debug|x64.Build.0 = Debug|x64
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Release|Win32.ActiveCfg = Release|Win32
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Release|Win32.Build.0 = Release|Win32
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Release|x64.ActiveCfg = Release|x64
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Release|x64.Build.0 = Release|x64
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Debug|Win32.ActiveCfg = Debug|Win32
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Debug|Win32.Build.0 = Debug|Win32
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Debug|x64.ActiveCfg = Debug|x64
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Debug|x64.Build.0 = Debug|x64
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Release|Win32.ActiveCfg = Release|Win32
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Release|Win32.Build.0 = Release|Win32
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Release|x64.ActiveCfg = Release|x64
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Release|x64.Build.0 = Release|x64
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Debug|Win32.ActiveCfg = Debug|Win32
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Debug|Win32.Build.0 = Debug|Win32
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Debug|x64.ActiveCfg = Debug|x64
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Debug|x64.Build.0 = Debug|x64
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Release|Win32.ActiveCfg = Release|Win32
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Release|Win32.Build.0 = Release|Win32
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Release|x64.ActiveCfg = Release|x64
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Release|x64.Build.0 = Release|x64
{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}.Debug|Win32.ActiveCfg = Debug|Win32
{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}.Debug|Win32.Build.0 = Debug|Win32
{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}.Debug|x64.ActiveCfg = Debug|x64
{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}.Debug|x64.Build.0 = Debug|x64
{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}.Release|Win32.ActiveCfg = Release|Win32
{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}.Release|Win32.Build.0 = Release|Win32
{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}.Release|x64.ActiveCfg = Release|x64
{2B6A4644-EBA9-DFB5-AF35-6C56EDF05C7F}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,131 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{301FE650-CD34-14E5-6B63-42E383FA02BC}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="c-ares.vcxproj">
<Project>{2b6a4644-eba9-dfb5-af35-6c56edf05c7f}</Project>
<Private>true</Private>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\uv-common.c" />
<ClCompile Include="..\src\uv-win.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\ares.h" />
<ClInclude Include="..\include\ares_version.h" />
<ClInclude Include="..\include\tree.h" />
<ClInclude Include="..\include\uv-win.h" />
<ClInclude Include="..\include\uv.h" />
<ClInclude Include="..\src\uv-common.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -238,6 +238,8 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
for (i = 0; i < naddrs; i++) for (i = 0; i < naddrs; i++)
hostent->h_addr_list[i] = (char *) &addrs[i]; hostent->h_addr_list[i] = (char *) &addrs[i];
hostent->h_addr_list[naddrs] = NULL; hostent->h_addr_list[naddrs] = NULL;
if (!naddrs && addrs)
free(addrs);
*host = hostent; *host = hostent;
return ARES_SUCCESS; return ARES_SUCCESS;
} }

View File

@ -0,0 +1,510 @@
/* ares_config.h. Generated from ares_config.h.in by configure. */
/* ares_config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* define this if ares is built for a big endian system */
/* #undef ARES_BIG_ENDIAN */
/* when building as static part of libcurl */
/* #undef BUILDING_LIBCURL */
/* when building c-ares library */
/* #undef CARES_BUILDING_LIBRARY */
/* when not building a shared library */
/* #undef CARES_STATICLIB */
/* Define to 1 to enable hiding of library internal symbols. */
/* #undef CARES_SYMBOL_HIDING */
/* Definition to make a library symbol externally visible. */
/* #undef CARES_SYMBOL_SCOPE_EXTERN */
/* if a /etc/inet dir is being used */
/* #undef ETC_INET */
/* Define to the type qualifier of arg 1 for getnameinfo. */
#define GETNAMEINFO_QUAL_ARG1 const
/* Define to the type of arg 1 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
/* Define to the type of arg 2 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG2 socklen_t
/* Define to the type of args 4 and 6 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG46 size_t
/* Define to the type of arg 7 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG7 int
/* Specifies the number of arguments to getservbyport_r */
#define GETSERVBYPORT_R_ARGS 4
/* Specifies the size of the buffer to pass to getservbyport_r */
#define GETSERVBYPORT_R_BUFSIZE sizeof(struct servent_data)
/* Define to 1 if you have AF_INET6. */
#define HAVE_AF_INET6 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
/* #undef HAVE_ARPA_NAMESER_COMPAT_H */
/* Define to 1 if you have the <arpa/nameser.h> header file. */
#define HAVE_ARPA_NAMESER_H 1
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if you have the `bitncmp' function. */
/* #undef HAVE_BITNCMP */
/* Define to 1 if bool is an available type. */
#define HAVE_BOOL_T 1
/* Define to 1 if you have the clock_gettime function and monotonic timer. */
#define HAVE_CLOCK_GETTIME_MONOTONIC 1
/* Define to 1 if you have the closesocket function. */
/* #undef HAVE_CLOSESOCKET */
/* Define to 1 if you have the CloseSocket camel case function. */
/* #undef HAVE_CLOSESOCKET_CAMEL */
/* Define to 1 if you have the connect function. */
#define HAVE_CONNECT 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the fcntl function. */
#define HAVE_FCNTL 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
#define HAVE_FCNTL_O_NONBLOCK 1
/* Define to 1 if you have the freeaddrinfo function. */
#define HAVE_FREEADDRINFO 1
/* Define to 1 if you have a working getaddrinfo function. */
#define HAVE_GETADDRINFO 1
/* Define to 1 if the getaddrinfo function is threadsafe. */
/* #undef HAVE_GETADDRINFO_THREADSAFE */
/* Define to 1 if you have the gethostbyaddr function. */
#define HAVE_GETHOSTBYADDR 1
/* Define to 1 if you have the gethostbyname function. */
#define HAVE_GETHOSTBYNAME 1
/* Define to 1 if you have the gethostname function. */
#define HAVE_GETHOSTNAME 1
/* Define to 1 if you have the getnameinfo function. */
#define HAVE_GETNAMEINFO 1
/* Define to 1 if you have the getservbyport_r function. */
#define HAVE_GETSERVBYPORT_R 1
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the `if_indextoname' function. */
#define HAVE_IF_INDEXTONAME 1
/* Define to 1 if you have the `inet_net_pton' function. */
#define HAVE_INET_NET_PTON 1
/* Define to 1 if inet_net_pton supports IPv6. */
/* #undef HAVE_INET_NET_PTON_IPV6 */
/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
#define HAVE_INET_NTOP 1
/* Define to 1 if you have a IPv6 capable working inet_pton function. */
#define HAVE_INET_PTON 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the ioctl function. */
#define HAVE_IOCTL 1
/* Define to 1 if you have the ioctlsocket function. */
/* #undef HAVE_IOCTLSOCKET */
/* Define to 1 if you have the IoctlSocket camel case function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL */
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
*/
/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
/* #undef HAVE_IOCTLSOCKET_FIONBIO */
/* Define to 1 if you have a working ioctl FIONBIO function. */
#define HAVE_IOCTL_FIONBIO 1
/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
#define HAVE_IOCTL_SIOCGIFADDR 1
/* Define to 1 if you have the `resolve' library (-lresolve). */
/* #undef HAVE_LIBRESOLVE */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* if your compiler supports LL */
#define HAVE_LL 1
/* Define to 1 if the compiler supports the 'long long' data type. */
#define HAVE_LONGLONG 1
/* Define to 1 if you have the malloc.h header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the memory.h header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the MSG_NOSIGNAL flag. */
/* #undef HAVE_MSG_NOSIGNAL */
/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#define HAVE_NETINET_TCP_H 1
/* Define to 1 if you have the <net/if.h> header file. */
#define HAVE_NET_IF_H 1
/* Define to 1 if you have PF_INET6. */
#define HAVE_PF_INET6 1
/* Define to 1 if you have the recv function. */
#define HAVE_RECV 1
/* Define to 1 if you have the recvfrom function. */
#define HAVE_RECVFROM 1
/* Define to 1 if you have the send function. */
#define HAVE_SEND 1
/* Define to 1 if you have the setsockopt function. */
#define HAVE_SETSOCKOPT 1
/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if sig_atomic_t is an available typedef. */
#define HAVE_SIG_ATOMIC_T 1
/* Define to 1 if sig_atomic_t is already defined as volatile. */
/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
/* Define to 1 if you have the socket function. */
#define HAVE_SOCKET 1
/* Define to 1 if you have the <socket.h> header file. */
/* #undef HAVE_SOCKET_H */
/* Define to 1 if you have the <stdbool.h> header file. */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the strcasecmp function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the strcmpi function. */
/* #undef HAVE_STRCMPI */
/* Define to 1 if you have the strdup function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the stricmp function. */
/* #undef HAVE_STRICMP */
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the strncasecmp function. */
#define HAVE_STRNCASECMP 1
/* Define to 1 if you have the strncmpi function. */
/* #undef HAVE_STRNCMPI */
/* Define to 1 if you have the strnicmp function. */
/* #undef HAVE_STRNICMP */
/* Define to 1 if you have the <stropts.h> header file. */
/* #undef HAVE_STROPTS_H */
/* Define to 1 if you have struct addrinfo. */
#define HAVE_STRUCT_ADDRINFO 1
/* Define to 1 if you have struct in6_addr. */
#define HAVE_STRUCT_IN6_ADDR 1
/* Define to 1 if you have struct sockaddr_in6. */
#define HAVE_STRUCT_SOCKADDR_IN6 1
/* if struct sockaddr_storage is defined */
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
/* Define to 1 if you have the timeval struct. */
#define HAVE_STRUCT_TIMEVAL 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the windows.h header file. */
/* #undef HAVE_WINDOWS_H */
/* Define to 1 if you have the winsock2.h header file. */
/* #undef HAVE_WINSOCK2_H */
/* Define to 1 if you have the winsock.h header file. */
/* #undef HAVE_WINSOCK_H */
/* Define to 1 if you have the writev function. */
#define HAVE_WRITEV 1
/* Define to 1 if you have the ws2tcpip.h header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to 1 if you are building a native Windows target. */
/* #undef NATIVE_WINDOWS */
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
/* #undef NEED_MALLOC_H */
/* Define to 1 if you need the memory.h header file even with stdlib.h */
/* #undef NEED_MEMORY_H */
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
/* #undef NEED_REENTRANT */
/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
/* #undef NEED_THREAD_SAFE */
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */
/* cpu-machine-OS */
#define OS "i386-unknown-openbsd4.7"
/* Name of package */
#define PACKAGE "c-ares"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares"
/* Define to the full name of this package. */
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "c-ares 1.7.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.7.1"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
/* Define to the type of arg 1 for recvfrom. */
#define RECVFROM_TYPE_ARG1 int
/* Define to the type pointed by arg 2 for recvfrom. */
#define RECVFROM_TYPE_ARG2 void
/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
#define RECVFROM_TYPE_ARG2_IS_VOID 1
/* Define to the type of arg 3 for recvfrom. */
#define RECVFROM_TYPE_ARG3 size_t
/* Define to the type of arg 4 for recvfrom. */
#define RECVFROM_TYPE_ARG4 int
/* Define to the type pointed by arg 5 for recvfrom. */
#define RECVFROM_TYPE_ARG5 struct sockaddr
/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
/* Define to the type pointed by arg 6 for recvfrom. */
#define RECVFROM_TYPE_ARG6 socklen_t
/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
/* Define to the function return type for recvfrom. */
#define RECVFROM_TYPE_RETV int
/* Define to the type of arg 1 for recv. */
#define RECV_TYPE_ARG1 int
/* Define to the type of arg 2 for recv. */
#define RECV_TYPE_ARG2 void *
/* Define to the type of arg 3 for recv. */
#define RECV_TYPE_ARG3 size_t
/* Define to the type of arg 4 for recv. */
#define RECV_TYPE_ARG4 int
/* Define to the function return type for recv. */
#define RECV_TYPE_RETV int
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to the type qualifier of arg 2 for send. */
#define SEND_QUAL_ARG2 const
/* Define to the type of arg 1 for send. */
#define SEND_TYPE_ARG1 int
/* Define to the type of arg 2 for send. */
#define SEND_TYPE_ARG2 void *
/* Define to the type of arg 3 for send. */
#define SEND_TYPE_ARG3 size_t
/* Define to the type of arg 4 for send. */
#define SEND_TYPE_ARG4 int
/* Define to the function return type for send. */
#define SEND_TYPE_RETV int
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG 4
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4
/* The size of `struct in6_addr', as computed by sizeof. */
#define SIZEOF_STRUCT_IN6_ADDR 16
/* The size of `struct in_addr', as computed by sizeof. */
#define SIZEOF_STRUCT_IN_ADDR 4
/* The size of `time_t', as computed by sizeof. */
#define SIZEOF_TIME_T 4
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Define to disable non-blocking sockets. */
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
#define VERSION "1.7.1"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to 1 if OS is AIX. */
#ifndef _ALL_SOURCE
/* # undef _ALL_SOURCE */
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Type to use in place of in_addr_t when system does not provide it. */
/* #undef in_addr_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* the signed version of size_t */
/* #undef ssize_t */

View File

@ -18,6 +18,7 @@
*/ */
#ifdef HAVE_INET_NTOP #ifdef HAVE_INET_NTOP
#include <arpa/inet.h>
#define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z) #define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z)
#else #else
const char *ares_inet_ntop(int af, const void *src, char *dst, size_t size); const char *ares_inet_ntop(int af, const void *src, char *dst, size_t size);

View File

@ -1,35 +0,0 @@
Revision history for libeio
TODO: maybe add mincore support? available on at least darwin, solaris, linux, freebsd
TODO: openbsd requites stdint.h for intptr_t - why posix?
1.0
- readdir: correctly handle malloc failures.
- readdir: new flags argument, can return inode
and possibly filetype, can sort in various ways.
- readdir: stop immediately when cancelled, do
not continue reading the directory.
- fix return value of eio_sendfile_sync.
- include sys/mman.h for msync.
- added EIO_STACKSIZE.
- added msync, mtouch support (untested).
- added sync_file_range (untested).
- fixed custom support.
- use a more robust feed-add detection method.
- "outbundled" from IO::AIO.
- eio_set_max_polltime did not properly convert time to ticks.
- tentatively support darwin in sendfile.
- fix freebsd/darwin sendfile.
- also use sendfile emulation for ENOTSUP and EOPNOTSUPP
error codes.
- add OS-independent EIO_MT_* and EIO_MS_* flag enums.
- add eio_statvfs/eio_fstatvfs.
- add eio_mlock/eio_mlockall and OS-independent MCL_* flag enums.
- no longer set errno to 0 before making syscalls, this only lures
people into the trap of believing errno shows success or failure.
- "fix" demo.c so that it works as non-root.
- suppoert utimes seperately from futimes, as some systems have
utimes but not futimes.
- use _POSIX_MEMLOCK_RANGE for mlock.
- do not (errornously) overwrite CFLAGS in configure.ac.

View File

@ -1,5 +0,0 @@
libtoolize
aclocal
automake --add-missing
autoconf
autoheader

View File

@ -1,303 +0,0 @@
=head1 NAME
libeio - truly asynchronous POSIX I/O
=head1 SYNOPSIS
#include <eio.h>
=head1 DESCRIPTION
The newest version of this document is also available as an html-formatted
web page you might find easier to navigate when reading it for the first
time: L<http://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.pod>.
Note that this library is a by-product of the C<IO::AIO> perl
module, and many of the subtler points regarding requets lifetime
and so on are only documented in its documentation at the
moment: L<http://pod.tst.eu/http://cvs.schmorp.de/IO-AIO/AIO.pm>.
=head2 FEATURES
This library provides fully asynchronous versions of most POSIX functions
dealign with I/O. Unlike most asynchronous libraries, this not only
includes C<read> and C<write>, but also C<open>, C<stat>, C<unlink> and
similar functions, as well as less rarely ones such as C<mknod>, C<futime>
or C<readlink>.
It also offers wrappers around C<sendfile> (Solaris, Linux, HP-UX and
FreeBSD, with emulation on other platforms) and C<readahead> (Linux, with
emulation elsewhere>).
The goal is to enable you to write fully non-blocking programs. For
example, in a game server, you would not want to freeze for a few seconds
just because the server is running a backup and you happen to call
C<readdir>.
=head2 TIME REPRESENTATION
Libeio represents time as a single floating point number, representing the
(fractional) number of seconds since the (POSIX) epoch (somewhere near
the beginning of 1970, details are complicated, don't ask). This type is
called C<eio_tstamp>, but it is guarenteed to be of type C<double> (or
better), so you can freely use C<double> yourself.
Unlike the name component C<stamp> might indicate, it is also used for
time differences throughout libeio.
=head2 FORK SUPPORT
Calling C<fork ()> is fully supported by this module. It is implemented in these steps:
1. wait till all requests in "execute" state have been handled
(basically requests that are already handed over to the kernel).
2. fork
3. in the parent, continue business as usual, done
4. in the child, destroy all ready and pending requests and free the
memory used by the worker threads. This gives you a fully empty
libeio queue.
=head1 INITIALISATION/INTEGRATION
Before you can call any eio functions you first have to initialise the
library. The library integrates into any event loop, but can also be used
without one, including in polling mode.
You have to provide the necessary glue yourself, however.
=over 4
=item int eio_init (void (*want_poll)(void), void (*done_poll)(void))
This function initialises the library. On success it returns C<0>, on
failure it returns C<-1> and sets C<errno> appropriately.
It accepts two function pointers specifying callbacks as argument, both of
which can be C<0>, in which case the callback isn't called.
=item want_poll callback
The C<want_poll> callback is invoked whenever libeio wants attention (i.e.
it wants to be polled by calling C<eio_poll>). It is "edge-triggered",
that is, it will only be called once when eio wants attention, until all
pending requests have been handled.
This callback is called while locks are being held, so I<you must
not call any libeio functions inside this callback>. That includes
C<eio_poll>. What you should do is notify some other thread, or wake up
your event loop, and then call C<eio_poll>.
=item done_poll callback
This callback is invoked when libeio detects that all pending requests
have been handled. It is "edge-triggered", that is, it will only be
called once after C<want_poll>. To put it differently, C<want_poll> and
C<done_poll> are invoked in pairs: after C<want_poll> you have to call
C<eio_poll ()> until either C<eio_poll> indicates that everything has been
handled or C<done_poll> has been called, which signals the same.
Note that C<eio_poll> might return after C<done_poll> and C<want_poll>
have been called again, so watch out for races in your code.
As with C<want_poll>, this callback is called while lcoks are being held,
so you I<must not call any libeio functions form within this callback>.
=item int eio_poll ()
This function has to be called whenever there are pending requests that
need finishing. You usually call this after C<want_poll> has indicated
that you should do so, but you can also call this function regularly to
poll for new results.
If any request invocation returns a non-zero value, then C<eio_poll ()>
immediately returns with that value as return value.
Otherwise, if all requests could be handled, it returns C<0>. If for some
reason not all requests have been handled, i.e. some are still pending, it
returns C<-1>.
=back
For libev, you would typically use an C<ev_async> watcher: the
C<want_poll> callback would invoke C<ev_async_send> to wake up the event
loop. Inside the callback set for the watcher, one would call C<eio_poll
()> (followed by C<ev_async_send> again if C<eio_poll> indicates that not
all requests have been handled yet). The race is taken care of because
libev resets/rearms the async watcher before calling your callback,
and therefore, before calling C<eio_poll>. This might result in (some)
spurious wake-ups, but is generally harmless.
For most other event loops, you would typically use a pipe - the event
loop should be told to wait for read readyness on the read end. In
C<want_poll> you would write a single byte, in C<done_poll> you would try
to read that byte, and in the callback for the read end, you would call
C<eio_poll>. The race is avoided here because the event loop should invoke
your callback again and again until the byte has been read (as the pipe
read callback does not read it, only C<done_poll>).
=head2 CONFIGURATION
The functions in this section can sometimes be useful, but the default
configuration will do in most case, so you should skip this section on
first reading.
=over 4
=item eio_set_max_poll_time (eio_tstamp nseconds)
This causes C<eio_poll ()> to return after it has detected that it was
running for C<nsecond> seconds or longer (this number can be fractional).
This can be used to limit the amount of time spent handling eio requests,
for example, in interactive programs, you might want to limit this time to
C<0.01> seconds or so.
Note that:
a) libeio doesn't know how long your request callbacks take, so the time
spent in C<eio_poll> is up to one callback invocation longer then this
interval.
b) this is implemented by calling C<gettimeofday> after each request,
which can be costly.
c) at least one request will be handled.
=item eio_set_max_poll_reqs (unsigned int nreqs)
When C<nreqs> is non-zero, then C<eio_poll> will not handle more than
C<nreqs> requests per invocation. This is a less costly way to limit the
amount of work done by C<eio_poll> then setting a time limit.
If you know your callbacks are generally fast, you could use this to
encourage interactiveness in your programs by setting it to C<10>, C<100>
or even C<1000>.
=item eio_set_min_parallel (unsigned int nthreads)
Make sure libeio can handle at least this many requests in parallel. It
might be able handle more.
=item eio_set_max_parallel (unsigned int nthreads)
Set the maximum number of threads that libeio will spawn.
=item eio_set_max_idle (unsigned int nthreads)
Libeio uses threads internally to handle most requests, and will start and stop threads on demand.
This call can be used to limit the number of idle threads (threads without
work to do): libeio will keep some threads idle in preperation for more
requests, but never longer than C<nthreads> threads.
In addition to this, libeio will also stop threads when they are idle for
a few seconds, regardless of this setting.
=item unsigned int eio_nthreads ()
Return the number of worker threads currently running.
=item unsigned int eio_nreqs ()
Return the number of requests currently handled by libeio. This is the
total number of requests that have been submitted to libeio, but not yet
destroyed.
=item unsigned int eio_nready ()
Returns the number of ready requests, i.e. requests that have been
submitted but have not yet entered the execution phase.
=item unsigned int eio_npending ()
Returns the number of pending requests, i.e. requests that have been
executed and have results, but have not been finished yet by a call to
C<eio_poll>).
=back
=head1 ANATOMY OF AN EIO REQUEST
#TODO
=head1 HIGH LEVEL REQUEST API
#TODO
=back
=head1 LOW LEVEL REQUEST API
#TODO
=head1 EMBEDDING
Libeio can be embedded directly into programs. This functionality is not
documented and not (yet) officially supported.
Note that, when including C<libeio.m4>, you are responsible for defining
the compilation environment (C<_LARGEFILE_SOURCE>, C<_GNU_SOURCE> etc.).
If you need to know how, check the C<IO::AIO> perl module, which does
exactly that.
=head1 COMPILETIME CONFIGURATION
These symbols, if used, must be defined when compiling F<eio.c>.
=over 4
=item EIO_STACKSIZE
This symbol governs the stack size for each eio thread. Libeio itself
was written to use very little stackspace, but when using C<EIO_CUSTOM>
requests, you might want to increase this.
If this symbol is undefined (the default) then libeio will use its default
stack size (C<sizeof (long) * 4096> currently). If it is defined, but
C<0>, then the default operating system stack size will be used. In all
other cases, the value must be an expression that evaluates to the desired
stack size.
=back
=head1 PORTABILITY REQUIREMENTS
In addition to a working ISO-C implementation, libeio relies on a few
additional extensions:
=over 4
=item POSIX threads
To be portable, this module uses threads, specifically, the POSIX threads
library must be available (and working, which partially excludes many xBSD
systems, where C<fork ()> is buggy).
=item POSIX-compatible filesystem API
This is actually a harder portability requirement: The libeio API is quite
demanding regarding POSIX API calls (symlinks, user/group management
etc.).
=item C<double> must hold a time value in seconds with enough accuracy
The type C<double> is used to represent timestamps. It is required to
have at least 51 bits of mantissa (and 9 bits of exponent), which is good
enough for at least into the year 4000. This requirement is fulfilled by
implementations implementing IEEE 754 (basically all existing ones).
=back
If you know of other additional requirements drop me a note.
=head1 AUTHOR
Marc Lehmann <libeio@schmorp.de>.

View File

@ -0,0 +1,185 @@
/* 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 "internal.h"
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
/*
* This is called once per second by loop->timer. It is used to
* constantly callback into c-ares for possibly processing timeouts.
*/
static void uv__ares_timeout(struct ev_loop* ev, struct ev_timer* watcher,
int revents) {
uv_loop_t* loop = ev_userdata(ev);
assert(ev == loop->ev);
assert((uv_loop_t*)watcher->data == loop);
assert(watcher == &loop->timer);
assert(revents == EV_TIMER);
assert(!uv_ares_handles_empty(loop));
ares_process_fd(loop->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
}
static void uv__ares_io(struct ev_loop* ev, struct ev_io* watcher,
int revents) {
uv_loop_t* loop = ev_userdata(ev);
assert(ev == loop->ev);
/* Reset the idle timer */
ev_timer_again(ev, &loop->timer);
/* Process DNS responses */
ares_process_fd(loop->channel,
revents & EV_READ ? watcher->fd : ARES_SOCKET_BAD,
revents & EV_WRITE ? watcher->fd : ARES_SOCKET_BAD);
}
/* Allocates and returns a new uv_ares_task_t */
static uv_ares_task_t* uv__ares_task_create(int fd) {
uv_ares_task_t* h = malloc(sizeof(uv_ares_task_t));
if (h == NULL) {
uv_fatal_error(ENOMEM, "malloc");
}
h->sock = fd;
ev_io_init(&h->read_watcher, uv__ares_io, fd, EV_READ);
ev_io_init(&h->write_watcher, uv__ares_io, fd, EV_WRITE);
h->read_watcher.data = h;
h->write_watcher.data = h;
return h;
}
/* Callback from ares when socket operation is started */
static void uv__ares_sockstate_cb(void* data, ares_socket_t sock,
int read, int write) {
uv_loop_t* loop = data;
uv_ares_task_t* h;
assert((uv_loop_t*)loop->timer.data == loop);
h = uv_find_ares_handle(loop, sock);
if (read || write) {
if (!h) {
/* New socket */
/* If this is the first socket then start the timer. */
if (!ev_is_active(&loop->timer)) {
assert(uv_ares_handles_empty(loop));
ev_timer_again(loop->ev, &loop->timer);
}
h = uv__ares_task_create(sock);
uv_add_ares_handle(loop, h);
}
if (read) {
ev_io_start(loop->ev, &h->read_watcher);
} else {
ev_io_stop(loop->ev, &h->read_watcher);
}
if (write) {
ev_io_start(loop->ev, &h->write_watcher);
} else {
ev_io_stop(loop->ev, &h->write_watcher);
}
} else {
/*
* read == 0 and write == 0 this is c-ares's way of notifying us that
* the socket is now closed. We must free the data associated with
* socket.
*/
assert(h && "When an ares socket is closed we should have a handle for it");
ev_io_stop(loop->ev, &h->read_watcher);
ev_io_stop(loop->ev, &h->write_watcher);
uv_remove_ares_handle(h);
free(h);
if (uv_ares_handles_empty(loop)) {
ev_timer_stop(loop->ev, &loop->timer);
}
}
}
/* c-ares integration initialize and terminate */
/* TODO: share this with windows? */
int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr,
struct ares_options *options, int optmask) {
int rc;
/* only allow single init at a time */
if (loop->channel != NULL) {
uv_err_new_artificial(loop, UV_EALREADY);
return -1;
}
/* set our callback as an option */
options->sock_state_cb = uv__ares_sockstate_cb;
options->sock_state_cb_data = loop;
optmask |= ARES_OPT_SOCK_STATE_CB;
/* We do the call to ares_init_option for caller. */
rc = ares_init_options(channelptr, options, optmask);
/* if success, save channel */
if (rc == ARES_SUCCESS) {
loop->channel = *channelptr;
}
/*
* Initialize the timeout timer. The timer won't be started until the
* first socket is opened.
*/
ev_timer_init(&loop->timer, uv__ares_timeout, 1., 1.);
loop->timer.data = loop;
return rc;
}
/* TODO share this with windows? */
void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
/* only allow destroy if did init */
if (loop->channel) {
ev_timer_stop(loop->ev, &loop->timer);
ares_destroy(channel);
loop->channel = NULL;
}
}

View File

@ -0,0 +1,799 @@
/* 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 "unix/internal.h"
#include <stddef.h> /* NULL */
#include <stdio.h> /* printf */
#include <stdlib.h>
#include <string.h> /* strerror */
#include <errno.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <limits.h> /* PATH_MAX */
#include <sys/uio.h> /* writev */
#ifdef __sun
# include <sys/types.h>
# include <sys/wait.h>
#endif
#if defined(__APPLE__)
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
#endif
#if defined(__FreeBSD__)
#include <sys/sysctl.h>
#include <sys/wait.h>
#endif
static uv_loop_t default_loop_struct;
static uv_loop_t* default_loop_ptr;
void uv__next(EV_P_ ev_idle* watcher, int revents);
static void uv__finish_close(uv_handle_t* handle);
#ifndef __GNUC__
#define __attribute__(a)
#endif
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
uv_udp_t* udp;
uv_async_t* async;
uv_timer_t* timer;
uv_stream_t* stream;
uv_process_t* process;
handle->close_cb = close_cb;
switch (handle->type) {
case UV_NAMED_PIPE:
uv_pipe_cleanup((uv_pipe_t*)handle);
/* Fall through. */
case UV_TTY:
case UV_TCP:
stream = (uv_stream_t*)handle;
uv_read_stop(stream);
ev_io_stop(stream->loop->ev, &stream->write_watcher);
uv__close(stream->fd);
stream->fd = -1;
if (stream->accepted_fd >= 0) {
uv__close(stream->accepted_fd);
stream->accepted_fd = -1;
}
assert(!ev_is_active(&stream->read_watcher));
assert(!ev_is_active(&stream->write_watcher));
break;
case UV_UDP:
udp = (uv_udp_t*)handle;
uv__udp_watcher_stop(udp, &udp->read_watcher);
uv__udp_watcher_stop(udp, &udp->write_watcher);
uv__close(udp->fd);
udp->fd = -1;
break;
case UV_PREPARE:
uv_prepare_stop((uv_prepare_t*) handle);
break;
case UV_CHECK:
uv_check_stop((uv_check_t*) handle);
break;
case UV_IDLE:
uv_idle_stop((uv_idle_t*) handle);
break;
case UV_ASYNC:
async = (uv_async_t*)handle;
ev_async_stop(async->loop->ev, &async->async_watcher);
ev_ref(async->loop->ev);
break;
case UV_TIMER:
timer = (uv_timer_t*)handle;
if (ev_is_active(&timer->timer_watcher)) {
ev_ref(timer->loop->ev);
}
ev_timer_stop(timer->loop->ev, &timer->timer_watcher);
break;
case UV_PROCESS:
process = (uv_process_t*)handle;
ev_child_stop(process->loop->ev, &process->child_watcher);
break;
case UV_FS_EVENT:
uv__fs_event_destroy((uv_fs_event_t*)handle);
break;
default:
assert(0);
}
handle->flags |= UV_CLOSING;
/* This is used to call the on_close callback in the next loop. */
ev_idle_start(handle->loop->ev, &handle->next_watcher);
ev_feed_event(handle->loop->ev, &handle->next_watcher, EV_IDLE);
assert(ev_is_pending(&handle->next_watcher));
}
uv_loop_t* uv_loop_new() {
uv_loop_t* loop = calloc(1, sizeof(uv_loop_t));
loop->ev = ev_loop_new(0);
ev_set_userdata(loop->ev, loop);
return loop;
}
void uv_loop_delete(uv_loop_t* loop) {
uv_ares_destroy(loop, loop->channel);
ev_loop_destroy(loop->ev);
free(loop);
}
uv_loop_t* uv_default_loop() {
if (!default_loop_ptr) {
default_loop_ptr = &default_loop_struct;
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
default_loop_struct.ev = ev_default_loop(EVBACKEND_KQUEUE);
#else
default_loop_struct.ev = ev_default_loop(EVFLAG_AUTO);
#endif
ev_set_userdata(default_loop_struct.ev, default_loop_ptr);
}
assert(default_loop_ptr->ev == EV_DEFAULT_UC);
return default_loop_ptr;
}
int uv_run(uv_loop_t* loop) {
ev_run(loop->ev, 0);
return 0;
}
void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle,
uv_handle_type type) {
loop->counters.handle_init++;
handle->loop = loop;
handle->type = type;
handle->flags = 0;
ev_init(&handle->next_watcher, uv__next);
handle->next_watcher.data = handle;
/* Ref the loop until this handle is closed. See uv__finish_close. */
ev_ref(loop->ev);
}
void uv__finish_close(uv_handle_t* handle) {
uv_loop_t* loop = handle->loop;
assert(handle->flags & UV_CLOSING);
assert(!(handle->flags & UV_CLOSED));
handle->flags |= UV_CLOSED;
switch (handle->type) {
case UV_PREPARE:
assert(!ev_is_active(&((uv_prepare_t*)handle)->prepare_watcher));
break;
case UV_CHECK:
assert(!ev_is_active(&((uv_check_t*)handle)->check_watcher));
break;
case UV_IDLE:
assert(!ev_is_active(&((uv_idle_t*)handle)->idle_watcher));
break;
case UV_ASYNC:
assert(!ev_is_active(&((uv_async_t*)handle)->async_watcher));
break;
case UV_TIMER:
assert(!ev_is_active(&((uv_timer_t*)handle)->timer_watcher));
break;
case UV_NAMED_PIPE:
case UV_TCP:
case UV_TTY:
assert(!ev_is_active(&((uv_stream_t*)handle)->read_watcher));
assert(!ev_is_active(&((uv_stream_t*)handle)->write_watcher));
assert(((uv_stream_t*)handle)->fd == -1);
uv__stream_destroy((uv_stream_t*)handle);
break;
case UV_UDP:
assert(!ev_is_active(&((uv_udp_t*)handle)->read_watcher));
assert(!ev_is_active(&((uv_udp_t*)handle)->write_watcher));
assert(((uv_udp_t*)handle)->fd == -1);
uv__udp_destroy((uv_udp_t*)handle);
break;
case UV_PROCESS:
assert(!ev_is_active(&((uv_process_t*)handle)->child_watcher));
break;
case UV_FS_EVENT:
break;
default:
assert(0);
break;
}
ev_idle_stop(loop->ev, &handle->next_watcher);
if (handle->close_cb) {
handle->close_cb(handle);
}
ev_unref(loop->ev);
}
void uv__next(EV_P_ ev_idle* watcher, int revents) {
uv_handle_t* handle = watcher->data;
assert(watcher == &handle->next_watcher);
assert(revents == EV_IDLE);
/* For now this function is only to handle the closing event, but we might
* put more stuff here later.
*/
assert(handle->flags & UV_CLOSING);
uv__finish_close(handle);
}
void uv_ref(uv_loop_t* loop) {
ev_ref(loop->ev);
}
void uv_unref(uv_loop_t* loop) {
ev_unref(loop->ev);
}
void uv_update_time(uv_loop_t* loop) {
ev_now_update(loop->ev);
}
int64_t uv_now(uv_loop_t* loop) {
return (int64_t)(ev_now(loop->ev) * 1000);
}
void uv__req_init(uv_req_t* req) {
/* loop->counters.req_init++; */
req->type = UV_UNKNOWN_REQ;
}
static void uv__prepare(EV_P_ ev_prepare* w, int revents) {
uv_prepare_t* prepare = w->data;
if (prepare->prepare_cb) {
prepare->prepare_cb(prepare, 0);
}
}
int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) {
uv__handle_init(loop, (uv_handle_t*)prepare, UV_PREPARE);
loop->counters.prepare_init++;
ev_prepare_init(&prepare->prepare_watcher, uv__prepare);
prepare->prepare_watcher.data = prepare;
prepare->prepare_cb = NULL;
return 0;
}
int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) {
int was_active = ev_is_active(&prepare->prepare_watcher);
prepare->prepare_cb = cb;
ev_prepare_start(prepare->loop->ev, &prepare->prepare_watcher);
if (!was_active) {
ev_unref(prepare->loop->ev);
}
return 0;
}
int uv_prepare_stop(uv_prepare_t* prepare) {
int was_active = ev_is_active(&prepare->prepare_watcher);
ev_prepare_stop(prepare->loop->ev, &prepare->prepare_watcher);
if (was_active) {
ev_ref(prepare->loop->ev);
}
return 0;
}
static void uv__check(EV_P_ ev_check* w, int revents) {
uv_check_t* check = w->data;
if (check->check_cb) {
check->check_cb(check, 0);
}
}
int uv_check_init(uv_loop_t* loop, uv_check_t* check) {
uv__handle_init(loop, (uv_handle_t*)check, UV_CHECK);
loop->counters.check_init++;
ev_check_init(&check->check_watcher, uv__check);
check->check_watcher.data = check;
check->check_cb = NULL;
return 0;
}
int uv_check_start(uv_check_t* check, uv_check_cb cb) {
int was_active = ev_is_active(&check->check_watcher);
check->check_cb = cb;
ev_check_start(check->loop->ev, &check->check_watcher);
if (!was_active) {
ev_unref(check->loop->ev);
}
return 0;
}
int uv_check_stop(uv_check_t* check) {
int was_active = ev_is_active(&check->check_watcher);
ev_check_stop(check->loop->ev, &check->check_watcher);
if (was_active) {
ev_ref(check->loop->ev);
}
return 0;
}
static void uv__idle(EV_P_ ev_idle* w, int revents) {
uv_idle_t* idle = (uv_idle_t*)(w->data);
if (idle->idle_cb) {
idle->idle_cb(idle, 0);
}
}
int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) {
uv__handle_init(loop, (uv_handle_t*)idle, UV_IDLE);
loop->counters.idle_init++;
ev_idle_init(&idle->idle_watcher, uv__idle);
idle->idle_watcher.data = idle;
idle->idle_cb = NULL;
return 0;
}
int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) {
int was_active = ev_is_active(&idle->idle_watcher);
idle->idle_cb = cb;
ev_idle_start(idle->loop->ev, &idle->idle_watcher);
if (!was_active) {
ev_unref(idle->loop->ev);
}
return 0;
}
int uv_idle_stop(uv_idle_t* idle) {
int was_active = ev_is_active(&idle->idle_watcher);
ev_idle_stop(idle->loop->ev, &idle->idle_watcher);
if (was_active) {
ev_ref(idle->loop->ev);
}
return 0;
}
int uv_is_active(uv_handle_t* handle) {
switch (handle->type) {
case UV_TIMER:
return ev_is_active(&((uv_timer_t*)handle)->timer_watcher);
case UV_PREPARE:
return ev_is_active(&((uv_prepare_t*)handle)->prepare_watcher);
case UV_CHECK:
return ev_is_active(&((uv_check_t*)handle)->check_watcher);
case UV_IDLE:
return ev_is_active(&((uv_idle_t*)handle)->idle_watcher);
default:
return 1;
}
}
static void uv__async(EV_P_ ev_async* w, int revents) {
uv_async_t* async = w->data;
if (async->async_cb) {
async->async_cb(async, 0);
}
}
int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) {
uv__handle_init(loop, (uv_handle_t*)async, UV_ASYNC);
loop->counters.async_init++;
ev_async_init(&async->async_watcher, uv__async);
async->async_watcher.data = async;
async->async_cb = async_cb;
/* Note: This does not have symmetry with the other libev wrappers. */
ev_async_start(loop->ev, &async->async_watcher);
ev_unref(loop->ev);
return 0;
}
int uv_async_send(uv_async_t* async) {
ev_async_send(async->loop->ev, &async->async_watcher);
return 0;
}
static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
uv_timer_t* timer = w->data;
if (!ev_is_active(w)) {
ev_ref(EV_A);
}
if (timer->timer_cb) {
timer->timer_cb(timer, 0);
}
}
int uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) {
uv__handle_init(loop, (uv_handle_t*)timer, UV_TIMER);
loop->counters.timer_init++;
ev_init(&timer->timer_watcher, uv__timer_cb);
timer->timer_watcher.data = timer;
return 0;
}
int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
int64_t repeat) {
if (ev_is_active(&timer->timer_watcher)) {
return -1;
}
timer->timer_cb = cb;
ev_timer_set(&timer->timer_watcher, timeout / 1000.0, repeat / 1000.0);
ev_timer_start(timer->loop->ev, &timer->timer_watcher);
ev_unref(timer->loop->ev);
return 0;
}
int uv_timer_stop(uv_timer_t* timer) {
if (ev_is_active(&timer->timer_watcher)) {
ev_ref(timer->loop->ev);
}
ev_timer_stop(timer->loop->ev, &timer->timer_watcher);
return 0;
}
int uv_timer_again(uv_timer_t* timer) {
if (!ev_is_active(&timer->timer_watcher)) {
uv_err_new(timer->loop, EINVAL);
return -1;
}
ev_timer_again(timer->loop->ev, &timer->timer_watcher);
return 0;
}
void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat) {
assert(timer->type == UV_TIMER);
timer->timer_watcher.repeat = repeat / 1000.0;
}
int64_t uv_timer_get_repeat(uv_timer_t* timer) {
assert(timer->type == UV_TIMER);
return (int64_t)(1000 * timer->timer_watcher.repeat);
}
static int uv_getaddrinfo_done(eio_req* req) {
uv_getaddrinfo_t* handle = req->data;
struct addrinfo *res = handle->res;
handle->res = NULL;
uv_unref(handle->loop);
free(handle->hints);
free(handle->service);
free(handle->hostname);
if (handle->retcode != 0) {
/* TODO how to display gai error strings? */
uv_err_new(handle->loop, handle->retcode);
}
handle->cb(handle, handle->retcode, res);
return 0;
}
static void getaddrinfo_thread_proc(eio_req *req) {
uv_getaddrinfo_t* handle = req->data;
handle->retcode = getaddrinfo(handle->hostname,
handle->service,
handle->hints,
&handle->res);
}
/* stub implementation of uv_getaddrinfo */
int uv_getaddrinfo(uv_loop_t* loop,
uv_getaddrinfo_t* handle,
uv_getaddrinfo_cb cb,
const char* hostname,
const char* service,
const struct addrinfo* hints) {
eio_req* req;
uv_eio_init(loop);
if (handle == NULL || cb == NULL ||
(hostname == NULL && service == NULL)) {
uv_err_new_artificial(loop, UV_EINVAL);
return -1;
}
uv__req_init((uv_req_t*)handle);
handle->type = UV_GETADDRINFO;
handle->loop = loop;
handle->cb = cb;
/* TODO don't alloc so much. */
if (hints) {
handle->hints = malloc(sizeof(struct addrinfo));
memcpy(&handle->hints, hints, sizeof(struct addrinfo));
}
else {
handle->hints = NULL;
}
/* TODO security! check lengths, check return values. */
handle->hostname = hostname ? strdup(hostname) : NULL;
handle->service = service ? strdup(service) : NULL;
handle->res = NULL;
handle->retcode = 0;
/* TODO check handle->hostname == NULL */
/* TODO check handle->service == NULL */
uv_ref(loop);
req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT,
uv_getaddrinfo_done, handle);
assert(req);
assert(req->data == handle);
return 0;
}
void uv_freeaddrinfo(struct addrinfo* ai) {
freeaddrinfo(ai);
}
/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
int uv__socket(int domain, int type, int protocol) {
#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
return socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
#else
int sockfd;
if ((sockfd = socket(domain, type, protocol)) == -1) {
return -1;
}
if (uv__nonblock(sockfd, 1) == -1 || uv__cloexec(sockfd, 1) == -1) {
uv__close(sockfd);
return -1;
}
return sockfd;
#endif
}
int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
int peerfd;
assert(sockfd >= 0);
do {
#if defined(HAVE_ACCEPT4)
peerfd = accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC);
#else
if ((peerfd = accept(sockfd, saddr, &slen)) != -1) {
if (uv__cloexec(peerfd, 1) == -1 || uv__nonblock(peerfd, 1) == -1) {
uv__close(peerfd);
return -1;
}
}
#endif
}
while (peerfd == -1 && errno == EINTR);
return peerfd;
}
int uv__close(int fd) {
int status;
/*
* Retry on EINTR. You may think this is academic but on linux
* and probably other Unices too, close(2) is interruptible.
* Failing to handle EINTR is a common source of fd leaks.
*/
do {
status = close(fd);
}
while (status == -1 && errno == EINTR);
return status;
}
int uv__nonblock(int fd, int set) {
int flags;
if ((flags = fcntl(fd, F_GETFL)) == -1) {
return -1;
}
if (set) {
flags |= O_NONBLOCK;
} else {
flags &= ~O_NONBLOCK;
}
if (fcntl(fd, F_SETFL, flags) == -1) {
return -1;
}
return 0;
}
int uv__cloexec(int fd, int set) {
int flags;
if ((flags = fcntl(fd, F_GETFD)) == -1) {
return -1;
}
if (set) {
flags |= FD_CLOEXEC;
} else {
flags &= ~FD_CLOEXEC;
}
if (fcntl(fd, F_SETFD, flags) == -1) {
return -1;
}
return 0;
}
/* TODO move to uv-common.c? */
size_t uv__strlcpy(char* dst, const char* src, size_t size) {
const char *org;
if (size == 0) {
return 0;
}
org = src;
while (--size && *src) {
*dst++ = *src++;
}
*dst = '\0';
return src - org;
}
uv_stream_t* uv_std_handle(uv_loop_t* loop, uv_std_type type) {
assert(0 && "implement me");
return NULL;
}

View File

@ -20,8 +20,10 @@
#include "uv.h" #include "uv.h"
#include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <errno.h>
#include <time.h> #include <time.h>
#undef NANOSEC #undef NANOSEC
@ -50,3 +52,17 @@ int uv_exepath(char* buffer, size_t* size) {
buffer[*size] = '\0'; buffer[*size] = '\0';
return 0; return 0;
} }
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
uv_err_new(loop, ENOSYS);
return -1;
}
void uv__fs_event_destroy(uv_fs_event_t* handle) {
assert(0 && "implement me");
}

View File

@ -19,11 +19,16 @@
*/ */
#include "uv.h" #include "uv.h"
#include "internal.h"
#include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <errno.h>
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
#include <mach/mach.h> #include <mach/mach.h>
#include <mach/mach_time.h> #include <mach/mach_time.h>
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
uint64_t uv_hrtime() { uint64_t uv_hrtime() {
@ -62,3 +67,17 @@ int uv_exepath(char* buffer, size_t* size) {
*size = strlen(buffer); *size = strlen(buffer);
return 0; return 0;
} }
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
uv_err_new(loop, ENOSYS);
return -1;
}
void uv__fs_event_destroy(uv_fs_event_t* handle) {
assert(0 && "implement me");
}

View File

@ -0,0 +1,63 @@
Revision history for libeio
TODO: maybe add mincore support? available on at least darwin, solaris, linux, freebsd
TODO: openbsd requires stdint.h for intptr_t - why posix?
TODO: make mtouch/readdir maybe others cancellable in-request
TODO: fadvise request
1.0
- fix a deadlock where a wakeup signal could be missed when
a timeout occured at the same time.
- use nonstandard but maybe-working-on-bsd fork technique.
- use fewer time() syscalls when waiting for new requests.
- fix a path-memory-leak in readdir when using the wrappers
(reported by Thomas L. Shinnick).
- support a max_idle value of 0.
- support setting of idle timeout value (eio_set_idle_timeout).
- readdir: correctly handle malloc failures.
- readdir: new flags argument, can return inode
and possibly filetype, can sort in various ways.
- readdir: stop immediately when cancelled, do
not continue reading the directory.
- fix return value of eio_sendfile_sync.
- include sys/mman.h for msync.
- added EIO_STACKSIZE.
- added msync, mtouch support (untested).
- added sync_file_range (untested).
- fixed custom support.
- use a more robust feed-add detection method.
- "outbundled" from IO::AIO.
- eio_set_max_polltime did not properly convert time to ticks.
- tentatively support darwin in sendfile.
- fix freebsd/darwin sendfile.
- also use sendfile emulation for ENOTSUP and EOPNOTSUPP
error codes.
- add OS-independent EIO_MT_* and EIO_MS_* flag enums.
- add eio_statvfs/eio_fstatvfs.
- add eio_mlock/eio_mlockall and OS-independent MCL_* flag enums.
- no longer set errno to 0 before making syscalls, this only lures
people into the trap of believing errno shows success or failure.
- "fix" demo.c so that it works as non-root.
- suppoert utimes seperately from futimes, as some systems have
utimes but not futimes.
- use _POSIX_MEMLOCK_RANGE for mlock.
- do not (errornously) overwrite CFLAGS in configure.ac.
- mknod used int3 for dev_t (§2 bit), not offs (64 bit).
- fix memory corruption in eio_readdirx for the flags
combination EIO_READDIR_STAT_ORDER | EIO_READDIR_DIRS_FIRST.
- port to openbsd (another blatantly broken non-UNIX/POSIX platform).
- fix eio_custom prototype.
- work around a Linux (and likely FreeBSD and other kernels) bug
where sendfile would not transfer all the requested bytes on
large transfers, using a heuristic.
- use libecb, and apply lots of minor space optimisations.
- disable sendfile on darwin, broken as everything else.
- add realpath request and implementation.
- cancelled requests will still invoke their request callbacks.
- add fallocate.
- do not acquire any locks when forking.
- incorporated some mingw32 changes by traviscline.
- added syncfs support, using direct syscall.
- set thread name on linux (ps -L/Hcx, top, gdb).
- remove useless use of volatile variables.

View File

@ -10,6 +10,6 @@ include_HEADERS = eio.h
lib_LTLIBRARIES = libeio.la lib_LTLIBRARIES = libeio.la
libeio_la_SOURCES = eio.c xthread.h config.h libeio_la_SOURCES = eio.c ecb.h xthread.h config.h
libeio_la_LDFLAGS = -version-info $(VERSION_INFO) libeio_la_LDFLAGS = -version-info $(VERSION_INFO)

View File

@ -0,0 +1,3 @@
#!/bin/sh
autoreconf --install --symlink --force

View File

@ -7,6 +7,9 @@
/* fdatasync(2) is available */ /* fdatasync(2) is available */
#define HAVE_FDATASYNC 1 #define HAVE_FDATASYNC 1
/* utimes(2) is available */
#define HAVE_UTIMES 1
/* futimes(2) is available */ /* futimes(2) is available */
#define HAVE_FUTIMES 1 #define HAVE_FUTIMES 1

View File

@ -0,0 +1,141 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* fallocate(2) is available */
/* #undef HAVE_FALLOCATE */
/* fdatasync(2) is available */
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060
#define HAVE_FDATASYNC 1
#else
#define HAVE_FDATASYNC 0
#endif
/* futimes(2) is available */
#define HAVE_FUTIMES 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* posix_fadvise(2) is available */
/* #undef HAVE_POSIX_FADVISE */
/* posix_madvise(2) is available */
#define HAVE_POSIX_MADVISE 1
/* prctl(PR_SET_NAME) is available */
/* #undef HAVE_PRCTL_SET_NAME */
/* pread(2) and pwrite(2) are available */
#define HAVE_PREADWRITE 1
/* readahead(2) is available (linux) */
/* #undef HAVE_READAHEAD */
/* sendfile(2) is available and supported */
#define HAVE_SENDFILE 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* sync_file_range(2) is available */
/* #undef HAVE_SYNC_FILE_RANGE */
/* Define to 1 if you have the <sys/prctl.h> header file. */
/* #undef HAVE_SYS_PRCTL_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* syscall(__NR_syncfs) is available */
/* #undef HAVE_SYS_SYNCFS */
/* Define to 1 if you have the <sys/syscall.h> header file. */
#define HAVE_SYS_SYSCALL_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* utimes(2) is available */
#define HAVE_UTIMES 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libeio"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Version number of package */
#define VERSION "1.0"
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */

View File

@ -7,6 +7,9 @@
/* fdatasync(2) is available */ /* fdatasync(2) is available */
/* #undef HAVE_FDATASYNC */ /* #undef HAVE_FDATASYNC */
/* utimes(2) is available */
#define HAVE_UTIMES 1
/* futimes(2) is available */ /* futimes(2) is available */
#define HAVE_FUTIMES 1 #define HAVE_FUTIMES 1

View File

@ -2,12 +2,7 @@
/* config.h.in. Generated from configure.ac by autoheader. */ /* config.h.in. Generated from configure.ac by autoheader. */
#include <linux/version.h> #include <linux/version.h>
#include <features.h>
#define LINUX_VERSION_CODE_FOR(major, minor, patch) \
(((major & 255) << 16) | ((minor & 255) << 8) | (patch & 255))
#define LINUX_VERSION_AT_LEAST(major, minor, patch) \
(LINUX_VERSION_CODE >= LINUX_VERSION_CODE_FOR(major, minor, patch))
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1 #define HAVE_DLFCN_H 1
@ -15,6 +10,9 @@
/* fdatasync(2) is available */ /* fdatasync(2) is available */
#define HAVE_FDATASYNC 1 #define HAVE_FDATASYNC 1
/* utimes(2) is available */
#define HAVE_UTIMES 1
/* futimes(2) is available */ /* futimes(2) is available */
#define HAVE_FUTIMES 1 #define HAVE_FUTIMES 1
@ -45,8 +43,12 @@
/* Define to 1 if you have the <string.h> header file. */ /* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1 #define HAVE_STRING_H 1
/* sync_file_range(2) is available */ /* sync_file_range(2) is available if kernel >= 2.6.17 and glibc >= 2.6 */
#define HAVE_SYNC_FILE_RANGE LINUX_VERSION_AT_LEAST(2, 6, 17) #if LINUX_VERSION_CODE >= 0x020611 && __GLIBC_PREREQ(2, 6)
#define HAVE_SYNC_FILE_RANGE 1
#else
#define HAVE_SYNC_FILE_RANGE 0
#endif
/* Define to 1 if you have the <sys/stat.h> header file. */ /* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1 #define HAVE_SYS_STAT_H 1

View File

@ -4,9 +4,11 @@
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1 #define HAVE_DLFCN_H 1
/* fdatasync(2) is not available on 10.5 but is on 10.6 /* fdatasync(2) is available */
* How should we deal with this? */ /* #undef HAVE_FDATASYNC */
/* #define HAVE_FDATASYNC 0 */
/* utimes(2) is available */
#define HAVE_UTIMES 1
/* futimes(2) is available */ /* futimes(2) is available */
#define HAVE_FUTIMES 1 #define HAVE_FUTIMES 1
@ -24,7 +26,7 @@
/* #undef HAVE_READAHEAD */ /* #undef HAVE_READAHEAD */
/* sendfile(2) is available and supported */ /* sendfile(2) is available and supported */
#define HAVE_SENDFILE 1 #define HAVE_SENDFILE 0
/* Define to 1 if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1 #define HAVE_STDINT_H 1
@ -69,9 +71,6 @@
/* Define to the one symbol short name of this package. */ /* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "" #define PACKAGE_TARNAME ""
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */ /* Define to the version of this package. */
#define PACKAGE_VERSION "" #define PACKAGE_VERSION ""

View File

@ -7,6 +7,9 @@
/* fdatasync(2) is available */ /* fdatasync(2) is available */
#define HAVE_FDATASYNC 1 #define HAVE_FDATASYNC 1
/* utimes(2) is available */
#define HAVE_UTIMES 1
/* futimes(2) is available */ /* futimes(2) is available */
/* #undef HAVE_FUTIMES */ /* #undef HAVE_FUTIMES */

View File

@ -5,17 +5,17 @@ AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE(libeio,1.0) AM_INIT_AUTOMAKE(libeio,1.0)
AM_MAINTAINER_MODE AM_MAINTAINER_MODE
AC_GNU_SOURCE
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_PROG_CC AC_PROG_CC
if test "x$GCC" = xyes ; then if test "x$GCC" = xyes ; then
CFLAGS="$CFLAGS -O3" CFLAGS="-O3 $CFLAGS"
fi fi
dnl somebody will forgive me
CFLAGS="-D_GNU_SOURCE $CFLAGS"
m4_include([libeio.m4]) m4_include([libeio.m4])
AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([Makefile])

View File

@ -0,0 +1,370 @@
/*
* libecb - http://software.schmorp.de/pkg/libecb
*
* Copyright (©) 2009-2011 Marc Alexander Lehmann <libecb@schmorp.de>
* Copyright (©) 2011 Emanuele Giaquinta
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ECB_H
#define ECB_H
#ifdef _WIN32
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
#if __GNUC__
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else /* _MSC_VER || __BORLANDC__ */
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#endif
#else
#include <inttypes.h>
#endif
/* many compilers define _GNUC_ to some versions but then only implement
* what their idiot authors think are the "more important" extensions,
* causing enourmous grief in return for some better fake benchmark numbers.
* or so.
* we try to detect these and simply assume they are not gcc - if they have
* an issue with that they should have done it right in the first place.
*/
#ifndef ECB_GCC_VERSION
#if !defined(__GNUC_MINOR__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__llvm__) || defined(__clang__)
#define ECB_GCC_VERSION(major,minor) 0
#else
#define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#endif
#endif
/*****************************************************************************/
#ifndef ECB_MEMORY_FENCE
#if ECB_GCC_VERSION(2,5)
#if defined(__x86) || defined(__i386)
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
#define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE /* non-lock xchg might be enough */
#define ECB_MEMORY_FENCE_RELEASE do { } while (0) /* unlikely to change in future cpus */
#elif __amd64
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("lfence" : : : "memory")
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("sfence") /* play safe - not needed in any current cpu */
#endif
#endif
#endif
#ifndef ECB_MEMORY_FENCE
#if ECB_GCC_VERSION(4,4)
#define ECB_MEMORY_FENCE __sync_synchronize ()
#define ECB_MEMORY_FENCE_ACQUIRE ({ char dummy = 0; __sync_lock_test_and_set (&dummy, 1); })
#define ECB_MEMORY_FENCE_RELEASE ({ char dummy = 1; __sync_lock_release (&dummy ); })
#elif _MSC_VER >= 1400 /* VC++ 2005 */
#pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
#define ECB_MEMORY_FENCE _ReadWriteBarrier ()
#define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
#define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
#elif defined(_WIN32)
#include <WinNT.h>
#define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
#define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
#define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
#endif
#endif
#ifndef ECB_MEMORY_FENCE
/*
* if you get undefined symbol references to pthread_mutex_lock,
* or failure to find pthread.h, then you should implement
* the ECB_MEMORY_FENCE operations for your cpu/compiler
* OR proide pthread.h and link against the posix thread library
* of your system.
*/
#include <pthread.h>
static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER;
#define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0)
#define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
#define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
#endif
/*****************************************************************************/
#define ECB_C99 (__STDC_VERSION__ >= 199901L)
#if __cplusplus
#define ecb_inline static inline
#elif ECB_GCC_VERSION(2,5)
#define ecb_inline static __inline__
#elif ECB_C99
#define ecb_inline static inline
#else
#define ecb_inline static
#endif
#if ECB_GCC_VERSION(3,3)
#define ecb_restrict __restrict__
#elif ECB_C99
#define ecb_restrict restrict
#else
#define ecb_restrict
#endif
typedef int ecb_bool;
#define ECB_CONCAT_(a, b) a ## b
#define ECB_CONCAT(a, b) ECB_CONCAT_(a, b)
#define ECB_STRINGIFY_(a) # a
#define ECB_STRINGIFY(a) ECB_STRINGIFY_(a)
#define ecb_function_ ecb_inline
#if ECB_GCC_VERSION(3,1)
#define ecb_attribute(attrlist) __attribute__(attrlist)
#define ecb_is_constant(expr) __builtin_constant_p (expr)
#define ecb_expect(expr,value) __builtin_expect ((expr),(value))
#define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
#else
#define ecb_attribute(attrlist)
#define ecb_is_constant(expr) 0
#define ecb_expect(expr,value) (expr)
#define ecb_prefetch(addr,rw,locality)
#endif
/* no emulation for ecb_decltype */
#if ECB_GCC_VERSION(4,5)
#define ecb_decltype(x) __decltype(x)
#elif ECB_GCC_VERSION(3,0)
#define ecb_decltype(x) __typeof(x)
#endif
#define ecb_noinline ecb_attribute ((__noinline__))
#define ecb_noreturn ecb_attribute ((__noreturn__))
#define ecb_unused ecb_attribute ((__unused__))
#define ecb_const ecb_attribute ((__const__))
#define ecb_pure ecb_attribute ((__pure__))
#if ECB_GCC_VERSION(4,3)
#define ecb_artificial ecb_attribute ((__artificial__))
#define ecb_hot ecb_attribute ((__hot__))
#define ecb_cold ecb_attribute ((__cold__))
#else
#define ecb_artificial
#define ecb_hot
#define ecb_cold
#endif
/* put around conditional expressions if you are very sure that the */
/* expression is mostly true or mostly false. note that these return */
/* booleans, not the expression. */
#define ecb_expect_false(expr) ecb_expect (!!(expr), 0)
#define ecb_expect_true(expr) ecb_expect (!!(expr), 1)
/* for compatibility to the rest of the world */
#define ecb_likely(expr) ecb_expect_true (expr)
#define ecb_unlikely(expr) ecb_expect_false (expr)
/* count trailing zero bits and count # of one bits */
#if ECB_GCC_VERSION(3,4)
/* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */
#define ecb_ld32(x) (__builtin_clz (x) ^ 31)
#define ecb_ld64(x) (__builtin_clzll (x) ^ 63)
#define ecb_ctz32(x) __builtin_ctz (x)
#define ecb_ctz64(x) __builtin_ctzll (x)
#define ecb_popcount32(x) __builtin_popcount (x)
/* no popcountll */
#else
ecb_function_ int ecb_ctz32 (uint32_t x) ecb_const;
ecb_function_ int
ecb_ctz32 (uint32_t x)
{
int r = 0;
x &= ~x + 1; /* this isolates the lowest bit */
#if ECB_branchless_on_i386
r += !!(x & 0xaaaaaaaa) << 0;
r += !!(x & 0xcccccccc) << 1;
r += !!(x & 0xf0f0f0f0) << 2;
r += !!(x & 0xff00ff00) << 3;
r += !!(x & 0xffff0000) << 4;
#else
if (x & 0xaaaaaaaa) r += 1;
if (x & 0xcccccccc) r += 2;
if (x & 0xf0f0f0f0) r += 4;
if (x & 0xff00ff00) r += 8;
if (x & 0xffff0000) r += 16;
#endif
return r;
}
ecb_function_ int ecb_ctz64 (uint64_t x) ecb_const;
ecb_function_ int
ecb_ctz64 (uint64_t x)
{
int shift = x & 0xffffffffU ? 0 : 32;
return ecb_ctz32 (x >> shift) + shift;
}
ecb_function_ int ecb_popcount32 (uint32_t x) ecb_const;
ecb_function_ int
ecb_popcount32 (uint32_t x)
{
x -= (x >> 1) & 0x55555555;
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
x = ((x >> 4) + x) & 0x0f0f0f0f;
x *= 0x01010101;
return x >> 24;
}
/* you have the choice beetween something with a table lookup, */
/* something using lots of bit arithmetic and a simple loop */
/* we went for the loop */
ecb_function_ int ecb_ld32 (uint32_t x) ecb_const;
ecb_function_ int ecb_ld32 (uint32_t x)
{
int r = 0;
if (x >> 16) { x >>= 16; r += 16; }
if (x >> 8) { x >>= 8; r += 8; }
if (x >> 4) { x >>= 4; r += 4; }
if (x >> 2) { x >>= 2; r += 2; }
if (x >> 1) { r += 1; }
return r;
}
ecb_function_ int ecb_ld64 (uint64_t x) ecb_const;
ecb_function_ int ecb_ld64 (uint64_t x)
{
int r = 0;
if (x >> 32) { x >>= 32; r += 32; }
return r + ecb_ld32 (x);
}
#endif
/* popcount64 is only available on 64 bit cpus as gcc builtin */
/* so for this version we are lazy */
ecb_function_ int ecb_popcount64 (uint64_t x) ecb_const;
ecb_function_ int
ecb_popcount64 (uint64_t x)
{
return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);
}
ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) ecb_const;
ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) ecb_const;
ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) ecb_const;
ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) ecb_const;
ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const;
ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const;
ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) ecb_const;
ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) ecb_const;
ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
#if ECB_GCC_VERSION(4,3)
#define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
#define ecb_bswap32(x) __builtin_bswap32 (x)
#define ecb_bswap64(x) __builtin_bswap64 (x)
#else
ecb_function_ uint16_t ecb_bswap16 (uint16_t x) ecb_const;
ecb_function_ uint16_t
ecb_bswap16 (uint16_t x)
{
return ecb_rotl16 (x, 8);
}
ecb_function_ uint32_t ecb_bswap32 (uint32_t x) ecb_const;
ecb_function_ uint32_t
ecb_bswap32 (uint32_t x)
{
return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16);
}
ecb_function_ uint64_t ecb_bswap64 (uint64_t x) ecb_const;
ecb_function_ uint64_t
ecb_bswap64 (uint64_t x)
{
return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32);
}
#endif
#if ECB_GCC_VERSION(4,5)
#define ecb_unreachable() __builtin_unreachable ()
#else
/* this seems to work fine, but gcc always emits a warning for it :/ */
ecb_function_ void ecb_unreachable (void) ecb_noreturn;
ecb_function_ void ecb_unreachable (void) { }
#endif
/* try to tell the compiler that some condition is definitely true */
#define ecb_assume(cond) do { if (!(cond)) ecb_unreachable (); } while (0)
ecb_function_ unsigned char ecb_byteorder_helper (void) ecb_const;
ecb_function_ unsigned char
ecb_byteorder_helper (void)
{
const uint32_t u = 0x11223344;
return *(unsigned char *)&u;
}
ecb_function_ ecb_bool ecb_big_endian (void) ecb_const;
ecb_function_ ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; }
ecb_function_ ecb_bool ecb_little_endian (void) ecb_const;
ecb_function_ ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
#if ECB_GCC_VERSION(3,0) || ECB_C99
#define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
#else
#define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
#endif
#if ecb_cplusplus_does_not_suck
/* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */
template<typename T, int N>
static inline int ecb_array_length (const T (&arr)[N])
{
return N;
}
#else
#define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,969 @@
=head1 NAME
libeio - truly asynchronous POSIX I/O
=head1 SYNOPSIS
#include <eio.h>
=head1 DESCRIPTION
The newest version of this document is also available as an html-formatted
web page you might find easier to navigate when reading it for the first
time: L<http://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.pod>.
Note that this library is a by-product of the C<IO::AIO> perl
module, and many of the subtler points regarding requests lifetime
and so on are only documented in its documentation at the
moment: L<http://pod.tst.eu/http://cvs.schmorp.de/IO-AIO/AIO.pm>.
=head2 FEATURES
This library provides fully asynchronous versions of most POSIX functions
dealing with I/O. Unlike most asynchronous libraries, this not only
includes C<read> and C<write>, but also C<open>, C<stat>, C<unlink> and
similar functions, as well as less rarely ones such as C<mknod>, C<futime>
or C<readlink>.
It also offers wrappers around C<sendfile> (Solaris, Linux, HP-UX and
FreeBSD, with emulation on other platforms) and C<readahead> (Linux, with
emulation elsewhere>).
The goal is to enable you to write fully non-blocking programs. For
example, in a game server, you would not want to freeze for a few seconds
just because the server is running a backup and you happen to call
C<readdir>.
=head2 TIME REPRESENTATION
Libeio represents time as a single floating point number, representing the
(fractional) number of seconds since the (POSIX) epoch (somewhere near
the beginning of 1970, details are complicated, don't ask). This type is
called C<eio_tstamp>, but it is guaranteed to be of type C<double> (or
better), so you can freely use C<double> yourself.
Unlike the name component C<stamp> might indicate, it is also used for
time differences throughout libeio.
=head2 FORK SUPPORT
Usage of pthreads in a program changes the semantics of fork
considerably. Specifically, only async-safe functions can be called after
fork. Libeio uses pthreads, so this applies, and makes using fork hard for
anything but relatively fork + exec uses.
This library only works in the process that initialised it: Forking is
fully supported, but using libeio in any other process than the one that
called C<eio_init> is not.
You might get around by not I<using> libeio before (or after) forking in
the parent, and using it in the child afterwards. You could also try to
call the L<eio_init> function again in the child, which will brutally
reinitialise all data structures, which isn't POSIX conformant, but
typically works.
Otherwise, the only recommendation you should follow is: treat fork code
the same way you treat signal handlers, and only ever call C<eio_init> in
the process that uses it, and only once ever.
=head1 INITIALISATION/INTEGRATION
Before you can call any eio functions you first have to initialise the
library. The library integrates into any event loop, but can also be used
without one, including in polling mode.
You have to provide the necessary glue yourself, however.
=over 4
=item int eio_init (void (*want_poll)(void), void (*done_poll)(void))
This function initialises the library. On success it returns C<0>, on
failure it returns C<-1> and sets C<errno> appropriately.
It accepts two function pointers specifying callbacks as argument, both of
which can be C<0>, in which case the callback isn't called.
There is currently no way to change these callbacks later, or to
"uninitialise" the library again.
=item want_poll callback
The C<want_poll> callback is invoked whenever libeio wants attention (i.e.
it wants to be polled by calling C<eio_poll>). It is "edge-triggered",
that is, it will only be called once when eio wants attention, until all
pending requests have been handled.
This callback is called while locks are being held, so I<you must
not call any libeio functions inside this callback>. That includes
C<eio_poll>. What you should do is notify some other thread, or wake up
your event loop, and then call C<eio_poll>.
=item done_poll callback
This callback is invoked when libeio detects that all pending requests
have been handled. It is "edge-triggered", that is, it will only be
called once after C<want_poll>. To put it differently, C<want_poll> and
C<done_poll> are invoked in pairs: after C<want_poll> you have to call
C<eio_poll ()> until either C<eio_poll> indicates that everything has been
handled or C<done_poll> has been called, which signals the same.
Note that C<eio_poll> might return after C<done_poll> and C<want_poll>
have been called again, so watch out for races in your code.
As with C<want_poll>, this callback is called while locks are being held,
so you I<must not call any libeio functions form within this callback>.
=item int eio_poll ()
This function has to be called whenever there are pending requests that
need finishing. You usually call this after C<want_poll> has indicated
that you should do so, but you can also call this function regularly to
poll for new results.
If any request invocation returns a non-zero value, then C<eio_poll ()>
immediately returns with that value as return value.
Otherwise, if all requests could be handled, it returns C<0>. If for some
reason not all requests have been handled, i.e. some are still pending, it
returns C<-1>.
=back
For libev, you would typically use an C<ev_async> watcher: the
C<want_poll> callback would invoke C<ev_async_send> to wake up the event
loop. Inside the callback set for the watcher, one would call C<eio_poll
()>.
If C<eio_poll ()> is configured to not handle all results in one go
(i.e. it returns C<-1>) then you should start an idle watcher that calls
C<eio_poll> until it returns something C<!= -1>.
A full-featured connector between libeio and libev would look as follows
(if C<eio_poll> is handling all requests, it can of course be simplified a
lot by removing the idle watcher logic):
static struct ev_loop *loop;
static ev_idle repeat_watcher;
static ev_async ready_watcher;
/* idle watcher callback, only used when eio_poll */
/* didn't handle all results in one call */
static void
repeat (EV_P_ ev_idle *w, int revents)
{
if (eio_poll () != -1)
ev_idle_stop (EV_A_ w);
}
/* eio has some results, process them */
static void
ready (EV_P_ ev_async *w, int revents)
{
if (eio_poll () == -1)
ev_idle_start (EV_A_ &repeat_watcher);
}
/* wake up the event loop */
static void
want_poll (void)
{
ev_async_send (loop, &ready_watcher)
}
void
my_init_eio ()
{
loop = EV_DEFAULT;
ev_idle_init (&repeat_watcher, repeat);
ev_async_init (&ready_watcher, ready);
ev_async_start (loop &watcher);
eio_init (want_poll, 0);
}
For most other event loops, you would typically use a pipe - the event
loop should be told to wait for read readiness on the read end. In
C<want_poll> you would write a single byte, in C<done_poll> you would try
to read that byte, and in the callback for the read end, you would call
C<eio_poll>.
You don't have to take special care in the case C<eio_poll> doesn't handle
all requests, as the done callback will not be invoked, so the event loop
will still signal readiness for the pipe until I<all> results have been
processed.
=head1 HIGH LEVEL REQUEST API
Libeio has both a high-level API, which consists of calling a request
function with a callback to be called on completion, and a low-level API
where you fill out request structures and submit them.
This section describes the high-level API.
=head2 REQUEST SUBMISSION AND RESULT PROCESSING
You submit a request by calling the relevant C<eio_TYPE> function with the
required parameters, a callback of type C<int (*eio_cb)(eio_req *req)>
(called C<eio_cb> below) and a freely usable C<void *data> argument.
The return value will either be 0, in case something went really wrong
(which can basically only happen on very fatal errors, such as C<malloc>
returning 0, which is rather unlikely), or a pointer to the newly-created
and submitted C<eio_req *>.
The callback will be called with an C<eio_req *> which contains the
results of the request. The members you can access inside that structure
vary from request to request, except for:
=over 4
=item C<ssize_t result>
This contains the result value from the call (usually the same as the
syscall of the same name).
=item C<int errorno>
This contains the value of C<errno> after the call.
=item C<void *data>
The C<void *data> member simply stores the value of the C<data> argument.
=back
The return value of the callback is normally C<0>, which tells libeio to
continue normally. If a callback returns a nonzero value, libeio will
stop processing results (in C<eio_poll>) and will return the value to its
caller.
Memory areas passed to libeio must stay valid as long as a request
executes, with the exception of paths, which are being copied
internally. Any memory libeio itself allocates will be freed after the
finish callback has been called. If you want to manage all memory passed
to libeio yourself you can use the low-level API.
For example, to open a file, you could do this:
static int
file_open_done (eio_req *req)
{
if (req->result < 0)
{
/* open() returned -1 */
errno = req->errorno;
perror ("open");
}
else
{
int fd = req->result;
/* now we have the new fd in fd */
}
return 0;
}
/* the first three arguments are passed to open(2) */
/* the remaining are priority, callback and data */
if (!eio_open ("/etc/passwd", O_RDONLY, 0, 0, file_open_done, 0))
abort (); /* something went wrong, we will all die!!! */
Note that you additionally need to call C<eio_poll> when the C<want_cb>
indicates that requests are ready to be processed.
=head2 CANCELLING REQUESTS
Sometimes the need for a request goes away before the request is
finished. In that case, one can cancel the request by a call to
C<eio_cancel>:
=over 4
=item eio_cancel (eio_req *req)
Cancel the request (and all its subrequests). If the request is currently
executing it might still continue to execute, and in other cases it might
still take a while till the request is cancelled.
Even if cancelled, the finish callback will still be invoked - the
callbacks of all cancellable requests need to check whether the request
has been cancelled by calling C<EIO_CANCELLED (req)>:
static int
my_eio_cb (eio_req *req)
{
if (EIO_CANCELLED (req))
return 0;
}
In addition, cancelled requests will I<either> have C<< req->result >>
set to C<-1> and C<errno> to C<ECANCELED>, or I<otherwise> they were
successfully executed, despite being cancelled (e.g. when they have
already been executed at the time they were cancelled).
C<EIO_CANCELLED> is still true for requests that have successfully
executed, as long as C<eio_cancel> was called on them at some point.
=back
=head2 AVAILABLE REQUESTS
The following request functions are available. I<All> of them return the
C<eio_req *> on success and C<0> on failure, and I<all> of them have the
same three trailing arguments: C<pri>, C<cb> and C<data>. The C<cb> is
mandatory, but in most cases, you pass in C<0> as C<pri> and C<0> or some
custom data value as C<data>.
=head3 POSIX API WRAPPERS
These requests simply wrap the POSIX call of the same name, with the same
arguments. If a function is not implemented by the OS and cannot be emulated
in some way, then all of these return C<-1> and set C<errorno> to C<ENOSYS>.
=over 4
=item eio_open (const char *path, int flags, mode_t mode, int pri, eio_cb cb, void *data)
=item eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data)
=item eio_chown (const char *path, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data)
=item eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data)
=item eio_mkdir (const char *path, mode_t mode, int pri, eio_cb cb, void *data)
=item eio_rmdir (const char *path, int pri, eio_cb cb, void *data)
=item eio_unlink (const char *path, int pri, eio_cb cb, void *data)
=item eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data)
=item eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data)
=item eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data)
=item eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data)
=item eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data)
=item eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data)
=item eio_close (int fd, int pri, eio_cb cb, void *data)
=item eio_sync (int pri, eio_cb cb, void *data)
=item eio_fsync (int fd, int pri, eio_cb cb, void *data)
=item eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
=item eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data)
=item eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data)
=item eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data)
=item eio_fchown (int fd, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data)
=item eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data)
These have the same semantics as the syscall of the same name, their
return value is available as C<< req->result >> later.
=item eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data)
=item eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data)
These two requests are called C<read> and C<write>, but actually wrap
C<pread> and C<pwrite>. On systems that lack these calls (such as cygwin),
libeio uses lseek/read_or_write/lseek and a mutex to serialise the
requests, so all these requests run serially and do not disturb each
other. However, they still disturb the file offset while they run, so it's
not safe to call these functions concurrently with non-libeio functions on
the same fd on these systems.
Not surprisingly, pread and pwrite are not thread-safe on Darwin (OS/X),
so it is advised not to submit multiple requests on the same fd on this
horrible pile of garbage.
=item eio_mlockall (int flags, int pri, eio_cb cb, void *data)
Like C<mlockall>, but the flag value constants are called
C<EIO_MCL_CURRENT> and C<EIO_MCL_FUTURE>.
=item eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
Just like msync, except that the flag values are called C<EIO_MS_ASYNC>,
C<EIO_MS_INVALIDATE> and C<EIO_MS_SYNC>.
=item eio_readlink (const char *path, int pri, eio_cb cb, void *data)
If successful, the path read by C<readlink(2)> can be accessed via C<<
req->ptr2 >> and is I<NOT> null-terminated, with the length specified as
C<< req->result >>.
if (req->result >= 0)
{
char *target = strndup ((char *)req->ptr2, req->result);
free (target);
}
=item eio_realpath (const char *path, int pri, eio_cb cb, void *data)
Similar to the realpath libc function, but unlike that one, C<<
req->result >> is C<-1> on failure. On success, the result is the length
of the returned path in C<ptr2> (which is I<NOT> 0-terminated) - this is
similar to readlink.
=item eio_stat (const char *path, int pri, eio_cb cb, void *data)
=item eio_lstat (const char *path, int pri, eio_cb cb, void *data)
=item eio_fstat (int fd, int pri, eio_cb cb, void *data)
Stats a file - if C<< req->result >> indicates success, then you can
access the C<struct stat>-like structure via C<< req->ptr2 >>:
EIO_STRUCT_STAT *statdata = (EIO_STRUCT_STAT *)req->ptr2;
=item eio_statvfs (const char *path, int pri, eio_cb cb, void *data)
=item eio_fstatvfs (int fd, int pri, eio_cb cb, void *data)
Stats a filesystem - if C<< req->result >> indicates success, then you can
access the C<struct statvfs>-like structure via C<< req->ptr2 >>:
EIO_STRUCT_STATVFS *statdata = (EIO_STRUCT_STATVFS *)req->ptr2;
=back
=head3 READING DIRECTORIES
Reading directories sounds simple, but can be rather demanding, especially
if you want to do stuff such as traversing a directory hierarchy or
processing all files in a directory. Libeio can assist these complex tasks
with it's C<eio_readdir> call.
=over 4
=item eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data)
This is a very complex call. It basically reads through a whole directory
(via the C<opendir>, C<readdir> and C<closedir> calls) and returns either
the names or an array of C<struct eio_dirent>, depending on the C<flags>
argument.
The C<< req->result >> indicates either the number of files found, or
C<-1> on error. On success, null-terminated names can be found as C<< req->ptr2 >>,
and C<struct eio_dirents>, if requested by C<flags>, can be found via C<<
req->ptr1 >>.
Here is an example that prints all the names:
int i;
char *names = (char *)req->ptr2;
for (i = 0; i < req->result; ++i)
{
printf ("name #%d: %s\n", i, names);
/* move to next name */
names += strlen (names) + 1;
}
Pseudo-entries such as F<.> and F<..> are never returned by C<eio_readdir>.
C<flags> can be any combination of:
=over 4
=item EIO_READDIR_DENTS
If this flag is specified, then, in addition to the names in C<ptr2>,
also an array of C<struct eio_dirent> is returned, in C<ptr1>. A C<struct
eio_dirent> looks like this:
struct eio_dirent
{
int nameofs; /* offset of null-terminated name string in (char *)req->ptr2 */
unsigned short namelen; /* size of filename without trailing 0 */
unsigned char type; /* one of EIO_DT_* */
signed char score; /* internal use */
ino_t inode; /* the inode number, if available, otherwise unspecified */
};
The only members you normally would access are C<nameofs>, which is the
byte-offset from C<ptr2> to the start of the name, C<namelen> and C<type>.
C<type> can be one of:
C<EIO_DT_UNKNOWN> - if the type is not known (very common) and you have to C<stat>
the name yourself if you need to know,
one of the "standard" POSIX file types (C<EIO_DT_REG>, C<EIO_DT_DIR>, C<EIO_DT_LNK>,
C<EIO_DT_FIFO>, C<EIO_DT_SOCK>, C<EIO_DT_CHR>, C<EIO_DT_BLK>)
or some OS-specific type (currently
C<EIO_DT_MPC> - multiplexed char device (v7+coherent),
C<EIO_DT_NAM> - xenix special named file,
C<EIO_DT_MPB> - multiplexed block device (v7+coherent),
C<EIO_DT_NWK> - HP-UX network special,
C<EIO_DT_CMP> - VxFS compressed,
C<EIO_DT_DOOR> - solaris door, or
C<EIO_DT_WHT>).
This example prints all names and their type:
int i;
struct eio_dirent *ents = (struct eio_dirent *)req->ptr1;
char *names = (char *)req->ptr2;
for (i = 0; i < req->result; ++i)
{
struct eio_dirent *ent = ents + i;
char *name = names + ent->nameofs;
printf ("name #%d: %s (type %d)\n", i, name, ent->type);
}
=item EIO_READDIR_DIRS_FIRST
When this flag is specified, then the names will be returned in an order
where likely directories come first, in optimal C<stat> order. This is
useful when you need to quickly find directories, or you want to find all
directories while avoiding to stat() each entry.
If the system returns type information in readdir, then this is used
to find directories directly. Otherwise, likely directories are names
beginning with ".", or otherwise names with no dots, of which names with
short names are tried first.
=item EIO_READDIR_STAT_ORDER
When this flag is specified, then the names will be returned in an order
suitable for stat()'ing each one. That is, when you plan to stat()
all files in the given directory, then the returned order will likely
be fastest.
If both this flag and C<EIO_READDIR_DIRS_FIRST> are specified, then the
likely directories come first, resulting in a less optimal stat order.
=item EIO_READDIR_FOUND_UNKNOWN
This flag should not be specified when calling C<eio_readdir>. Instead,
it is being set by C<eio_readdir> (you can access the C<flags> via C<<
req->int1 >>, when any of the C<type>'s found were C<EIO_DT_UNKNOWN>. The
absence of this flag therefore indicates that all C<type>'s are known,
which can be used to speed up some algorithms.
A typical use case would be to identify all subdirectories within a
directory - you would ask C<eio_readdir> for C<EIO_READDIR_DIRS_FIRST>. If
then this flag is I<NOT> set, then all the entries at the beginning of the
returned array of type C<EIO_DT_DIR> are the directories. Otherwise, you
should start C<stat()>'ing the entries starting at the beginning of the
array, stopping as soon as you found all directories (the count can be
deduced by the link count of the directory).
=back
=back
=head3 OS-SPECIFIC CALL WRAPPERS
These wrap OS-specific calls (usually Linux ones), and might or might not
be emulated on other operating systems. Calls that are not emulated will
return C<-1> and set C<errno> to C<ENOSYS>.
=over 4
=item eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data)
Wraps the C<sendfile> syscall. The arguments follow the Linux version, but
libeio supports and will use similar calls on FreeBSD, HP/UX, Solaris and
Darwin.
If the OS doesn't support some sendfile-like call, or the call fails,
indicating support for the given file descriptor type (for example,
Linux's sendfile might not support file to file copies), then libeio will
emulate the call in userspace, so there are almost no limitations on its
use.
=item eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data)
Calls C<readahead(2)>. If the syscall is missing, then the call is
emulated by simply reading the data (currently in 64kiB chunks).
=item eio_syncfs (int fd, int pri, eio_cb cb, void *data)
Calls Linux' C<syncfs> syscall, if available. Returns C<-1> and sets
C<errno> to C<ENOSYS> if the call is missing I<but still calls sync()>,
if the C<fd> is C<< >= 0 >>, so you can probe for the availability of the
syscall with a negative C<fd> argument and checking for C<-1/ENOSYS>.
=item eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
Calls C<sync_file_range>. If the syscall is missing, then this is the same
as calling C<fdatasync>.
Flags can be any combination of C<EIO_SYNC_FILE_RANGE_WAIT_BEFORE>,
C<EIO_SYNC_FILE_RANGE_WRITE> and C<EIO_SYNC_FILE_RANGE_WAIT_AFTER>.
=item eio_fallocate (int fd, int mode, off_t offset, off_t len, int pri, eio_cb cb, void *data)
Calls C<fallocate> (note: I<NOT> C<posix_fallocate>!). If the syscall is
missing, then it returns failure and sets C<errno> to C<ENOSYS>.
The C<mode> argument can be C<0> (for behaviour similar to
C<posix_fallocate>), or C<EIO_FALLOC_FL_KEEP_SIZE>, which keeps the size
of the file unchanged (but still preallocates space beyond end of file).
=back
=head3 LIBEIO-SPECIFIC REQUESTS
These requests are specific to libeio and do not correspond to any OS call.
=over 4
=item eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
Reads (C<flags == 0>) or modifies (C<flags == EIO_MT_MODIFY) the given
memory area, page-wise, that is, it reads (or reads and writes back) the
first octet of every page that spans the memory area.
This can be used to page in some mmapped file, or dirty some pages. Note
that dirtying is an unlocked read-write access, so races can ensue when
the some other thread modifies the data stored in that memory area.
=item eio_custom (void (*)(eio_req *) execute, int pri, eio_cb cb, void *data)
Executes a custom request, i.e., a user-specified callback.
The callback gets the C<eio_req *> as parameter and is expected to read
and modify any request-specific members. Specifically, it should set C<<
req->result >> to the result value, just like other requests.
Here is an example that simply calls C<open>, like C<eio_open>, but it
uses the C<data> member as filename and uses a hardcoded C<O_RDONLY>. If
you want to pass more/other parameters, you either need to pass some
struct or so via C<data> or provide your own wrapper using the low-level
API.
static int
my_open_done (eio_req *req)
{
int fd = req->result;
return 0;
}
static void
my_open (eio_req *req)
{
req->result = open (req->data, O_RDONLY);
}
eio_custom (my_open, 0, my_open_done, "/etc/passwd");
=item eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data)
This is a request that takes C<delay> seconds to execute, but otherwise
does nothing - it simply puts one of the worker threads to sleep for this
long.
This request can be used to artificially increase load, e.g. for debugging
or benchmarking reasons.
=item eio_nop (int pri, eio_cb cb, void *data)
This request does nothing, except go through the whole request cycle. This
can be used to measure latency or in some cases to simplify code, but is
not really of much use.
=back
=head3 GROUPING AND LIMITING REQUESTS
There is one more rather special request, C<eio_grp>. It is a very special
aio request: Instead of doing something, it is a container for other eio
requests.
There are two primary use cases for this: a) bundle many requests into a
single, composite, request with a definite callback and the ability to
cancel the whole request with its subrequests and b) limiting the number
of "active" requests.
Further below you will find more discussion of these topics - first
follows the reference section detailing the request generator and other
methods.
=over 4
=item eio_req *grp = eio_grp (eio_cb cb, void *data)
Creates, submits and returns a group request. Note that it doesn't have a
priority, unlike all other requests.
=item eio_grp_add (eio_req *grp, eio_req *req)
Adds a request to the request group.
=item eio_grp_cancel (eio_req *grp)
Cancels all requests I<in> the group, but I<not> the group request
itself. You can cancel the group request I<and> all subrequests via a
normal C<eio_cancel> call.
=back
=head4 GROUP REQUEST LIFETIME
Left alone, a group request will instantly move to the pending state and
will be finished at the next call of C<eio_poll>.
The usefulness stems from the fact that, if a subrequest is added to a
group I<before> a call to C<eio_poll>, via C<eio_grp_add>, then the group
will not finish until all the subrequests have finished.
So the usage cycle of a group request is like this: after it is created,
you normally instantly add a subrequest. If none is added, the group
request will finish on it's own. As long as subrequests are added before
the group request is finished it will be kept from finishing, that is the
callbacks of any subrequests can, in turn, add more requests to the group,
and as long as any requests are active, the group request itself will not
finish.
=head4 CREATING COMPOSITE REQUESTS
Imagine you wanted to create an C<eio_load> request that opens a file,
reads it and closes it. This means it has to execute at least three eio
requests, but for various reasons it might be nice if that request looked
like any other eio request.
This can be done with groups:
=over 4
=item 1) create the request object
Create a group that contains all further requests. This is the request you
can return as "the load request".
=item 2) open the file, maybe
Next, open the file with C<eio_open> and add the request to the group
request and you are finished setting up the request.
If, for some reason, you cannot C<eio_open> (path is a null ptr?) you
can set C<< grp->result >> to C<-1> to signal an error and let the group
request finish on its own.
=item 3) open callback adds more requests
In the open callback, if the open was not successful, copy C<<
req->errorno >> to C<< grp->errorno >> and set C<< grp->errorno >> to
C<-1> to signal an error.
Otherwise, malloc some memory or so and issue a read request, adding the
read request to the group.
=item 4) continue issuing requests till finished
In the real callback, check for errors and possibly continue with
C<eio_close> or any other eio request in the same way.
As soon as no new requests are added the group request will finish. Make
sure you I<always> set C<< grp->result >> to some sensible value.
=back
=head4 REQUEST LIMITING
#TODO
void eio_grp_limit (eio_req *grp, int limit);
=back
=head1 LOW LEVEL REQUEST API
#TODO
=head1 ANATOMY AND LIFETIME OF AN EIO REQUEST
A request is represented by a structure of type C<eio_req>. To initialise
it, clear it to all zero bytes:
eio_req req;
memset (&req, 0, sizeof (req));
A more common way to initialise a new C<eio_req> is to use C<calloc>:
eio_req *req = calloc (1, sizeof (*req));
In either case, libeio neither allocates, initialises or frees the
C<eio_req> structure for you - it merely uses it.
zero
#TODO
=head2 CONFIGURATION
The functions in this section can sometimes be useful, but the default
configuration will do in most case, so you should skip this section on
first reading.
=over 4
=item eio_set_max_poll_time (eio_tstamp nseconds)
This causes C<eio_poll ()> to return after it has detected that it was
running for C<nsecond> seconds or longer (this number can be fractional).
This can be used to limit the amount of time spent handling eio requests,
for example, in interactive programs, you might want to limit this time to
C<0.01> seconds or so.
Note that:
=over 4
=item a) libeio doesn't know how long your request callbacks take, so the
time spent in C<eio_poll> is up to one callback invocation longer then
this interval.
=item b) this is implemented by calling C<gettimeofday> after each
request, which can be costly.
=item c) at least one request will be handled.
=back
=item eio_set_max_poll_reqs (unsigned int nreqs)
When C<nreqs> is non-zero, then C<eio_poll> will not handle more than
C<nreqs> requests per invocation. This is a less costly way to limit the
amount of work done by C<eio_poll> then setting a time limit.
If you know your callbacks are generally fast, you could use this to
encourage interactiveness in your programs by setting it to C<10>, C<100>
or even C<1000>.
=item eio_set_min_parallel (unsigned int nthreads)
Make sure libeio can handle at least this many requests in parallel. It
might be able handle more.
=item eio_set_max_parallel (unsigned int nthreads)
Set the maximum number of threads that libeio will spawn.
=item eio_set_max_idle (unsigned int nthreads)
Libeio uses threads internally to handle most requests, and will start and stop threads on demand.
This call can be used to limit the number of idle threads (threads without
work to do): libeio will keep some threads idle in preparation for more
requests, but never longer than C<nthreads> threads.
In addition to this, libeio will also stop threads when they are idle for
a few seconds, regardless of this setting.
=item unsigned int eio_nthreads ()
Return the number of worker threads currently running.
=item unsigned int eio_nreqs ()
Return the number of requests currently handled by libeio. This is the
total number of requests that have been submitted to libeio, but not yet
destroyed.
=item unsigned int eio_nready ()
Returns the number of ready requests, i.e. requests that have been
submitted but have not yet entered the execution phase.
=item unsigned int eio_npending ()
Returns the number of pending requests, i.e. requests that have been
executed and have results, but have not been finished yet by a call to
C<eio_poll>).
=back
=head1 EMBEDDING
Libeio can be embedded directly into programs. This functionality is not
documented and not (yet) officially supported.
Note that, when including C<libeio.m4>, you are responsible for defining
the compilation environment (C<_LARGEFILE_SOURCE>, C<_GNU_SOURCE> etc.).
If you need to know how, check the C<IO::AIO> perl module, which does
exactly that.
=head1 COMPILETIME CONFIGURATION
These symbols, if used, must be defined when compiling F<eio.c>.
=over 4
=item EIO_STACKSIZE
This symbol governs the stack size for each eio thread. Libeio itself
was written to use very little stackspace, but when using C<EIO_CUSTOM>
requests, you might want to increase this.
If this symbol is undefined (the default) then libeio will use its default
stack size (C<sizeof (void *) * 4096> currently). If it is defined, but
C<0>, then the default operating system stack size will be used. In all
other cases, the value must be an expression that evaluates to the desired
stack size.
=back
=head1 PORTABILITY REQUIREMENTS
In addition to a working ISO-C implementation, libeio relies on a few
additional extensions:
=over 4
=item POSIX threads
To be portable, this module uses threads, specifically, the POSIX threads
library must be available (and working, which partially excludes many xBSD
systems, where C<fork ()> is buggy).
=item POSIX-compatible filesystem API
This is actually a harder portability requirement: The libeio API is quite
demanding regarding POSIX API calls (symlinks, user/group management
etc.).
=item C<double> must hold a time value in seconds with enough accuracy
The type C<double> is used to represent timestamps. It is required to
have at least 51 bits of mantissa (and 9 bits of exponent), which is good
enough for at least into the year 4000. This requirement is fulfilled by
implementations implementing IEEE 754 (basically all existing ones).
=back
If you know of other additional requirements drop me a note.
=head1 AUTHOR
Marc Lehmann <libeio@schmorp.de>.

View File

@ -1,3 +1,7 @@
dnl openbsd in it's neverending brokenness requires stdint.h for intptr_t,
dnl but that header isn't very portable...
AC_CHECK_HEADERS([stdint.h sys/syscall.h sys/prctl.h])
AC_SEARCH_LIBS( AC_SEARCH_LIBS(
pthread_create, pthread_create,
[pthread pthreads pthreadVC2], [pthread pthreads pthreadVC2],
@ -119,6 +123,41 @@ int main (void)
],ac_cv_sync_file_range=yes,ac_cv_sync_file_range=no)]) ],ac_cv_sync_file_range=yes,ac_cv_sync_file_range=no)])
test $ac_cv_sync_file_range = yes && AC_DEFINE(HAVE_SYNC_FILE_RANGE, 1, sync_file_range(2) is available) test $ac_cv_sync_file_range = yes && AC_DEFINE(HAVE_SYNC_FILE_RANGE, 1, sync_file_range(2) is available)
AC_CACHE_CHECK(for fallocate, ac_cv_fallocate, [AC_LINK_IFELSE([
#include <fcntl.h>
int main (void)
{
int fd = 0;
int mode = 0;
off_t offset = 1;
off_t len = 1;
int res;
res = fallocate (fd, mode, offset, len);
return 0;
}
],ac_cv_fallocate=yes,ac_cv_fallocate=no)])
test $ac_cv_fallocate = yes && AC_DEFINE(HAVE_FALLOCATE, 1, fallocate(2) is available)
AC_CACHE_CHECK(for sys_syncfs, ac_cv_sys_syncfs, [AC_LINK_IFELSE([
#include <unistd.h>
#include <sys/syscall.h>
int main (void)
{
int res = syscall (__NR_syncfs, (int)0);
}
],ac_cv_sys_syncfs=yes,ac_cv_sys_syncfs=no)])
test $ac_cv_sys_syncfs = yes && AC_DEFINE(HAVE_SYS_SYNCFS, 1, syscall(__NR_syncfs) is available)
AC_CACHE_CHECK(for prctl_set_name, ac_cv_prctl_set_name, [AC_LINK_IFELSE([
#include <sys/prctl.h>
int main (void)
{
char name[] = "test123";
int res = prctl (PR_SET_NAME, (unsigned long)name, 0, 0, 0);
}
],ac_cv_prctl_set_name=yes,ac_cv_prctl_set_name=no)])
test $ac_cv_prctl_set_name = yes && AC_DEFINE(HAVE_PRCTL_SET_NAME, 1, prctl(PR_SET_NAME) is available)
dnl ############################################################################# dnl #############################################################################
dnl # these checks exist for the benefit of IO::AIO dnl # these checks exist for the benefit of IO::AIO

View File

@ -2,7 +2,7 @@
#define XTHREAD_H_ #define XTHREAD_H_
/* whether word reads are potentially non-atomic. /* whether word reads are potentially non-atomic.
* this is conservatice, likely most arches this runs * this is conservative, likely most arches this runs
* on have atomic word read/writes. * on have atomic word read/writes.
*/ */
#ifndef WORDACCESS_UNSAFE #ifndef WORDACCESS_UNSAFE
@ -17,14 +17,6 @@
#ifdef _WIN32 #ifdef _WIN32
#ifndef __MINGW32__
typedef int ssize_t
#endif
#define NTDDI_VERSION NTDDI_WIN2K // needed to get win2000 api calls
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x400
#endif
#include <stdio.h>//D #include <stdio.h>//D
#include <fcntl.h> #include <fcntl.h>
#include <io.h> #include <io.h>
@ -34,18 +26,20 @@ typedef int ssize_t
#include <windows.h> #include <windows.h>
#include <pthread.h> #include <pthread.h>
#define sigset_t int #define sigset_t int
#define sigfillset(a)
#define pthread_sigmask(a,b,c) #define pthread_sigmask(a,b,c)
#define sigaddset(a,b) #define sigaddset(a,b)
#define sigemptyset(s) #define sigemptyset(s)
#define sigfillset(s)
typedef pthread_mutex_t xmutex_t; typedef pthread_mutex_t xmutex_t;
#define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER #define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
#define X_MUTEX_CREATE(mutex) pthread_mutex_init (&(mutex), 0)
#define X_LOCK(mutex) pthread_mutex_lock (&(mutex)) #define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) #define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
typedef pthread_cond_t xcond_t; typedef pthread_cond_t xcond_t;
#define X_COND_INIT PTHREAD_COND_INITIALIZER #define X_COND_INIT PTHREAD_COND_INITIALIZER
#define X_COND_CREATE(cond) pthread_cond_init (&(cond), 0)
#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond)) #define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex)) #define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to)) #define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
@ -101,14 +95,23 @@ thread_create (xthread_t *tid, void *(*proc)(void *), void *arg)
typedef pthread_mutex_t xmutex_t; typedef pthread_mutex_t xmutex_t;
#if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) #if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)
# define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP # define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
# define X_MUTEX_CREATE(mutex) \
do { \
pthread_mutexattr_t attr; \
pthread_mutexattr_init (&attr); \
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP); \
pthread_mutex_init (&(mutex), &attr); \
} while (0)
#else #else
# define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER # define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
# define X_MUTEX_CREATE(mutex) pthread_mutex_init (&(mutex), 0)
#endif #endif
#define X_LOCK(mutex) pthread_mutex_lock (&(mutex)) #define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) #define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
typedef pthread_cond_t xcond_t; typedef pthread_cond_t xcond_t;
#define X_COND_INIT PTHREAD_COND_INITIALIZER #define X_COND_INIT PTHREAD_COND_INITIALIZER
#define X_COND_CREATE(cond) pthread_cond_init (&(cond), 0)
#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond)) #define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex)) #define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to)) #define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
@ -122,8 +125,8 @@ typedef pthread_t xthread_t;
# define PTHREAD_STACK_MIN 0 # define PTHREAD_STACK_MIN 0
#endif #endif
#ifndef X_STACKSIZE #ifndef XTHREAD_STACKSIZE
# define X_STACKSIZE sizeof (long) * 4096 # define XTHREAD_STACKSIZE sizeof (void *) * 4096
#endif #endif
static int static int

View File

@ -0,0 +1,110 @@
/* 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.
*/
/*
* TODO Share this code with Windows.
* See https://github.com/joyent/libuv/issues/76
*/
#include "uv.h"
#include "internal.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* TODO Expose callback to user to handle fatal error like V8 does. */
void uv_fatal_error(const int errorno, const char* syscall) {
char* buf = NULL;
const char* errmsg;
if (buf) {
errmsg = buf;
} else {
errmsg = "Unknown error";
}
if (syscall) {
fprintf(stderr, "\nlibuv fatal error. %s: (%d) %s\n", syscall, errorno,
errmsg);
} else {
fprintf(stderr, "\nlibuv fatal error. (%d) %s\n", errorno, errmsg);
}
abort();
}
uv_err_t uv_last_error(uv_loop_t* loop) {
return loop->last_err;
}
char* uv_strerror(uv_err_t err) {
return strerror(err.sys_errno_);
}
uv_err_code uv_translate_sys_error(int sys_errno) {
switch (sys_errno) {
case 0: return UV_OK;
case ENOENT: return UV_ENOENT;
case EACCES: return UV_EACCESS;
case EBADF: return UV_EBADF;
case EPIPE: return UV_EPIPE;
case EAGAIN: return UV_EAGAIN;
case ECONNRESET: return UV_ECONNRESET;
case EFAULT: return UV_EFAULT;
case EMFILE: return UV_EMFILE;
case EMSGSIZE: return UV_EMSGSIZE;
case EINVAL: return UV_EINVAL;
case ECONNREFUSED: return UV_ECONNREFUSED;
case EADDRINUSE: return UV_EADDRINUSE;
case EADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
case ENOTCONN: return UV_ENOTCONN;
case EEXIST: return UV_EEXIST;
default: return UV_UNKNOWN;
}
assert(0 && "unreachable");
return -1;
}
uv_err_t uv_err_new_artificial(uv_loop_t* loop, int code) {
uv_err_t err;
err.sys_errno_ = 0;
err.code = code;
loop->last_err = err;
return err;
}
uv_err_t uv_err_new(uv_loop_t* loop, int sys_error) {
uv_err_t err;
err.sys_errno_ = sys_error;
err.code = uv_translate_sys_error(sys_error);
loop->last_err = err;
return err;
}

View File

@ -2,12 +2,7 @@
/* config.h.in. Generated from configure.ac by autoheader. */ /* config.h.in. Generated from configure.ac by autoheader. */
#include <linux/version.h> #include <linux/version.h>
#include <features.h>
#define LINUX_VERSION_CODE_FOR(major, minor, patch) \
(((major & 255) << 16) | ((minor & 255) << 8) | (patch & 255))
#define LINUX_VERSION_AT_LEAST(major, minor, patch) \
(LINUX_VERSION_CODE >= LINUX_VERSION_CODE_FOR(major, minor, patch))
/* Define to 1 if you have the `clock_gettime' function. */ /* Define to 1 if you have the `clock_gettime' function. */
/* #undef HAVE_CLOCK_GETTIME */ /* #undef HAVE_CLOCK_GETTIME */
@ -18,14 +13,26 @@
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1 #define HAVE_DLFCN_H 1
/* Define to 1 if you have the `epoll_ctl' function. */ /* epoll_ctl(2) is available if kernel >= 2.6.9 and glibc >= 2.4 */
#if LINUX_VERSION_CODE >= 0x020609 && __GLIBC_PREREQ(2, 4)
#define HAVE_EPOLL_CTL 1 #define HAVE_EPOLL_CTL 1
#else
#define HAVE_EPOLL_CTL 0
#endif
/* Define to 1 if you have the `eventfd' function. */ /* eventfd(2) is available if kernel >= 2.6.22 and glibc >= 2.8 */
#define HAVE_EVENTFD LINUX_VERSION_AT_LEAST(2, 6, 22) #if LINUX_VERSION_CODE >= 0x020616 && __GLIBC_PREREQ(2, 8)
#define HAVE_EVENTFD 1
#else
#define HAVE_EVENTFD 0
#endif
/* Define to 1 if you have the `inotify_init' function. */ /* inotify_init(2) is available if kernel >= 2.6.13 and glibc >= 2.4 */
#define HAVE_INOTIFY_INIT LINUX_VERSION_AT_LEAST(2, 6, 13) #if LINUX_VERSION_CODE >= 0x02060d && __GLIBC_PREREQ(2, 4)
#define HAVE_INOTIFY_INIT 1
#else
#define HAVE_INOTIFY_INIT 0
#endif
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1 #define HAVE_INTTYPES_H 1
@ -60,8 +67,12 @@
/* Define to 1 if you have the `select' function. */ /* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1 #define HAVE_SELECT 1
/* Define to 1 if you have the `signalfd' function. */ /* signalfd(2) is available if kernel >= 2.6.22 and glibc >= 2.8 */
#define HAVE_SIGNALFD LINUX_VERSION_AT_LEAST(2, 6, 22) #if LINUX_VERSION_CODE >= 0x020616 && __GLIBC_PREREQ(2, 8)
#define HAVE_SIGNALFD 1
#else
#define HAVE_SIGNALFD 0
#endif
/* Define to 1 if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1 #define HAVE_STDINT_H 1

View File

@ -0,0 +1,120 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the `clock_gettime' function. */
/* #undef HAVE_CLOCK_GETTIME */
/* "use syscall interface for clock_gettime" */
/* #undef HAVE_CLOCK_SYSCALL */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `epoll_ctl' function. */
/* #undef HAVE_EPOLL_CTL */
/* Define to 1 if you have the `eventfd' function. */
/* #undef HAVE_EVENTFD */
/* Define to 1 if you have the `inotify_init' function. */
/* #undef HAVE_INOTIFY_INIT */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `kqueue' function. */
#define HAVE_KQUEUE 1
/* Define to 1 if you have the `m' library (-lm). */
#define HAVE_LIBM 1
/* Define to 1 if you have the `rt' library (-lrt). */
/* #undef HAVE_LIBRT */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `nanosleep' function. */
/* #undef HAVE_NANOSLEEP */
/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1
/* Define to 1 if you have the <poll.h> header file. */
#define HAVE_POLL_H 1
/* Define to 1 if you have the `port_create' function. */
/* #undef HAVE_PORT_CREATE */
/* Define to 1 if you have the <port.h> header file. */
/* #undef HAVE_PORT_H */
/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/epoll.h> header file. */
/* #undef HAVE_SYS_EPOLL_H */
/* Define to 1 if you have the <sys/eventfd.h> header file. */
/* #undef HAVE_SYS_EVENTFD_H */
/* Define to 1 if you have the <sys/event.h> header file. */
#define HAVE_SYS_EVENT_H 1
/* Define to 1 if you have the <sys/inotify.h> header file. */
/* #undef HAVE_SYS_INOTIFY_H */
/* Define to 1 if you have the <sys/queue.h> header file. */
#define HAVE_SYS_QUEUE_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libev"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "3.9"

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