Initial import of UDT + barchart mods + barchart JNI
commit
0b24133f5d
|
@ -0,0 +1,181 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="converted.config.1797282818">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="converted.config.1797282818" moduleId="org.eclipse.cdt.core.settings" name="convertedConfig">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MachO" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="false" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="false"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="false" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="false"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="false" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="false"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.pathentry">
|
||||
<pathentry base-path="UDT" include="jvm/include" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/asm" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/bits" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/net" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/netinet" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/sys" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/gdk-pixbuf-2.0" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/gtk-2.0" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/glib-2.0" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/gio-unix-2.0/" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/pixman-1" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/freetype2" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/libpng12" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/i686-w64-mingw32/include" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/include/x86_64-linux-gnu" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/lib/gcc/x86_64-linux-gnu/4.8/include/" kind="inc" path="" system="true"/>
|
||||
<pathentry include="/usr/share/mingw-w64/include/" kind="inc" path="" system="true"/>
|
||||
<pathentry kind="mac" name="ENABLE_LGPL" path="" value="true"/>
|
||||
<pathentry kind="mac" name="ENABLE_CRYPTO" path="" value="true"/>
|
||||
<pathentry kind="mac" name="DEBUG" path="" value="true"/>
|
||||
<pathentry kind="mac" name="CUSTOM_RUNTIME" path="" value="true"/>
|
||||
<pathentry kind="mac" name="ENABLE_INPUT_MONITOR" path="" value="true"/>
|
||||
<pathentry kind="mac" name="WRAP_BIND_SOCKETS" path="" value="true"/>
|
||||
<pathentry kind="mac" name="GDK3_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="GTK3_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="GTK_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="GDK_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="GOBJ_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="PIXBUF_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="X11_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="GTHREAD_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="X11_TEST_LIB" path="" value="1"/>
|
||||
<pathentry kind="mac" name="DEFAULT_OS" path="" value=""linux""/>
|
||||
<pathentry kind="mac" name="DEFAULT_OS_ARCH" path="" value=""x86_64""/>
|
||||
<pathentry kind="src" path="src"/>
|
||||
<pathentry kind="out" path="bin"/>
|
||||
<pathentry kind="con" path="org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="clean_windows" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_windows.mak</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="windows_32" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_windows.mak COMPILE_OS=windows COMPILE_OS_ARCH=32</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="windows_64" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_windows.mak COMPILE_OS=windows COMPILE_OS_ARCH=64</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean_macosx" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_macosx.mak</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="macosx_32" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_macosx.mak COMPILE_OS=macosx COMPILE_OS_ARCH=32</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="macosx_64" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_macosx.mak COMPILE_OS=macosx COMPILE_OS_ARCH=64</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean_linux" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_linux.mak</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="linux_32" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_linux.mak COMPILE_OS=linux COMPILE_OS_ARCH=32</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="linux_64" path="" targetID="org.eclipse.cdt.make.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-f make_linux.mak COMPILE_OS=linux COMPILE_OS_ARCH=64</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cproject>
|
|
@ -0,0 +1 @@
|
|||
/bin/
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>UDT</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.make.core.makeBuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.core.errorOutputParser</key>
|
||||
<value>org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.GmakeErrorParser;</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.build.arguments</key>
|
||||
<value>-f 'make_${system:OS}.mak'</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.build.command</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.build.location</key>
|
||||
<value>/UDT/</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.build.target.auto</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.build.target.clean</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.build.target.inc</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.environment</key>
|
||||
<value>DEFAULT_WS=${system_property:osgi.ws}|JAVA_ROOT=${system_property:java.home}/..|DEFAULT_OS_ARCH=${system_property:osgi.arch}|PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig:/opt/kde3/lib64/pkgconfig:/opt/gnome/lib64/pkgconfig:/opt/gnome/lib64/pkgconfig:/opt/gnome/share/pkgconfig|DEFAULT_OS=${system_property:osgi.os}|</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.make.core.ScannerConfigBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.make.core.makeNature</nature>
|
||||
<nature>org.eclipse.cdt.make.core.ScannerConfigNature</nature>
|
||||
<nature>org.eclipse.pde.FeatureNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,186 @@
|
|||
#!/bin/bash
|
||||
#*******************************************************************************
|
||||
#
|
||||
# This will build ALL variants!
|
||||
#
|
||||
# This expects the following environment variables set:
|
||||
#
|
||||
# COMPILE_OS - linux, macosx, windows
|
||||
# COMPILE_OS_ARCH - 32, 64, arm
|
||||
#
|
||||
#
|
||||
# possible packages you might need in order to compile:
|
||||
# gcc-4.8 gcc-4.8-multilib g++-4.8-multilib gdb make libgtk2.0-dev libxtst-dev libc6-dev-i386 mingw-w64
|
||||
# ccache libssl0.9.8
|
||||
#
|
||||
# Then, in gcc_apple_amd64 dir: sudo dpkg -i *.deb (this is 64bit gcc to build macosx binaries)
|
||||
#
|
||||
# Because we fake the 32bit/arm library calls during compile time (the libs are
|
||||
# loaded during run time) we can build 32bit/arm builds on a 64bit system without needing multi-arch
|
||||
# GTK libraries (fyi: there aren't any... and DO NOT install the i386 ones, since they will REMOVE what
|
||||
# you already have - buggering your system!)
|
||||
#
|
||||
#
|
||||
#
|
||||
# TODO: clean up below, verify arm builds.
|
||||
# # arm: gcc-arm-linux-gnueabi gcc-4.8-arm-linux-gnueabihf
|
||||
# hf or no hf? beaglebone, rasbpi, ODROID-U3, other ARM devices
|
||||
#
|
||||
# ARMv7sf needs gcc-arm-linux-gnueabi, ARMv7hf needs gcc-arm-linux-gnueabihf
|
||||
#
|
||||
# To compile for the ARMv7 (BeagleBone Black), follow:
|
||||
# http://www.michaelhleonard.com/cross-compile-for-beaglebone-black/
|
||||
#
|
||||
# for raspi/BBB
|
||||
# http://www.michaelhleonard.com/cross-compile-for-beaglebone-black/
|
||||
# http://derekmolloy.ie/beaglebone/setting-up-eclipse-on-the-beaglebone-for-c-development/
|
||||
# http://stackoverflow.com/questions/9324772/cross-compiling-static-c-hello-world-for-android-using-arm-linux-gnueabi-gcc?rq=1
|
||||
#
|
||||
#
|
||||
#for ANY OTHER OS/ARCH, the easiest, and most straight forward method is to use
|
||||
# crosstool-ng. http://crosstool-ng.org/
|
||||
# howto's:
|
||||
# http://raspberrypi.stackexchange.com/questions/1/how-do-i-build-a-gcc-4-7-toolchain-for-cross-compiling
|
||||
# http://www.bootc.net/archives/2012/05/26/how-to-build-a-cross-compiler-for-your-raspberry-pi/
|
||||
# http://www.ps3devwiki.com/wiki/Cross_Compiling
|
||||
#
|
||||
#
|
||||
######################################################################
|
||||
# as per: http://stackoverflow.com/questions/8937492/what-is-upxs-best-compression-method
|
||||
# it is NOT a good idea to compress exe's. WHY? Because they run slower, and HDD space is no longer a concern.
|
||||
# especially since the executable is ~ 500k.
|
||||
######################################################################
|
||||
|
||||
readonly true=1 yes=1 no=0 false=0
|
||||
|
||||
|
||||
BUILD_ENV=`uname -s`-`uname -m`
|
||||
|
||||
|
||||
if [[ "$BUILD_ENV" != "Linux-x86_64" ]]; then
|
||||
echo " ********"
|
||||
echo " ******** Can ONLY build on [[ $BUILD_ENV ]]"
|
||||
echo " ********"
|
||||
return false
|
||||
fi
|
||||
|
||||
echo " ********"
|
||||
echo " ******** Build Environment: [[ $BUILD_ENV ]]"
|
||||
echo " ********"
|
||||
|
||||
export PROGRAM_DEPLOY=true
|
||||
|
||||
#############
|
||||
#core function that will build our targets
|
||||
#############
|
||||
build() {
|
||||
BUILD_TYPE=$1
|
||||
export COMPILE_OS=$2
|
||||
export COMPILE_OS_ARCH=$3
|
||||
|
||||
echo " ********"
|
||||
echo " ******** Building: ${COMPILE_OS}""_""${COMPILE_OS_ARCH}"
|
||||
echo " ********"
|
||||
|
||||
# compile
|
||||
make -f $BUILD_TYPE all
|
||||
}
|
||||
|
||||
|
||||
####################################################################
|
||||
####################################################################
|
||||
####################################################################
|
||||
####################################################################
|
||||
# DONE WITH FUNCTIONS
|
||||
####################################################################
|
||||
####################################################################
|
||||
####################################################################
|
||||
BUILD_ALL=false
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
BUILD_ALL=true
|
||||
elif [[ "$1" == "all" ]]; then
|
||||
BUILD_ALL=true
|
||||
fi
|
||||
|
||||
|
||||
# No args will build all.
|
||||
if [[ $BUILD_ALL == true ]]; then
|
||||
if [ -z "$1" ]; then
|
||||
echo " ******** Building linux (32/64), macosx (32/64), windows (32/64)"
|
||||
echo " ******** Press enter to continue... "
|
||||
read VARNAME
|
||||
fi
|
||||
|
||||
# LINUX
|
||||
build "make_linux.mak" linux 32
|
||||
build "make_linux.mak" linux 64
|
||||
|
||||
|
||||
# WINDOWS
|
||||
build "make_windows.mak" windows 32
|
||||
build "make_windows.mak" windows 64
|
||||
|
||||
|
||||
# MAC
|
||||
build "make_macosx.mak" macosx 32
|
||||
build "make_macosx.mak" macosx 64
|
||||
else
|
||||
# LINUX
|
||||
if [[ "$1" == "linux" ]]; then
|
||||
echo " ******** Building linux (32/64)"
|
||||
|
||||
build "make_linux.mak" linux 32
|
||||
build "make_linux.mak" linux 64
|
||||
elif [[ "$1" == "linux_32" ]]; then
|
||||
build "make_linux.mak" linux 32
|
||||
elif [[ "$1" == "linux_64" ]]; then
|
||||
build "make_linux.mak" linux 64
|
||||
|
||||
# WINDOWS
|
||||
elif [[ "$1" == "windows" ]]; then
|
||||
#all
|
||||
echo " ******** Building windows (32/64)"
|
||||
|
||||
build "make_windows.mak" windows 32
|
||||
build "make_windows.mak" windows 64
|
||||
|
||||
elif [[ "$1" == "windows_32" ]]; then
|
||||
build "make_windows.mak" windows 32
|
||||
elif [[ "$1" == "windows_64" ]]; then
|
||||
build "make_windows.mak" windows 64
|
||||
|
||||
# MAC
|
||||
elif [[ "$1" == "macosx" ]]; then
|
||||
#all
|
||||
echo " ******** Building macosx (32/64)"
|
||||
|
||||
build "make_macosx.mak" macosx 32
|
||||
build "make_macosx.mak" macosx 64
|
||||
elif [[ "$1" == "macosx_32" ]]; then
|
||||
build "make_macosx.mak" macosx 32
|
||||
elif [[ "$1" == "macosx_64" ]]; then
|
||||
build "make_macosx.mak" macosx 64
|
||||
|
||||
else
|
||||
echo "Please one of the following:"
|
||||
echo " [all] - builds all of them"
|
||||
echo ""
|
||||
echo "linux"
|
||||
echo " linux [all] - builds 32 and 64 bit linux"
|
||||
echo " linux_32 [all] - builds 32 bit linux"
|
||||
echo " linux_64 [all] - builds 64 bit linux"
|
||||
echo ""
|
||||
echo "mac"
|
||||
echo " macosx [all] - builds 32 and 64 bit mac"
|
||||
echo " macosx_32 [all] - builds 32 bit mac"
|
||||
echo " macosx_64 [all] - builds 64 bit mac"
|
||||
echo ""
|
||||
echo "windows"
|
||||
echo " windows [all] - builds 32 and 64 bit windows"
|
||||
echo " windows_32 [all] - builds 32 bit windows"
|
||||
echo " windows_64 [all] - builds 64 bit windows"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
|
@ -0,0 +1,544 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef CLASSFILE_CONSTANTS_H
|
||||
#define CLASSFILE_CONSTANTS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Classfile version number for this information */
|
||||
#define JVM_CLASSFILE_MAJOR_VERSION 50
|
||||
#define JVM_CLASSFILE_MINOR_VERSION 0
|
||||
|
||||
/* Flags */
|
||||
|
||||
enum {
|
||||
JVM_ACC_PUBLIC = 0x0001,
|
||||
JVM_ACC_PRIVATE = 0x0002,
|
||||
JVM_ACC_PROTECTED = 0x0004,
|
||||
JVM_ACC_STATIC = 0x0008,
|
||||
JVM_ACC_FINAL = 0x0010,
|
||||
JVM_ACC_SYNCHRONIZED = 0x0020,
|
||||
JVM_ACC_SUPER = 0x0020,
|
||||
JVM_ACC_VOLATILE = 0x0040,
|
||||
JVM_ACC_BRIDGE = 0x0040,
|
||||
JVM_ACC_TRANSIENT = 0x0080,
|
||||
JVM_ACC_VARARGS = 0x0080,
|
||||
JVM_ACC_NATIVE = 0x0100,
|
||||
JVM_ACC_INTERFACE = 0x0200,
|
||||
JVM_ACC_ABSTRACT = 0x0400,
|
||||
JVM_ACC_STRICT = 0x0800,
|
||||
JVM_ACC_SYNTHETIC = 0x1000,
|
||||
JVM_ACC_ANNOTATION = 0x2000,
|
||||
JVM_ACC_ENUM = 0x4000
|
||||
};
|
||||
|
||||
/* Used in newarray instruction. */
|
||||
|
||||
enum {
|
||||
JVM_T_BOOLEAN = 4,
|
||||
JVM_T_CHAR = 5,
|
||||
JVM_T_FLOAT = 6,
|
||||
JVM_T_DOUBLE = 7,
|
||||
JVM_T_BYTE = 8,
|
||||
JVM_T_SHORT = 9,
|
||||
JVM_T_INT = 10,
|
||||
JVM_T_LONG = 11
|
||||
};
|
||||
|
||||
/* Constant Pool Entries */
|
||||
|
||||
enum {
|
||||
JVM_CONSTANT_Utf8 = 1,
|
||||
JVM_CONSTANT_Unicode = 2, /* unused */
|
||||
JVM_CONSTANT_Integer = 3,
|
||||
JVM_CONSTANT_Float = 4,
|
||||
JVM_CONSTANT_Long = 5,
|
||||
JVM_CONSTANT_Double = 6,
|
||||
JVM_CONSTANT_Class = 7,
|
||||
JVM_CONSTANT_String = 8,
|
||||
JVM_CONSTANT_Fieldref = 9,
|
||||
JVM_CONSTANT_Methodref = 10,
|
||||
JVM_CONSTANT_InterfaceMethodref = 11,
|
||||
JVM_CONSTANT_NameAndType = 12
|
||||
};
|
||||
|
||||
/* StackMapTable type item numbers */
|
||||
|
||||
enum {
|
||||
JVM_ITEM_Top = 0,
|
||||
JVM_ITEM_Integer = 1,
|
||||
JVM_ITEM_Float = 2,
|
||||
JVM_ITEM_Double = 3,
|
||||
JVM_ITEM_Long = 4,
|
||||
JVM_ITEM_Null = 5,
|
||||
JVM_ITEM_UninitializedThis = 6,
|
||||
JVM_ITEM_Object = 7,
|
||||
JVM_ITEM_Uninitialized = 8
|
||||
};
|
||||
|
||||
/* Type signatures */
|
||||
|
||||
enum {
|
||||
JVM_SIGNATURE_ARRAY = '[',
|
||||
JVM_SIGNATURE_BYTE = 'B',
|
||||
JVM_SIGNATURE_CHAR = 'C',
|
||||
JVM_SIGNATURE_CLASS = 'L',
|
||||
JVM_SIGNATURE_ENDCLASS = ';',
|
||||
JVM_SIGNATURE_ENUM = 'E',
|
||||
JVM_SIGNATURE_FLOAT = 'F',
|
||||
JVM_SIGNATURE_DOUBLE = 'D',
|
||||
JVM_SIGNATURE_FUNC = '(',
|
||||
JVM_SIGNATURE_ENDFUNC = ')',
|
||||
JVM_SIGNATURE_INT = 'I',
|
||||
JVM_SIGNATURE_LONG = 'J',
|
||||
JVM_SIGNATURE_SHORT = 'S',
|
||||
JVM_SIGNATURE_VOID = 'V',
|
||||
JVM_SIGNATURE_BOOLEAN = 'Z'
|
||||
};
|
||||
|
||||
/* Opcodes */
|
||||
|
||||
enum {
|
||||
JVM_OPC_nop = 0,
|
||||
JVM_OPC_aconst_null = 1,
|
||||
JVM_OPC_iconst_m1 = 2,
|
||||
JVM_OPC_iconst_0 = 3,
|
||||
JVM_OPC_iconst_1 = 4,
|
||||
JVM_OPC_iconst_2 = 5,
|
||||
JVM_OPC_iconst_3 = 6,
|
||||
JVM_OPC_iconst_4 = 7,
|
||||
JVM_OPC_iconst_5 = 8,
|
||||
JVM_OPC_lconst_0 = 9,
|
||||
JVM_OPC_lconst_1 = 10,
|
||||
JVM_OPC_fconst_0 = 11,
|
||||
JVM_OPC_fconst_1 = 12,
|
||||
JVM_OPC_fconst_2 = 13,
|
||||
JVM_OPC_dconst_0 = 14,
|
||||
JVM_OPC_dconst_1 = 15,
|
||||
JVM_OPC_bipush = 16,
|
||||
JVM_OPC_sipush = 17,
|
||||
JVM_OPC_ldc = 18,
|
||||
JVM_OPC_ldc_w = 19,
|
||||
JVM_OPC_ldc2_w = 20,
|
||||
JVM_OPC_iload = 21,
|
||||
JVM_OPC_lload = 22,
|
||||
JVM_OPC_fload = 23,
|
||||
JVM_OPC_dload = 24,
|
||||
JVM_OPC_aload = 25,
|
||||
JVM_OPC_iload_0 = 26,
|
||||
JVM_OPC_iload_1 = 27,
|
||||
JVM_OPC_iload_2 = 28,
|
||||
JVM_OPC_iload_3 = 29,
|
||||
JVM_OPC_lload_0 = 30,
|
||||
JVM_OPC_lload_1 = 31,
|
||||
JVM_OPC_lload_2 = 32,
|
||||
JVM_OPC_lload_3 = 33,
|
||||
JVM_OPC_fload_0 = 34,
|
||||
JVM_OPC_fload_1 = 35,
|
||||
JVM_OPC_fload_2 = 36,
|
||||
JVM_OPC_fload_3 = 37,
|
||||
JVM_OPC_dload_0 = 38,
|
||||
JVM_OPC_dload_1 = 39,
|
||||
JVM_OPC_dload_2 = 40,
|
||||
JVM_OPC_dload_3 = 41,
|
||||
JVM_OPC_aload_0 = 42,
|
||||
JVM_OPC_aload_1 = 43,
|
||||
JVM_OPC_aload_2 = 44,
|
||||
JVM_OPC_aload_3 = 45,
|
||||
JVM_OPC_iaload = 46,
|
||||
JVM_OPC_laload = 47,
|
||||
JVM_OPC_faload = 48,
|
||||
JVM_OPC_daload = 49,
|
||||
JVM_OPC_aaload = 50,
|
||||
JVM_OPC_baload = 51,
|
||||
JVM_OPC_caload = 52,
|
||||
JVM_OPC_saload = 53,
|
||||
JVM_OPC_istore = 54,
|
||||
JVM_OPC_lstore = 55,
|
||||
JVM_OPC_fstore = 56,
|
||||
JVM_OPC_dstore = 57,
|
||||
JVM_OPC_astore = 58,
|
||||
JVM_OPC_istore_0 = 59,
|
||||
JVM_OPC_istore_1 = 60,
|
||||
JVM_OPC_istore_2 = 61,
|
||||
JVM_OPC_istore_3 = 62,
|
||||
JVM_OPC_lstore_0 = 63,
|
||||
JVM_OPC_lstore_1 = 64,
|
||||
JVM_OPC_lstore_2 = 65,
|
||||
JVM_OPC_lstore_3 = 66,
|
||||
JVM_OPC_fstore_0 = 67,
|
||||
JVM_OPC_fstore_1 = 68,
|
||||
JVM_OPC_fstore_2 = 69,
|
||||
JVM_OPC_fstore_3 = 70,
|
||||
JVM_OPC_dstore_0 = 71,
|
||||
JVM_OPC_dstore_1 = 72,
|
||||
JVM_OPC_dstore_2 = 73,
|
||||
JVM_OPC_dstore_3 = 74,
|
||||
JVM_OPC_astore_0 = 75,
|
||||
JVM_OPC_astore_1 = 76,
|
||||
JVM_OPC_astore_2 = 77,
|
||||
JVM_OPC_astore_3 = 78,
|
||||
JVM_OPC_iastore = 79,
|
||||
JVM_OPC_lastore = 80,
|
||||
JVM_OPC_fastore = 81,
|
||||
JVM_OPC_dastore = 82,
|
||||
JVM_OPC_aastore = 83,
|
||||
JVM_OPC_bastore = 84,
|
||||
JVM_OPC_castore = 85,
|
||||
JVM_OPC_sastore = 86,
|
||||
JVM_OPC_pop = 87,
|
||||
JVM_OPC_pop2 = 88,
|
||||
JVM_OPC_dup = 89,
|
||||
JVM_OPC_dup_x1 = 90,
|
||||
JVM_OPC_dup_x2 = 91,
|
||||
JVM_OPC_dup2 = 92,
|
||||
JVM_OPC_dup2_x1 = 93,
|
||||
JVM_OPC_dup2_x2 = 94,
|
||||
JVM_OPC_swap = 95,
|
||||
JVM_OPC_iadd = 96,
|
||||
JVM_OPC_ladd = 97,
|
||||
JVM_OPC_fadd = 98,
|
||||
JVM_OPC_dadd = 99,
|
||||
JVM_OPC_isub = 100,
|
||||
JVM_OPC_lsub = 101,
|
||||
JVM_OPC_fsub = 102,
|
||||
JVM_OPC_dsub = 103,
|
||||
JVM_OPC_imul = 104,
|
||||
JVM_OPC_lmul = 105,
|
||||
JVM_OPC_fmul = 106,
|
||||
JVM_OPC_dmul = 107,
|
||||
JVM_OPC_idiv = 108,
|
||||
JVM_OPC_ldiv = 109,
|
||||
JVM_OPC_fdiv = 110,
|
||||
JVM_OPC_ddiv = 111,
|
||||
JVM_OPC_irem = 112,
|
||||
JVM_OPC_lrem = 113,
|
||||
JVM_OPC_frem = 114,
|
||||
JVM_OPC_drem = 115,
|
||||
JVM_OPC_ineg = 116,
|
||||
JVM_OPC_lneg = 117,
|
||||
JVM_OPC_fneg = 118,
|
||||
JVM_OPC_dneg = 119,
|
||||
JVM_OPC_ishl = 120,
|
||||
JVM_OPC_lshl = 121,
|
||||
JVM_OPC_ishr = 122,
|
||||
JVM_OPC_lshr = 123,
|
||||
JVM_OPC_iushr = 124,
|
||||
JVM_OPC_lushr = 125,
|
||||
JVM_OPC_iand = 126,
|
||||
JVM_OPC_land = 127,
|
||||
JVM_OPC_ior = 128,
|
||||
JVM_OPC_lor = 129,
|
||||
JVM_OPC_ixor = 130,
|
||||
JVM_OPC_lxor = 131,
|
||||
JVM_OPC_iinc = 132,
|
||||
JVM_OPC_i2l = 133,
|
||||
JVM_OPC_i2f = 134,
|
||||
JVM_OPC_i2d = 135,
|
||||
JVM_OPC_l2i = 136,
|
||||
JVM_OPC_l2f = 137,
|
||||
JVM_OPC_l2d = 138,
|
||||
JVM_OPC_f2i = 139,
|
||||
JVM_OPC_f2l = 140,
|
||||
JVM_OPC_f2d = 141,
|
||||
JVM_OPC_d2i = 142,
|
||||
JVM_OPC_d2l = 143,
|
||||
JVM_OPC_d2f = 144,
|
||||
JVM_OPC_i2b = 145,
|
||||
JVM_OPC_i2c = 146,
|
||||
JVM_OPC_i2s = 147,
|
||||
JVM_OPC_lcmp = 148,
|
||||
JVM_OPC_fcmpl = 149,
|
||||
JVM_OPC_fcmpg = 150,
|
||||
JVM_OPC_dcmpl = 151,
|
||||
JVM_OPC_dcmpg = 152,
|
||||
JVM_OPC_ifeq = 153,
|
||||
JVM_OPC_ifne = 154,
|
||||
JVM_OPC_iflt = 155,
|
||||
JVM_OPC_ifge = 156,
|
||||
JVM_OPC_ifgt = 157,
|
||||
JVM_OPC_ifle = 158,
|
||||
JVM_OPC_if_icmpeq = 159,
|
||||
JVM_OPC_if_icmpne = 160,
|
||||
JVM_OPC_if_icmplt = 161,
|
||||
JVM_OPC_if_icmpge = 162,
|
||||
JVM_OPC_if_icmpgt = 163,
|
||||
JVM_OPC_if_icmple = 164,
|
||||
JVM_OPC_if_acmpeq = 165,
|
||||
JVM_OPC_if_acmpne = 166,
|
||||
JVM_OPC_goto = 167,
|
||||
JVM_OPC_jsr = 168,
|
||||
JVM_OPC_ret = 169,
|
||||
JVM_OPC_tableswitch = 170,
|
||||
JVM_OPC_lookupswitch = 171,
|
||||
JVM_OPC_ireturn = 172,
|
||||
JVM_OPC_lreturn = 173,
|
||||
JVM_OPC_freturn = 174,
|
||||
JVM_OPC_dreturn = 175,
|
||||
JVM_OPC_areturn = 176,
|
||||
JVM_OPC_return = 177,
|
||||
JVM_OPC_getstatic = 178,
|
||||
JVM_OPC_putstatic = 179,
|
||||
JVM_OPC_getfield = 180,
|
||||
JVM_OPC_putfield = 181,
|
||||
JVM_OPC_invokevirtual = 182,
|
||||
JVM_OPC_invokespecial = 183,
|
||||
JVM_OPC_invokestatic = 184,
|
||||
JVM_OPC_invokeinterface = 185,
|
||||
JVM_OPC_xxxunusedxxx = 186,
|
||||
JVM_OPC_new = 187,
|
||||
JVM_OPC_newarray = 188,
|
||||
JVM_OPC_anewarray = 189,
|
||||
JVM_OPC_arraylength = 190,
|
||||
JVM_OPC_athrow = 191,
|
||||
JVM_OPC_checkcast = 192,
|
||||
JVM_OPC_instanceof = 193,
|
||||
JVM_OPC_monitorenter = 194,
|
||||
JVM_OPC_monitorexit = 195,
|
||||
JVM_OPC_wide = 196,
|
||||
JVM_OPC_multianewarray = 197,
|
||||
JVM_OPC_ifnull = 198,
|
||||
JVM_OPC_ifnonnull = 199,
|
||||
JVM_OPC_goto_w = 200,
|
||||
JVM_OPC_jsr_w = 201,
|
||||
JVM_OPC_MAX = 201
|
||||
};
|
||||
|
||||
/* Opcode length initializer, use with something like:
|
||||
* unsigned char opcode_length[JVM_OPC_MAX+1] = JVM_OPCODE_LENGTH_INITIALIZER;
|
||||
*/
|
||||
#define JVM_OPCODE_LENGTH_INITIALIZER { \
|
||||
1, /* nop */ \
|
||||
1, /* aconst_null */ \
|
||||
1, /* iconst_m1 */ \
|
||||
1, /* iconst_0 */ \
|
||||
1, /* iconst_1 */ \
|
||||
1, /* iconst_2 */ \
|
||||
1, /* iconst_3 */ \
|
||||
1, /* iconst_4 */ \
|
||||
1, /* iconst_5 */ \
|
||||
1, /* lconst_0 */ \
|
||||
1, /* lconst_1 */ \
|
||||
1, /* fconst_0 */ \
|
||||
1, /* fconst_1 */ \
|
||||
1, /* fconst_2 */ \
|
||||
1, /* dconst_0 */ \
|
||||
1, /* dconst_1 */ \
|
||||
2, /* bipush */ \
|
||||
3, /* sipush */ \
|
||||
2, /* ldc */ \
|
||||
3, /* ldc_w */ \
|
||||
3, /* ldc2_w */ \
|
||||
2, /* iload */ \
|
||||
2, /* lload */ \
|
||||
2, /* fload */ \
|
||||
2, /* dload */ \
|
||||
2, /* aload */ \
|
||||
1, /* iload_0 */ \
|
||||
1, /* iload_1 */ \
|
||||
1, /* iload_2 */ \
|
||||
1, /* iload_3 */ \
|
||||
1, /* lload_0 */ \
|
||||
1, /* lload_1 */ \
|
||||
1, /* lload_2 */ \
|
||||
1, /* lload_3 */ \
|
||||
1, /* fload_0 */ \
|
||||
1, /* fload_1 */ \
|
||||
1, /* fload_2 */ \
|
||||
1, /* fload_3 */ \
|
||||
1, /* dload_0 */ \
|
||||
1, /* dload_1 */ \
|
||||
1, /* dload_2 */ \
|
||||
1, /* dload_3 */ \
|
||||
1, /* aload_0 */ \
|
||||
1, /* aload_1 */ \
|
||||
1, /* aload_2 */ \
|
||||
1, /* aload_3 */ \
|
||||
1, /* iaload */ \
|
||||
1, /* laload */ \
|
||||
1, /* faload */ \
|
||||
1, /* daload */ \
|
||||
1, /* aaload */ \
|
||||
1, /* baload */ \
|
||||
1, /* caload */ \
|
||||
1, /* saload */ \
|
||||
2, /* istore */ \
|
||||
2, /* lstore */ \
|
||||
2, /* fstore */ \
|
||||
2, /* dstore */ \
|
||||
2, /* astore */ \
|
||||
1, /* istore_0 */ \
|
||||
1, /* istore_1 */ \
|
||||
1, /* istore_2 */ \
|
||||
1, /* istore_3 */ \
|
||||
1, /* lstore_0 */ \
|
||||
1, /* lstore_1 */ \
|
||||
1, /* lstore_2 */ \
|
||||
1, /* lstore_3 */ \
|
||||
1, /* fstore_0 */ \
|
||||
1, /* fstore_1 */ \
|
||||
1, /* fstore_2 */ \
|
||||
1, /* fstore_3 */ \
|
||||
1, /* dstore_0 */ \
|
||||
1, /* dstore_1 */ \
|
||||
1, /* dstore_2 */ \
|
||||
1, /* dstore_3 */ \
|
||||
1, /* astore_0 */ \
|
||||
1, /* astore_1 */ \
|
||||
1, /* astore_2 */ \
|
||||
1, /* astore_3 */ \
|
||||
1, /* iastore */ \
|
||||
1, /* lastore */ \
|
||||
1, /* fastore */ \
|
||||
1, /* dastore */ \
|
||||
1, /* aastore */ \
|
||||
1, /* bastore */ \
|
||||
1, /* castore */ \
|
||||
1, /* sastore */ \
|
||||
1, /* pop */ \
|
||||
1, /* pop2 */ \
|
||||
1, /* dup */ \
|
||||
1, /* dup_x1 */ \
|
||||
1, /* dup_x2 */ \
|
||||
1, /* dup2 */ \
|
||||
1, /* dup2_x1 */ \
|
||||
1, /* dup2_x2 */ \
|
||||
1, /* swap */ \
|
||||
1, /* iadd */ \
|
||||
1, /* ladd */ \
|
||||
1, /* fadd */ \
|
||||
1, /* dadd */ \
|
||||
1, /* isub */ \
|
||||
1, /* lsub */ \
|
||||
1, /* fsub */ \
|
||||
1, /* dsub */ \
|
||||
1, /* imul */ \
|
||||
1, /* lmul */ \
|
||||
1, /* fmul */ \
|
||||
1, /* dmul */ \
|
||||
1, /* idiv */ \
|
||||
1, /* ldiv */ \
|
||||
1, /* fdiv */ \
|
||||
1, /* ddiv */ \
|
||||
1, /* irem */ \
|
||||
1, /* lrem */ \
|
||||
1, /* frem */ \
|
||||
1, /* drem */ \
|
||||
1, /* ineg */ \
|
||||
1, /* lneg */ \
|
||||
1, /* fneg */ \
|
||||
1, /* dneg */ \
|
||||
1, /* ishl */ \
|
||||
1, /* lshl */ \
|
||||
1, /* ishr */ \
|
||||
1, /* lshr */ \
|
||||
1, /* iushr */ \
|
||||
1, /* lushr */ \
|
||||
1, /* iand */ \
|
||||
1, /* land */ \
|
||||
1, /* ior */ \
|
||||
1, /* lor */ \
|
||||
1, /* ixor */ \
|
||||
1, /* lxor */ \
|
||||
3, /* iinc */ \
|
||||
1, /* i2l */ \
|
||||
1, /* i2f */ \
|
||||
1, /* i2d */ \
|
||||
1, /* l2i */ \
|
||||
1, /* l2f */ \
|
||||
1, /* l2d */ \
|
||||
1, /* f2i */ \
|
||||
1, /* f2l */ \
|
||||
1, /* f2d */ \
|
||||
1, /* d2i */ \
|
||||
1, /* d2l */ \
|
||||
1, /* d2f */ \
|
||||
1, /* i2b */ \
|
||||
1, /* i2c */ \
|
||||
1, /* i2s */ \
|
||||
1, /* lcmp */ \
|
||||
1, /* fcmpl */ \
|
||||
1, /* fcmpg */ \
|
||||
1, /* dcmpl */ \
|
||||
1, /* dcmpg */ \
|
||||
3, /* ifeq */ \
|
||||
3, /* ifne */ \
|
||||
3, /* iflt */ \
|
||||
3, /* ifge */ \
|
||||
3, /* ifgt */ \
|
||||
3, /* ifle */ \
|
||||
3, /* if_icmpeq */ \
|
||||
3, /* if_icmpne */ \
|
||||
3, /* if_icmplt */ \
|
||||
3, /* if_icmpge */ \
|
||||
3, /* if_icmpgt */ \
|
||||
3, /* if_icmple */ \
|
||||
3, /* if_acmpeq */ \
|
||||
3, /* if_acmpne */ \
|
||||
3, /* goto */ \
|
||||
3, /* jsr */ \
|
||||
2, /* ret */ \
|
||||
99, /* tableswitch */ \
|
||||
99, /* lookupswitch */ \
|
||||
1, /* ireturn */ \
|
||||
1, /* lreturn */ \
|
||||
1, /* freturn */ \
|
||||
1, /* dreturn */ \
|
||||
1, /* areturn */ \
|
||||
1, /* return */ \
|
||||
3, /* getstatic */ \
|
||||
3, /* putstatic */ \
|
||||
3, /* getfield */ \
|
||||
3, /* putfield */ \
|
||||
3, /* invokevirtual */ \
|
||||
3, /* invokespecial */ \
|
||||
3, /* invokestatic */ \
|
||||
5, /* invokeinterface */ \
|
||||
0, /* xxxunusedxxx */ \
|
||||
3, /* new */ \
|
||||
2, /* newarray */ \
|
||||
3, /* anewarray */ \
|
||||
1, /* arraylength */ \
|
||||
1, /* athrow */ \
|
||||
3, /* checkcast */ \
|
||||
3, /* instanceof */ \
|
||||
1, /* monitorenter */ \
|
||||
1, /* monitorexit */ \
|
||||
0, /* wide */ \
|
||||
4, /* multianewarray */ \
|
||||
3, /* ifnull */ \
|
||||
3, /* ifnonnull */ \
|
||||
5, /* goto_w */ \
|
||||
5 /* jsr_w */ \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CLASSFILE_CONSTANTS */
|
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JAWT_H_
|
||||
#define _JAVASOFT_JAWT_H_
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AWT native interface (new in JDK 1.3)
|
||||
*
|
||||
* The AWT native interface allows a native C or C++ application a means
|
||||
* by which to access native structures in AWT. This is to facilitate moving
|
||||
* legacy C and C++ applications to Java and to target the needs of the
|
||||
* community who, at present, wish to do their own native rendering to canvases
|
||||
* for performance reasons. Standard extensions such as Java3D also require a
|
||||
* means to access the underlying native data structures of AWT.
|
||||
*
|
||||
* There may be future extensions to this API depending on demand.
|
||||
*
|
||||
* A VM does not have to implement this API in order to pass the JCK.
|
||||
* It is recommended, however, that this API is implemented on VMs that support
|
||||
* standard extensions, such as Java3D.
|
||||
*
|
||||
* Since this is a native API, any program which uses it cannot be considered
|
||||
* 100% pure java.
|
||||
*/
|
||||
|
||||
/*
|
||||
* AWT Native Drawing Surface (JAWT_DrawingSurface).
|
||||
*
|
||||
* For each platform, there is a native drawing surface structure. This
|
||||
* platform-specific structure can be found in jawt_md.h. It is recommended
|
||||
* that additional platforms follow the same model. It is also recommended
|
||||
* that VMs on Win32 and Solaris support the existing structures in jawt_md.h.
|
||||
*
|
||||
*******************
|
||||
* EXAMPLE OF USAGE:
|
||||
*******************
|
||||
*
|
||||
* In Win32, a programmer wishes to access the HWND of a canvas to perform
|
||||
* native rendering into it. The programmer has declared the paint() method
|
||||
* for their canvas subclass to be native:
|
||||
*
|
||||
*
|
||||
* MyCanvas.java:
|
||||
*
|
||||
* import java.awt.*;
|
||||
*
|
||||
* public class MyCanvas extends Canvas {
|
||||
*
|
||||
* static {
|
||||
* System.loadLibrary("mylib");
|
||||
* }
|
||||
*
|
||||
* public native void paint(Graphics g);
|
||||
* }
|
||||
*
|
||||
*
|
||||
* myfile.c:
|
||||
*
|
||||
* #include "jawt_md.h"
|
||||
* #include <assert.h>
|
||||
*
|
||||
* JNIEXPORT void JNICALL
|
||||
* Java_MyCanvas_paint(JNIEnv* env, jobject canvas, jobject graphics)
|
||||
* {
|
||||
* JAWT awt;
|
||||
* JAWT_DrawingSurface* ds;
|
||||
* JAWT_DrawingSurfaceInfo* dsi;
|
||||
* JAWT_Win32DrawingSurfaceInfo* dsi_win;
|
||||
* jboolean result;
|
||||
* jint lock;
|
||||
*
|
||||
* // Get the AWT
|
||||
* awt.version = JAWT_VERSION_1_3;
|
||||
* result = JAWT_GetAWT(env, &awt);
|
||||
* assert(result != JNI_FALSE);
|
||||
*
|
||||
* // Get the drawing surface
|
||||
* ds = awt.GetDrawingSurface(env, canvas);
|
||||
* assert(ds != NULL);
|
||||
*
|
||||
* // Lock the drawing surface
|
||||
* lock = ds->Lock(ds);
|
||||
* assert((lock & JAWT_LOCK_ERROR) == 0);
|
||||
*
|
||||
* // Get the drawing surface info
|
||||
* dsi = ds->GetDrawingSurfaceInfo(ds);
|
||||
*
|
||||
* // Get the platform-specific drawing info
|
||||
* dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
|
||||
*
|
||||
* //////////////////////////////
|
||||
* // !!! DO PAINTING HERE !!! //
|
||||
* //////////////////////////////
|
||||
*
|
||||
* // Free the drawing surface info
|
||||
* ds->FreeDrawingSurfaceInfo(dsi);
|
||||
*
|
||||
* // Unlock the drawing surface
|
||||
* ds->Unlock(ds);
|
||||
*
|
||||
* // Free the drawing surface
|
||||
* awt.FreeDrawingSurface(ds);
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* JAWT_Rectangle
|
||||
* Structure for a native rectangle.
|
||||
*/
|
||||
typedef struct jawt_Rectangle {
|
||||
jint x;
|
||||
jint y;
|
||||
jint width;
|
||||
jint height;
|
||||
} JAWT_Rectangle;
|
||||
|
||||
struct jawt_DrawingSurface;
|
||||
|
||||
/*
|
||||
* JAWT_DrawingSurfaceInfo
|
||||
* Structure for containing the underlying drawing information of a component.
|
||||
*/
|
||||
typedef struct jawt_DrawingSurfaceInfo {
|
||||
/*
|
||||
* Pointer to the platform-specific information. This can be safely
|
||||
* cast to a JAWT_Win32DrawingSurfaceInfo on Windows or a
|
||||
* JAWT_X11DrawingSurfaceInfo on Solaris. See jawt_md.h for details.
|
||||
*/
|
||||
void* platformInfo;
|
||||
/* Cached pointer to the underlying drawing surface */
|
||||
struct jawt_DrawingSurface* ds;
|
||||
/* Bounding rectangle of the drawing surface */
|
||||
JAWT_Rectangle bounds;
|
||||
/* Number of rectangles in the clip */
|
||||
jint clipSize;
|
||||
/* Clip rectangle array */
|
||||
JAWT_Rectangle* clip;
|
||||
} JAWT_DrawingSurfaceInfo;
|
||||
|
||||
#define JAWT_LOCK_ERROR 0x00000001
|
||||
#define JAWT_LOCK_CLIP_CHANGED 0x00000002
|
||||
#define JAWT_LOCK_BOUNDS_CHANGED 0x00000004
|
||||
#define JAWT_LOCK_SURFACE_CHANGED 0x00000008
|
||||
|
||||
/*
|
||||
* JAWT_DrawingSurface
|
||||
* Structure for containing the underlying drawing information of a component.
|
||||
* All operations on a JAWT_DrawingSurface MUST be performed from the same
|
||||
* thread as the call to GetDrawingSurface.
|
||||
*/
|
||||
typedef struct jawt_DrawingSurface {
|
||||
/*
|
||||
* Cached reference to the Java environment of the calling thread.
|
||||
* If Lock(), Unlock(), GetDrawingSurfaceInfo() or
|
||||
* FreeDrawingSurfaceInfo() are called from a different thread,
|
||||
* this data member should be set before calling those functions.
|
||||
*/
|
||||
JNIEnv* env;
|
||||
/* Cached reference to the target object */
|
||||
jobject target;
|
||||
/*
|
||||
* Lock the surface of the target component for native rendering.
|
||||
* When finished drawing, the surface must be unlocked with
|
||||
* Unlock(). This function returns a bitmask with one or more of the
|
||||
* following values:
|
||||
*
|
||||
* JAWT_LOCK_ERROR - When an error has occurred and the surface could not
|
||||
* be locked.
|
||||
*
|
||||
* JAWT_LOCK_CLIP_CHANGED - When the clip region has changed.
|
||||
*
|
||||
* JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed.
|
||||
*
|
||||
* JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed
|
||||
*/
|
||||
jint (JNICALL *Lock)
|
||||
(struct jawt_DrawingSurface* ds);
|
||||
/*
|
||||
* Get the drawing surface info.
|
||||
* The value returned may be cached, but the values may change if
|
||||
* additional calls to Lock() or Unlock() are made.
|
||||
* Lock() must be called before this can return a valid value.
|
||||
* Returns NULL if an error has occurred.
|
||||
* When finished with the returned value, FreeDrawingSurfaceInfo must be
|
||||
* called.
|
||||
*/
|
||||
JAWT_DrawingSurfaceInfo* (JNICALL *GetDrawingSurfaceInfo)
|
||||
(struct jawt_DrawingSurface* ds);
|
||||
/*
|
||||
* Free the drawing surface info.
|
||||
*/
|
||||
void (JNICALL *FreeDrawingSurfaceInfo)
|
||||
(JAWT_DrawingSurfaceInfo* dsi);
|
||||
/*
|
||||
* Unlock the drawing surface of the target component for native rendering.
|
||||
*/
|
||||
void (JNICALL *Unlock)
|
||||
(struct jawt_DrawingSurface* ds);
|
||||
} JAWT_DrawingSurface;
|
||||
|
||||
/*
|
||||
* JAWT
|
||||
* Structure for containing native AWT functions.
|
||||
*/
|
||||
typedef struct jawt {
|
||||
/*
|
||||
* Version of this structure. This must always be set before
|
||||
* calling JAWT_GetAWT()
|
||||
*/
|
||||
jint version;
|
||||
/*
|
||||
* Return a drawing surface from a target jobject. This value
|
||||
* may be cached.
|
||||
* Returns NULL if an error has occurred.
|
||||
* Target must be a java.awt.Component (should be a Canvas
|
||||
* or Window for native rendering).
|
||||
* FreeDrawingSurface() must be called when finished with the
|
||||
* returned JAWT_DrawingSurface.
|
||||
*/
|
||||
JAWT_DrawingSurface* (JNICALL *GetDrawingSurface)
|
||||
(JNIEnv* env, jobject target);
|
||||
/*
|
||||
* Free the drawing surface allocated in GetDrawingSurface.
|
||||
*/
|
||||
void (JNICALL *FreeDrawingSurface)
|
||||
(JAWT_DrawingSurface* ds);
|
||||
/*
|
||||
* Since 1.4
|
||||
* Locks the entire AWT for synchronization purposes
|
||||
*/
|
||||
void (JNICALL *Lock)(JNIEnv* env);
|
||||
/*
|
||||
* Since 1.4
|
||||
* Unlocks the entire AWT for synchronization purposes
|
||||
*/
|
||||
void (JNICALL *Unlock)(JNIEnv* env);
|
||||
/*
|
||||
* Since 1.4
|
||||
* Returns a reference to a java.awt.Component from a native
|
||||
* platform handle. On Windows, this corresponds to an HWND;
|
||||
* on Solaris and Linux, this is a Drawable. For other platforms,
|
||||
* see the appropriate machine-dependent header file for a description.
|
||||
* The reference returned by this function is a local
|
||||
* reference that is only valid in this environment.
|
||||
* This function returns a NULL reference if no component could be
|
||||
* found with matching platform information.
|
||||
*/
|
||||
jobject (JNICALL *GetComponent)(JNIEnv* env, void* platformInfo);
|
||||
|
||||
} JAWT;
|
||||
|
||||
/*
|
||||
* Get the AWT native structure. This function returns JNI_FALSE if
|
||||
* an error occurs.
|
||||
*/
|
||||
_JNI_IMPORT_OR_EXPORT_
|
||||
jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt);
|
||||
|
||||
#define JAWT_VERSION_1_3 0x00010003
|
||||
#define JAWT_VERSION_1_4 0x00010004
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* !_JAVASOFT_JAWT_H_ */
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Java Debug Wire Protocol Transport Service Provider Interface.
|
||||
*/
|
||||
|
||||
#ifndef JDWPTRANSPORT_H
|
||||
#define JDWPTRANSPORT_H
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
enum {
|
||||
JDWPTRANSPORT_VERSION_1_0 = 0x00010000
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct jdwpTransportNativeInterface_;
|
||||
|
||||
struct _jdwpTransportEnv;
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef _jdwpTransportEnv jdwpTransportEnv;
|
||||
#else
|
||||
typedef const struct jdwpTransportNativeInterface_ *jdwpTransportEnv;
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Errors. Universal errors with JVMTI/JVMDI equivalents keep the
|
||||
* values the same.
|
||||
*/
|
||||
typedef enum {
|
||||
JDWPTRANSPORT_ERROR_NONE = 0,
|
||||
JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT = 103,
|
||||
JDWPTRANSPORT_ERROR_OUT_OF_MEMORY = 110,
|
||||
JDWPTRANSPORT_ERROR_INTERNAL = 113,
|
||||
JDWPTRANSPORT_ERROR_ILLEGAL_STATE = 201,
|
||||
JDWPTRANSPORT_ERROR_IO_ERROR = 202,
|
||||
JDWPTRANSPORT_ERROR_TIMEOUT = 203,
|
||||
JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE = 204
|
||||
} jdwpTransportError;
|
||||
|
||||
|
||||
/*
|
||||
* Structure to define capabilities
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int can_timeout_attach :1;
|
||||
unsigned int can_timeout_accept :1;
|
||||
unsigned int can_timeout_handshake :1;
|
||||
unsigned int reserved3 :1;
|
||||
unsigned int reserved4 :1;
|
||||
unsigned int reserved5 :1;
|
||||
unsigned int reserved6 :1;
|
||||
unsigned int reserved7 :1;
|
||||
unsigned int reserved8 :1;
|
||||
unsigned int reserved9 :1;
|
||||
unsigned int reserved10 :1;
|
||||
unsigned int reserved11 :1;
|
||||
unsigned int reserved12 :1;
|
||||
unsigned int reserved13 :1;
|
||||
unsigned int reserved14 :1;
|
||||
unsigned int reserved15 :1;
|
||||
} JDWPTransportCapabilities;
|
||||
|
||||
|
||||
/*
|
||||
* Structures to define packet layout.
|
||||
*
|
||||
* See: http://java.sun.com/j2se/1.5/docs/guide/jpda/jdwp-spec.html
|
||||
*/
|
||||
|
||||
enum {
|
||||
JDWPTRANSPORT_FLAGS_NONE = 0x0,
|
||||
JDWPTRANSPORT_FLAGS_REPLY = 0x80
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
jint len;
|
||||
jint id;
|
||||
jbyte flags;
|
||||
jbyte cmdSet;
|
||||
jbyte cmd;
|
||||
jbyte *data;
|
||||
} jdwpCmdPacket;
|
||||
|
||||
typedef struct {
|
||||
jint len;
|
||||
jint id;
|
||||
jbyte flags;
|
||||
jshort errorCode;
|
||||
jbyte *data;
|
||||
} jdwpReplyPacket;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
jdwpCmdPacket cmd;
|
||||
jdwpReplyPacket reply;
|
||||
} type;
|
||||
} jdwpPacket;
|
||||
|
||||
/*
|
||||
* JDWP functions called by the transport.
|
||||
*/
|
||||
typedef struct jdwpTransportCallback {
|
||||
void *(*alloc)(jint numBytes); /* Call this for all allocations */
|
||||
void (*free)(void *buffer); /* Call this for all deallocations */
|
||||
} jdwpTransportCallback;
|
||||
|
||||
typedef jint (JNICALL *jdwpTransport_OnLoad_t)(JavaVM *jvm,
|
||||
jdwpTransportCallback *callback,
|
||||
jint version,
|
||||
jdwpTransportEnv** env);
|
||||
|
||||
|
||||
|
||||
/* Function Interface */
|
||||
|
||||
struct jdwpTransportNativeInterface_ {
|
||||
/* 1 : RESERVED */
|
||||
void *reserved1;
|
||||
|
||||
/* 2 : Get Capabilities */
|
||||
jdwpTransportError (JNICALL *GetCapabilities)(jdwpTransportEnv* env,
|
||||
JDWPTransportCapabilities *capabilities_ptr);
|
||||
|
||||
/* 3 : Attach */
|
||||
jdwpTransportError (JNICALL *Attach)(jdwpTransportEnv* env,
|
||||
const char* address,
|
||||
jlong attach_timeout,
|
||||
jlong handshake_timeout);
|
||||
|
||||
/* 4: StartListening */
|
||||
jdwpTransportError (JNICALL *StartListening)(jdwpTransportEnv* env,
|
||||
const char* address,
|
||||
char** actual_address);
|
||||
|
||||
/* 5: StopListening */
|
||||
jdwpTransportError (JNICALL *StopListening)(jdwpTransportEnv* env);
|
||||
|
||||
/* 6: Accept */
|
||||
jdwpTransportError (JNICALL *Accept)(jdwpTransportEnv* env,
|
||||
jlong accept_timeout,
|
||||
jlong handshake_timeout);
|
||||
|
||||
/* 7: IsOpen */
|
||||
jboolean (JNICALL *IsOpen)(jdwpTransportEnv* env);
|
||||
|
||||
/* 8: Close */
|
||||
jdwpTransportError (JNICALL *Close)(jdwpTransportEnv* env);
|
||||
|
||||
/* 9: ReadPacket */
|
||||
jdwpTransportError (JNICALL *ReadPacket)(jdwpTransportEnv* env,
|
||||
jdwpPacket *pkt);
|
||||
|
||||
/* 10: Write Packet */
|
||||
jdwpTransportError (JNICALL *WritePacket)(jdwpTransportEnv* env,
|
||||
const jdwpPacket* pkt);
|
||||
|
||||
/* 11: GetLastError */
|
||||
jdwpTransportError (JNICALL *GetLastError)(jdwpTransportEnv* env,
|
||||
char** error);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Use inlined functions so that C++ code can use syntax such as
|
||||
* env->Attach("mymachine:5000", 10*1000, 0);
|
||||
*
|
||||
* rather than using C's :-
|
||||
*
|
||||
* (*env)->Attach(env, "mymachine:5000", 10*1000, 0);
|
||||
*/
|
||||
struct _jdwpTransportEnv {
|
||||
const struct jdwpTransportNativeInterface_ *functions;
|
||||
#ifdef __cplusplus
|
||||
|
||||
jdwpTransportError GetCapabilities(JDWPTransportCapabilities *capabilities_ptr) {
|
||||
return functions->GetCapabilities(this, capabilities_ptr);
|
||||
}
|
||||
|
||||
jdwpTransportError Attach(const char* address, jlong attach_timeout,
|
||||
jlong handshake_timeout) {
|
||||
return functions->Attach(this, address, attach_timeout, handshake_timeout);
|
||||
}
|
||||
|
||||
jdwpTransportError StartListening(const char* address,
|
||||
char** actual_address) {
|
||||
return functions->StartListening(this, address, actual_address);
|
||||
}
|
||||
|
||||
jdwpTransportError StopListening(void) {
|
||||
return functions->StopListening(this);
|
||||
}
|
||||
|
||||
jdwpTransportError Accept(jlong accept_timeout, jlong handshake_timeout) {
|
||||
return functions->Accept(this, accept_timeout, handshake_timeout);
|
||||
}
|
||||
|
||||
jboolean IsOpen(void) {
|
||||
return functions->IsOpen(this);
|
||||
}
|
||||
|
||||
jdwpTransportError Close(void) {
|
||||
return functions->Close(this);
|
||||
}
|
||||
|
||||
jdwpTransportError ReadPacket(jdwpPacket *pkt) {
|
||||
return functions->ReadPacket(this, pkt);
|
||||
}
|
||||
|
||||
jdwpTransportError WritePacket(const jdwpPacket* pkt) {
|
||||
return functions->WritePacket(this, pkt);
|
||||
}
|
||||
|
||||
jdwpTransportError GetLastError(char** error) {
|
||||
return functions->GetLastError(this, error);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __cplusplus */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* JDWPTRANSPORT_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This header file defines the data structures sent by the VM
|
||||
* through the JVMTI CompiledMethodLoad callback function via the
|
||||
* "void * compile_info" parameter. The memory pointed to by the
|
||||
* compile_info parameter may not be referenced after returning from
|
||||
* the CompiledMethodLoad callback. These are VM implementation
|
||||
* specific data structures that may evolve in future releases. A
|
||||
* JVMTI agent should interpret a non-NULL compile_info as a pointer
|
||||
* to a region of memory containing a list of records. In a typical
|
||||
* usage scenario, a JVMTI agent would cast each record to a
|
||||
* jvmtiCompiledMethodLoadRecordHeader, a struct that represents
|
||||
* arbitrary information. This struct contains a kind field to indicate
|
||||
* the kind of information being passed, and a pointer to the next
|
||||
* record. If the kind field indicates inlining information, then the
|
||||
* agent would cast the record to a jvmtiCompiledMethodLoadInlineRecord.
|
||||
* This record contains an array of PCStackInfo structs, which indicate
|
||||
* for every pc address what are the methods on the invocation stack.
|
||||
* The "methods" and "bcis" fields in each PCStackInfo struct specify a
|
||||
* 1-1 mapping between these inlined methods and their bytecode indices.
|
||||
* This can be used to derive the proper source lines of the inlined
|
||||
* methods.
|
||||
*/
|
||||
|
||||
#ifndef _JVMTI_CMLR_H_
|
||||
#define _JVMTI_CMLR_H_
|
||||
|
||||
enum {
|
||||
JVMTI_CMLR_MAJOR_VERSION_1 = 0x00000001,
|
||||
JVMTI_CMLR_MINOR_VERSION_0 = 0x00000000,
|
||||
|
||||
JVMTI_CMLR_MAJOR_VERSION = 0x00000001,
|
||||
JVMTI_CMLR_MINOR_VERSION = 0x00000000
|
||||
|
||||
/*
|
||||
* This comment is for the "JDK import from HotSpot" sanity check:
|
||||
* version: 1.0.0
|
||||
*/
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
JVMTI_CMLR_DUMMY = 1,
|
||||
JVMTI_CMLR_INLINE_INFO = 2
|
||||
} jvmtiCMLRKind;
|
||||
|
||||
/*
|
||||
* Record that represents arbitrary information passed through JVMTI
|
||||
* CompiledMethodLoadEvent void pointer.
|
||||
*/
|
||||
typedef struct _jvmtiCompiledMethodLoadRecordHeader {
|
||||
jvmtiCMLRKind kind; /* id for the kind of info passed in the record */
|
||||
jint majorinfoversion; /* major and minor info version values. Init'ed */
|
||||
jint minorinfoversion; /* to current version value in jvmtiExport.cpp. */
|
||||
|
||||
struct _jvmtiCompiledMethodLoadRecordHeader* next;
|
||||
} jvmtiCompiledMethodLoadRecordHeader;
|
||||
|
||||
/*
|
||||
* Record that gives information about the methods on the compile-time
|
||||
* stack at a specific pc address of a compiled method. Each element in
|
||||
* the methods array maps to same element in the bcis array.
|
||||
*/
|
||||
typedef struct _PCStackInfo {
|
||||
void* pc; /* the pc address for this compiled method */
|
||||
jint numstackframes; /* number of methods on the stack */
|
||||
jmethodID* methods; /* array of numstackframes method ids */
|
||||
jint* bcis; /* array of numstackframes bytecode indices */
|
||||
} PCStackInfo;
|
||||
|
||||
/*
|
||||
* Record that contains inlining information for each pc address of
|
||||
* an nmethod.
|
||||
*/
|
||||
typedef struct _jvmtiCompiledMethodLoadInlineRecord {
|
||||
jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
|
||||
jint numpcs; /* number of pc descriptors in this nmethod */
|
||||
PCStackInfo* pcinfo; /* array of numpcs pc descriptors */
|
||||
} jvmtiCompiledMethodLoadInlineRecord;
|
||||
|
||||
/*
|
||||
* Dummy record used to test that we can pass records with different
|
||||
* information through the void pointer provided that they can be cast
|
||||
* to a jvmtiCompiledMethodLoadRecordHeader.
|
||||
*/
|
||||
|
||||
typedef struct _jvmtiCompiledMethodLoadDummyRecord {
|
||||
jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
|
||||
char message[50];
|
||||
} jvmtiCompiledMethodLoadDummyRecord;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JAWT_MD_H_
|
||||
#define _JAVASOFT_JAWT_MD_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include "jawt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* X11-specific declarations for AWT native interface.
|
||||
* See notes in jawt.h for an example of use.
|
||||
*/
|
||||
typedef struct jawt_X11DrawingSurfaceInfo {
|
||||
Drawable drawable;
|
||||
Display* display;
|
||||
VisualID visualID;
|
||||
Colormap colormapID;
|
||||
int depth;
|
||||
/*
|
||||
* Since 1.4
|
||||
* Returns a pixel value from a set of RGB values.
|
||||
* This is useful for paletted color (256 color) modes.
|
||||
*/
|
||||
int (JNICALL *GetAWTColor)(JAWT_DrawingSurface* ds,
|
||||
int r, int g, int b);
|
||||
} JAWT_X11DrawingSurfaceInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_JAVASOFT_JAWT_MD_H_ */
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JNI_MD_H_
|
||||
#define _JAVASOFT_JNI_MD_H_
|
||||
|
||||
#define JNIEXPORT
|
||||
#define JNIIMPORT
|
||||
#define JNICALL
|
||||
|
||||
typedef int jint;
|
||||
#ifdef _LP64 /* 64-bit Solaris */
|
||||
typedef long jlong;
|
||||
#else
|
||||
typedef long long jlong;
|
||||
#endif
|
||||
|
||||
typedef signed char jbyte;
|
||||
|
||||
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// AWTCocoaComponent.h
|
||||
//
|
||||
// Copyright (c) 2003 Apple Computer Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <JavaVM/jni.h>
|
||||
|
||||
// This is implemented by a com.apple.eawt.CocoaComponent. It receives messages
|
||||
// from java safely on the AppKit thread. See the com.apple.eawt.CocoaComponent
|
||||
// java documentation for more information.
|
||||
@protocol AWTCocoaComponent
|
||||
-(void)awtMessage:(jint)messageID message:(jobject)message env:(JNIEnv*)env;
|
||||
@end
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* @(#)JDWP.h 1.33 05/11/17
|
||||
*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef JDWP_JDWP_H
|
||||
#define JDWP_JDWP_H
|
||||
|
||||
#include "JDWPCommands.h"
|
||||
|
||||
/*
|
||||
* JDWPCommands.h is the javah'ed version of all the constants defined
|
||||
* com.sun.tools.jdi.JDWP and all its nested classes. Since the names are
|
||||
* very long, the macros below are provided for convenience.
|
||||
*/
|
||||
|
||||
#define JDWP_COMMAND_SET(name) JDWP_ ## name
|
||||
#define JDWP_COMMAND(set, name) JDWP_ ## set ## _ ## name
|
||||
#define JDWP_REQUEST_MODIFIER(name) \
|
||||
JDWP_EventRequest_Set_Out_modifiers_Modifier_ ## name
|
||||
#define JDWP_EVENT(name) \
|
||||
JDWP_EventKind_ ## name
|
||||
#define JDWP_THREAD_STATUS(name) \
|
||||
JDWP_ThreadStatus_ ## name
|
||||
#define JDWP_SUSPEND_STATUS(name) \
|
||||
JDWP_SuspendStatus_SUSPEND_STATUS_ ## name
|
||||
#define JDWP_CLASS_STATUS(name) \
|
||||
JDWP_ClassStatus_ ## name
|
||||
#define JDWP_TYPE_TAG(name) \
|
||||
JDWP_TypeTag_ ## name
|
||||
#define JDWP_TAG(name) \
|
||||
JDWP_Tag_ ## name
|
||||
#define JDWP_STEP_DEPTH(name) \
|
||||
JDWP_StepDepth_ ## name
|
||||
#define JDWP_STEP_SIZE(name) \
|
||||
JDWP_StepSize_ ## name
|
||||
#define JDWP_SUSPEND_POLICY(name) \
|
||||
JDWP_SuspendPolicy_ ## name
|
||||
#define JDWP_INVOKE_OPTIONS(name) \
|
||||
JDWP_InvokeOptions_INVOKE_ ## name
|
||||
#define JDWP_ERROR(name) \
|
||||
JDWP_Error_ ## name
|
||||
#define JDWP_HIGHEST_COMMAND_SET 17
|
||||
#define JDWP_REQUEST_NONE -1
|
||||
|
||||
/* This typedef helps keep the event and error types straight. */
|
||||
typedef unsigned short jdwpError;
|
||||
typedef unsigned char jdwpEvent;
|
||||
typedef jint jdwpThreadStatus;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,257 @@
|
|||
#define JDWP_VirtualMachine 1
|
||||
#define JDWP_VirtualMachine_Version 1
|
||||
#define JDWP_VirtualMachine_ClassesBySignature 2
|
||||
#define JDWP_VirtualMachine_AllClasses 3
|
||||
#define JDWP_VirtualMachine_AllThreads 4
|
||||
#define JDWP_VirtualMachine_TopLevelThreadGroups 5
|
||||
#define JDWP_VirtualMachine_Dispose 6
|
||||
#define JDWP_VirtualMachine_IDSizes 7
|
||||
#define JDWP_VirtualMachine_Suspend 8
|
||||
#define JDWP_VirtualMachine_Resume 9
|
||||
#define JDWP_VirtualMachine_Exit 10
|
||||
#define JDWP_VirtualMachine_CreateString 11
|
||||
#define JDWP_VirtualMachine_Capabilities 12
|
||||
#define JDWP_VirtualMachine_ClassPaths 13
|
||||
#define JDWP_VirtualMachine_DisposeObjects 14
|
||||
#define JDWP_VirtualMachine_HoldEvents 15
|
||||
#define JDWP_VirtualMachine_ReleaseEvents 16
|
||||
#define JDWP_VirtualMachine_CapabilitiesNew 17
|
||||
#define JDWP_VirtualMachine_RedefineClasses 18
|
||||
#define JDWP_VirtualMachine_SetDefaultStratum 19
|
||||
#define JDWP_VirtualMachine_AllClassesWithGeneric 20
|
||||
#define JDWP_VirtualMachine_InstanceCounts 21
|
||||
#define JDWP_ReferenceType 2
|
||||
#define JDWP_ReferenceType_Signature 1
|
||||
#define JDWP_ReferenceType_ClassLoader 2
|
||||
#define JDWP_ReferenceType_Modifiers 3
|
||||
#define JDWP_ReferenceType_Fields 4
|
||||
#define JDWP_ReferenceType_Methods 5
|
||||
#define JDWP_ReferenceType_GetValues 6
|
||||
#define JDWP_ReferenceType_SourceFile 7
|
||||
#define JDWP_ReferenceType_NestedTypes 8
|
||||
#define JDWP_ReferenceType_Status 9
|
||||
#define JDWP_ReferenceType_Interfaces 10
|
||||
#define JDWP_ReferenceType_ClassObject 11
|
||||
#define JDWP_ReferenceType_SourceDebugExtension 12
|
||||
#define JDWP_ReferenceType_SignatureWithGeneric 13
|
||||
#define JDWP_ReferenceType_FieldsWithGeneric 14
|
||||
#define JDWP_ReferenceType_MethodsWithGeneric 15
|
||||
#define JDWP_ReferenceType_Instances 16
|
||||
#define JDWP_ReferenceType_ClassFileVersion 17
|
||||
#define JDWP_ReferenceType_ConstantPool 18
|
||||
#define JDWP_ClassType 3
|
||||
#define JDWP_ClassType_Superclass 1
|
||||
#define JDWP_ClassType_SetValues 2
|
||||
#define JDWP_ClassType_InvokeMethod 3
|
||||
#define JDWP_ClassType_NewInstance 4
|
||||
#define JDWP_ArrayType 4
|
||||
#define JDWP_ArrayType_NewInstance 1
|
||||
#define JDWP_InterfaceType 5
|
||||
#define JDWP_Method 6
|
||||
#define JDWP_Method_LineTable 1
|
||||
#define JDWP_Method_VariableTable 2
|
||||
#define JDWP_Method_Bytecodes 3
|
||||
#define JDWP_Method_IsObsolete 4
|
||||
#define JDWP_Method_VariableTableWithGeneric 5
|
||||
#define JDWP_Field 8
|
||||
#define JDWP_ObjectReference 9
|
||||
#define JDWP_ObjectReference_ReferenceType 1
|
||||
#define JDWP_ObjectReference_GetValues 2
|
||||
#define JDWP_ObjectReference_SetValues 3
|
||||
#define JDWP_ObjectReference_MonitorInfo 5
|
||||
#define JDWP_ObjectReference_InvokeMethod 6
|
||||
#define JDWP_ObjectReference_DisableCollection 7
|
||||
#define JDWP_ObjectReference_EnableCollection 8
|
||||
#define JDWP_ObjectReference_IsCollected 9
|
||||
#define JDWP_ObjectReference_ReferringObjects 10
|
||||
#define JDWP_StringReference 10
|
||||
#define JDWP_StringReference_Value 1
|
||||
#define JDWP_ThreadReference 11
|
||||
#define JDWP_ThreadReference_Name 1
|
||||
#define JDWP_ThreadReference_Suspend 2
|
||||
#define JDWP_ThreadReference_Resume 3
|
||||
#define JDWP_ThreadReference_Status 4
|
||||
#define JDWP_ThreadReference_ThreadGroup 5
|
||||
#define JDWP_ThreadReference_Frames 6
|
||||
#define JDWP_ThreadReference_FrameCount 7
|
||||
#define JDWP_ThreadReference_OwnedMonitors 8
|
||||
#define JDWP_ThreadReference_CurrentContendedMonitor 9
|
||||
#define JDWP_ThreadReference_Stop 10
|
||||
#define JDWP_ThreadReference_Interrupt 11
|
||||
#define JDWP_ThreadReference_SuspendCount 12
|
||||
#define JDWP_ThreadReference_OwnedMonitorsStackDepthInfo 13
|
||||
#define JDWP_ThreadReference_ForceEarlyReturn 14
|
||||
#define JDWP_ThreadGroupReference 12
|
||||
#define JDWP_ThreadGroupReference_Name 1
|
||||
#define JDWP_ThreadGroupReference_Parent 2
|
||||
#define JDWP_ThreadGroupReference_Children 3
|
||||
#define JDWP_ArrayReference 13
|
||||
#define JDWP_ArrayReference_Length 1
|
||||
#define JDWP_ArrayReference_GetValues 2
|
||||
#define JDWP_ArrayReference_SetValues 3
|
||||
#define JDWP_ClassLoaderReference 14
|
||||
#define JDWP_ClassLoaderReference_VisibleClasses 1
|
||||
#define JDWP_EventRequest 15
|
||||
#define JDWP_EventRequest_Set 1
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_Count 1
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_Conditional 2
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_ThreadOnly 3
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_ClassOnly 4
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_ClassMatch 5
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_ClassExclude 6
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly 7
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_ExceptionOnly 8
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_FieldOnly 9
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_Step 10
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_InstanceOnly 11
|
||||
#define JDWP_EventRequest_Set_Out_modifiers_Modifier_SourceNameMatch 12
|
||||
#define JDWP_EventRequest_Clear 2
|
||||
#define JDWP_EventRequest_ClearAllBreakpoints 3
|
||||
#define JDWP_StackFrame 16
|
||||
#define JDWP_StackFrame_GetValues 1
|
||||
#define JDWP_StackFrame_SetValues 2
|
||||
#define JDWP_StackFrame_ThisObject 3
|
||||
#define JDWP_StackFrame_PopFrames 4
|
||||
#define JDWP_ClassObjectReference 17
|
||||
#define JDWP_ClassObjectReference_ReflectedType 1
|
||||
#define JDWP_Event 64
|
||||
#define JDWP_Event_Composite 100
|
||||
#define JDWP_Event_Composite_Event_events_Events_VMStart JDWP.EventKind.VM_START
|
||||
#define JDWP_Event_Composite_Event_events_Events_SingleStep JDWP.EventKind.SINGLE_STEP
|
||||
#define JDWP_Event_Composite_Event_events_Events_Breakpoint JDWP.EventKind.BREAKPOINT
|
||||
#define JDWP_Event_Composite_Event_events_Events_MethodEntry JDWP.EventKind.METHOD_ENTRY
|
||||
#define JDWP_Event_Composite_Event_events_Events_MethodExit JDWP.EventKind.METHOD_EXIT
|
||||
#define JDWP_Event_Composite_Event_events_Events_MethodExitWithReturnValue JDWP.EventKind.METHOD_EXIT_WITH_RETURN_VALUE
|
||||
#define JDWP_Event_Composite_Event_events_Events_MonitorContendedEnter JDWP.EventKind.MONITOR_CONTENDED_ENTER
|
||||
#define JDWP_Event_Composite_Event_events_Events_MonitorContendedEntered JDWP.EventKind.MONITOR_CONTENDED_ENTERED
|
||||
#define JDWP_Event_Composite_Event_events_Events_MonitorWait JDWP.EventKind.MONITOR_WAIT
|
||||
#define JDWP_Event_Composite_Event_events_Events_MonitorWaited JDWP.EventKind.MONITOR_WAITED
|
||||
#define JDWP_Event_Composite_Event_events_Events_Exception JDWP.EventKind.EXCEPTION
|
||||
#define JDWP_Event_Composite_Event_events_Events_ThreadStart JDWP.EventKind.THREAD_START
|
||||
#define JDWP_Event_Composite_Event_events_Events_ThreadDeath JDWP.EventKind.THREAD_DEATH
|
||||
#define JDWP_Event_Composite_Event_events_Events_ClassPrepare JDWP.EventKind.CLASS_PREPARE
|
||||
#define JDWP_Event_Composite_Event_events_Events_ClassUnload JDWP.EventKind.CLASS_UNLOAD
|
||||
#define JDWP_Event_Composite_Event_events_Events_FieldAccess JDWP.EventKind.FIELD_ACCESS
|
||||
#define JDWP_Event_Composite_Event_events_Events_FieldModification JDWP.EventKind.FIELD_MODIFICATION
|
||||
#define JDWP_Event_Composite_Event_events_Events_VMDeath JDWP.EventKind.VM_DEATH
|
||||
#define JDWP_Error_NONE 0
|
||||
#define JDWP_Error_INVALID_THREAD 10
|
||||
#define JDWP_Error_INVALID_THREAD_GROUP 11
|
||||
#define JDWP_Error_INVALID_PRIORITY 12
|
||||
#define JDWP_Error_THREAD_NOT_SUSPENDED 13
|
||||
#define JDWP_Error_THREAD_SUSPENDED 14
|
||||
#define JDWP_Error_THREAD_NOT_ALIVE 15
|
||||
#define JDWP_Error_INVALID_OBJECT 20
|
||||
#define JDWP_Error_INVALID_CLASS 21
|
||||
#define JDWP_Error_CLASS_NOT_PREPARED 22
|
||||
#define JDWP_Error_INVALID_METHODID 23
|
||||
#define JDWP_Error_INVALID_LOCATION 24
|
||||
#define JDWP_Error_INVALID_FIELDID 25
|
||||
#define JDWP_Error_INVALID_FRAMEID 30
|
||||
#define JDWP_Error_NO_MORE_FRAMES 31
|
||||
#define JDWP_Error_OPAQUE_FRAME 32
|
||||
#define JDWP_Error_NOT_CURRENT_FRAME 33
|
||||
#define JDWP_Error_TYPE_MISMATCH 34
|
||||
#define JDWP_Error_INVALID_SLOT 35
|
||||
#define JDWP_Error_DUPLICATE 40
|
||||
#define JDWP_Error_NOT_FOUND 41
|
||||
#define JDWP_Error_INVALID_MONITOR 50
|
||||
#define JDWP_Error_NOT_MONITOR_OWNER 51
|
||||
#define JDWP_Error_INTERRUPT 52
|
||||
#define JDWP_Error_INVALID_CLASS_FORMAT 60
|
||||
#define JDWP_Error_CIRCULAR_CLASS_DEFINITION 61
|
||||
#define JDWP_Error_FAILS_VERIFICATION 62
|
||||
#define JDWP_Error_ADD_METHOD_NOT_IMPLEMENTED 63
|
||||
#define JDWP_Error_SCHEMA_CHANGE_NOT_IMPLEMENTED 64
|
||||
#define JDWP_Error_INVALID_TYPESTATE 65
|
||||
#define JDWP_Error_HIERARCHY_CHANGE_NOT_IMPLEMENTED 66
|
||||
#define JDWP_Error_DELETE_METHOD_NOT_IMPLEMENTED 67
|
||||
#define JDWP_Error_UNSUPPORTED_VERSION 68
|
||||
#define JDWP_Error_NAMES_DONT_MATCH 69
|
||||
#define JDWP_Error_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED 70
|
||||
#define JDWP_Error_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED 71
|
||||
#define JDWP_Error_NOT_IMPLEMENTED 99
|
||||
#define JDWP_Error_NULL_POINTER 100
|
||||
#define JDWP_Error_ABSENT_INFORMATION 101
|
||||
#define JDWP_Error_INVALID_EVENT_TYPE 102
|
||||
#define JDWP_Error_ILLEGAL_ARGUMENT 103
|
||||
#define JDWP_Error_OUT_OF_MEMORY 110
|
||||
#define JDWP_Error_ACCESS_DENIED 111
|
||||
#define JDWP_Error_VM_DEAD 112
|
||||
#define JDWP_Error_INTERNAL 113
|
||||
#define JDWP_Error_UNATTACHED_THREAD 115
|
||||
#define JDWP_Error_INVALID_TAG 500
|
||||
#define JDWP_Error_ALREADY_INVOKING 502
|
||||
#define JDWP_Error_INVALID_INDEX 503
|
||||
#define JDWP_Error_INVALID_LENGTH 504
|
||||
#define JDWP_Error_INVALID_STRING 506
|
||||
#define JDWP_Error_INVALID_CLASS_LOADER 507
|
||||
#define JDWP_Error_INVALID_ARRAY 508
|
||||
#define JDWP_Error_TRANSPORT_LOAD 509
|
||||
#define JDWP_Error_TRANSPORT_INIT 510
|
||||
#define JDWP_Error_NATIVE_METHOD 511
|
||||
#define JDWP_Error_INVALID_COUNT 512
|
||||
#define JDWP_EventKind_SINGLE_STEP 1
|
||||
#define JDWP_EventKind_BREAKPOINT 2
|
||||
#define JDWP_EventKind_FRAME_POP 3
|
||||
#define JDWP_EventKind_EXCEPTION 4
|
||||
#define JDWP_EventKind_USER_DEFINED 5
|
||||
#define JDWP_EventKind_THREAD_START 6
|
||||
#define JDWP_EventKind_THREAD_DEATH 7
|
||||
#define JDWP_EventKind_THREAD_END 7
|
||||
#define JDWP_EventKind_CLASS_PREPARE 8
|
||||
#define JDWP_EventKind_CLASS_UNLOAD 9
|
||||
#define JDWP_EventKind_CLASS_LOAD 10
|
||||
#define JDWP_EventKind_FIELD_ACCESS 20
|
||||
#define JDWP_EventKind_FIELD_MODIFICATION 21
|
||||
#define JDWP_EventKind_EXCEPTION_CATCH 30
|
||||
#define JDWP_EventKind_METHOD_ENTRY 40
|
||||
#define JDWP_EventKind_METHOD_EXIT 41
|
||||
#define JDWP_EventKind_METHOD_EXIT_WITH_RETURN_VALUE 42
|
||||
#define JDWP_EventKind_MONITOR_CONTENDED_ENTER 43
|
||||
#define JDWP_EventKind_MONITOR_CONTENDED_ENTERED 44
|
||||
#define JDWP_EventKind_MONITOR_WAIT 45
|
||||
#define JDWP_EventKind_MONITOR_WAITED 46
|
||||
#define JDWP_EventKind_VM_START 90
|
||||
#define JDWP_EventKind_VM_INIT 90
|
||||
#define JDWP_EventKind_VM_DEATH 99
|
||||
#define JDWP_EventKind_VM_DISCONNECTED 100
|
||||
#define JDWP_ThreadStatus_ZOMBIE 0
|
||||
#define JDWP_ThreadStatus_RUNNING 1
|
||||
#define JDWP_ThreadStatus_SLEEPING 2
|
||||
#define JDWP_ThreadStatus_MONITOR 3
|
||||
#define JDWP_ThreadStatus_WAIT 4
|
||||
#define JDWP_SuspendStatus_SUSPEND_STATUS_SUSPENDED 0x1
|
||||
#define JDWP_ClassStatus_VERIFIED 1
|
||||
#define JDWP_ClassStatus_PREPARED 2
|
||||
#define JDWP_ClassStatus_INITIALIZED 4
|
||||
#define JDWP_ClassStatus_ERROR 8
|
||||
#define JDWP_TypeTag_CLASS 1
|
||||
#define JDWP_TypeTag_INTERFACE 2
|
||||
#define JDWP_TypeTag_ARRAY 3
|
||||
#define JDWP_Tag_ARRAY 91
|
||||
#define JDWP_Tag_BYTE 66
|
||||
#define JDWP_Tag_CHAR 67
|
||||
#define JDWP_Tag_OBJECT 76
|
||||
#define JDWP_Tag_FLOAT 70
|
||||
#define JDWP_Tag_DOUBLE 68
|
||||
#define JDWP_Tag_INT 73
|
||||
#define JDWP_Tag_LONG 74
|
||||
#define JDWP_Tag_SHORT 83
|
||||
#define JDWP_Tag_VOID 86
|
||||
#define JDWP_Tag_BOOLEAN 90
|
||||
#define JDWP_Tag_STRING 115
|
||||
#define JDWP_Tag_THREAD 116
|
||||
#define JDWP_Tag_THREAD_GROUP 103
|
||||
#define JDWP_Tag_CLASS_LOADER 108
|
||||
#define JDWP_Tag_CLASS_OBJECT 99
|
||||
#define JDWP_StepDepth_INTO 0
|
||||
#define JDWP_StepDepth_OVER 1
|
||||
#define JDWP_StepDepth_OUT 2
|
||||
#define JDWP_StepSize_MIN 0
|
||||
#define JDWP_StepSize_LINE 1
|
||||
#define JDWP_SuspendPolicy_NONE 0
|
||||
#define JDWP_SuspendPolicy_EVENT_THREAD 1
|
||||
#define JDWP_SuspendPolicy_ALL 2
|
||||
#define JDWP_InvokeOptions_INVOKE_SINGLE_THREADED 0x01
|
||||
#define JDWP_InvokeOptions_INVOKE_NONVIRTUAL 0x02
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* JavaVM.h
|
||||
*
|
||||
* Copyright (C) 1997-2001, Apple Computer, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#import <JavaVM/NSJavaVirtualMachine.h>
|
||||
#import <JavaVM/NSJavaConfiguration.h>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* NSJavaConfiguration.h
|
||||
*
|
||||
* Copyright (c) 1997-2001, Apple Computer, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* LaurentR- April, 2000
|
||||
* - added:
|
||||
* NSDefaultJavaLibraryKey
|
||||
* NSDefaultJavaDebugLibraryKey
|
||||
* NSDefaultObjCJavaLibraryKey
|
||||
* NSDefaultObjCJavaDebugLibraryKey
|
||||
* NSJavaVMArgumentsKey
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// The configuration dictionary contains a set of vendor-specific key/value
|
||||
// pairs and a set of default key/value pairs. If no vendor is specified,
|
||||
// NSJavaConfiguration uses the NSDefaultJavaVendorKey key to determine which
|
||||
// vendor-specific dictionary should be searched before the top-level dictionary// is searched. eg.:
|
||||
/*
|
||||
{
|
||||
Vendor = sun;
|
||||
default = {
|
||||
DefaultClasspath = "/NextLibrary/Java";
|
||||
};
|
||||
next = {
|
||||
Compiler = "/usr/bin/javac";
|
||||
VM = "/usr/bin/java";
|
||||
};
|
||||
sun = {
|
||||
Compiler = "/NextLibrary/JDK/bin/javac";
|
||||
VM = "/NextLibrary/JDK/bin/java";
|
||||
};
|
||||
}
|
||||
*/
|
||||
// In this case, if no vendor is specified, the `sun' mappings will be searched
|
||||
// first. The value for `VM' would be "/NextLibrary/JDK/bin/java" and the value
|
||||
// for `DefaultClasspath' would be "/NextLibrary/Java".
|
||||
//
|
||||
// This search patter is applied to three dictionaries, in order:
|
||||
// - the JavaConfiguration dictionary in the defaults for the application
|
||||
// - the dictionary in the "JavaConfiguration" domain of the user defaults
|
||||
// - the configuration file (/NextLibrary/Java/JavaConfig.plist).
|
||||
// This permits per-application, per-user and per-system specifications.
|
||||
|
||||
|
||||
extern NSString *NSDefaultJavaVendorKey;
|
||||
|
||||
extern NSString *NSDefaultJavaVMKey;
|
||||
extern NSString *NSDefaultJavaCompilerKey;
|
||||
extern NSString *NSDefaultJavaClassPathKey;
|
||||
extern NSString *NSDefaultJavaLibraryKey;
|
||||
extern NSString *NSDefaultJavaDebugLibraryKey;
|
||||
extern NSString *NSDefaultObjCJavaLibraryKey;
|
||||
extern NSString *NSDefaultObjCJavaDebugLibraryKey;
|
||||
extern NSString *NSJavaVMArgumentsKey;
|
||||
|
||||
|
||||
@interface NSJavaConfiguration : NSObject
|
||||
{
|
||||
NSString *_vendorName;
|
||||
}
|
||||
|
||||
+ (NSJavaConfiguration *) defaultConfiguration;
|
||||
|
||||
+ (NSJavaConfiguration *) configurationForVendor:(NSString *)vendorName;
|
||||
+ (NSArray *) vendorNames;
|
||||
|
||||
- init;
|
||||
- initWithVendor:(NSString *)vendorName;
|
||||
- (NSString *) vendorName;
|
||||
|
||||
- valueForKey:(NSString *)keyName;
|
||||
- valueForKey:(NSString *)keyName expandEnvironmentVariables:(BOOL)flag;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* NSJavaVirtualMachine.h
|
||||
*
|
||||
* Copyright (c) 1997-2001, Apple Computer, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSJavaVirtualMachine : NSObject
|
||||
{
|
||||
@private
|
||||
void *_vmdata;
|
||||
}
|
||||
|
||||
|
||||
// Returns the default virtual machine - if necessary, calls alloc + init
|
||||
|
||||
+ (id) defaultVirtualMachine;
|
||||
|
||||
// Returns a class path. First checks NSProcessInfo for an environment variable
|
||||
// called CLASSPATH and if that doesn't exist, uses NSJavaConfiguration to find
|
||||
// the default class path.
|
||||
|
||||
+ (NSString *) defaultClassPath;
|
||||
|
||||
// Note that any NSThreads spawned after this method returns will automatically
|
||||
// be attached to the virtual machine. Likewise, it is not necessary to attach
|
||||
// the thread that is actually creating the virtual machine. If you spawn a
|
||||
// thread before creating the virtual machine, or if you use the cthread/pthread
|
||||
// or any other non-NSThread api for creating a thread, you must explicitly
|
||||
// attach those threads before messaging any Java object from that thread.
|
||||
// This is most easily done by using the -attachCurrentThread method.
|
||||
// Use -detachCurrentThread to detach explicitly attached threads when done.
|
||||
|
||||
- initWithClassPath:(NSString *)classPath;
|
||||
|
||||
- (void) attachCurrentThread;
|
||||
- (void) detachCurrentThread;
|
||||
|
||||
- (Class)findClass:(NSString *)className;
|
||||
- (Class)defineClass:(NSData *)javaClassData withName:(NSString *)className;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface NSObject (InstantiatingJavaObjects)
|
||||
|
||||
// Instantiating java objects for when no -init/constructor mapping works.
|
||||
// The class these methods are invoked on *must* be a class returned by the
|
||||
// -findClass: method (or NSClassFromString() function), otherwise
|
||||
// NSInvalidJavaClassException is raised. The signature is specified using the
|
||||
// rather counter-intuitive format defined by the Java Virtual Machine
|
||||
// specification. Try looking in JavaVM/vm-interface.h for help.
|
||||
|
||||
+ (id) newWithSignature:(NSString *)signature, ...;
|
||||
+ (id) newWithSignature:(NSString *)signature arguments:(va_list)args;
|
||||
|
||||
@end
|
||||
|
||||
extern NSString *NSInvalidJavaClassException;
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// jawt_md.h
|
||||
// Copyright (c) 2002-2010 Apple Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef _JAVASOFT_JAWT_MD_H_
|
||||
#define _JAVASOFT_JAWT_MD_H_
|
||||
|
||||
#include "jawt.h"
|
||||
|
||||
#import <AppKit/NSView.h>
|
||||
#import <QuartzCore/CALayer.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* JAWT on Mac OS X has two rendering models; legacy NSView, and CALayer.
|
||||
*
|
||||
* The CALayer based model returns an object conforming to the JAWT_SurfaceLayers
|
||||
* protocol in it's JAWT_DrawingSurfaceInfo->platformInfo pointer. A CALayer
|
||||
* assigned to the "layer" property overlays the rectangle of the java.awt.Component.
|
||||
* The client CALayer traces the rect of the Java component as it is moved and resized.
|
||||
*
|
||||
* If there is a superlayer for the entire window, it is also accessible via
|
||||
* the "windowLayer" property. This layer is useful for embedding the Java
|
||||
* window in other layer graphs.
|
||||
*
|
||||
*
|
||||
* The legacy NSView model provides raw access to the NSView hierarchy which
|
||||
* mirrors the Java component hierarchy. The legacy NSView drawing model is deprecated,
|
||||
* and will not be available in future versions of Java for Mac OS X.
|
||||
*
|
||||
* Clients can opt-into the CALayer model by OR'ing the JAWT_MACOSX_USE_CALAYER into the requested JAWT version.
|
||||
*
|
||||
* JAWT awt;
|
||||
* awt.version = JAWT_VERSION_1_4 | JAWT_MACOSX_USE_CALAYER;
|
||||
* jboolean success = JAWT_GetAWT(env, &awt);
|
||||
*
|
||||
* Future versions of Java for Mac OS X will only support the CALayer model,
|
||||
* and will not return a JAWT_MacOSXDrawingSurfaceInfo struct.
|
||||
*/
|
||||
|
||||
#define JAWT_MACOSX_USE_CALAYER 0x80000000
|
||||
|
||||
// CALayer-based rendering
|
||||
@protocol JAWT_SurfaceLayers
|
||||
@property (readwrite, retain) CALayer *layer;
|
||||
@property (readonly) CALayer *windowLayer;
|
||||
@end
|
||||
|
||||
|
||||
// Legacy NSView-based rendering
|
||||
typedef struct JAWT_MacOSXDrawingSurfaceInfo {
|
||||
NSView *cocoaViewRef; // the view is guaranteed to be valid only for the duration of Component.paint method
|
||||
}
|
||||
JAWT_MacOSXDrawingSurfaceInfo;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_JAVASOFT_JAWT_MD_H_ */
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* @(#)jni_md.h 1.19 05/11/17
|
||||
*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JNI_MD_H_
|
||||
#define _JAVASOFT_JNI_MD_H_
|
||||
|
||||
#define JNIEXPORT __attribute__((visibility("default")))
|
||||
#define JNIIMPORT
|
||||
#define JNICALL
|
||||
|
||||
#if defined(__LP64__) && __LP64__ /* for -Wundef */
|
||||
typedef int jint;
|
||||
#else
|
||||
typedef long jint;
|
||||
#endif
|
||||
typedef long long jlong;
|
||||
typedef signed char jbyte;
|
||||
|
||||
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Whooho. api's and stuff
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JAWT_MD_H_
|
||||
#define _JAVASOFT_JAWT_MD_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include "jawt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Microsoft win32-specific declarations for using the AWT native interface.
|
||||
*/
|
||||
typedef struct jawt_Win32DrawingSurfaceInfo {
|
||||
/* Tada. The native window, DDB, or DIB handle */
|
||||
union {
|
||||
HWND hwnd;
|
||||
HBITMAP hbitmap;
|
||||
void* pbits;
|
||||
};
|
||||
/*
|
||||
* This HDC should be the one always used, instead of the one returned from
|
||||
* BeginPaint() or any particular calls to GetDC().
|
||||
*/
|
||||
HDC hdc;
|
||||
HPALETTE hpalette;
|
||||
} JAWT_Win32DrawingSurfaceInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* jni_md.h header file
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JNI_MD_H_
|
||||
#define _JAVASOFT_JNI_MD_H_
|
||||
|
||||
#define JNIEXPORT __declspec(dllexport)
|
||||
#define JNIIMPORT __declspec(dllimport)
|
||||
#define JNICALL __stdcall
|
||||
|
||||
/* stuff and such */
|
||||
typedef long jint;
|
||||
typedef __int64 jlong;
|
||||
typedef signed char jbyte;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,81 @@
|
|||
################################################################################
|
||||
# Makefile for creating the app launcher program.
|
||||
#
|
||||
# This + parent makefiles expect the following environment variables set:
|
||||
#
|
||||
# COMPILE_OS - linux, macosx, windows
|
||||
# COMPILE_OS_ARCH - 32, 64, arm
|
||||
#
|
||||
################################################################################
|
||||
|
||||
DEPLOY_PATH=../../java_builder/ProjectBuilder/deploy
|
||||
TARGET_PATH=../../resources/JavaLauncher
|
||||
JVM=jvm
|
||||
|
||||
#setup architecture and path parameters
|
||||
ifeq ($(COMPILE_OS_ARCH),32)
|
||||
CCFLAGS +=-DI386
|
||||
M_ARCH=-m32
|
||||
DIST_OS_NAME=$(COMPILE_OS)_32
|
||||
else ifeq ($(COMPILE_OS_ARCH),64)
|
||||
CCFLAGS +=-DAMD64
|
||||
M_ARCH=-m64
|
||||
DIST_OS_NAME=$(COMPILE_OS)_64
|
||||
else ifeq ($(COMPILE_OS_ARCH),ARM)
|
||||
#todo finish filling this out
|
||||
CCFLAGS +=-DARM
|
||||
endif
|
||||
|
||||
|
||||
# mingw doesn't support the M_ARCH flag.
|
||||
ifeq ($(COMPILE_OS),windows)
|
||||
M_ARCH =
|
||||
endif
|
||||
|
||||
CCFLAGS +=${M_ARCH}
|
||||
|
||||
#Makes it small AND FAST
|
||||
CCFLAGS +=-O2
|
||||
|
||||
ifneq ($(COMPILE_OS),macosx)
|
||||
CCFLAGS +=-flto
|
||||
endif
|
||||
|
||||
# warnings and speed/space tricks
|
||||
FLAGS += \
|
||||
-P -ftrapv -funroll-loops -fno-strict-aliasing \
|
||||
-fvisibility=hidden -fvisibility-inlines-hidden -finline-functions \
|
||||
-Wextra -Wshadow -Wpointer-arith -Wcast-align \
|
||||
-Wstrict-overflow=5 -Wsign-compare
|
||||
|
||||
ifneq ($(COMPILE_OS),windows)
|
||||
CCFLAGS +=-fPIC
|
||||
endif
|
||||
|
||||
|
||||
#common path includes
|
||||
CCFLAGS += \
|
||||
-isystem$(JVM)/include \
|
||||
-isystem$(JVM)/include/$(COMPILE_OS) \
|
||||
-Isrc/
|
||||
|
||||
JNI_OBJS = com_barchart_udt_CCC.o com_barchart_udt_SocketUDT.o JNICCC.o JNICCCFactory.o JNIHelpers.o
|
||||
UDT_OBJS = api.o buffer.o cache.o ccc.o channel.o udtCommon.o core.o epoll.o list.o md5.o packet.o queue.o window.o
|
||||
|
||||
$(JNI_OBJS): %.o: src/jni/%.cpp src/jni/%.h
|
||||
@$(CPP) $(CCFLAGS) $< -c
|
||||
|
||||
$(UDT_OBJS): %.o: src/%.cpp src/%.h src/udt.h
|
||||
@$(CPP) $(CCFLAGS) $< -c
|
||||
|
||||
lib: $(UDT_OBJS) $(JNI_OBJS)
|
||||
@$(CPP) $(CCFLAGS) $(LDFLAGS) -o $(DIST_NAME) $^ $(LIBS)
|
||||
|
||||
udt: lib
|
||||
|
||||
dist-clean: clean
|
||||
@rm -f *.dll *.so *.dylib
|
||||
|
||||
clean:
|
||||
@rm -f *.o *.a
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#*******************************************************************************
|
||||
# Makefile for creating the GTK launcher program.
|
||||
#
|
||||
# This makefile expects the utility "pkg-config" to be in the PATH.
|
||||
#
|
||||
# This makefile expect the following environment variables set:
|
||||
#
|
||||
# COMPILE_OS - linux, macosx, windows
|
||||
# COMPILE_OS_ARCH - 32, 64, arm
|
||||
#*******************************************************************************
|
||||
|
||||
include make_common.mak
|
||||
|
||||
DIST_NAME=libbarchart-udt-core-2.3.1-mod.so
|
||||
DIST_PATH=windows_$(COMPILE_OS_ARCH)
|
||||
|
||||
CPP=g++
|
||||
CC=gcc
|
||||
|
||||
LDFLAGS = -shared
|
||||
LIBS = -lpthread -ldl -lm
|
||||
|
||||
CCFLAGS += \
|
||||
-DLINUX \
|
||||
-isystem/usr/include \
|
||||
-pthread \
|
||||
|
||||
all: dist-clean udt
|
||||
@echo "\nDONE WITH COMPILE...."
|
||||
@mkdir -p "bin/$(DIST_OS_NAME)"
|
||||
@mv "$(DIST_NAME)" "bin/$(DIST_OS_NAME)"
|
||||
@# now cleanup
|
||||
@$(MAKE) -s -f make_common.mak clean
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#**********************************************************************
|
||||
# Makefile for creating the Carbon eclipse launcher program.
|
||||
#
|
||||
# This makefile expects the following environment variables set:
|
||||
#
|
||||
# cross compile libs from : https://launchpad.net/~flosoft/+archive/cross-apple/+packages
|
||||
#
|
||||
# This makefile expect the following environment variables set:
|
||||
#
|
||||
# COMPILE_OS - linux, macosx, windows
|
||||
# COMPILE_OS_ARCH - 32, 64, arm
|
||||
#*******************************************************************************
|
||||
|
||||
include make_common.mak
|
||||
|
||||
DIST_NAME=libbarchart-udt-core-2.3.1-mod.dylib
|
||||
DIST_PATH=windows_$(COMPILE_OS_ARCH)
|
||||
|
||||
CPP=i686-apple-darwin10-g++
|
||||
CC=i686-apple-darwin10-gcc
|
||||
|
||||
LDFLAGS = -shared -dynamiclib -compatibility_version 1.0 -current_version 1.0 -mmacosx-version-min=10.5
|
||||
LIBS = -lpthread -lm
|
||||
|
||||
#setup architecture parameters
|
||||
ifeq ($(COMPILE_OS_ARCH),32)
|
||||
CCFLAGS += -arch i386
|
||||
else
|
||||
MACOSX_IS_64BIT=true
|
||||
CCFLAGS += -arch x86_64
|
||||
endif
|
||||
|
||||
CCFLAGS += -DMACOSX
|
||||
|
||||
all: dist-clean udt
|
||||
@echo "\nDONE WITH COMPILE...."
|
||||
@mkdir -p "bin/$(DIST_OS_NAME)"
|
||||
@mv "$(DIST_NAME)" "bin/$(DIST_OS_NAME)"
|
||||
@# now cleanup
|
||||
@$(MAKE) -s -f make_common.mak clean
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#*******************************************************************************
|
||||
# Makefile for creating the launcher program.
|
||||
#
|
||||
# This makefile expects the following environment variables set:
|
||||
#
|
||||
# Allow for cross-compiling under linux.
|
||||
# USES mingw-w64 !!!! (NOT mingw32, which is deprecated)
|
||||
#
|
||||
#*******************************************************************************
|
||||
|
||||
include make_common.mak
|
||||
|
||||
DIST_NAME=libbarchart-udt-core-2.3.1-mod.dll
|
||||
DIST_PATH=windows_$(COMPILE_OS_ARCH)
|
||||
|
||||
ifeq ($(COMPILE_OS_ARCH),32)
|
||||
MINGVER = i686
|
||||
#mingw flags
|
||||
CCFLAGS +=-DWINVER=0x0501
|
||||
|
||||
#32 bit support is XP+
|
||||
CCFLAGS +=-D_WIN32_WINNT=0x0501
|
||||
else
|
||||
MINGVER = x86_64
|
||||
#mingw flags
|
||||
CCFLAGS +=-DWINVER=0x0600
|
||||
|
||||
#64 bit support is vista+ ONLY
|
||||
CCFLAGS +=-D_WIN32_WINNT=0x0600
|
||||
endif
|
||||
|
||||
CPP = $(shell which $(MINGVER)-w64-mingw32-g++)
|
||||
STRIP = $(shell which $(MINGVER)-w64-mingw32-strip)
|
||||
|
||||
|
||||
LDFLAGS = -shared -static -static-libgcc -static-libstdc++ -Wl,--kill-at
|
||||
LIBS = -lkernel32 -luser32 -lws2_32
|
||||
|
||||
CCFLAGS += \
|
||||
-isystem/usr/$(MINGVER)-w64-mingw32/include \
|
||||
-DWINDOWS \
|
||||
|
||||
all: dist-clean udt
|
||||
@echo "\nDONE WITH COMPILE...."
|
||||
@# now cleanup
|
||||
@# now strip the DLL of unneeded, since it can be HUGE
|
||||
$(STRIP) --strip-debug --strip-unneeded $(DIST_NAME)
|
||||
@mkdir -p "bin/$(DIST_OS_NAME)"
|
||||
@mv "$(DIST_NAME)" "bin/$(DIST_OS_NAME)"
|
||||
@$(MAKE) -s -f make_common.mak clean
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,273 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 09/28/2010
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_API_H__
|
||||
#define __UDT_API_H__
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "udt.h"
|
||||
#include "packet.h"
|
||||
#include "queue.h"
|
||||
#include "cache.h"
|
||||
#include "epoll.h"
|
||||
|
||||
class CUDT;
|
||||
|
||||
class CUDTSocket
|
||||
{
|
||||
public:
|
||||
CUDTSocket();
|
||||
~CUDTSocket();
|
||||
|
||||
UDTSTATUS m_Status; // current socket state
|
||||
|
||||
uint64_t m_TimeStamp; // time when the socket is closed
|
||||
|
||||
int m_iIPversion; // IP version
|
||||
sockaddr* m_pSelfAddr; // pointer to the local address of the socket
|
||||
sockaddr* m_pPeerAddr; // pointer to the peer address of the socket
|
||||
|
||||
UDTSOCKET m_SocketID; // socket ID
|
||||
UDTSOCKET m_ListenSocket; // ID of the listener socket; 0 means this is an independent socket
|
||||
|
||||
UDTSOCKET m_PeerID; // peer socket ID
|
||||
int32_t m_iISN; // initial sequence number, used to tell different connection from same IP:port
|
||||
|
||||
CUDT* m_pUDT; // pointer to the UDT entity
|
||||
|
||||
std::set<UDTSOCKET>* m_pQueuedSockets; // set of connections waiting for accept()
|
||||
std::set<UDTSOCKET>* m_pAcceptSockets; // set of accept()ed connections
|
||||
|
||||
udt_pthread_cond_t m_AcceptCond; // used to block "accept" call
|
||||
udt_pthread_mutex_t m_AcceptLock; // mutex associated to m_AcceptCond
|
||||
|
||||
unsigned int m_uiBackLog; // maximum number of connections in queue
|
||||
|
||||
int m_iMuxID; // multiplexer ID
|
||||
|
||||
udt_pthread_mutex_t m_ControlLock; // lock this socket exclusively for control APIs: bind/listen/connect
|
||||
|
||||
private:
|
||||
CUDTSocket(const CUDTSocket&);
|
||||
CUDTSocket& operator=(const CUDTSocket&);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CUDTUnited
|
||||
{
|
||||
friend class CUDT;
|
||||
friend class CRendezvousQueue;
|
||||
|
||||
public:
|
||||
CUDTUnited();
|
||||
~CUDTUnited();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// initialize the UDT library.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// 0 if success, otherwise -1 is returned.
|
||||
|
||||
int startup();
|
||||
|
||||
// Functionality:
|
||||
// release the UDT library.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// 0 if success, otherwise -1 is returned.
|
||||
|
||||
int cleanup();
|
||||
|
||||
// Functionality:
|
||||
// Create a new UDT socket.
|
||||
// Parameters:
|
||||
// 0) [in] af: IP version, IPv4 (AF_INET) or IPv6 (AF_INET6).
|
||||
// 1) [in] type: socket type, SOCK_STREAM or SOCK_DGRAM
|
||||
// Returned value:
|
||||
// The new UDT socket ID, or INVALID_SOCK.
|
||||
|
||||
UDTSOCKET newSocket(int af, int type);
|
||||
|
||||
// Functionality:
|
||||
// Create a new UDT connection.
|
||||
// Parameters:
|
||||
// 0) [in] listen: the listening UDT socket;
|
||||
// 1) [in] peer: peer address.
|
||||
// 2) [in/out] hs: handshake information from peer side (in), negotiated value (out);
|
||||
// Returned value:
|
||||
// If the new connection is successfully created: 1 success, 0 already exist, -1 error.
|
||||
|
||||
int newConnection(const UDTSOCKET listen, const sockaddr* peer, CHandShake* hs);
|
||||
|
||||
// Functionality:
|
||||
// look up the UDT entity according to its ID.
|
||||
// Parameters:
|
||||
// 0) [in] u: the UDT socket ID.
|
||||
// Returned value:
|
||||
// Pointer to the UDT entity.
|
||||
|
||||
CUDT* lookup(const UDTSOCKET u);
|
||||
|
||||
// Functionality:
|
||||
// Check the status of the UDT socket.
|
||||
// Parameters:
|
||||
// 0) [in] u: the UDT socket ID.
|
||||
// Returned value:
|
||||
// UDT socket status, or NONEXIST if not found.
|
||||
|
||||
UDTSTATUS getStatus(const UDTSOCKET u);
|
||||
|
||||
// socket APIs
|
||||
|
||||
int bind(const UDTSOCKET u, const sockaddr* name, int namelen);
|
||||
int bind(const UDTSOCKET u, UDPSOCKET udpsock);
|
||||
int listen(const UDTSOCKET u, int backlog);
|
||||
UDTSOCKET accept(const UDTSOCKET listen, sockaddr* addr, int* addrlen);
|
||||
int connect(const UDTSOCKET u, const sockaddr* name, int namelen);
|
||||
int close(const UDTSOCKET u);
|
||||
int getpeername(const UDTSOCKET u, sockaddr* name, int* namelen);
|
||||
int getsockname(const UDTSOCKET u, sockaddr* name, int* namelen);
|
||||
int select(ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout);
|
||||
int selectEx(const std::vector<UDTSOCKET>& fds, std::vector<UDTSOCKET>* readfds, std::vector<UDTSOCKET>* writefds, std::vector<UDTSOCKET>* exceptfds, int64_t msTimeOut);
|
||||
int epoll_create();
|
||||
int epoll_add_usock(const int eid, const UDTSOCKET u, const int* events = NULL);
|
||||
int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events = NULL);
|
||||
int epoll_remove_usock(const int eid, const UDTSOCKET u);
|
||||
int epoll_remove_ssock(const int eid, const SYSSOCKET s);
|
||||
int epoll_wait(const int eid, std::set<UDTSOCKET>* readfds, std::set<UDTSOCKET>* writefds, int64_t msTimeOut, std::set<SYSSOCKET>* lrfds = NULL, std::set<SYSSOCKET>* lwfds = NULL);
|
||||
int epoll_release(const int eid);
|
||||
|
||||
// BARCHART
|
||||
int epoll_update_usock(const int eid, const UDTSOCKET u, const int* events = NULL);
|
||||
// BARCHART
|
||||
int epoll_verify_usock(const int eid, const UDTSOCKET u, int* events);
|
||||
|
||||
// Functionality:
|
||||
// record the UDT exception.
|
||||
// Parameters:
|
||||
// 0) [in] e: pointer to a UDT exception instance.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setError(CUDTException* e);
|
||||
|
||||
// Functionality:
|
||||
// look up the most recent UDT exception.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// pointer to a UDT exception instance.
|
||||
|
||||
CUDTException* getError();
|
||||
|
||||
private:
|
||||
// void init();
|
||||
|
||||
private:
|
||||
std::map<UDTSOCKET, CUDTSocket*> m_Sockets; // stores all the socket structures
|
||||
|
||||
udt_pthread_mutex_t m_ControlLock; // used to synchronize UDT API
|
||||
|
||||
udt_pthread_mutex_t m_IDLock; // used to synchronize ID generation
|
||||
UDTSOCKET m_SocketID; // seed to generate a new unique socket ID
|
||||
|
||||
std::map<int64_t, std::set<UDTSOCKET> > m_PeerRec;// record sockets from peers to avoid repeated connection request, int64_t = (socker_id << 30) + isn
|
||||
|
||||
private:
|
||||
udt_pthread_key_t m_TLSError; // thread local error record (last error)
|
||||
#ifndef WINDOWS
|
||||
static void TLSDestroy(void* e) {if (NULL != e) delete (CUDTException*)e;}
|
||||
#else
|
||||
std::map<DWORD, CUDTException*> m_mTLSRecord;
|
||||
void checkTLSValue();
|
||||
udt_pthread_mutex_t m_TLSLock;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void connect_complete(const UDTSOCKET u);
|
||||
CUDTSocket* locate(const UDTSOCKET u);
|
||||
CUDTSocket* locate(const sockaddr* peer, const UDTSOCKET id, int32_t isn);
|
||||
void updateMux(CUDTSocket* s, const sockaddr* addr = NULL, const UDPSOCKET* = NULL);
|
||||
void updateMux(CUDTSocket* s, const CUDTSocket* ls);
|
||||
|
||||
private:
|
||||
std::map<int, CMultiplexer> m_mMultiplexer; // UDP multiplexer
|
||||
udt_pthread_mutex_t m_MultiplexerLock;
|
||||
|
||||
private:
|
||||
CCache<CInfoBlock>* m_pCache; // UDT network information cache
|
||||
|
||||
private:
|
||||
volatile bool m_bClosing;
|
||||
udt_pthread_mutex_t m_GCStopLock;
|
||||
udt_pthread_cond_t m_GCStopCond;
|
||||
|
||||
udt_pthread_mutex_t m_InitLock;
|
||||
int m_iInstanceCount; // number of startup() called by application
|
||||
bool m_bGCStatus; // if the GC thread is working (true)
|
||||
|
||||
udt_pthread_t m_GCThread;
|
||||
#ifndef WINDOWS
|
||||
static void* garbageCollect(void*);
|
||||
#else
|
||||
static DWORD WINAPI garbageCollect(LPVOID);
|
||||
#endif
|
||||
|
||||
std::map<UDTSOCKET, CUDTSocket*> m_ClosedSockets; // temporarily store closed sockets
|
||||
|
||||
void checkBrokenSockets();
|
||||
void removeSocket(const UDTSOCKET u);
|
||||
|
||||
private:
|
||||
CEPoll m_EPoll; // handling epoll data structures and events
|
||||
|
||||
private:
|
||||
CUDTUnited(const CUDTUnited&);
|
||||
CUDTUnited& operator=(const CUDTUnited&);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,652 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 03/12/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include "buffer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
CSndBuffer::CSndBuffer(int size, int mss):
|
||||
m_BufLock(),
|
||||
m_pBlock(NULL),
|
||||
m_pFirstBlock(NULL),
|
||||
m_pCurrBlock(NULL),
|
||||
m_pLastBlock(NULL),
|
||||
m_pBuffer(NULL),
|
||||
m_iNextMsgNo(1),
|
||||
m_iSize(size),
|
||||
m_iMSS(mss),
|
||||
m_iCount(0)
|
||||
{
|
||||
// initial physical buffer of "size"
|
||||
m_pBuffer = new Buffer;
|
||||
m_pBuffer->m_pcData = new char [m_iSize * m_iMSS];
|
||||
m_pBuffer->m_iSize = m_iSize;
|
||||
m_pBuffer->m_pNext = NULL;
|
||||
|
||||
// circular linked list for out bound packets
|
||||
m_pBlock = new Block;
|
||||
Block* pb = m_pBlock;
|
||||
for (int i = 1; i < m_iSize; ++ i)
|
||||
{
|
||||
pb->m_pNext = new Block;
|
||||
pb->m_iMsgNo = 0;
|
||||
pb = pb->m_pNext;
|
||||
}
|
||||
pb->m_pNext = m_pBlock;
|
||||
|
||||
pb = m_pBlock;
|
||||
char* pc = m_pBuffer->m_pcData;
|
||||
for (int i = 0; i < m_iSize; ++ i)
|
||||
{
|
||||
pb->m_pcData = pc;
|
||||
pb = pb->m_pNext;
|
||||
pc += m_iMSS;
|
||||
}
|
||||
|
||||
m_pFirstBlock = m_pCurrBlock = m_pLastBlock = m_pBlock;
|
||||
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_init(&m_BufLock, NULL);
|
||||
#else
|
||||
m_BufLock = CreateMutex(NULL, false, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
CSndBuffer::~CSndBuffer()
|
||||
{
|
||||
Block* pb = m_pBlock->m_pNext;
|
||||
while (pb != m_pBlock)
|
||||
{
|
||||
Block* temp = pb;
|
||||
pb = pb->m_pNext;
|
||||
delete temp;
|
||||
}
|
||||
delete m_pBlock;
|
||||
|
||||
while (m_pBuffer != NULL)
|
||||
{
|
||||
Buffer* temp = m_pBuffer;
|
||||
m_pBuffer = m_pBuffer->m_pNext;
|
||||
delete [] temp->m_pcData;
|
||||
delete temp;
|
||||
}
|
||||
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_destroy(&m_BufLock);
|
||||
#else
|
||||
CloseHandle(m_BufLock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSndBuffer::addBuffer(const char* data, int len, int ttl, bool order)
|
||||
{
|
||||
int size = len / m_iMSS;
|
||||
if ((len % m_iMSS) != 0)
|
||||
size ++;
|
||||
|
||||
// dynamically increase sender buffer
|
||||
while (size + m_iCount >= m_iSize)
|
||||
increase();
|
||||
|
||||
uint64_t time = CTimer::getTime();
|
||||
int32_t inorder = order;
|
||||
inorder <<= 29;
|
||||
|
||||
Block* s = m_pLastBlock;
|
||||
for (int i = 0; i < size; ++ i)
|
||||
{
|
||||
int pktlen = len - i * m_iMSS;
|
||||
if (pktlen > m_iMSS)
|
||||
pktlen = m_iMSS;
|
||||
|
||||
memcpy(s->m_pcData, data + i * m_iMSS, pktlen);
|
||||
s->m_iLength = pktlen;
|
||||
|
||||
s->m_iMsgNo = m_iNextMsgNo | inorder;
|
||||
if (i == 0)
|
||||
s->m_iMsgNo |= 0x80000000;
|
||||
if (i == size - 1)
|
||||
s->m_iMsgNo |= 0x40000000;
|
||||
|
||||
s->m_OriginTime = time;
|
||||
s->m_iTTL = ttl;
|
||||
|
||||
s = s->m_pNext;
|
||||
}
|
||||
m_pLastBlock = s;
|
||||
|
||||
CGuard::enterCS(m_BufLock);
|
||||
m_iCount += size;
|
||||
CGuard::leaveCS(m_BufLock);
|
||||
|
||||
m_iNextMsgNo ++;
|
||||
if (m_iNextMsgNo == CMsgNo::m_iMaxMsgNo)
|
||||
m_iNextMsgNo = 1;
|
||||
}
|
||||
|
||||
int CSndBuffer::addBufferFromFile(fstream& ifs, int len)
|
||||
{
|
||||
int size = len / m_iMSS;
|
||||
if ((len % m_iMSS) != 0)
|
||||
size ++;
|
||||
|
||||
// dynamically increase sender buffer
|
||||
while (size + m_iCount >= m_iSize)
|
||||
increase();
|
||||
|
||||
Block* s = m_pLastBlock;
|
||||
int total = 0;
|
||||
for (int i = 0; i < size; ++ i)
|
||||
{
|
||||
if (ifs.bad() || ifs.fail() || ifs.eof())
|
||||
break;
|
||||
|
||||
int pktlen = len - i * m_iMSS;
|
||||
if (pktlen > m_iMSS)
|
||||
pktlen = m_iMSS;
|
||||
|
||||
ifs.read(s->m_pcData, pktlen);
|
||||
if ((pktlen = ifs.gcount()) <= 0)
|
||||
break;
|
||||
|
||||
// currently file transfer is only available in streaming mode, message is always in order, ttl = infinite
|
||||
s->m_iMsgNo = m_iNextMsgNo | 0x20000000;
|
||||
if (i == 0)
|
||||
s->m_iMsgNo |= 0x80000000;
|
||||
if (i == size - 1)
|
||||
s->m_iMsgNo |= 0x40000000;
|
||||
|
||||
s->m_iLength = pktlen;
|
||||
s->m_iTTL = -1;
|
||||
s = s->m_pNext;
|
||||
|
||||
total += pktlen;
|
||||
}
|
||||
m_pLastBlock = s;
|
||||
|
||||
CGuard::enterCS(m_BufLock);
|
||||
m_iCount += size;
|
||||
CGuard::leaveCS(m_BufLock);
|
||||
|
||||
m_iNextMsgNo ++;
|
||||
if (m_iNextMsgNo == CMsgNo::m_iMaxMsgNo)
|
||||
m_iNextMsgNo = 1;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int CSndBuffer::readData(char** data, int32_t& msgno)
|
||||
{
|
||||
// No data to read
|
||||
if (m_pCurrBlock == m_pLastBlock)
|
||||
return 0;
|
||||
|
||||
*data = m_pCurrBlock->m_pcData;
|
||||
int readlen = m_pCurrBlock->m_iLength;
|
||||
msgno = m_pCurrBlock->m_iMsgNo;
|
||||
|
||||
m_pCurrBlock = m_pCurrBlock->m_pNext;
|
||||
|
||||
return readlen;
|
||||
}
|
||||
|
||||
int CSndBuffer::readData(char** data, const int offset, int32_t& msgno, int& msglen)
|
||||
{
|
||||
CGuard bufferguard(m_BufLock);
|
||||
|
||||
Block* p = m_pFirstBlock;
|
||||
|
||||
for (int i = 0; i < offset; ++ i)
|
||||
p = p->m_pNext;
|
||||
|
||||
if ((p->m_iTTL >= 0) && ((CTimer::getTime() - p->m_OriginTime) / 1000 > (uint64_t)p->m_iTTL))
|
||||
{
|
||||
msgno = p->m_iMsgNo & 0x1FFFFFFF;
|
||||
|
||||
msglen = 1;
|
||||
p = p->m_pNext;
|
||||
bool move = false;
|
||||
while (msgno == (p->m_iMsgNo & 0x1FFFFFFF))
|
||||
{
|
||||
if (p == m_pCurrBlock)
|
||||
move = true;
|
||||
p = p->m_pNext;
|
||||
if (move)
|
||||
m_pCurrBlock = p;
|
||||
msglen ++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
*data = p->m_pcData;
|
||||
int readlen = p->m_iLength;
|
||||
msgno = p->m_iMsgNo;
|
||||
|
||||
return readlen;
|
||||
}
|
||||
|
||||
void CSndBuffer::ackData(int offset)
|
||||
{
|
||||
CGuard bufferguard(m_BufLock);
|
||||
|
||||
for (int i = 0; i < offset; ++ i)
|
||||
m_pFirstBlock = m_pFirstBlock->m_pNext;
|
||||
|
||||
m_iCount -= offset;
|
||||
|
||||
CTimer::triggerEvent();
|
||||
}
|
||||
|
||||
int CSndBuffer::getCurrBufSize() const
|
||||
{
|
||||
return m_iCount;
|
||||
}
|
||||
|
||||
void CSndBuffer::increase()
|
||||
{
|
||||
int unitsize = m_pBuffer->m_iSize;
|
||||
|
||||
// new physical buffer
|
||||
Buffer* nbuf = NULL;
|
||||
try
|
||||
{
|
||||
nbuf = new Buffer;
|
||||
nbuf->m_pcData = new char [unitsize * m_iMSS];
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete nbuf;
|
||||
throw CUDTException(3, 2, 0);
|
||||
}
|
||||
nbuf->m_iSize = unitsize;
|
||||
nbuf->m_pNext = NULL;
|
||||
|
||||
// insert the buffer at the end of the buffer list
|
||||
Buffer* p = m_pBuffer;
|
||||
while (NULL != p->m_pNext)
|
||||
p = p->m_pNext;
|
||||
p->m_pNext = nbuf;
|
||||
|
||||
// new packet blocks
|
||||
Block* nblk = NULL;
|
||||
try
|
||||
{
|
||||
nblk = new Block;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete nblk;
|
||||
throw CUDTException(3, 2, 0);
|
||||
}
|
||||
Block* pb = nblk;
|
||||
for (int i = 1; i < unitsize; ++ i)
|
||||
{
|
||||
pb->m_pNext = new Block;
|
||||
pb = pb->m_pNext;
|
||||
}
|
||||
|
||||
// insert the new blocks onto the existing one
|
||||
pb->m_pNext = m_pLastBlock->m_pNext;
|
||||
m_pLastBlock->m_pNext = nblk;
|
||||
|
||||
pb = nblk;
|
||||
char* pc = nbuf->m_pcData;
|
||||
for (int i = 0; i < unitsize; ++ i)
|
||||
{
|
||||
pb->m_pcData = pc;
|
||||
pb = pb->m_pNext;
|
||||
pc += m_iMSS;
|
||||
}
|
||||
|
||||
m_iSize += unitsize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CRcvBuffer::CRcvBuffer(CUnitQueue* queue, int bufsize):
|
||||
m_pUnit(NULL),
|
||||
m_iSize(bufsize),
|
||||
m_pUnitQueue(queue),
|
||||
m_iStartPos(0),
|
||||
m_iLastAckPos(0),
|
||||
m_iMaxPos(0),
|
||||
m_iNotch(0)
|
||||
{
|
||||
m_pUnit = new CUnit* [m_iSize];
|
||||
for (int i = 0; i < m_iSize; ++ i)
|
||||
m_pUnit[i] = NULL;
|
||||
}
|
||||
|
||||
CRcvBuffer::~CRcvBuffer()
|
||||
{
|
||||
for (int i = 0; i < m_iSize; ++ i)
|
||||
{
|
||||
if (NULL != m_pUnit[i])
|
||||
{
|
||||
m_pUnit[i]->m_iFlag = 0;
|
||||
-- m_pUnitQueue->m_iCount;
|
||||
}
|
||||
}
|
||||
|
||||
delete [] m_pUnit;
|
||||
}
|
||||
|
||||
int CRcvBuffer::addData(CUnit* unit, int offset)
|
||||
{
|
||||
int pos = (m_iLastAckPos + offset) % m_iSize;
|
||||
if (offset > m_iMaxPos)
|
||||
m_iMaxPos = offset;
|
||||
|
||||
if (NULL != m_pUnit[pos])
|
||||
return -1;
|
||||
|
||||
m_pUnit[pos] = unit;
|
||||
|
||||
unit->m_iFlag = 1;
|
||||
++ m_pUnitQueue->m_iCount;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CRcvBuffer::readBuffer(char* data, int len)
|
||||
{
|
||||
int p = m_iStartPos;
|
||||
int lastack = m_iLastAckPos;
|
||||
int rs = len;
|
||||
|
||||
while ((p != lastack) && (rs > 0))
|
||||
{
|
||||
int unitsize = m_pUnit[p]->m_Packet.getLength() - m_iNotch;
|
||||
if (unitsize > rs)
|
||||
unitsize = rs;
|
||||
|
||||
memcpy(data, m_pUnit[p]->m_Packet.m_pcData + m_iNotch, unitsize);
|
||||
data += unitsize;
|
||||
|
||||
if ((rs > unitsize) || (rs == m_pUnit[p]->m_Packet.getLength() - m_iNotch))
|
||||
{
|
||||
CUnit* tmp = m_pUnit[p];
|
||||
m_pUnit[p] = NULL;
|
||||
tmp->m_iFlag = 0;
|
||||
-- m_pUnitQueue->m_iCount;
|
||||
|
||||
if (++ p == m_iSize)
|
||||
p = 0;
|
||||
|
||||
m_iNotch = 0;
|
||||
}
|
||||
else
|
||||
m_iNotch += rs;
|
||||
|
||||
rs -= unitsize;
|
||||
}
|
||||
|
||||
m_iStartPos = p;
|
||||
return len - rs;
|
||||
}
|
||||
|
||||
int CRcvBuffer::readBufferToFile(fstream& ofs, int len)
|
||||
{
|
||||
int p = m_iStartPos;
|
||||
int lastack = m_iLastAckPos;
|
||||
int rs = len;
|
||||
|
||||
while ((p != lastack) && (rs > 0))
|
||||
{
|
||||
int unitsize = m_pUnit[p]->m_Packet.getLength() - m_iNotch;
|
||||
if (unitsize > rs)
|
||||
unitsize = rs;
|
||||
|
||||
ofs.write(m_pUnit[p]->m_Packet.m_pcData + m_iNotch, unitsize);
|
||||
if (ofs.fail())
|
||||
break;
|
||||
|
||||
if ((rs > unitsize) || (rs == m_pUnit[p]->m_Packet.getLength() - m_iNotch))
|
||||
{
|
||||
CUnit* tmp = m_pUnit[p];
|
||||
m_pUnit[p] = NULL;
|
||||
tmp->m_iFlag = 0;
|
||||
-- m_pUnitQueue->m_iCount;
|
||||
|
||||
if (++ p == m_iSize)
|
||||
p = 0;
|
||||
|
||||
m_iNotch = 0;
|
||||
}
|
||||
else
|
||||
m_iNotch += rs;
|
||||
|
||||
rs -= unitsize;
|
||||
}
|
||||
|
||||
m_iStartPos = p;
|
||||
|
||||
return len - rs;
|
||||
}
|
||||
|
||||
void CRcvBuffer::ackData(int len)
|
||||
{
|
||||
m_iLastAckPos = (m_iLastAckPos + len) % m_iSize;
|
||||
m_iMaxPos -= len;
|
||||
if (m_iMaxPos < 0)
|
||||
m_iMaxPos = 0;
|
||||
|
||||
CTimer::triggerEvent();
|
||||
}
|
||||
|
||||
int CRcvBuffer::getAvailBufSize() const
|
||||
{
|
||||
// One slot must be empty in order to tell the difference between "empty buffer" and "full buffer"
|
||||
return m_iSize - getRcvDataSize() - 1;
|
||||
}
|
||||
|
||||
int CRcvBuffer::getRcvDataSize() const
|
||||
{
|
||||
if (m_iLastAckPos >= m_iStartPos)
|
||||
return m_iLastAckPos - m_iStartPos;
|
||||
|
||||
return m_iSize + m_iLastAckPos - m_iStartPos;
|
||||
}
|
||||
|
||||
void CRcvBuffer::dropMsg(int32_t msgno)
|
||||
{
|
||||
for (int i = m_iStartPos, n = (m_iLastAckPos + m_iMaxPos) % m_iSize; i != n; i = (i + 1) % m_iSize)
|
||||
if ((NULL != m_pUnit[i]) && (msgno == m_pUnit[i]->m_Packet.m_iMsgNo))
|
||||
m_pUnit[i]->m_iFlag = 3;
|
||||
}
|
||||
|
||||
int CRcvBuffer::readMsg(char* data, int len)
|
||||
{
|
||||
int p, q;
|
||||
bool passack;
|
||||
if (!scanMsg(p, q, passack))
|
||||
return 0;
|
||||
|
||||
int rs = len;
|
||||
while (p != (q + 1) % m_iSize)
|
||||
{
|
||||
int unitsize = m_pUnit[p]->m_Packet.getLength();
|
||||
if ((rs >= 0) && (unitsize > rs))
|
||||
unitsize = rs;
|
||||
|
||||
if (unitsize > 0)
|
||||
{
|
||||
memcpy(data, m_pUnit[p]->m_Packet.m_pcData, unitsize);
|
||||
data += unitsize;
|
||||
rs -= unitsize;
|
||||
}
|
||||
|
||||
if (!passack)
|
||||
{
|
||||
CUnit* tmp = m_pUnit[p];
|
||||
m_pUnit[p] = NULL;
|
||||
tmp->m_iFlag = 0;
|
||||
-- m_pUnitQueue->m_iCount;
|
||||
}
|
||||
else
|
||||
m_pUnit[p]->m_iFlag = 2;
|
||||
|
||||
if (++ p == m_iSize)
|
||||
p = 0;
|
||||
}
|
||||
|
||||
if (!passack)
|
||||
m_iStartPos = (q + 1) % m_iSize;
|
||||
|
||||
return len - rs;
|
||||
}
|
||||
|
||||
int CRcvBuffer::getRcvMsgNum()
|
||||
{
|
||||
int p, q;
|
||||
bool passack;
|
||||
return scanMsg(p, q, passack) ? 1 : 0;
|
||||
}
|
||||
|
||||
bool CRcvBuffer::scanMsg(int& p, int& q, bool& passack)
|
||||
{
|
||||
// empty buffer
|
||||
if ((m_iStartPos == m_iLastAckPos) && (m_iMaxPos <= 0))
|
||||
return false;
|
||||
|
||||
//skip all bad msgs at the beginning
|
||||
while (m_iStartPos != m_iLastAckPos)
|
||||
{
|
||||
if (NULL == m_pUnit[m_iStartPos])
|
||||
{
|
||||
if (++ m_iStartPos == m_iSize)
|
||||
m_iStartPos = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((1 == m_pUnit[m_iStartPos]->m_iFlag) && (m_pUnit[m_iStartPos]->m_Packet.getMsgBoundary() > 1))
|
||||
{
|
||||
bool good = true;
|
||||
|
||||
// look ahead for the whole message
|
||||
for (int i = m_iStartPos; i != m_iLastAckPos;)
|
||||
{
|
||||
if ((NULL == m_pUnit[i]) || (1 != m_pUnit[i]->m_iFlag))
|
||||
{
|
||||
good = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((m_pUnit[i]->m_Packet.getMsgBoundary() == 1) || (m_pUnit[i]->m_Packet.getMsgBoundary() == 3))
|
||||
break;
|
||||
|
||||
if (++ i == m_iSize)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (good)
|
||||
break;
|
||||
}
|
||||
|
||||
CUnit* tmp = m_pUnit[m_iStartPos];
|
||||
m_pUnit[m_iStartPos] = NULL;
|
||||
tmp->m_iFlag = 0;
|
||||
-- m_pUnitQueue->m_iCount;
|
||||
|
||||
if (++ m_iStartPos == m_iSize)
|
||||
m_iStartPos = 0;
|
||||
}
|
||||
|
||||
p = -1; // message head
|
||||
q = m_iStartPos; // message tail
|
||||
passack = m_iStartPos == m_iLastAckPos;
|
||||
bool found = false;
|
||||
|
||||
// looking for the first message
|
||||
for (int i = 0, n = m_iMaxPos + getRcvDataSize(); i <= n; ++ i)
|
||||
{
|
||||
if ((NULL != m_pUnit[q]) && (1 == m_pUnit[q]->m_iFlag))
|
||||
{
|
||||
switch (m_pUnit[q]->m_Packet.getMsgBoundary())
|
||||
{
|
||||
case 3: // 11
|
||||
p = q;
|
||||
found = true;
|
||||
break;
|
||||
|
||||
case 2: // 10
|
||||
p = q;
|
||||
break;
|
||||
|
||||
case 1: // 01
|
||||
if (p != -1)
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// a hole in this message, not valid, restart search
|
||||
p = -1;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
// the msg has to be ack'ed or it is allowed to read out of order, and was not read before
|
||||
if (!passack || !m_pUnit[q]->m_Packet.getMsgOrderFlag())
|
||||
break;
|
||||
|
||||
found = false;
|
||||
}
|
||||
|
||||
if (++ q == m_iSize)
|
||||
q = 0;
|
||||
|
||||
if (q == m_iLastAckPos)
|
||||
passack = true;
|
||||
}
|
||||
|
||||
// no msg found
|
||||
if (!found)
|
||||
{
|
||||
// if the message is larger than the receiver buffer, return part of the message
|
||||
if ((p != -1) && ((q + 1) % m_iSize == p))
|
||||
found = true;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 05/05/2009
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_BUFFER_H__
|
||||
#define __UDT_BUFFER_H__
|
||||
|
||||
|
||||
#include "udt.h"
|
||||
#include "list.h"
|
||||
#include "queue.h"
|
||||
#include <fstream>
|
||||
|
||||
class CSndBuffer
|
||||
{
|
||||
public:
|
||||
CSndBuffer(int size = 32, int mss = 1500);
|
||||
~CSndBuffer();
|
||||
|
||||
// Functionality:
|
||||
// Insert a user buffer into the sending list.
|
||||
// Parameters:
|
||||
// 0) [in] data: pointer to the user data block.
|
||||
// 1) [in] len: size of the block.
|
||||
// 2) [in] ttl: time to live in milliseconds
|
||||
// 3) [in] order: if the block should be delivered in order, for DGRAM only
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void addBuffer(const char* data, int len, int ttl = -1, bool order = false);
|
||||
|
||||
// Functionality:
|
||||
// Read a block of data from file and insert it into the sending list.
|
||||
// Parameters:
|
||||
// 0) [in] ifs: input file stream.
|
||||
// 1) [in] len: size of the block.
|
||||
// Returned value:
|
||||
// actual size of data added from the file.
|
||||
|
||||
int addBufferFromFile(std::fstream& ifs, int len);
|
||||
|
||||
// Functionality:
|
||||
// Find data position to pack a DATA packet from the furthest reading point.
|
||||
// Parameters:
|
||||
// 0) [out] data: the pointer to the data position.
|
||||
// 1) [out] msgno: message number of the packet.
|
||||
// Returned value:
|
||||
// Actual length of data read.
|
||||
|
||||
int readData(char** data, int32_t& msgno);
|
||||
|
||||
// Functionality:
|
||||
// Find data position to pack a DATA packet for a retransmission.
|
||||
// Parameters:
|
||||
// 0) [out] data: the pointer to the data position.
|
||||
// 1) [in] offset: offset from the last ACK point.
|
||||
// 2) [out] msgno: message number of the packet.
|
||||
// 3) [out] msglen: length of the message
|
||||
// Returned value:
|
||||
// Actual length of data read.
|
||||
|
||||
int readData(char** data, const int offset, int32_t& msgno, int& msglen);
|
||||
|
||||
// Functionality:
|
||||
// Update the ACK point and may release/unmap/return the user data according to the flag.
|
||||
// Parameters:
|
||||
// 0) [in] offset: number of packets acknowledged.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void ackData(int offset);
|
||||
|
||||
// Functionality:
|
||||
// Read size of data still in the sending list.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Current size of the data in the sending list.
|
||||
|
||||
int getCurrBufSize() const;
|
||||
|
||||
private:
|
||||
void increase();
|
||||
|
||||
private:
|
||||
udt_pthread_mutex_t m_BufLock; // used to synchronize buffer operation
|
||||
|
||||
struct Block
|
||||
{
|
||||
char* m_pcData; // pointer to the data block
|
||||
int m_iLength; // length of the block
|
||||
|
||||
int32_t m_iMsgNo; // message number
|
||||
uint64_t m_OriginTime; // original request time
|
||||
int m_iTTL; // time to live (milliseconds)
|
||||
|
||||
Block* m_pNext; // next block
|
||||
} *m_pBlock, *m_pFirstBlock, *m_pCurrBlock, *m_pLastBlock;
|
||||
|
||||
// m_pBlock: The head pointer
|
||||
// m_pFirstBlock: The first block
|
||||
// m_pCurrBlock: The current block
|
||||
// m_pLastBlock: The last block (if first == last, buffer is empty)
|
||||
|
||||
struct Buffer
|
||||
{
|
||||
char* m_pcData; // buffer
|
||||
int m_iSize; // size
|
||||
Buffer* m_pNext; // next buffer
|
||||
} *m_pBuffer; // physical buffer
|
||||
|
||||
int32_t m_iNextMsgNo; // next message number
|
||||
|
||||
int m_iSize; // buffer size (number of packets)
|
||||
int m_iMSS; // maximum seqment/packet size
|
||||
|
||||
int m_iCount; // number of used blocks
|
||||
|
||||
private:
|
||||
CSndBuffer(const CSndBuffer&);
|
||||
CSndBuffer& operator=(const CSndBuffer&);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CRcvBuffer
|
||||
{
|
||||
public:
|
||||
CRcvBuffer(CUnitQueue* queue, int bufsize = 65536);
|
||||
~CRcvBuffer();
|
||||
|
||||
// Functionality:
|
||||
// Write data into the buffer.
|
||||
// Parameters:
|
||||
// 0) [in] unit: pointer to a data unit containing new packet
|
||||
// 1) [in] offset: offset from last ACK point.
|
||||
// Returned value:
|
||||
// 0 is success, -1 if data is repeated.
|
||||
|
||||
int addData(CUnit* unit, int offset);
|
||||
|
||||
// Functionality:
|
||||
// Read data into a user buffer.
|
||||
// Parameters:
|
||||
// 0) [in] data: pointer to user buffer.
|
||||
// 1) [in] len: length of user buffer.
|
||||
// Returned value:
|
||||
// size of data read.
|
||||
|
||||
int readBuffer(char* data, int len);
|
||||
|
||||
// Functionality:
|
||||
// Read data directly into file.
|
||||
// Parameters:
|
||||
// 0) [in] file: C++ file stream.
|
||||
// 1) [in] len: expected length of data to write into the file.
|
||||
// Returned value:
|
||||
// size of data read.
|
||||
|
||||
int readBufferToFile(std::fstream& ofs, int len);
|
||||
|
||||
// Functionality:
|
||||
// Update the ACK point of the buffer.
|
||||
// Parameters:
|
||||
// 0) [in] len: size of data to be acknowledged.
|
||||
// Returned value:
|
||||
// 1 if a user buffer is fulfilled, otherwise 0.
|
||||
|
||||
void ackData(int len);
|
||||
|
||||
// Functionality:
|
||||
// Query how many buffer space left for data receiving.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// size of available buffer space (including user buffer) for data receiving.
|
||||
|
||||
int getAvailBufSize() const;
|
||||
|
||||
// Functionality:
|
||||
// Query how many data has been continuously received (for reading).
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// size of valid (continous) data for reading.
|
||||
|
||||
int getRcvDataSize() const;
|
||||
|
||||
// Functionality:
|
||||
// mark the message to be dropped from the message list.
|
||||
// Parameters:
|
||||
// 0) [in] msgno: message nuumer.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void dropMsg(int32_t msgno);
|
||||
|
||||
// Functionality:
|
||||
// read a message.
|
||||
// Parameters:
|
||||
// 0) [out] data: buffer to write the message into.
|
||||
// 1) [in] len: size of the buffer.
|
||||
// Returned value:
|
||||
// actuall size of data read.
|
||||
|
||||
int readMsg(char* data, int len);
|
||||
|
||||
// Functionality:
|
||||
// Query how many messages are available now.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// number of messages available for recvmsg.
|
||||
|
||||
int getRcvMsgNum();
|
||||
|
||||
private:
|
||||
bool scanMsg(int& start, int& end, bool& passack);
|
||||
|
||||
private:
|
||||
CUnit** m_pUnit; // pointer to the protocol buffer
|
||||
int m_iSize; // size of the protocol buffer
|
||||
CUnitQueue* m_pUnitQueue; // the shared unit queue
|
||||
|
||||
int m_iStartPos; // the head position for I/O (inclusive)
|
||||
int m_iLastAckPos; // the last ACKed position (exclusive)
|
||||
// EMPTY: m_iStartPos = m_iLastAckPos FULL: m_iStartPos = m_iLastAckPos + 1
|
||||
int m_iMaxPos; // the furthest data position
|
||||
|
||||
int m_iNotch; // the starting read point of the first unit
|
||||
|
||||
private:
|
||||
CRcvBuffer();
|
||||
CRcvBuffer(const CRcvBuffer&);
|
||||
CRcvBuffer& operator=(const CRcvBuffer&);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,121 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 05/05/2009
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef WINDOWS
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
#include "cache.h"
|
||||
#include "core.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
CInfoBlock& CInfoBlock::operator=(const CInfoBlock& obj)
|
||||
{
|
||||
std::copy(obj.m_piIP, obj.m_piIP + 3, m_piIP);
|
||||
m_iIPversion = obj.m_iIPversion;
|
||||
m_ullTimeStamp = obj.m_ullTimeStamp;
|
||||
m_iRTT = obj.m_iRTT;
|
||||
m_iBandwidth = obj.m_iBandwidth;
|
||||
m_iLossRate = obj.m_iLossRate;
|
||||
m_iReorderDistance = obj.m_iReorderDistance;
|
||||
m_dInterval = obj.m_dInterval;
|
||||
m_dCWnd = obj.m_dCWnd;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CInfoBlock::operator==(const CInfoBlock& obj)
|
||||
{
|
||||
if (m_iIPversion != obj.m_iIPversion)
|
||||
return false;
|
||||
|
||||
else if (m_iIPversion == AF_INET)
|
||||
return (m_piIP[0] == obj.m_piIP[0]);
|
||||
|
||||
for (int i = 0; i < 4; ++ i)
|
||||
{
|
||||
if (m_piIP[i] != obj.m_piIP[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CInfoBlock* CInfoBlock::clone()
|
||||
{
|
||||
CInfoBlock* obj = new CInfoBlock;
|
||||
|
||||
std::copy(m_piIP, m_piIP + 3, obj->m_piIP);
|
||||
obj->m_iIPversion = m_iIPversion;
|
||||
obj->m_ullTimeStamp = m_ullTimeStamp;
|
||||
obj->m_iRTT = m_iRTT;
|
||||
obj->m_iBandwidth = m_iBandwidth;
|
||||
obj->m_iLossRate = m_iLossRate;
|
||||
obj->m_iReorderDistance = m_iReorderDistance;
|
||||
obj->m_dInterval = m_dInterval;
|
||||
obj->m_dCWnd = m_dCWnd;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
int CInfoBlock::getKey()
|
||||
{
|
||||
if (m_iIPversion == AF_INET)
|
||||
return m_piIP[0];
|
||||
|
||||
return m_piIP[0] + m_piIP[1] + m_piIP[2] + m_piIP[3];
|
||||
}
|
||||
|
||||
void CInfoBlock::convert(const sockaddr* addr, int ver, uint32_t ip[])
|
||||
{
|
||||
if (ver == AF_INET)
|
||||
{
|
||||
ip[0] = ((sockaddr_in*)addr)->sin_addr.s_addr;
|
||||
ip[1] = ip[2] = ip[3] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy((char*)ip, (char*)((sockaddr_in6*)addr)->sin6_addr.s6_addr, 16);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,293 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/27/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_CACHE_H__
|
||||
#define __UDT_CACHE_H__
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "udtCommon.h"
|
||||
#include "udt.h"
|
||||
|
||||
class CCacheItem
|
||||
{
|
||||
public:
|
||||
virtual ~CCacheItem() {}
|
||||
|
||||
public:
|
||||
virtual CCacheItem& operator=(const CCacheItem&) = 0;
|
||||
|
||||
// The "==" operator SHOULD only compare key values.
|
||||
virtual bool operator==(const CCacheItem&) = 0;
|
||||
|
||||
// Functionality:
|
||||
// get a deep copy clone of the current item
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Pointer to the new item, or NULL if failed.
|
||||
|
||||
virtual CCacheItem* clone() = 0;
|
||||
|
||||
// Functionality:
|
||||
// get a random key value between 0 and MAX_INT to be used for the hash in cache
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// A random hash key.
|
||||
|
||||
virtual int getKey() = 0;
|
||||
|
||||
// If there is any shared resources between the cache item and its clone,
|
||||
// the shared resource should be released by this function.
|
||||
virtual void release() {}
|
||||
};
|
||||
|
||||
template<typename T> class CCache
|
||||
{
|
||||
public:
|
||||
CCache(int size = 1024):
|
||||
m_iMaxSize(size),
|
||||
m_iHashSize(size * 3),
|
||||
m_iCurrSize(0)
|
||||
{
|
||||
m_vHashPtr.resize(m_iHashSize);
|
||||
CGuard::createMutex(m_Lock);
|
||||
}
|
||||
|
||||
~CCache()
|
||||
{
|
||||
clear();
|
||||
CGuard::releaseMutex(m_Lock);
|
||||
}
|
||||
|
||||
public:
|
||||
// Functionality:
|
||||
// find the matching item in the cache.
|
||||
// Parameters:
|
||||
// 0) [in/out] data: storage for the retrieved item; initially it must carry the key information
|
||||
// Returned value:
|
||||
// 0 if found a match, otherwise -1.
|
||||
|
||||
int lookup(T* data)
|
||||
{
|
||||
CGuard cacheguard(m_Lock);
|
||||
|
||||
int key = data->getKey();
|
||||
if (key < 0)
|
||||
return -1;
|
||||
if (key >= m_iMaxSize)
|
||||
key %= m_iHashSize;
|
||||
|
||||
const ItemPtrList& item_list = m_vHashPtr[key];
|
||||
for (typename ItemPtrList::const_iterator i = item_list.begin(); i != item_list.end(); ++ i)
|
||||
{
|
||||
if (*data == ***i)
|
||||
{
|
||||
// copy the cached info
|
||||
*data = ***i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Functionality:
|
||||
// update an item in the cache, or insert one if it doesn't exist; oldest item may be removed
|
||||
// Parameters:
|
||||
// 0) [in] data: the new item to updated/inserted to the cache
|
||||
// Returned value:
|
||||
// 0 if success, otherwise -1.
|
||||
|
||||
int update(T* data)
|
||||
{
|
||||
CGuard cacheguard(m_Lock);
|
||||
|
||||
int key = data->getKey();
|
||||
if (key < 0)
|
||||
return -1;
|
||||
if (key >= m_iMaxSize)
|
||||
key %= m_iHashSize;
|
||||
|
||||
T* curr = NULL;
|
||||
|
||||
ItemPtrList& item_list = m_vHashPtr[key];
|
||||
for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i)
|
||||
{
|
||||
if (*data == ***i)
|
||||
{
|
||||
// update the existing entry with the new value
|
||||
***i = *data;
|
||||
curr = **i;
|
||||
|
||||
// remove the current entry
|
||||
m_StorageList.erase(*i);
|
||||
item_list.erase(i);
|
||||
|
||||
// re-insert to the front
|
||||
m_StorageList.push_front(curr);
|
||||
item_list.push_front(m_StorageList.begin());
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// create new entry and insert to front
|
||||
curr = data->clone();
|
||||
m_StorageList.push_front(curr);
|
||||
item_list.push_front(m_StorageList.begin());
|
||||
|
||||
++ m_iCurrSize;
|
||||
if (m_iCurrSize >= m_iMaxSize)
|
||||
{
|
||||
// Cache overflow, remove oldest entry.
|
||||
T* last_data = m_StorageList.back();
|
||||
int last_key = last_data->getKey() % m_iHashSize;
|
||||
|
||||
item_list = m_vHashPtr[last_key];
|
||||
for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i)
|
||||
{
|
||||
if (*last_data == ***i)
|
||||
{
|
||||
item_list.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
last_data->release();
|
||||
delete last_data;
|
||||
m_StorageList.pop_back();
|
||||
-- m_iCurrSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Functionality:
|
||||
// Specify the cache size (i.e., max number of items).
|
||||
// Parameters:
|
||||
// 0) [in] size: max cache size.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setSizeLimit(int size)
|
||||
{
|
||||
m_iMaxSize = size;
|
||||
m_iHashSize = size * 3;
|
||||
m_vHashPtr.resize(m_iHashSize);
|
||||
}
|
||||
|
||||
// Functionality:
|
||||
// Clear all entries in the cache, restore to initialization state.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (typename std::list<T*>::iterator i = m_StorageList.begin(); i != m_StorageList.end(); ++ i)
|
||||
{
|
||||
(*i)->release();
|
||||
delete *i;
|
||||
}
|
||||
m_StorageList.clear();
|
||||
for (typename std::vector<ItemPtrList>::iterator i = m_vHashPtr.begin(); i != m_vHashPtr.end(); ++ i)
|
||||
i->clear();
|
||||
m_iCurrSize = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<T*> m_StorageList;
|
||||
typedef typename std::list<T*>::iterator ItemPtr;
|
||||
typedef std::list<ItemPtr> ItemPtrList;
|
||||
std::vector<ItemPtrList> m_vHashPtr;
|
||||
|
||||
int m_iMaxSize;
|
||||
int m_iHashSize;
|
||||
int m_iCurrSize;
|
||||
|
||||
udt_pthread_mutex_t m_Lock;
|
||||
|
||||
private:
|
||||
CCache(const CCache&);
|
||||
CCache& operator=(const CCache&);
|
||||
};
|
||||
|
||||
|
||||
class CInfoBlock
|
||||
{
|
||||
public:
|
||||
uint32_t m_piIP[4]; // IP address, machine read only, not human readable format
|
||||
int m_iIPversion; // IP version
|
||||
uint64_t m_ullTimeStamp; // last update time
|
||||
int m_iRTT; // RTT
|
||||
int m_iBandwidth; // estimated bandwidth
|
||||
int m_iLossRate; // average loss rate
|
||||
int m_iReorderDistance; // packet reordering distance
|
||||
double m_dInterval; // inter-packet time, congestion control
|
||||
double m_dCWnd; // congestion window size, congestion control
|
||||
|
||||
public:
|
||||
virtual ~CInfoBlock() {}
|
||||
virtual CInfoBlock& operator=(const CInfoBlock& obj);
|
||||
virtual bool operator==(const CInfoBlock& obj);
|
||||
virtual CInfoBlock* clone();
|
||||
virtual int getKey();
|
||||
virtual void release() {}
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// convert sockaddr structure to an integer array
|
||||
// Parameters:
|
||||
// 0) [in] addr: network address
|
||||
// 1) [in] ver: IP version
|
||||
// 2) [out] ip: the result machine readable IP address in integer array
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
static void convert(const sockaddr* addr, int ver, uint32_t ip[]);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,314 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 02/28/2012
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include "core.h"
|
||||
#include "ccc.h"
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
CCC::CCC():
|
||||
m_iSYNInterval(CUDT::m_iSYNInterval),
|
||||
m_dPktSndPeriod(1.0),
|
||||
m_dCWndSize(16.0),
|
||||
m_iBandwidth(),
|
||||
m_dMaxCWndSize(),
|
||||
m_iMSS(),
|
||||
m_iSndCurrSeqNo(),
|
||||
m_iRcvRate(),
|
||||
m_iRTT(),
|
||||
m_pcParam(NULL),
|
||||
m_iPSize(0),
|
||||
m_UDT(),
|
||||
m_iACKPeriod(0),
|
||||
m_iACKInterval(0),
|
||||
m_bUserDefinedRTO(false),
|
||||
m_iRTO(-1),
|
||||
m_PerfInfo()
|
||||
{
|
||||
}
|
||||
|
||||
CCC::~CCC()
|
||||
{
|
||||
delete [] m_pcParam;
|
||||
}
|
||||
|
||||
void CCC::setACKTimer(int msINT)
|
||||
{
|
||||
m_iACKPeriod = msINT > m_iSYNInterval ? m_iSYNInterval : msINT;
|
||||
}
|
||||
|
||||
void CCC::setACKInterval(int pktINT)
|
||||
{
|
||||
m_iACKInterval = pktINT;
|
||||
}
|
||||
|
||||
void CCC::setRTO(int usRTO)
|
||||
{
|
||||
m_bUserDefinedRTO = true;
|
||||
m_iRTO = usRTO;
|
||||
}
|
||||
|
||||
void CCC::sendCustomMsg(CPacket& pkt) const
|
||||
{
|
||||
CUDT* u = CUDT::getUDTHandle(m_UDT);
|
||||
|
||||
if (NULL != u)
|
||||
{
|
||||
pkt.m_iID = u->m_PeerID;
|
||||
u->m_pSndQueue->sendto(u->m_pPeerAddr, pkt);
|
||||
}
|
||||
}
|
||||
|
||||
const CPerfMon* CCC::getPerfInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
CUDT* u = CUDT::getUDTHandle(m_UDT);
|
||||
if (NULL != u)
|
||||
u->sample(&m_PerfInfo, false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &m_PerfInfo;
|
||||
}
|
||||
|
||||
void CCC::setMSS(int mss)
|
||||
{
|
||||
m_iMSS = mss;
|
||||
}
|
||||
|
||||
void CCC::setBandwidth(int bw)
|
||||
{
|
||||
m_iBandwidth = bw;
|
||||
}
|
||||
|
||||
void CCC::setSndCurrSeqNo(int32_t seqno)
|
||||
{
|
||||
m_iSndCurrSeqNo = seqno;
|
||||
}
|
||||
|
||||
void CCC::setRcvRate(int rcvrate)
|
||||
{
|
||||
m_iRcvRate = rcvrate;
|
||||
}
|
||||
|
||||
void CCC::setMaxCWndSize(int cwnd)
|
||||
{
|
||||
m_dMaxCWndSize = cwnd;
|
||||
}
|
||||
|
||||
void CCC::setRTT(int rtt)
|
||||
{
|
||||
m_iRTT = rtt;
|
||||
}
|
||||
|
||||
void CCC::setUserParam(const char* param, int size)
|
||||
{
|
||||
delete [] m_pcParam;
|
||||
m_pcParam = new char[size];
|
||||
memcpy(m_pcParam, param, size);
|
||||
m_iPSize = size;
|
||||
}
|
||||
|
||||
//
|
||||
CUDTCC::CUDTCC():
|
||||
m_iRCInterval(),
|
||||
m_LastRCTime(),
|
||||
m_bSlowStart(),
|
||||
m_iLastAck(),
|
||||
m_bLoss(),
|
||||
m_iLastDecSeq(),
|
||||
m_dLastDecPeriod(),
|
||||
m_iNAKCount(),
|
||||
m_iDecRandom(),
|
||||
m_iAvgNAKNum(),
|
||||
m_iDecCount()
|
||||
{
|
||||
}
|
||||
|
||||
void CUDTCC::init()
|
||||
{
|
||||
m_iRCInterval = m_iSYNInterval;
|
||||
m_LastRCTime = CTimer::getTime();
|
||||
setACKTimer(m_iRCInterval);
|
||||
|
||||
m_bSlowStart = true;
|
||||
m_iLastAck = m_iSndCurrSeqNo;
|
||||
m_bLoss = false;
|
||||
m_iLastDecSeq = CSeqNo::decseq(m_iLastAck);
|
||||
m_dLastDecPeriod = 1;
|
||||
m_iAvgNAKNum = 0;
|
||||
m_iNAKCount = 0;
|
||||
m_iDecRandom = 1;
|
||||
|
||||
m_dCWndSize = 16;
|
||||
m_dPktSndPeriod = 1;
|
||||
}
|
||||
|
||||
void CUDTCC::onACK(int32_t ack)
|
||||
{
|
||||
int64_t B = 0;
|
||||
double inc = 0;
|
||||
// Note: 1/24/2012
|
||||
// The minimum increase parameter is increased from "1.0 / m_iMSS" to 0.01
|
||||
// because the original was too small and caused sending rate to stay at low level
|
||||
// for long time.
|
||||
const double min_inc = 0.01;
|
||||
|
||||
uint64_t currtime = CTimer::getTime();
|
||||
if (currtime - m_LastRCTime < (uint64_t)m_iRCInterval)
|
||||
return;
|
||||
|
||||
m_LastRCTime = currtime;
|
||||
|
||||
if (m_bSlowStart)
|
||||
{
|
||||
m_dCWndSize += CSeqNo::seqlen(m_iLastAck, ack);
|
||||
m_iLastAck = ack;
|
||||
|
||||
if (m_dCWndSize > m_dMaxCWndSize)
|
||||
{
|
||||
m_bSlowStart = false;
|
||||
if (m_iRcvRate > 0)
|
||||
m_dPktSndPeriod = 1000000.0 / m_iRcvRate;
|
||||
else
|
||||
m_dPktSndPeriod = m_dCWndSize / (m_iRTT + m_iRCInterval);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_dCWndSize = m_iRcvRate / 1000000.0 * (m_iRTT + m_iRCInterval) + 16;
|
||||
|
||||
// During Slow Start, no rate increase
|
||||
if (m_bSlowStart)
|
||||
return;
|
||||
|
||||
if (m_bLoss)
|
||||
{
|
||||
m_bLoss = false;
|
||||
return;
|
||||
}
|
||||
|
||||
B = (int64_t)(m_iBandwidth - 1000000.0 / m_dPktSndPeriod);
|
||||
if ((m_dPktSndPeriod > m_dLastDecPeriod) && ((m_iBandwidth / 9) < B))
|
||||
B = m_iBandwidth / 9;
|
||||
if (B <= 0)
|
||||
inc = min_inc;
|
||||
else
|
||||
{
|
||||
// inc = max(10 ^ ceil(log10( B * MSS * 8 ) * Beta / MSS, 1/MSS)
|
||||
// Beta = 1.5 * 10^(-6)
|
||||
|
||||
inc = pow(10.0, ceil(log10(B * m_iMSS * 8.0))) * 0.0000015 / m_iMSS;
|
||||
|
||||
if (inc < min_inc)
|
||||
inc = min_inc;
|
||||
}
|
||||
|
||||
m_dPktSndPeriod = (m_dPktSndPeriod * m_iRCInterval) / (m_dPktSndPeriod * inc + m_iRCInterval);
|
||||
}
|
||||
|
||||
void CUDTCC::onLoss(const int32_t* losslist, int)
|
||||
{
|
||||
//Slow Start stopped, if it hasn't yet
|
||||
if (m_bSlowStart)
|
||||
{
|
||||
m_bSlowStart = false;
|
||||
if (m_iRcvRate > 0)
|
||||
{
|
||||
// Set the sending rate to the receiving rate.
|
||||
m_dPktSndPeriod = 1000000.0 / m_iRcvRate;
|
||||
return;
|
||||
}
|
||||
// If no receiving rate is observed, we have to compute the sending
|
||||
// rate according to the current window size, and decrease it
|
||||
// using the method below.
|
||||
m_dPktSndPeriod = m_dCWndSize / (m_iRTT + m_iRCInterval);
|
||||
}
|
||||
|
||||
m_bLoss = true;
|
||||
|
||||
if (CSeqNo::seqcmp(losslist[0] & 0x7FFFFFFF, m_iLastDecSeq) > 0)
|
||||
{
|
||||
m_dLastDecPeriod = m_dPktSndPeriod;
|
||||
m_dPktSndPeriod = ceil(m_dPktSndPeriod * 1.125);
|
||||
|
||||
m_iAvgNAKNum = (int)ceil(m_iAvgNAKNum * 0.875 + m_iNAKCount * 0.125);
|
||||
m_iNAKCount = 1;
|
||||
m_iDecCount = 1;
|
||||
|
||||
m_iLastDecSeq = m_iSndCurrSeqNo;
|
||||
|
||||
// remove global synchronization using randomization
|
||||
srand(m_iLastDecSeq);
|
||||
m_iDecRandom = (int)ceil(m_iAvgNAKNum * (double(rand()) / RAND_MAX));
|
||||
if (m_iDecRandom < 1)
|
||||
m_iDecRandom = 1;
|
||||
}
|
||||
else if ((m_iDecCount ++ < 5) && (0 == (++ m_iNAKCount % m_iDecRandom)))
|
||||
{
|
||||
// 0.875^5 = 0.51, rate should not be decreased by more than half within a congestion period
|
||||
m_dPktSndPeriod = ceil(m_dPktSndPeriod * 1.125);
|
||||
m_iLastDecSeq = m_iSndCurrSeqNo;
|
||||
}
|
||||
}
|
||||
|
||||
void CUDTCC::onTimeout()
|
||||
{
|
||||
if (m_bSlowStart)
|
||||
{
|
||||
m_bSlowStart = false;
|
||||
if (m_iRcvRate > 0)
|
||||
m_dPktSndPeriod = 1000000.0 / m_iRcvRate;
|
||||
else
|
||||
m_dPktSndPeriod = m_dCWndSize / (m_iRTT + m_iRCInterval);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
m_dLastDecPeriod = m_dPktSndPeriod;
|
||||
m_dPktSndPeriod = ceil(m_dPktSndPeriod * 2);
|
||||
m_iLastDecSeq = m_iLastAck;
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,278 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 02/28/2012
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef __UDT_CCC_H__
|
||||
#define __UDT_CCC_H__
|
||||
|
||||
|
||||
#include "udt.h"
|
||||
#include "packet.h"
|
||||
|
||||
|
||||
class UDT_API CCC
|
||||
{
|
||||
friend class CUDT;
|
||||
|
||||
public:
|
||||
CCC();
|
||||
virtual ~CCC();
|
||||
|
||||
private:
|
||||
CCC(const CCC&);
|
||||
CCC& operator=(const CCC&) {return *this;}
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Callback function to be called (only) at the start of a UDT connection.
|
||||
// note that this is different from CCC(), which is always called.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void init() {}
|
||||
|
||||
// Functionality:
|
||||
// Callback function to be called when a UDT connection is closed.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void close() {}
|
||||
|
||||
// Functionality:
|
||||
// Callback function to be called when an ACK packet is received.
|
||||
// Parameters:
|
||||
// 0) [in] ackno: the data sequence number acknowledged by this ACK.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void onACK(int32_t) {}
|
||||
|
||||
// Functionality:
|
||||
// Callback function to be called when a loss report is received.
|
||||
// Parameters:
|
||||
// 0) [in] losslist: list of sequence number of packets, in the format describled in packet.cpp.
|
||||
// 1) [in] size: length of the loss list.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void onLoss(const int32_t*, int) {}
|
||||
|
||||
// Functionality:
|
||||
// Callback function to be called when a timeout event occurs.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void onTimeout() {}
|
||||
|
||||
// Functionality:
|
||||
// Callback function to be called when a data is sent.
|
||||
// Parameters:
|
||||
// 0) [in] seqno: the data sequence number.
|
||||
// 1) [in] size: the payload size.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void onPktSent(const CPacket*) {}
|
||||
|
||||
// Functionality:
|
||||
// Callback function to be called when a data is received.
|
||||
// Parameters:
|
||||
// 0) [in] seqno: the data sequence number.
|
||||
// 1) [in] size: the payload size.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void onPktReceived(const CPacket*) {}
|
||||
|
||||
// Functionality:
|
||||
// Callback function to Process a user defined packet.
|
||||
// Parameters:
|
||||
// 0) [in] pkt: the user defined packet.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void processCustomMsg(const CPacket*) {}
|
||||
|
||||
protected:
|
||||
|
||||
// Functionality:
|
||||
// Set periodical acknowldging and the ACK period.
|
||||
// Parameters:
|
||||
// 0) [in] msINT: the period to send an ACK.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setACKTimer(int msINT);
|
||||
|
||||
// Functionality:
|
||||
// Set packet-based acknowldging and the number of packets to send an ACK.
|
||||
// Parameters:
|
||||
// 0) [in] pktINT: the number of packets to send an ACK.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setACKInterval(int pktINT);
|
||||
|
||||
// Functionality:
|
||||
// Set RTO value.
|
||||
// Parameters:
|
||||
// 0) [in] msRTO: RTO in macroseconds.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setRTO(int usRTO);
|
||||
|
||||
// Functionality:
|
||||
// Send a user defined control packet.
|
||||
// Parameters:
|
||||
// 0) [in] pkt: user defined packet.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void sendCustomMsg(CPacket& pkt) const;
|
||||
|
||||
// Functionality:
|
||||
// retrieve performance information.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Pointer to a performance info structure.
|
||||
|
||||
const CPerfMon* getPerfInfo();
|
||||
|
||||
// Functionality:
|
||||
// Set user defined parameters.
|
||||
// Parameters:
|
||||
// 0) [in] param: the paramters in one buffer.
|
||||
// 1) [in] size: the size of the buffer.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setUserParam(const char* param, int size);
|
||||
|
||||
private:
|
||||
void setMSS(int mss);
|
||||
void setMaxCWndSize(int cwnd);
|
||||
void setBandwidth(int bw);
|
||||
void setSndCurrSeqNo(int32_t seqno);
|
||||
void setRcvRate(int rcvrate);
|
||||
void setRTT(int rtt);
|
||||
|
||||
protected:
|
||||
const int32_t& m_iSYNInterval; // UDT constant parameter, SYN
|
||||
|
||||
double m_dPktSndPeriod; // Packet sending period, in microseconds
|
||||
double m_dCWndSize; // Congestion window size, in packets
|
||||
|
||||
int m_iBandwidth; // estimated bandwidth, packets per second
|
||||
double m_dMaxCWndSize; // maximum cwnd size, in packets
|
||||
|
||||
int m_iMSS; // Maximum Packet Size, including all packet headers
|
||||
int32_t m_iSndCurrSeqNo; // current maximum seq no sent out
|
||||
int m_iRcvRate; // packet arrive rate at receiver side, packets per second
|
||||
int m_iRTT; // current estimated RTT, microsecond
|
||||
|
||||
char* m_pcParam; // user defined parameter
|
||||
int m_iPSize; // size of m_pcParam
|
||||
|
||||
private:
|
||||
UDTSOCKET m_UDT; // The UDT entity that this congestion control algorithm is bound to
|
||||
|
||||
int m_iACKPeriod; // Periodical timer to send an ACK, in milliseconds
|
||||
int m_iACKInterval; // How many packets to send one ACK, in packets
|
||||
|
||||
bool m_bUserDefinedRTO; // if the RTO value is defined by users
|
||||
int m_iRTO; // RTO value, microseconds
|
||||
|
||||
CPerfMon m_PerfInfo; // protocol statistics information
|
||||
};
|
||||
|
||||
class CCCVirtualFactory
|
||||
{
|
||||
public:
|
||||
virtual ~CCCVirtualFactory() {}
|
||||
|
||||
virtual CCC* create() = 0;
|
||||
virtual CCCVirtualFactory* clone() = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CCCFactory: public CCCVirtualFactory
|
||||
{
|
||||
public:
|
||||
virtual ~CCCFactory() {}
|
||||
|
||||
virtual CCC* create() {return new T;}
|
||||
virtual CCCVirtualFactory* clone() {return new CCCFactory<T>;}
|
||||
};
|
||||
|
||||
class CUDTCC: public CCC
|
||||
{
|
||||
public:
|
||||
CUDTCC();
|
||||
|
||||
public:
|
||||
virtual void init();
|
||||
virtual void onACK(int32_t);
|
||||
virtual void onLoss(const int32_t*, int);
|
||||
virtual void onTimeout();
|
||||
|
||||
private:
|
||||
int m_iRCInterval; // UDT Rate control interval
|
||||
uint64_t m_LastRCTime; // last rate increase time
|
||||
bool m_bSlowStart; // if in slow start phase
|
||||
int32_t m_iLastAck; // last ACKed seq no
|
||||
bool m_bLoss; // if loss happened since last rate increase
|
||||
int32_t m_iLastDecSeq; // max pkt seq no sent out when last decrease happened
|
||||
double m_dLastDecPeriod; // value of pktsndperiod when last decrease happened
|
||||
int m_iNAKCount; // NAK counter
|
||||
int m_iDecRandom; // random threshold on decrease by number of loss events
|
||||
int m_iAvgNAKNum; // average number of NAKs per congestion
|
||||
int m_iDecCount; // number of decreases in a congestion epoch
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,338 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/27/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cerrno>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#endif
|
||||
#include "channel.h"
|
||||
#include "packet.h"
|
||||
|
||||
#ifdef WINDOWS
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
#ifndef WINDOWS
|
||||
#define NET_ERROR errno
|
||||
#else
|
||||
#define NET_ERROR WSAGetLastError()
|
||||
#endif
|
||||
|
||||
|
||||
CChannel::CChannel():
|
||||
m_iIPversion(AF_INET),
|
||||
m_iSockAddrSize(sizeof(sockaddr_in)),
|
||||
m_iSocket(),
|
||||
m_iSndBufSize(65536),
|
||||
m_iRcvBufSize(65536)
|
||||
{
|
||||
}
|
||||
|
||||
CChannel::CChannel(int version):
|
||||
m_iIPversion(version),
|
||||
m_iSocket(),
|
||||
m_iSndBufSize(65536),
|
||||
m_iRcvBufSize(65536)
|
||||
{
|
||||
m_iSockAddrSize = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
|
||||
}
|
||||
|
||||
CChannel::~CChannel()
|
||||
{
|
||||
}
|
||||
|
||||
void CChannel::open(const sockaddr* addr)
|
||||
{
|
||||
// construct an socket
|
||||
m_iSocket = ::socket(m_iIPversion, SOCK_DGRAM, 0);
|
||||
|
||||
#ifdef WINDOWS
|
||||
if (INVALID_SOCKET == m_iSocket)
|
||||
#else
|
||||
if (m_iSocket < 0)
|
||||
#endif
|
||||
throw CUDTException(1, 0, NET_ERROR);
|
||||
|
||||
if (NULL != addr)
|
||||
{
|
||||
socklen_t namelen = m_iSockAddrSize;
|
||||
|
||||
if (0 != ::bind(m_iSocket, addr, namelen))
|
||||
throw CUDTException(1, 3, NET_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
//sendto or WSASendTo will also automatically bind the socket
|
||||
addrinfo hints;
|
||||
addrinfo* res;
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = m_iIPversion;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
if (0 != ::getaddrinfo(NULL, "0", &hints, &res))
|
||||
throw CUDTException(1, 3, NET_ERROR);
|
||||
|
||||
if (0 != ::bind(m_iSocket, res->ai_addr, res->ai_addrlen))
|
||||
throw CUDTException(1, 3, NET_ERROR);
|
||||
|
||||
::freeaddrinfo(res);
|
||||
}
|
||||
|
||||
setUDPSockOpt();
|
||||
}
|
||||
|
||||
void CChannel::open(UDPSOCKET udpsock)
|
||||
{
|
||||
m_iSocket = udpsock;
|
||||
setUDPSockOpt();
|
||||
}
|
||||
|
||||
void CChannel::setUDPSockOpt()
|
||||
{
|
||||
#if defined(BSD) || defined(MACOSX)
|
||||
// BSD system will fail setsockopt if the requested buffer size exceeds system maximum value
|
||||
int maxsize = 64000;
|
||||
if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&m_iRcvBufSize, sizeof(int)))
|
||||
::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&maxsize, sizeof(int));
|
||||
if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&m_iSndBufSize, sizeof(int)))
|
||||
::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&maxsize, sizeof(int));
|
||||
#else
|
||||
// for other systems, if requested is greated than maximum, the maximum value will be automactally used
|
||||
if ((0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&m_iRcvBufSize, sizeof(int))) ||
|
||||
(0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&m_iSndBufSize, sizeof(int))))
|
||||
throw CUDTException(1, 3, NET_ERROR);
|
||||
#endif
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
#if defined (BSD) || defined (MACOSX)
|
||||
// Known BSD bug as the day I wrote this code.
|
||||
// A small time out value will cause the socket to block forever.
|
||||
tv.tv_usec = 10000;
|
||||
#else
|
||||
tv.tv_usec = 100;
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
// Set non-blocking I/O
|
||||
// UNIX does not support SO_RCVTIMEO
|
||||
int opts = ::fcntl(m_iSocket, F_GETFL);
|
||||
if (-1 == ::fcntl(m_iSocket, F_SETFL, opts | O_NONBLOCK))
|
||||
throw CUDTException(1, 3, NET_ERROR);
|
||||
#elif WINDOWS
|
||||
DWORD ot = 1; //milliseconds
|
||||
if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&ot, sizeof(DWORD)))
|
||||
throw CUDTException(1, 3, NET_ERROR);
|
||||
#else
|
||||
// Set receiving time-out value
|
||||
if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(timeval)))
|
||||
throw CUDTException(1, 3, NET_ERROR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CChannel::close() const
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
::close(m_iSocket);
|
||||
#else
|
||||
::closesocket(m_iSocket);
|
||||
#endif
|
||||
}
|
||||
|
||||
int CChannel::getSndBufSize()
|
||||
{
|
||||
socklen_t size = sizeof(socklen_t);
|
||||
::getsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char *)&m_iSndBufSize, &size);
|
||||
return m_iSndBufSize;
|
||||
}
|
||||
|
||||
int CChannel::getRcvBufSize()
|
||||
{
|
||||
socklen_t size = sizeof(socklen_t);
|
||||
::getsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char *)&m_iRcvBufSize, &size);
|
||||
return m_iRcvBufSize;
|
||||
}
|
||||
|
||||
void CChannel::setSndBufSize(int size)
|
||||
{
|
||||
m_iSndBufSize = size;
|
||||
}
|
||||
|
||||
void CChannel::setRcvBufSize(int size)
|
||||
{
|
||||
m_iRcvBufSize = size;
|
||||
}
|
||||
|
||||
void CChannel::getSockAddr(sockaddr* addr) const
|
||||
{
|
||||
socklen_t namelen = m_iSockAddrSize;
|
||||
::getsockname(m_iSocket, addr, &namelen);
|
||||
}
|
||||
|
||||
void CChannel::getPeerAddr(sockaddr* addr) const
|
||||
{
|
||||
socklen_t namelen = m_iSockAddrSize;
|
||||
::getpeername(m_iSocket, addr, &namelen);
|
||||
}
|
||||
|
||||
int CChannel::sendto(const sockaddr* addr, CPacket& packet) const
|
||||
{
|
||||
// convert control information into network order
|
||||
if (packet.getFlag())
|
||||
for (int i = 0, n = packet.getLength() / 4; i < n; ++ i)
|
||||
*((uint32_t *)packet.m_pcData + i) = htonl(*((uint32_t *)packet.m_pcData + i));
|
||||
|
||||
// convert packet header into network order
|
||||
//for (int j = 0; j < 4; ++ j)
|
||||
// packet.m_nHeader[j] = htonl(packet.m_nHeader[j]);
|
||||
uint32_t* p = packet.m_nHeader;
|
||||
for (int j = 0; j < 4; ++ j)
|
||||
{
|
||||
*p = htonl(*p);
|
||||
++ p;
|
||||
}
|
||||
|
||||
#ifndef WINDOWS
|
||||
msghdr mh;
|
||||
mh.msg_name = (sockaddr*)addr;
|
||||
mh.msg_namelen = m_iSockAddrSize;
|
||||
mh.msg_iov = (iovec*)packet.m_PacketVector;
|
||||
mh.msg_iovlen = 2;
|
||||
mh.msg_control = NULL;
|
||||
mh.msg_controllen = 0;
|
||||
mh.msg_flags = 0;
|
||||
|
||||
int res = ::sendmsg(m_iSocket, &mh, 0);
|
||||
#else
|
||||
DWORD size = CPacket::m_iPktHdrSize + packet.getLength();
|
||||
int addrsize = m_iSockAddrSize;
|
||||
int res = ::WSASendTo(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, 0, addr, addrsize, NULL, NULL);
|
||||
res = (0 == res) ? size : -1;
|
||||
#endif
|
||||
|
||||
// convert back into local host order
|
||||
//for (int k = 0; k < 4; ++ k)
|
||||
// packet.m_nHeader[k] = ntohl(packet.m_nHeader[k]);
|
||||
p = packet.m_nHeader;
|
||||
for (int k = 0; k < 4; ++ k)
|
||||
{
|
||||
*p = ntohl(*p);
|
||||
++ p;
|
||||
}
|
||||
|
||||
if (packet.getFlag())
|
||||
{
|
||||
for (int l = 0, n = packet.getLength() / 4; l < n; ++ l)
|
||||
*((uint32_t *)packet.m_pcData + l) = ntohl(*((uint32_t *)packet.m_pcData + l));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int CChannel::recvfrom(sockaddr* addr, CPacket& packet) const
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
msghdr mh;
|
||||
mh.msg_name = addr;
|
||||
mh.msg_namelen = m_iSockAddrSize;
|
||||
mh.msg_iov = packet.m_PacketVector;
|
||||
mh.msg_iovlen = 2;
|
||||
mh.msg_control = NULL;
|
||||
mh.msg_controllen = 0;
|
||||
mh.msg_flags = 0;
|
||||
|
||||
#ifdef UNIX
|
||||
fd_set set;
|
||||
timeval tv;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(m_iSocket, &set);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
::select(m_iSocket+1, &set, NULL, &set, &tv);
|
||||
#endif
|
||||
|
||||
int res = ::recvmsg(m_iSocket, &mh, 0);
|
||||
#else
|
||||
DWORD size = CPacket::m_iPktHdrSize + packet.getLength();
|
||||
DWORD flag = 0;
|
||||
int addrsize = m_iSockAddrSize;
|
||||
|
||||
int res = ::WSARecvFrom(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, &flag, addr, &addrsize, NULL, NULL);
|
||||
res = (0 == res) ? size : -1;
|
||||
#endif
|
||||
|
||||
if (res <= 0)
|
||||
{
|
||||
packet.setLength(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
packet.setLength(res - CPacket::m_iPktHdrSize);
|
||||
|
||||
// convert back into local host order
|
||||
//for (int i = 0; i < 4; ++ i)
|
||||
// packet.m_nHeader[i] = ntohl(packet.m_nHeader[i]);
|
||||
uint32_t* p = packet.m_nHeader;
|
||||
for (int i = 0; i < 4; ++ i)
|
||||
{
|
||||
*p = ntohl(*p);
|
||||
++ p;
|
||||
}
|
||||
|
||||
if (packet.getFlag())
|
||||
{
|
||||
for (int j = 0, n = packet.getLength() / 4; j < n; ++ j)
|
||||
*((uint32_t *)packet.m_pcData + j) = ntohl(*((uint32_t *)packet.m_pcData + j));
|
||||
}
|
||||
|
||||
return packet.getLength();
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/27/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_CHANNEL_H__
|
||||
#define __UDT_CHANNEL_H__
|
||||
|
||||
|
||||
#include "udt.h"
|
||||
#include "packet.h"
|
||||
|
||||
|
||||
class CChannel
|
||||
{
|
||||
public:
|
||||
CChannel();
|
||||
CChannel(int version);
|
||||
~CChannel();
|
||||
|
||||
// Functionality:
|
||||
// Open a UDP channel.
|
||||
// Parameters:
|
||||
// 0) [in] addr: The local address that UDP will use.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void open(const sockaddr* addr = NULL);
|
||||
|
||||
// Functionality:
|
||||
// Open a UDP channel based on an existing UDP socket.
|
||||
// Parameters:
|
||||
// 0) [in] udpsock: UDP socket descriptor.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void open(UDPSOCKET udpsock);
|
||||
|
||||
// Functionality:
|
||||
// Disconnect and close the UDP entity.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void close() const;
|
||||
|
||||
// Functionality:
|
||||
// Get the UDP sending buffer size.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Current UDP sending buffer size.
|
||||
|
||||
int getSndBufSize();
|
||||
|
||||
// Functionality:
|
||||
// Get the UDP receiving buffer size.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Current UDP receiving buffer size.
|
||||
|
||||
int getRcvBufSize();
|
||||
|
||||
// Functionality:
|
||||
// Set the UDP sending buffer size.
|
||||
// Parameters:
|
||||
// 0) [in] size: expected UDP sending buffer size.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setSndBufSize(int size);
|
||||
|
||||
// Functionality:
|
||||
// Set the UDP receiving buffer size.
|
||||
// Parameters:
|
||||
// 0) [in] size: expected UDP receiving buffer size.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setRcvBufSize(int size);
|
||||
|
||||
// Functionality:
|
||||
// Query the socket address that the channel is using.
|
||||
// Parameters:
|
||||
// 0) [out] addr: pointer to store the returned socket address.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void getSockAddr(sockaddr* addr) const;
|
||||
|
||||
// Functionality:
|
||||
// Query the peer side socket address that the channel is connect to.
|
||||
// Parameters:
|
||||
// 0) [out] addr: pointer to store the returned socket address.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void getPeerAddr(sockaddr* addr) const;
|
||||
|
||||
// Functionality:
|
||||
// Send a packet to the given address.
|
||||
// Parameters:
|
||||
// 0) [in] addr: pointer to the destination address.
|
||||
// 1) [in] packet: reference to a CPacket entity.
|
||||
// Returned value:
|
||||
// Actual size of data sent.
|
||||
|
||||
int sendto(const sockaddr* addr, CPacket& packet) const;
|
||||
|
||||
// Functionality:
|
||||
// Receive a packet from the channel and record the source address.
|
||||
// Parameters:
|
||||
// 0) [in] addr: pointer to the source address.
|
||||
// 1) [in] packet: reference to a CPacket entity.
|
||||
// Returned value:
|
||||
// Actual size of data received.
|
||||
|
||||
int recvfrom(sockaddr* addr, CPacket& packet) const;
|
||||
|
||||
private:
|
||||
void setUDPSockOpt();
|
||||
|
||||
private:
|
||||
int m_iIPversion; // IP version
|
||||
int m_iSockAddrSize; // socket address structure size (pre-defined to avoid run-time test)
|
||||
|
||||
UDPSOCKET m_iSocket; // socket descriptor
|
||||
|
||||
int m_iSndBufSize; // UDP sending buffer size
|
||||
int m_iRcvBufSize; // UDP receiving buffer size
|
||||
};
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,463 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 02/28/2012
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_CORE_H__
|
||||
#define __UDT_CORE_H__
|
||||
|
||||
|
||||
#include "udt.h"
|
||||
#include "udtCommon.h"
|
||||
#include "list.h"
|
||||
#include "buffer.h"
|
||||
#include "window.h"
|
||||
#include "packet.h"
|
||||
#include "channel.h"
|
||||
#include "api.h"
|
||||
#include "ccc.h"
|
||||
#include "cache.h"
|
||||
#include "queue.h"
|
||||
|
||||
enum UDTSockType {UDT_STREAM = 1, UDT_DGRAM};
|
||||
|
||||
class CUDT
|
||||
{
|
||||
friend class CUDTSocket;
|
||||
friend class CUDTUnited;
|
||||
friend class CCC;
|
||||
friend struct CUDTComp;
|
||||
friend class CCache<CInfoBlock>;
|
||||
friend class CRendezvousQueue;
|
||||
friend class CSndQueue;
|
||||
friend class CRcvQueue;
|
||||
friend class CSndUList;
|
||||
friend class CRcvUList;
|
||||
|
||||
private: // constructor and desctructor
|
||||
CUDT();
|
||||
CUDT(const CUDT& ancestor);
|
||||
const CUDT& operator=(const CUDT&) {return *this;}
|
||||
~CUDT();
|
||||
|
||||
public: //API
|
||||
static int startup();
|
||||
static int cleanup();
|
||||
static UDTSOCKET socket(int af, int type = SOCK_STREAM, int protocol = 0);
|
||||
static int bind(UDTSOCKET u, const sockaddr* name, int namelen);
|
||||
static int bind(UDTSOCKET u, UDPSOCKET udpsock);
|
||||
static int listen(UDTSOCKET u, int backlog);
|
||||
static UDTSOCKET accept(UDTSOCKET u, sockaddr* addr, int* addrlen);
|
||||
static int connect(UDTSOCKET u, const sockaddr* name, int namelen);
|
||||
static int close(UDTSOCKET u);
|
||||
static int getpeername(UDTSOCKET u, sockaddr* name, int* namelen);
|
||||
static int getsockname(UDTSOCKET u, sockaddr* name, int* namelen);
|
||||
static int getsockopt(UDTSOCKET u, int level, UDTOpt optname, void* optval, int* optlen);
|
||||
static int setsockopt(UDTSOCKET u, int level, UDTOpt optname, const void* optval, int optlen);
|
||||
static int send(UDTSOCKET u, const char* buf, int len, int flags);
|
||||
static int recv(UDTSOCKET u, char* buf, int len, int flags);
|
||||
static int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl = -1, bool inorder = false);
|
||||
static int recvmsg(UDTSOCKET u, char* buf, int len);
|
||||
static int64_t sendfile(UDTSOCKET u, std::fstream& ifs, int64_t& offset, int64_t size, int block = 364000);
|
||||
static int64_t recvfile(UDTSOCKET u, std::fstream& ofs, int64_t& offset, int64_t size, int block = 7280000);
|
||||
static int select(int nfds, ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout);
|
||||
static int selectEx(const std::vector<UDTSOCKET>& fds, std::vector<UDTSOCKET>* readfds, std::vector<UDTSOCKET>* writefds, std::vector<UDTSOCKET>* exceptfds, int64_t msTimeOut);
|
||||
static int epoll_create();
|
||||
static int epoll_add_usock(const int eid, const UDTSOCKET u, const int* events = NULL);
|
||||
static int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events = NULL);
|
||||
static int epoll_remove_usock(const int eid, const UDTSOCKET u);
|
||||
static int epoll_remove_ssock(const int eid, const SYSSOCKET s);
|
||||
static int epoll_wait(const int eid, std::set<UDTSOCKET>* readfds, std::set<UDTSOCKET>* writefds, int64_t msTimeOut, std::set<SYSSOCKET>* lrfds = NULL, std::set<SYSSOCKET>* wrfds = NULL);
|
||||
static int epoll_release(const int eid);
|
||||
static CUDTException& getlasterror();
|
||||
static int perfmon(UDTSOCKET u, CPerfMon* perf, bool clear = true);
|
||||
static UDTSTATUS getsockstate(UDTSOCKET u);
|
||||
|
||||
// BARCHART
|
||||
static int epoll_update_usock(const int eid, const UDTSOCKET u, const int* events = NULL);
|
||||
// BARCHART
|
||||
static int epoll_verify_usock(const int eid, const UDTSOCKET u, int* events);
|
||||
|
||||
public: // internal API
|
||||
static CUDT* getUDTHandle(UDTSOCKET u);
|
||||
|
||||
private:
|
||||
// Functionality:
|
||||
// initialize a UDT entity and bind to a local address.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void open();
|
||||
|
||||
// Functionality:
|
||||
// Start listening to any connection request.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void listen();
|
||||
|
||||
// Functionality:
|
||||
// Connect to a UDT entity listening at address "peer".
|
||||
// Parameters:
|
||||
// 0) [in] peer: The address of the listening UDT entity.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void connect(const sockaddr* peer);
|
||||
|
||||
// Functionality:
|
||||
// Process the response handshake packet.
|
||||
// Parameters:
|
||||
// 0) [in] pkt: handshake packet.
|
||||
// Returned value:
|
||||
// Return 0 if connected, positive value if connection is in progress, otherwise error code.
|
||||
|
||||
int connect(const CPacket& pkt) throw ();
|
||||
|
||||
// Functionality:
|
||||
// Connect to a UDT entity listening at address "peer", which has sent "hs" request.
|
||||
// Parameters:
|
||||
// 0) [in] peer: The address of the listening UDT entity.
|
||||
// 1) [in/out] hs: The handshake information sent by the peer side (in), negotiated value (out).
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void connect(const sockaddr* peer, CHandShake* hs);
|
||||
|
||||
// Functionality:
|
||||
// Close the opened UDT entity.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void close();
|
||||
|
||||
// Functionality:
|
||||
// Request UDT to send out a data block "data" with size of "len".
|
||||
// Parameters:
|
||||
// 0) [in] data: The address of the application data to be sent.
|
||||
// 1) [in] len: The size of the data block.
|
||||
// Returned value:
|
||||
// Actual size of data sent.
|
||||
|
||||
int send(const char* data, int len);
|
||||
|
||||
// Functionality:
|
||||
// Request UDT to receive data to a memory block "data" with size of "len".
|
||||
// Parameters:
|
||||
// 0) [out] data: data received.
|
||||
// 1) [in] len: The desired size of data to be received.
|
||||
// Returned value:
|
||||
// Actual size of data received.
|
||||
|
||||
int recv(char* data, int len);
|
||||
|
||||
// Functionality:
|
||||
// send a message of a memory block "data" with size of "len".
|
||||
// Parameters:
|
||||
// 0) [out] data: data received.
|
||||
// 1) [in] len: The desired size of data to be received.
|
||||
// 2) [in] ttl: the time-to-live of the message.
|
||||
// 3) [in] inorder: if the message should be delivered in order.
|
||||
// Returned value:
|
||||
// Actual size of data sent.
|
||||
|
||||
int sendmsg(const char* data, int len, int ttl, bool inorder);
|
||||
|
||||
// Functionality:
|
||||
// Receive a message to buffer "data".
|
||||
// Parameters:
|
||||
// 0) [out] data: data received.
|
||||
// 1) [in] len: size of the buffer.
|
||||
// Returned value:
|
||||
// Actual size of data received.
|
||||
|
||||
int recvmsg(char* data, int len);
|
||||
|
||||
// Functionality:
|
||||
// Request UDT to send out a file described as "fd", starting from "offset", with size of "size".
|
||||
// Parameters:
|
||||
// 0) [in] ifs: The input file stream.
|
||||
// 1) [in, out] offset: From where to read and send data; output is the new offset when the call returns.
|
||||
// 2) [in] size: How many data to be sent.
|
||||
// 3) [in] block: size of block per read from disk
|
||||
// Returned value:
|
||||
// Actual size of data sent.
|
||||
|
||||
int64_t sendfile(std::fstream& ifs, int64_t& offset, int64_t size, int block = 366000);
|
||||
|
||||
// Functionality:
|
||||
// Request UDT to receive data into a file described as "fd", starting from "offset", with expected size of "size".
|
||||
// Parameters:
|
||||
// 0) [out] ofs: The output file stream.
|
||||
// 1) [in, out] offset: From where to write data; output is the new offset when the call returns.
|
||||
// 2) [in] size: How many data to be received.
|
||||
// 3) [in] block: size of block per write to disk
|
||||
// Returned value:
|
||||
// Actual size of data received.
|
||||
|
||||
int64_t recvfile(std::fstream& ofs, int64_t& offset, int64_t size, int block = 7320000);
|
||||
|
||||
// Functionality:
|
||||
// Configure UDT options.
|
||||
// Parameters:
|
||||
// 0) [in] optName: The enum name of a UDT option.
|
||||
// 1) [in] optval: The value to be set.
|
||||
// 2) [in] optlen: size of "optval".
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setOpt(UDTOpt optName, const void* optval, int optlen);
|
||||
|
||||
// Functionality:
|
||||
// Read UDT options.
|
||||
// Parameters:
|
||||
// 0) [in] optName: The enum name of a UDT option.
|
||||
// 1) [in] optval: The value to be returned.
|
||||
// 2) [out] optlen: size of "optval".
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void getOpt(UDTOpt optName, void* optval, int& optlen);
|
||||
|
||||
// Functionality:
|
||||
// read the performance data since last sample() call.
|
||||
// Parameters:
|
||||
// 0) [in, out] perf: pointer to a CPerfMon structure to record the performance data.
|
||||
// 1) [in] clear: flag to decide if the local performance trace should be cleared.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void sample(CPerfMon* perf, bool clear = true);
|
||||
|
||||
private:
|
||||
static CUDTUnited s_UDTUnited; // UDT global management base
|
||||
|
||||
public:
|
||||
static const UDTSOCKET INVALID_SOCK; // invalid socket descriptor
|
||||
static const int ERROR; // socket api error returned value
|
||||
|
||||
private: // Identification
|
||||
UDTSOCKET m_SocketID; // UDT socket number
|
||||
UDTSockType m_iSockType; // Type of the UDT connection (SOCK_STREAM or SOCK_DGRAM)
|
||||
UDTSOCKET m_PeerID; // peer id, for multiplexer
|
||||
static const int m_iVersion; // UDT version, for compatibility use
|
||||
|
||||
private: // Packet sizes
|
||||
int m_iPktSize; // Maximum/regular packet size, in bytes
|
||||
int m_iPayloadSize; // Maximum/regular payload size, in bytes
|
||||
|
||||
private: // Options
|
||||
int m_iMSS; // Maximum Segment Size, in bytes
|
||||
bool m_bSynSending; // Sending syncronization mode
|
||||
bool m_bSynRecving; // Receiving syncronization mode
|
||||
int m_iFlightFlagSize; // Maximum number of packets in flight from the peer side
|
||||
int m_iSndBufSize; // Maximum UDT sender buffer size
|
||||
int m_iRcvBufSize; // Maximum UDT receiver buffer size
|
||||
linger m_Linger; // Linger information on close
|
||||
int m_iUDPSndBufSize; // UDP sending buffer size
|
||||
int m_iUDPRcvBufSize; // UDP receiving buffer size
|
||||
int m_iIPversion; // IP version
|
||||
bool m_bRendezvous; // Rendezvous connection mode
|
||||
int m_iSndTimeOut; // sending timeout in milliseconds
|
||||
int m_iRcvTimeOut; // receiving timeout in milliseconds
|
||||
bool m_bReuseAddr; // reuse an exiting port or not, for UDP multiplexer
|
||||
int64_t m_llMaxBW; // maximum data transfer rate (threshold)
|
||||
|
||||
private: // congestion control
|
||||
CCCVirtualFactory* m_pCCFactory; // Factory class to create a specific CC instance
|
||||
CCC* m_pCC; // congestion control class
|
||||
CCache<CInfoBlock>* m_pCache; // network information cache
|
||||
|
||||
private: // Status
|
||||
volatile bool m_bListening; // If the UDT entit is listening to connection
|
||||
volatile bool m_bConnecting; // The short phase when connect() is called but not yet completed
|
||||
volatile bool m_bConnected; // Whether the connection is on or off
|
||||
volatile bool m_bClosing; // If the UDT entity is closing
|
||||
volatile bool m_bShutdown; // If the peer side has shutdown the connection
|
||||
volatile bool m_bBroken; // If the connection has been broken
|
||||
volatile bool m_bPeerHealth; // If the peer status is normal
|
||||
bool m_bOpened; // If the UDT entity has been opened
|
||||
int m_iBrokenCounter; // a counter (number of GC checks) to let the GC tag this socket as disconnected
|
||||
|
||||
int m_iEXPCount; // Expiration counter
|
||||
int m_iBandwidth; // Estimated bandwidth, number of packets per second
|
||||
int m_iRTT; // RTT, in microseconds
|
||||
int m_iRTTVar; // RTT variance
|
||||
int m_iDeliveryRate; // Packet arrival rate at the receiver side
|
||||
|
||||
uint64_t m_ullLingerExpiration; // Linger expiration time (for GC to close a socket with data in sending buffer)
|
||||
|
||||
CHandShake m_ConnReq; // connection request
|
||||
CHandShake m_ConnRes; // connection response
|
||||
int64_t m_llLastReqTime; // last time when a connection request is sent
|
||||
|
||||
private: // Sending related data
|
||||
CSndBuffer* m_pSndBuffer; // Sender buffer
|
||||
CSndLossList* m_pSndLossList; // Sender loss list
|
||||
CPktTimeWindow* m_pSndTimeWindow; // Packet sending time window
|
||||
|
||||
volatile uint64_t m_ullInterval; // Inter-packet time, in CPU clock cycles
|
||||
uint64_t m_ullTimeDiff; // aggregate difference in inter-packet time
|
||||
|
||||
volatile int m_iFlowWindowSize; // Flow control window size
|
||||
volatile double m_dCongestionWindow; // congestion window size
|
||||
|
||||
volatile int32_t m_iSndLastAck; // Last ACK received
|
||||
volatile int32_t m_iSndLastDataAck; // The real last ACK that updates the sender buffer and loss list
|
||||
volatile int32_t m_iSndCurrSeqNo; // The largest sequence number that has been sent
|
||||
int32_t m_iLastDecSeq; // Sequence number sent last decrease occurs
|
||||
int32_t m_iSndLastAck2; // Last ACK2 sent back
|
||||
uint64_t m_ullSndLastAck2Time; // The time when last ACK2 was sent back
|
||||
|
||||
int32_t m_iISN; // Initial Sequence Number
|
||||
|
||||
void CCUpdate();
|
||||
|
||||
private: // Receiving related data
|
||||
CRcvBuffer* m_pRcvBuffer; // Receiver buffer
|
||||
CRcvLossList* m_pRcvLossList; // Receiver loss list
|
||||
CACKWindow* m_pACKWindow; // ACK history window
|
||||
CPktTimeWindow* m_pRcvTimeWindow; // Packet arrival time window
|
||||
|
||||
int32_t m_iRcvLastAck; // Last sent ACK
|
||||
uint64_t m_ullLastAckTime; // Timestamp of last ACK
|
||||
int32_t m_iRcvLastAckAck; // Last sent ACK that has been acknowledged
|
||||
int32_t m_iAckSeqNo; // Last ACK sequence number
|
||||
int32_t m_iRcvCurrSeqNo; // Largest received sequence number
|
||||
|
||||
uint64_t m_ullLastWarningTime; // Last time that a warning message is sent
|
||||
|
||||
int32_t m_iPeerISN; // Initial Sequence Number of the peer side
|
||||
|
||||
private: // synchronization: mutexes and conditions
|
||||
udt_pthread_mutex_t m_ConnectionLock; // used to synchronize connection operation
|
||||
|
||||
udt_pthread_cond_t m_SendBlockCond; // used to block "send" call
|
||||
udt_pthread_mutex_t m_SendBlockLock; // lock associated to m_SendBlockCond
|
||||
|
||||
udt_pthread_mutex_t m_AckLock; // used to protected sender's loss list when processing ACK
|
||||
|
||||
udt_pthread_cond_t m_RecvDataCond; // used to block "recv" when there is no data
|
||||
udt_pthread_mutex_t m_RecvDataLock; // lock associated to m_RecvDataCond
|
||||
|
||||
udt_pthread_mutex_t m_SendLock; // used to synchronize "send" call
|
||||
udt_pthread_mutex_t m_RecvLock; // used to synchronize "recv" call
|
||||
|
||||
void initSynch();
|
||||
void destroySynch();
|
||||
void releaseSynch();
|
||||
|
||||
private: // Generation and processing of packets
|
||||
void sendCtrl(int pkttype, void* lparam = NULL, void* rparam = NULL, int size = 0);
|
||||
void processCtrl(CPacket& ctrlpkt);
|
||||
int packData(CPacket& packet, uint64_t& ts);
|
||||
int processData(CUnit* unit);
|
||||
int listen(sockaddr* addr, CPacket& packet);
|
||||
|
||||
private: // Trace
|
||||
uint64_t m_StartTime; // timestamp when the UDT entity is started
|
||||
int64_t m_llSentTotal; // total number of sent data packets, including retransmissions
|
||||
int64_t m_llRecvTotal; // total number of received packets
|
||||
int m_iSndLossTotal; // total number of lost packets (sender side)
|
||||
int m_iRcvLossTotal; // total number of lost packets (receiver side)
|
||||
int m_iRetransTotal; // total number of retransmitted packets
|
||||
int m_iSentACKTotal; // total number of sent ACK packets
|
||||
int m_iRecvACKTotal; // total number of received ACK packets
|
||||
int m_iSentNAKTotal; // total number of sent NAK packets
|
||||
int m_iRecvNAKTotal; // total number of received NAK packets
|
||||
int64_t m_llSndDurationTotal; // total real time for sending
|
||||
|
||||
uint64_t m_LastSampleTime; // last performance sample time
|
||||
int64_t m_llTraceSent; // number of pakctes sent in the last trace interval
|
||||
int64_t m_llTraceRecv; // number of pakctes received in the last trace interval
|
||||
int m_iTraceSndLoss; // number of lost packets in the last trace interval (sender side)
|
||||
int m_iTraceRcvLoss; // number of lost packets in the last trace interval (receiver side)
|
||||
int m_iTraceRetrans; // number of retransmitted packets in the last trace interval
|
||||
int m_iSentACK; // number of ACKs sent in the last trace interval
|
||||
int m_iRecvACK; // number of ACKs received in the last trace interval
|
||||
int m_iSentNAK; // number of NAKs sent in the last trace interval
|
||||
int m_iRecvNAK; // number of NAKs received in the last trace interval
|
||||
int64_t m_llSndDuration; // real time for sending
|
||||
int64_t m_llSndDurationCounter; // timers to record the sending duration
|
||||
|
||||
private: // Timers
|
||||
uint64_t m_ullCPUFrequency; // CPU clock frequency, used for Timer, ticks per microsecond
|
||||
|
||||
static const int m_iSYNInterval; // Periodical Rate Control Interval, 10000 microsecond
|
||||
static const int m_iSelfClockInterval; // ACK interval for self-clocking
|
||||
|
||||
uint64_t m_ullNextACKTime; // Next ACK time, in CPU clock cycles, same below
|
||||
uint64_t m_ullNextNAKTime; // Next NAK time
|
||||
|
||||
volatile uint64_t m_ullSYNInt; // SYN interval
|
||||
volatile uint64_t m_ullACKInt; // ACK interval
|
||||
volatile uint64_t m_ullNAKInt; // NAK interval
|
||||
volatile uint64_t m_ullLastRspTime; // time stamp of last response from the peer
|
||||
|
||||
uint64_t m_ullMinNakInt; // NAK timeout lower bound; too small value can cause unnecessary retransmission
|
||||
uint64_t m_ullMinExpInt; // timeout lower bound threshold: too small timeout can cause problem
|
||||
|
||||
int m_iPktCount; // packet counter for ACK
|
||||
int m_iLightACKCount; // light ACK counter
|
||||
|
||||
uint64_t m_ullTargetTime; // scheduled time of next packet sending
|
||||
|
||||
void checkTimers();
|
||||
|
||||
private: // for UDP multiplexer
|
||||
CSndQueue* m_pSndQueue; // packet sending queue
|
||||
CRcvQueue* m_pRcvQueue; // packet receiving queue
|
||||
sockaddr* m_pPeerAddr; // peer address
|
||||
uint32_t m_piSelfIP[4]; // local UDP IP address
|
||||
CSNode* m_pSNode; // node information for UDT list used in snd queue
|
||||
CRNode* m_pRNode; // node information for UDT list used in rcv queue
|
||||
|
||||
private: // for epoll
|
||||
std::set<int> m_sPollID; // set of epoll ID to trigger
|
||||
void addEPoll(const int eid);
|
||||
void removeEPoll(const int eid);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,427 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/01/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef LINUX
|
||||
#include <sys/epoll.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
|
||||
#include "udtCommon.h"
|
||||
#include "epoll.h"
|
||||
#include "udt.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
CEPoll::CEPoll():
|
||||
m_iIDSeed(0)
|
||||
{
|
||||
CGuard::createMutex(m_EPollLock);
|
||||
}
|
||||
|
||||
CEPoll::~CEPoll()
|
||||
{
|
||||
CGuard::releaseMutex(m_EPollLock);
|
||||
}
|
||||
|
||||
int CEPoll::create()
|
||||
{
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
int localid = 0;
|
||||
|
||||
#ifdef LINUX
|
||||
localid = epoll_create(1024);
|
||||
if (localid < 0)
|
||||
throw CUDTException(-1, 0, errno);
|
||||
#else
|
||||
// on BSD, use kqueue
|
||||
// on Solaris, use /dev/poll
|
||||
// on Windows, select
|
||||
#endif
|
||||
|
||||
if (++ m_iIDSeed >= 0x7FFFFFFF)
|
||||
m_iIDSeed = 0;
|
||||
|
||||
CEPollDesc desc;
|
||||
desc.m_iID = m_iIDSeed;
|
||||
desc.m_iLocalID = localid;
|
||||
m_mPolls[desc.m_iID] = desc;
|
||||
|
||||
return desc.m_iID;
|
||||
}
|
||||
|
||||
int CEPoll::add_usock(const int eid, const UDTSOCKET& u, const int* events)
|
||||
{
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
|
||||
if (p == m_mPolls.end())
|
||||
throw CUDTException(5, 13);
|
||||
|
||||
// BARCHART: Manage all event types.
|
||||
if (!events || (*events & UDT_EPOLL_IN))
|
||||
p->second.m_sUDTSocksIn.insert(u);
|
||||
if (!events || (*events & UDT_EPOLL_OUT))
|
||||
p->second.m_sUDTSocksOut.insert(u);
|
||||
if (!events || (*events & UDT_EPOLL_ERR))
|
||||
p->second.m_sUDTSocksEx.insert(u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// BARCHART
|
||||
int CEPoll::update_usock(const int eid, const UDTSOCKET& u, const int* events)
|
||||
{
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
|
||||
if (p == m_mPolls.end()){
|
||||
throw CUDTException(5, 13);
|
||||
}
|
||||
|
||||
if(events){
|
||||
if (*events & UDT_EPOLL_IN){
|
||||
p->second.m_sUDTSocksIn.insert(u);
|
||||
}else{
|
||||
p->second.m_sUDTSocksIn.erase(u);
|
||||
}
|
||||
if (*events & UDT_EPOLL_OUT){
|
||||
p->second.m_sUDTSocksOut.insert(u);
|
||||
} else{
|
||||
p->second.m_sUDTSocksOut.erase(u);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// BARCHART
|
||||
int CEPoll::verify_usock(const int eid, const UDTSOCKET& u, int* events)
|
||||
{
|
||||
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
|
||||
if (p == m_mPolls.end()){
|
||||
throw CUDTException(5, 13);
|
||||
}
|
||||
|
||||
if(events){
|
||||
if(p->second.m_sUDTSocksIn.find(u) != p->second.m_sUDTSocksIn.end()){
|
||||
*events |= UDT_EPOLL_IN;
|
||||
}
|
||||
if(p->second.m_sUDTSocksOut.find(u) != p->second.m_sUDTSocksOut.end()){
|
||||
*events |= UDT_EPOLL_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int CEPoll::add_ssock(const int eid, const SYSSOCKET& s, const int* events)
|
||||
{
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
|
||||
if (p == m_mPolls.end())
|
||||
throw CUDTException(5, 13);
|
||||
|
||||
#ifdef LINUX
|
||||
epoll_event ev;
|
||||
|
||||
if (NULL == events)
|
||||
ev.events = EPOLLIN | EPOLLOUT | EPOLLERR;
|
||||
else
|
||||
{
|
||||
ev.events = 0;
|
||||
if (*events & UDT_EPOLL_IN)
|
||||
ev.events |= EPOLLIN;
|
||||
if (*events & UDT_EPOLL_OUT)
|
||||
ev.events |= EPOLLOUT;
|
||||
if (*events & UDT_EPOLL_ERR)
|
||||
ev.events |= EPOLLERR;
|
||||
}
|
||||
|
||||
ev.data.fd = s;
|
||||
if (::epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_ADD, s, &ev) < 0)
|
||||
throw CUDTException();
|
||||
#endif
|
||||
|
||||
p->second.m_sLocals.insert(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CEPoll::remove_usock(const int eid, const UDTSOCKET& u)
|
||||
{
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
|
||||
if (p == m_mPolls.end())
|
||||
throw CUDTException(5, 13);
|
||||
|
||||
p->second.m_sUDTSocksIn.erase(u);
|
||||
p->second.m_sUDTSocksOut.erase(u);
|
||||
|
||||
// when the socket is removed from a monitoring, it is not available anymore for any IO notification
|
||||
p->second.m_sUDTReads.erase(u);
|
||||
p->second.m_sUDTWrites.erase(u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CEPoll::remove_ssock(const int eid, const SYSSOCKET& s)
|
||||
{
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
|
||||
if (p == m_mPolls.end())
|
||||
throw CUDTException(5, 13);
|
||||
|
||||
#ifdef LINUX
|
||||
epoll_event ev; // ev is ignored, for compatibility with old Linux kernel only.
|
||||
if (::epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_DEL, s, &ev) < 0)
|
||||
throw CUDTException();
|
||||
#endif
|
||||
|
||||
p->second.m_sLocals.erase(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CEPoll::wait(const int eid, set<UDTSOCKET>* readfds, set<UDTSOCKET>* writefds, int64_t msTimeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds)
|
||||
{
|
||||
// if all fields is NULL and waiting time is infinite, then this would be a deadlock
|
||||
if (!readfds && !writefds && !lrfds && lwfds && (msTimeOut < 0))
|
||||
throw CUDTException(5, 3, 0);
|
||||
|
||||
// Clear these sets in case the app forget to do it.
|
||||
if (readfds) readfds->clear();
|
||||
if (writefds) writefds->clear();
|
||||
if (lrfds) lrfds->clear();
|
||||
if (lwfds) lwfds->clear();
|
||||
|
||||
int total = 0;
|
||||
|
||||
int64_t entertime = CTimer::getTime();
|
||||
while (true)
|
||||
{
|
||||
CGuard::enterCS(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
|
||||
if (p == m_mPolls.end())
|
||||
{
|
||||
CGuard::leaveCS(m_EPollLock);
|
||||
throw CUDTException(5, 13);
|
||||
}
|
||||
|
||||
if (p->second.m_sUDTSocksIn.empty() && p->second.m_sUDTSocksOut.empty() && p->second.m_sLocals.empty() && (msTimeOut < 0))
|
||||
{
|
||||
// no socket is being monitored, this may be a deadlock
|
||||
CGuard::leaveCS(m_EPollLock);
|
||||
throw CUDTException(5, 3);
|
||||
}
|
||||
|
||||
// Sockets with exceptions are returned to both read and write sets.
|
||||
if ((NULL != readfds) && (!p->second.m_sUDTReads.empty() || !p->second.m_sUDTExcepts.empty()))
|
||||
{
|
||||
*readfds = p->second.m_sUDTReads;
|
||||
for (set<UDTSOCKET>::const_iterator i = p->second.m_sUDTExcepts.begin(); i != p->second.m_sUDTExcepts.end(); ++ i)
|
||||
readfds->insert(*i);
|
||||
total += p->second.m_sUDTReads.size() + p->second.m_sUDTExcepts.size();
|
||||
}
|
||||
if ((NULL != writefds) && (!p->second.m_sUDTWrites.empty() || !p->second.m_sUDTExcepts.empty()))
|
||||
{
|
||||
*writefds = p->second.m_sUDTWrites;
|
||||
for (set<UDTSOCKET>::const_iterator i = p->second.m_sUDTExcepts.begin(); i != p->second.m_sUDTExcepts.end(); ++ i)
|
||||
writefds->insert(*i);
|
||||
total += p->second.m_sUDTWrites.size() + p->second.m_sUDTExcepts.size();
|
||||
}
|
||||
|
||||
// BARCHART: Remove errors when reported.
|
||||
if(total > 0 && !p->second.m_sUDTExcepts.empty()){
|
||||
p->second.m_sUDTExcepts.clear();
|
||||
}
|
||||
|
||||
if (lrfds || lwfds)
|
||||
{
|
||||
#ifdef LINUX
|
||||
const int max_events = p->second.m_sLocals.size();
|
||||
epoll_event ev[max_events];
|
||||
int nfds = ::epoll_wait(p->second.m_iLocalID, ev, max_events, 0);
|
||||
|
||||
for (int i = 0; i < nfds; ++ i)
|
||||
{
|
||||
if ((NULL != lrfds) && (ev[i].events & EPOLLIN))
|
||||
{
|
||||
lrfds->insert(ev[i].data.fd);
|
||||
++ total;
|
||||
}
|
||||
if ((NULL != lwfds) && (ev[i].events & EPOLLOUT))
|
||||
{
|
||||
lwfds->insert(ev[i].data.fd);
|
||||
++ total;
|
||||
}
|
||||
}
|
||||
#else
|
||||
//currently "select" is used for all non-Linux platforms.
|
||||
//faster approaches can be applied for specific systems in the future.
|
||||
|
||||
//"select" has a limitation on the number of sockets
|
||||
|
||||
fd_set readfds2;
|
||||
fd_set writefds2;
|
||||
FD_ZERO(&readfds2);
|
||||
FD_ZERO(&writefds2);
|
||||
|
||||
for (set<SYSSOCKET>::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i)
|
||||
{
|
||||
if (lrfds)
|
||||
FD_SET(*i, &readfds2);
|
||||
if (lwfds)
|
||||
FD_SET(*i, &writefds2);
|
||||
}
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
if (::select(0, &readfds2, &writefds2, NULL, &tv) > 0)
|
||||
{
|
||||
for (set<SYSSOCKET>::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i)
|
||||
{
|
||||
if (lrfds && FD_ISSET(*i, &readfds2))
|
||||
{
|
||||
lrfds->insert(*i);
|
||||
++ total;
|
||||
}
|
||||
if (lwfds && FD_ISSET(*i, &writefds2))
|
||||
{
|
||||
lwfds->insert(*i);
|
||||
++ total;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CGuard::leaveCS(m_EPollLock);
|
||||
|
||||
if (total > 0)
|
||||
return total;
|
||||
|
||||
if ((msTimeOut >= 0) && (int64_t(CTimer::getTime() - entertime) >= msTimeOut * 1000LL))
|
||||
throw CUDTException(6, 3, 0);
|
||||
|
||||
CTimer::waitForEvent();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CEPoll::release(const int eid)
|
||||
{
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator i = m_mPolls.find(eid);
|
||||
if (i == m_mPolls.end())
|
||||
throw CUDTException(5, 13);
|
||||
|
||||
#ifdef LINUX
|
||||
// release local/system epoll descriptor
|
||||
::close(i->second.m_iLocalID);
|
||||
#endif
|
||||
|
||||
m_mPolls.erase(i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void update_epoll_sets(const UDTSOCKET& uid, const set<UDTSOCKET>& watch, set<UDTSOCKET>& result, bool enable)
|
||||
{
|
||||
if (enable && (watch.find(uid) != watch.end()))
|
||||
{
|
||||
result.insert(uid);
|
||||
}
|
||||
else if (!enable)
|
||||
{
|
||||
result.erase(uid);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int CEPoll::update_events(const UDTSOCKET& uid, std::set<int>& eids, int events, bool enable)
|
||||
{
|
||||
CGuard pg(m_EPollLock);
|
||||
|
||||
map<int, CEPollDesc>::iterator p;
|
||||
|
||||
vector<int> lost;
|
||||
for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i)
|
||||
{
|
||||
p = m_mPolls.find(*i);
|
||||
if (p == m_mPolls.end())
|
||||
{
|
||||
lost.push_back(*i);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((events & UDT_EPOLL_IN) != 0)
|
||||
update_epoll_sets(uid, p->second.m_sUDTSocksIn, p->second.m_sUDTReads, enable);
|
||||
if ((events & UDT_EPOLL_OUT) != 0)
|
||||
update_epoll_sets(uid, p->second.m_sUDTSocksOut, p->second.m_sUDTWrites, enable);
|
||||
if ((events & UDT_EPOLL_ERR) != 0)
|
||||
update_epoll_sets(uid, p->second.m_sUDTSocksEx, p->second.m_sUDTExcepts, enable);
|
||||
}
|
||||
}
|
||||
|
||||
for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i)
|
||||
eids.erase(*i);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 08/20/2010
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_EPOLL_H__
|
||||
#define __UDT_EPOLL_H__
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "udt.h"
|
||||
|
||||
|
||||
struct CEPollDesc
|
||||
{
|
||||
int m_iID; // epoll ID
|
||||
std::set<UDTSOCKET> m_sUDTSocksOut; // set of UDT sockets waiting for write events
|
||||
std::set<UDTSOCKET> m_sUDTSocksIn; // set of UDT sockets waiting for read events
|
||||
std::set<UDTSOCKET> m_sUDTSocksEx; // set of UDT sockets waiting for exceptions
|
||||
|
||||
int m_iLocalID; // local system epoll ID
|
||||
std::set<SYSSOCKET> m_sLocals; // set of local (non-UDT) descriptors
|
||||
|
||||
std::set<UDTSOCKET> m_sUDTWrites; // UDT sockets ready for write
|
||||
std::set<UDTSOCKET> m_sUDTReads; // UDT sockets ready for read
|
||||
std::set<UDTSOCKET> m_sUDTExcepts; // UDT sockets with exceptions (connection broken, etc.)
|
||||
};
|
||||
|
||||
class CEPoll
|
||||
{
|
||||
friend class CUDT;
|
||||
friend class CRendezvousQueue;
|
||||
|
||||
public:
|
||||
CEPoll();
|
||||
~CEPoll();
|
||||
|
||||
public: // for CUDTUnited API
|
||||
|
||||
// Functionality:
|
||||
// create a new EPoll.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// new EPoll ID if success, otherwise an error number.
|
||||
|
||||
int create();
|
||||
|
||||
// Functionality:
|
||||
// add a UDT socket to an EPoll.
|
||||
// Parameters:
|
||||
// 0) [in] eid: EPoll ID.
|
||||
// 1) [in] u: UDT Socket ID.
|
||||
// 2) [in] events: events to watch.
|
||||
// Returned value:
|
||||
// 0 if success, otherwise an error number.
|
||||
|
||||
int add_usock(const int eid, const UDTSOCKET& u, const int* events = NULL);
|
||||
|
||||
// BARCHART
|
||||
int update_usock(const int eid, const UDTSOCKET& u, const int* events = NULL);
|
||||
// BARCHART
|
||||
int verify_usock(const int eid, const UDTSOCKET& u, int* events);
|
||||
|
||||
// Functionality:
|
||||
// add a system socket to an EPoll.
|
||||
// Parameters:
|
||||
// 0) [in] eid: EPoll ID.
|
||||
// 1) [in] s: system Socket ID.
|
||||
// 2) [in] events: events to watch.
|
||||
// Returned value:
|
||||
// 0 if success, otherwise an error number.
|
||||
|
||||
int add_ssock(const int eid, const SYSSOCKET& s, const int* events = NULL);
|
||||
|
||||
// Functionality:
|
||||
// remove a UDT socket event from an EPoll; socket will be removed if no events to watch
|
||||
// Parameters:
|
||||
// 0) [in] eid: EPoll ID.
|
||||
// 1) [in] u: UDT socket ID.
|
||||
// Returned value:
|
||||
// 0 if success, otherwise an error number.
|
||||
|
||||
int remove_usock(const int eid, const UDTSOCKET& u);
|
||||
|
||||
// Functionality:
|
||||
// remove a system socket event from an EPoll; socket will be removed if no events to watch
|
||||
// Parameters:
|
||||
// 0) [in] eid: EPoll ID.
|
||||
// 1) [in] s: system socket ID.
|
||||
// Returned value:
|
||||
// 0 if success, otherwise an error number.
|
||||
|
||||
int remove_ssock(const int eid, const SYSSOCKET& s);
|
||||
|
||||
// Functionality:
|
||||
// wait for EPoll events or timeout.
|
||||
// Parameters:
|
||||
// 0) [in] eid: EPoll ID.
|
||||
// 1) [out] readfds: UDT sockets available for reading.
|
||||
// 2) [out] writefds: UDT sockets available for writing.
|
||||
// 3) [in] msTimeOut: timeout threshold, in milliseconds.
|
||||
// 4) [out] lrfds: system file descriptors for reading.
|
||||
// 5) [out] lwfds: system file descriptors for writing.
|
||||
// Returned value:
|
||||
// number of sockets available for IO.
|
||||
|
||||
int wait(const int eid, std::set<UDTSOCKET>* readfds, std::set<UDTSOCKET>* writefds, int64_t msTimeOut, std::set<SYSSOCKET>* lrfds, std::set<SYSSOCKET>* lwfds);
|
||||
|
||||
// Functionality:
|
||||
// close and release an EPoll.
|
||||
// Parameters:
|
||||
// 0) [in] eid: EPoll ID.
|
||||
// Returned value:
|
||||
// 0 if success, otherwise an error number.
|
||||
|
||||
int release(const int eid);
|
||||
|
||||
public: // for CUDT to acknowledge IO status
|
||||
|
||||
// Functionality:
|
||||
// Update events available for a UDT socket.
|
||||
// Parameters:
|
||||
// 0) [in] uid: UDT socket ID.
|
||||
// 1) [in] eids: EPoll IDs to be set
|
||||
// 1) [in] events: Combination of events to update
|
||||
// 1) [in] enable: true -> enable, otherwise disable
|
||||
// Returned value:
|
||||
// 0 if success, otherwise an error number
|
||||
|
||||
int update_events(const UDTSOCKET& uid, std::set<int>& eids, int events, bool enable);
|
||||
|
||||
private:
|
||||
int m_iIDSeed; // seed to generate a new ID
|
||||
udt_pthread_mutex_t m_SeedLock;
|
||||
|
||||
std::map<int, CEPollDesc> m_mPolls; // all epolls
|
||||
udt_pthread_mutex_t m_EPollLock;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* =================================================================================
|
||||
*
|
||||
* BSD LICENCE (http://en.wikipedia.org/wiki/BSD_licenses)
|
||||
*
|
||||
* Copyright (C) 2009-2013, Barchart, Inc. (http://www.barchart.com/)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the Barchart, Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Developers: Andrei Pozolotin, CCob
|
||||
*
|
||||
* =================================================================================
|
||||
*/
|
||||
|
||||
#include "../jni/JNICCC.h"
|
||||
|
||||
#include "../jni/JNICCCFactory.h"
|
||||
#include "../jni/JNIHelpers.h"
|
||||
|
||||
JNIEnv* AttachToJVM(JavaVM* vm)
|
||||
{
|
||||
JNIEnv* env = NULL;
|
||||
|
||||
jint result = vm->GetEnv(reinterpret_cast<void**>(&env),JNI_VERSION_1_4);
|
||||
|
||||
if(result == JNI_EDETACHED)
|
||||
vm->AttachCurrentThread(reinterpret_cast<void**>(&env),NULL);
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
JNICCC::JNICCC(JNIEnv* env, jobject objCCC) :
|
||||
_objCCC( env->NewGlobalRef(objCCC)){
|
||||
|
||||
env->GetJavaVM(&_javaVM);
|
||||
|
||||
if(_objCCC != NULL){
|
||||
jclass cccClass = env->GetObjectClass(_objCCC);
|
||||
|
||||
//We cannot statically store the methodid's as the objCCC
|
||||
//class maybe a subclass of CCC which means the method id's would differ
|
||||
_methodInit = env->GetMethodID(cccClass, "init", "()V" );
|
||||
_methodClose = env->GetMethodID(cccClass, "close", "()V" );
|
||||
_methodOnACK = env->GetMethodID(cccClass, "onACK", "(I)V" );
|
||||
_methodOnLoss = env->GetMethodID(cccClass, "onLoss", "([I)V" );
|
||||
_methodTimeout = env->GetMethodID(cccClass, "onTimeout", "()V" );
|
||||
_methodOnPktSent = NULL;
|
||||
_methodProcessCustomMsg = NULL;
|
||||
|
||||
env->SetLongField(objCCC,udt_CCC_fld_nativeHandleID,(jlong)(intptr_t)this);
|
||||
}
|
||||
}
|
||||
|
||||
JNICCC::~JNICCC() {
|
||||
|
||||
JNIEnv* env = AttachToJVM(_javaVM);
|
||||
|
||||
if(_objCCC)
|
||||
env->DeleteGlobalRef(_objCCC);
|
||||
}
|
||||
|
||||
jobject JNICCC::getJavaCCC(){
|
||||
return _objCCC;
|
||||
}
|
||||
|
||||
void JNICCC::init(){
|
||||
|
||||
CCC::init();
|
||||
|
||||
if(_objCCC){
|
||||
JNIEnv* env = AttachToJVM(_javaVM);
|
||||
env->CallVoidMethod(_objCCC, _methodInit);
|
||||
}
|
||||
}
|
||||
|
||||
void JNICCC::close(){
|
||||
|
||||
CCC::close();
|
||||
|
||||
if(_objCCC){
|
||||
JNIEnv* env = AttachToJVM(_javaVM);
|
||||
env->CallVoidMethod(_objCCC, _methodClose);
|
||||
}
|
||||
}
|
||||
|
||||
void JNICCC::onACK(const int32_t& ack){
|
||||
|
||||
CCC::onACK(ack);
|
||||
|
||||
if(_objCCC){
|
||||
JNIEnv* env = AttachToJVM(_javaVM);
|
||||
env->CallVoidMethod(_objCCC, _methodOnACK, ack);
|
||||
}
|
||||
}
|
||||
|
||||
void JNICCC::onLoss(const int32_t* losslist, const int& size){
|
||||
//TODO: map to Java CCC class;
|
||||
CCC::onLoss(losslist,size);
|
||||
}
|
||||
|
||||
void JNICCC::onTimeout(){
|
||||
|
||||
CCC::onTimeout();
|
||||
|
||||
if(_objCCC){
|
||||
JNIEnv* env = AttachToJVM(_javaVM);
|
||||
env->CallVoidMethod(_objCCC, _methodTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
void JNICCC::onPktSent(const CPacket* pkt){
|
||||
CCC::onPktSent(pkt);
|
||||
}
|
||||
|
||||
void JNICCC::onPktReceived(const CPacket* pkt){
|
||||
CCC::onPktReceived(pkt);
|
||||
}
|
||||
|
||||
void JNICCC::processCustomMsg(const CPacket* pkt){
|
||||
CCC::processCustomMsg(pkt);
|
||||
}
|
||||
|
||||
void JNICCC::setACKTimer(const int& msINT){
|
||||
CCC::setACKTimer(msINT);
|
||||
}
|
||||
|
||||
void JNICCC::setACKInterval(const int& pktINT){
|
||||
CCC::setACKInterval(pktINT);
|
||||
}
|
||||
|
||||
void JNICCC::setRTO(const int& usRTO){
|
||||
CCC::setRTO(usRTO);
|
||||
}
|
||||
|
||||
void JNICCC::setPacketSndPeriod(const double sndPeriod){
|
||||
m_dPktSndPeriod = sndPeriod;
|
||||
}
|
||||
|
||||
void JNICCC::setCWndSize(const double cWndSize){
|
||||
m_dCWndSize = cWndSize;
|
||||
}
|
||||
|
||||
const CPerfMon* JNICCC::getPerfInfo(){
|
||||
return CCC::getPerfInfo();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* =================================================================================
|
||||
*
|
||||
* BSD LICENCE (http://en.wikipedia.org/wiki/BSD_licenses)
|
||||
*
|
||||
* Copyright (C) 2009-2013, Barchart, Inc. (http://www.barchart.com/)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the Barchart, Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Developers: Andrei Pozolotin, CCob
|
||||
*
|
||||
* =================================================================================
|
||||
*/
|
||||
|
||||
#ifndef JNICCC_H_
|
||||
#define JNICCC_H_
|
||||
|
||||
#include "ccc.h"
|
||||
#include <jni.h>
|
||||
|
||||
class JNICCCFactory;
|
||||
|
||||
class JNICCC: public CCC {
|
||||
|
||||
friend JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_initNative (JNIEnv *env, jobject self);
|
||||
|
||||
private:
|
||||
|
||||
jobject _objCCC;
|
||||
JavaVM* _javaVM;
|
||||
|
||||
jmethodID _methodInit;
|
||||
jmethodID _methodClose;
|
||||
jmethodID _methodOnACK;
|
||||
jmethodID _methodOnLoss;
|
||||
jmethodID _methodTimeout;
|
||||
jmethodID _methodOnPktSent;
|
||||
jmethodID _methodProcessCustomMsg;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~JNICCC();
|
||||
|
||||
jobject getJavaCCC();
|
||||
|
||||
//we need to override the visibility
|
||||
//of the setXXX calls since we are
|
||||
//emulating class inheritance from Java
|
||||
void setACKTimer(const int& msINT);
|
||||
|
||||
void setACKInterval(const int& pktINT);
|
||||
|
||||
void setRTO(const int& usRTO);
|
||||
|
||||
void setPacketSndPeriod(const double sndPeriod);
|
||||
|
||||
void setCWndSize(const double cWndSize);
|
||||
|
||||
const CPerfMon* getPerfInfo();
|
||||
|
||||
private:
|
||||
|
||||
//we don't want to allow any overrides on this
|
||||
//class since it will be emulated in the Java layer
|
||||
|
||||
JNICCC(JNIEnv* env, jobject objCCC);
|
||||
|
||||
void init();
|
||||
|
||||
void close();
|
||||
|
||||
void onACK(const int32_t&);
|
||||
|
||||
void onLoss(const int32_t*, const int&);
|
||||
|
||||
void onTimeout();
|
||||
|
||||
void onPktSent(const CPacket*);
|
||||
|
||||
void onPktReceived(const CPacket*);
|
||||
|
||||
void processCustomMsg(const CPacket*);
|
||||
|
||||
};
|
||||
|
||||
#endif /* JNICCC_H_ */
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
* =================================================================================
|
||||
*
|
||||
* BSD LICENCE (http://en.wikipedia.org/wiki/BSD_licenses)
|
||||
*
|
||||
* Copyright (C) 2009-2013, Barchart, Inc. (http://www.barchart.com/)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the Barchart, Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Developers: Andrei Pozolotin, CCob
|
||||
*
|
||||
* =================================================================================
|
||||
*/
|
||||
#include "../jni/JNICCCFactory.h"
|
||||
|
||||
#include "../jni/JNICCC.h"
|
||||
#include "../jni/JNIHelpers.h"
|
||||
|
||||
jmethodID JNICCCFactory::_udt_clsFactoryInterfaceUDT_create = NULL;
|
||||
jmethodID JNICCCFactory::_udt_clsFactoryInterfaceUDT_cloneFactory = NULL;
|
||||
|
||||
bool JNICCCFactory::initJNITypes(JNIEnv* env){
|
||||
|
||||
if(_udt_clsFactoryInterfaceUDT_create != NULL)
|
||||
return true;
|
||||
|
||||
if(udt_FactoryInterfaceUDT==NULL)
|
||||
return false;
|
||||
|
||||
_udt_clsFactoryInterfaceUDT_cloneFactory = env->GetMethodID(udt_FactoryInterfaceUDT, "cloneFactory", "()Lcom/barchart/udt/FactoryInterfaceUDT;");
|
||||
_udt_clsFactoryInterfaceUDT_create = env->GetMethodID(udt_FactoryInterfaceUDT, "create", "()Lcom/barchart/udt/CCC;");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JNIEnv* JNICCCFactory::AttachToJVM()
|
||||
{
|
||||
JNIEnv* env = NULL;
|
||||
|
||||
jint result = _javaVM->GetEnv(reinterpret_cast<void**>(&env),JNI_VERSION_1_4);
|
||||
|
||||
if(result == JNI_EDETACHED)
|
||||
_javaVM->AttachCurrentThread(reinterpret_cast<void**>(&env),NULL);
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
|
||||
JNICCCFactory::JNICCCFactory(JNIEnv* env, jobject factoryUDT) {
|
||||
|
||||
initJNITypes(env);
|
||||
|
||||
if(factoryUDT==NULL){
|
||||
;//TODO create new exception
|
||||
}
|
||||
|
||||
env->GetJavaVM(&_javaVM);
|
||||
|
||||
//We need to create a global JNI ref since
|
||||
//we are storing the jobject as a member variable
|
||||
//for use later on
|
||||
_factoryUDT = env->NewGlobalRef(factoryUDT);
|
||||
|
||||
}
|
||||
|
||||
JNICCCFactory::~JNICCCFactory(){
|
||||
|
||||
JNIEnv* env = AttachToJVM();
|
||||
|
||||
if(_factoryUDT != NULL){
|
||||
env->DeleteLocalRef(_factoryUDT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CCC* JNICCCFactory::create(){
|
||||
|
||||
JNIEnv* env = AttachToJVM();
|
||||
|
||||
jobject objCCC = env->CallObjectMethod(_factoryUDT,_udt_clsFactoryInterfaceUDT_create);
|
||||
|
||||
if(objCCC==NULL && !env->ExceptionCheck() ){
|
||||
UDT_ThrowExceptionUDT_Message(env, 0, "failed to allocate CCC class via com.barchart.udt.FactoryInterfaceUDT");
|
||||
}
|
||||
|
||||
return reinterpret_cast<CCC*> ((intptr_t) env->GetLongField(objCCC,udt_CCC_fld_nativeHandleID));
|
||||
}
|
||||
|
||||
CCCVirtualFactory* JNICCCFactory::clone(){
|
||||
|
||||
JNIEnv* env = AttachToJVM();
|
||||
|
||||
jobject objFactoryUDT = env->CallObjectMethod(_factoryUDT,_udt_clsFactoryInterfaceUDT_cloneFactory);
|
||||
|
||||
return new JNICCCFactory(env,objFactoryUDT);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* =================================================================================
|
||||
*
|
||||
* BSD LICENCE (http://en.wikipedia.org/wiki/BSD_licenses)
|
||||
*
|
||||
* Copyright (C) 2009-2013, Barchart, Inc. (http://www.barchart.com/)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the Barchart, Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Developers: Andrei Pozolotin, CCob
|
||||
*
|
||||
* =================================================================================
|
||||
*/
|
||||
|
||||
#ifndef JNICCCFACTORY_H_
|
||||
#define JNICCCFACTORY_H_
|
||||
|
||||
#include "ccc.h"
|
||||
#include <jni.h>
|
||||
|
||||
class JNICCCFactory: public CCCVirtualFactory {
|
||||
|
||||
private:
|
||||
|
||||
static jmethodID _udt_clsFactoryInterfaceUDT_create;
|
||||
static jmethodID _udt_clsFactoryInterfaceUDT_cloneFactory;
|
||||
|
||||
JavaVM* _javaVM;
|
||||
jobject _factoryUDT;
|
||||
|
||||
static bool initJNITypes(JNIEnv* env);
|
||||
|
||||
JNIEnv* AttachToJVM();
|
||||
|
||||
public:
|
||||
JNICCCFactory(JNIEnv* env, jobject factoryUDT);
|
||||
virtual ~JNICCCFactory();
|
||||
|
||||
CCC* create();
|
||||
|
||||
CCCVirtualFactory* clone();
|
||||
};
|
||||
|
||||
#endif /* JNICCCFACTORY_H_ */
|
|
@ -0,0 +1,301 @@
|
|||
/**
|
||||
* =================================================================================
|
||||
*
|
||||
* BSD LICENCE (http://en.wikipedia.org/wiki/BSD_licenses)
|
||||
*
|
||||
* Copyright (C) 2009-2013, Barchart, Inc. (http://www.barchart.com/)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the Barchart, Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Developers: Andrei Pozolotin, CCob
|
||||
*
|
||||
* =================================================================================
|
||||
*/
|
||||
|
||||
#include "../jni/JNIHelpers.h"
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
// ### JNI
|
||||
|
||||
#define JNI_UPDATE 0 // jni object release with copy
|
||||
//
|
||||
|
||||
// ### JDK references
|
||||
|
||||
// JDK classes
|
||||
|
||||
jclass jdk_Boolean; // java.lang.Boolean
|
||||
jclass jdk_Integer; // java.lang.Integer
|
||||
jclass jdk_Long; // java.lang.Long
|
||||
|
||||
jclass jdk_InetAddress; // java.net.InetAddress
|
||||
jclass jdk_InetSocketAddress; // java.net.InetSocketAddress
|
||||
|
||||
jclass jdk_SocketException; // java.net.SocketException
|
||||
|
||||
jclass jdk_Set; // java.util.Set
|
||||
jclass jdk_Iterator; // java.util.Iterator
|
||||
|
||||
// JDK methods
|
||||
|
||||
jmethodID jdk_Boolean_init; // new Boolean(boolean x)
|
||||
jmethodID jdk_Integer_init; // new Integer(int x)
|
||||
jmethodID jdk_Long_init; // new Long(long x)
|
||||
|
||||
jmethodID jdk_InetAddress_getAddress; // byte[] getAddress()
|
||||
jmethodID jdk_InetAddress_getByAddress; // static InetAddress getByAddress(byte[])
|
||||
|
||||
jmethodID jdk_InetSocketAddress_init; // new InetSocketAddress(InetAddress x)
|
||||
jmethodID jdk_InetSocketAddress_getAddress; //
|
||||
jmethodID jdk_InetSocketAddress_getPort; //
|
||||
|
||||
jmethodID jdk_Set_iterator; // Iterator set.iterator()
|
||||
jmethodID jdk_Set_add; // boolean set.add(Object)
|
||||
jmethodID jdk_Set_contains; // boolean set.contains(Object)
|
||||
|
||||
jmethodID jdk_Iterator_hasNext; // boolean iterator.hasNext()
|
||||
jmethodID jdk_Iterator_next; // Object iterator.next()
|
||||
|
||||
// UDT classes
|
||||
|
||||
jclass udt_FactoryInterfaceUDT; //com.barchart.udt.FactoryInterfaceUDT
|
||||
|
||||
// UDT methods
|
||||
|
||||
jfieldID udt_CCC_fld_nativeHandleID;
|
||||
|
||||
void X_InitClassReference(JNIEnv *env, jclass *classReference,
|
||||
const char *className) {
|
||||
CHK_NUL_RET_RET(env, "env");
|
||||
CHK_NUL_RET_RET(className, "className");
|
||||
CHK_NUL_RET_RET(classReference, "classReference");
|
||||
jclass klaz = env->FindClass(className);
|
||||
CHK_NUL_RET_RET(klaz, "klaz");
|
||||
*classReference = static_cast<jclass>(env->NewGlobalRef((jobject) klaz));
|
||||
CHK_NUL_RET_RET(*classReference, "*classReference");
|
||||
}
|
||||
|
||||
void X_FreeClassReference(JNIEnv *env, jclass* globalRef) {
|
||||
CHK_NUL_RET_RET(env, "env");
|
||||
CHK_NUL_RET_RET(globalRef, "globalRef");
|
||||
env->DeleteGlobalRef(*globalRef);
|
||||
*globalRef = NULL;
|
||||
}
|
||||
|
||||
// use native bool parameter
|
||||
jobject X_NewBoolean(JNIEnv *env, bool value) {
|
||||
CHK_NUL_RET_NUL(env, "env");
|
||||
return env->NewObject(jdk_Boolean, jdk_Boolean_init,
|
||||
BOOLEAN(value) );
|
||||
}
|
||||
|
||||
// use native 32 bit int parameter
|
||||
jobject X_NewInteger(JNIEnv *env, int value) {
|
||||
CHK_NUL_RET_NUL(env, "env");
|
||||
return env->NewObject(jdk_Integer, jdk_Integer_init, (jint) value);
|
||||
}
|
||||
|
||||
// use native 64 bit long parameter
|
||||
jobject X_NewLong(JNIEnv* env, int64_t value) {
|
||||
CHK_NUL_RET_NUL(env, "env");
|
||||
return env->NewObject(jdk_Long, jdk_Long_init, (jlong) value);
|
||||
}
|
||||
|
||||
// NOTE: ipv4 only
|
||||
int X_InitSockAddr(sockaddr* sockAddr) {
|
||||
CHK_NUL_RET_ERR(sockAddr, "sockAddr");
|
||||
sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;
|
||||
sockAddrIn->sin_family = AF_INET;
|
||||
memset(&(sockAddrIn->sin_zero), '\0', 8);
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
// NOTE: ipv4 only
|
||||
int X_ConvertInetAddressToInteger( //
|
||||
JNIEnv* env, //
|
||||
jobject objInetAddress, //
|
||||
jint* address //
|
||||
) {
|
||||
|
||||
CHK_NUL_RET_ERR(env, "env");
|
||||
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");
|
||||
CHK_NUL_RET_ERR(address, "address");
|
||||
|
||||
const jbyteArray objArray = (jbyteArray) env->CallObjectMethod(
|
||||
objInetAddress, jdk_InetAddress_getAddress);
|
||||
CHK_NUL_RET_ERR(objArray, "objArray");
|
||||
|
||||
const int sizeArray = env->GetArrayLength(objArray);
|
||||
|
||||
switch (sizeArray) {
|
||||
case 4:
|
||||
// IPV4
|
||||
break;
|
||||
case 16:
|
||||
// IPV6
|
||||
default:
|
||||
CHK_LOG("unsupported address size", "sizeArray");
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
jbyte* refArray = env->GetByteArrayElements(objArray, NULL);
|
||||
|
||||
int value = 0;
|
||||
value |= (0xFF000000 & (refArray[0] << 24));
|
||||
value |= (0x00FF0000 & (refArray[1] << 16));
|
||||
value |= (0x0000FF00 & (refArray[2] << 8));
|
||||
value |= (0x000000FF & (refArray[3]));
|
||||
|
||||
env->ReleaseByteArrayElements(objArray, refArray, 0);
|
||||
|
||||
*address = value;
|
||||
|
||||
return JNI_OK;
|
||||
|
||||
}
|
||||
|
||||
// NOTE: ipv4 only
|
||||
int X_ConvertInetSocketAddressToSockaddr( //
|
||||
JNIEnv* env, //
|
||||
jobject objInetSocketAddress, //
|
||||
sockaddr* sockAddr //
|
||||
) {
|
||||
|
||||
CHK_NUL_RET_ERR(env, "env");
|
||||
CHK_NUL_RET_ERR(sockAddr, "sockAddr");
|
||||
CHK_NUL_RET_ERR(objInetSocketAddress, "objInetSocketAddress");
|
||||
|
||||
const jobject objInetAddress = env->CallObjectMethod(objInetSocketAddress,
|
||||
jdk_InetSocketAddress_getAddress);
|
||||
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");
|
||||
|
||||
jint address = 0;
|
||||
jint port = env->CallIntMethod(objInetSocketAddress,
|
||||
jdk_InetSocketAddress_getPort);
|
||||
|
||||
const int rv = X_ConvertInetAddressToInteger(env, objInetAddress, &address);
|
||||
if (rv == JNI_ERR) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;
|
||||
|
||||
sockAddrIn->sin_addr.s_addr = htonl(address);
|
||||
sockAddrIn->sin_port = htons(port);
|
||||
|
||||
return JNI_OK;
|
||||
|
||||
}
|
||||
|
||||
// NOTE: only ipv4
|
||||
jobject X_NewInetAddress( //
|
||||
JNIEnv* env, //
|
||||
const jint address //
|
||||
) {
|
||||
|
||||
CHK_NUL_RET_NUL(env, "env");
|
||||
|
||||
char valArray[4];
|
||||
valArray[0] = (address & 0xFF000000) >> 24;
|
||||
valArray[1] = (address & 0x00FF0000) >> 16;
|
||||
valArray[2] = (address & 0x0000FF00) >> 8;
|
||||
valArray[3] = (address & 0x000000FF);
|
||||
|
||||
const jbyteArray objArray = env->NewByteArray(4);
|
||||
|
||||
env->SetByteArrayRegion(objArray, (jint) 0, (jint) 4, (jbyte*) valArray);
|
||||
|
||||
const jobject objInetAddress = env->CallStaticObjectMethod(
|
||||
jdk_InetAddress, jdk_InetAddress_getByAddress, objArray);
|
||||
CHK_NUL_RET_NUL(objInetAddress, "objInetAddress");
|
||||
|
||||
return objInetAddress;
|
||||
|
||||
}
|
||||
|
||||
// NOTE: ipv4 only
|
||||
jobject X_NewInetSocketAddress( //
|
||||
JNIEnv* env, //
|
||||
sockaddr* sockAddr //
|
||||
) {
|
||||
|
||||
CHK_NUL_RET_NUL(env, "env");
|
||||
CHK_NUL_RET_NUL(sockAddr, "sockAddr");
|
||||
|
||||
sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;
|
||||
const jint address = ntohl(sockAddrIn->sin_addr.s_addr);
|
||||
const jint port = ntohs(sockAddrIn->sin_port);
|
||||
|
||||
const jobject objInetAddress = X_NewInetAddress(env, address);
|
||||
CHK_NUL_RET_NUL(objInetAddress, "objInetAddress");
|
||||
|
||||
const jobject objInetSocketAddress = env->NewObject(
|
||||
jdk_InetSocketAddress, jdk_InetSocketAddress_init,
|
||||
objInetAddress, port);
|
||||
CHK_NUL_RET_NUL(objInetSocketAddress, "objInetSocketAddress");
|
||||
|
||||
return objInetSocketAddress;
|
||||
|
||||
}
|
||||
|
||||
bool X_IsSockaddrEqualsInetSocketAddress( //
|
||||
JNIEnv* env, //
|
||||
sockaddr* sockAddr, //
|
||||
jobject objSocketAddress //
|
||||
) {
|
||||
|
||||
CHK_NUL_RET_FLS(env, "env");
|
||||
CHK_NUL_RET_FLS(sockAddr, "sockAddr");
|
||||
CHK_NUL_RET_FLS(objSocketAddress, "objSocketAddress");
|
||||
|
||||
sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;
|
||||
|
||||
jint address1 = ntohl(sockAddrIn->sin_addr.s_addr);
|
||||
jint port1 = ntohs(sockAddrIn->sin_port);
|
||||
|
||||
jint address2 = 0;
|
||||
jint port2 = env->CallIntMethod(objSocketAddress,
|
||||
jdk_InetSocketAddress_getPort);
|
||||
|
||||
jobject objInetAddress = env->CallObjectMethod(objSocketAddress,
|
||||
jdk_InetSocketAddress_getAddress);
|
||||
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");
|
||||
|
||||
const int rv = X_ConvertInetAddressToInteger(env, objInetAddress,
|
||||
&address2);
|
||||
if (rv == JNI_ERR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (address1 == address2 && port1 == port2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
/**
|
||||
* =================================================================================
|
||||
*
|
||||
* BSD LICENCE (http://en.wikipedia.org/wiki/BSD_licenses)
|
||||
*
|
||||
* Copyright (C) 2009-2013, Barchart, Inc. (http://www.barchart.com/)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the Barchart, Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Developers: Andrei Pozolotin, CCob
|
||||
*
|
||||
* =================================================================================
|
||||
*/
|
||||
|
||||
#ifndef JNIHELPERS_H_
|
||||
#define JNIHELPERS_H_
|
||||
|
||||
#include "udt.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
// ### JNI
|
||||
|
||||
#define JNI_UPDATE 0 // jni object release with copy
|
||||
//
|
||||
|
||||
extern "C"{
|
||||
|
||||
// ### JDK references
|
||||
|
||||
// JDK classes
|
||||
|
||||
extern jclass jdk_Boolean; // java.lang.Boolean
|
||||
extern jclass jdk_Integer; // java.lang.Integer
|
||||
extern jclass jdk_Long; // java.lang.Long
|
||||
|
||||
extern jclass jdk_InetAddress; // java.net.InetAddress
|
||||
extern jclass jdk_InetSocketAddress; // java.net.InetSocketAddress
|
||||
|
||||
extern jclass jdk_SocketException; // java.net.SocketException
|
||||
extern jclass jdk_Set; // java.util.Set
|
||||
extern jclass jdk_Iterator; // java.util.Iterator
|
||||
|
||||
// JDK methods
|
||||
|
||||
extern jmethodID jdk_Boolean_init; // new Boolean(boolean x)
|
||||
extern jmethodID jdk_Integer_init; // new Integer(int x)
|
||||
extern jmethodID jdk_Long_init; // new Long(long x)
|
||||
|
||||
extern jmethodID jdk_InetAddress_getAddress; // byte[] getAddress()
|
||||
extern jmethodID jdk_InetAddress_getByAddress; // static InetAddress getByAddress(byte[])
|
||||
|
||||
extern jmethodID jdk_InetSocketAddress_init; // new InetSocketAddress(InetAddress x)
|
||||
extern jmethodID jdk_InetSocketAddress_getAddress; // InetAddress InetSocketAddress.getAddress()
|
||||
extern jmethodID jdk_InetSocketAddress_getPort; // int InetSocketAddress.getPort()
|
||||
|
||||
extern jmethodID jdk_Set_iterator; // Iterator Set.iterator()
|
||||
extern jmethodID jdk_Set_add; // boolean Set.add(Object)
|
||||
extern jmethodID jdk_Set_contains; // boolean Set.contains(Object)
|
||||
|
||||
extern jmethodID jdk_Iterator_hasNext; // boolean Iterator.hasNext()
|
||||
extern jmethodID jdk_Iterator_next; // Object Iterator.next()
|
||||
|
||||
// UDT classes
|
||||
|
||||
extern jclass udt_FactoryInterfaceUDT;
|
||||
|
||||
// UDT methods
|
||||
|
||||
extern jfieldID udt_CCC_fld_nativeHandleID;
|
||||
|
||||
//#define EOL "\n"
|
||||
|
||||
// special UDT method return value
|
||||
#define UDT_TIMEOUT 0
|
||||
|
||||
// TODO make more portable mingw / msvc
|
||||
#ifdef _MSC_VER
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
//
|
||||
// null pointer safety
|
||||
//
|
||||
#define CHK_LOG(title,comment) printf ("%s function: %s comment: %s", title, __func__, comment);
|
||||
//
|
||||
#define CHK_NUL_RET_RET(reference,comment) if ((reference) == NULL) \
|
||||
{ CHK_LOG("CHK_NUL_RET_RET;",comment); return; }
|
||||
//
|
||||
#define CHK_NUL_RET_NUL(reference,comment) if ((reference) == NULL) \
|
||||
{ CHK_LOG("CHK_NUL_RET_NUL;",comment); return NULL; }
|
||||
//
|
||||
#define CHK_NUL_RET_FLS(reference,comment) if ((reference) == NULL) \
|
||||
{ CHK_LOG("CHK_NUL_RET_FLS;",comment); return false; }
|
||||
//
|
||||
#define CHK_NUL_RET_ERR(reference,comment) if ((reference) == NULL) \
|
||||
{ CHK_LOG("CHK_NUL_RET_ERR;",comment); return JNI_ERR; }
|
||||
//
|
||||
// c++ <-> java, bool <-> boolean conversions
|
||||
#define BOOL(x) (((x) == JNI_TRUE) ? true : false) // from java to c++
|
||||
#define BOOLEAN(x) ((jboolean) ( ((x) == true) ? JNI_TRUE : JNI_FALSE )) // from c++ to java
|
||||
//
|
||||
// free/malloc convenience
|
||||
#define FREE(x) if ((x) != NULL) { free(x); x = NULL; }
|
||||
#define MALLOC(var,type,size) type* var = (type*) malloc(sizeof(type) * size);
|
||||
|
||||
// declare unused explicitly or else see compiler warnings
|
||||
#define UNUSED(x) ((void)(x))
|
||||
|
||||
void X_InitClassReference(JNIEnv *env, jclass *classReference,
|
||||
const char *className);
|
||||
|
||||
void X_FreeClassReference(JNIEnv *env, jclass* globalRef);
|
||||
|
||||
jobject X_NewBoolean(JNIEnv *env, bool value);
|
||||
|
||||
jobject X_NewInteger(JNIEnv *env, int value);
|
||||
|
||||
jobject X_NewLong(JNIEnv* env, int64_t value);
|
||||
|
||||
int X_InitSockAddr(sockaddr* sockAddr);
|
||||
|
||||
inline bool X_IsInRange(jlong min, jlong var, jlong max) {
|
||||
if (min <= var && var <= max) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void X_ConvertMillisIntoTimeValue(const jlong millisTimeout,
|
||||
timeval* timeValue) {
|
||||
if (millisTimeout < 0) { // infinite wait
|
||||
timeValue->tv_sec = INT_MAX;
|
||||
timeValue->tv_usec = 0;
|
||||
} else if (millisTimeout > 0) { // finite wait
|
||||
timeValue->tv_sec = millisTimeout / 1000; // msvc C4244
|
||||
timeValue->tv_usec = (millisTimeout % 1000) * 1000;
|
||||
} else { // immediate return (not less the UDT event slice of 10 ms)
|
||||
timeValue->tv_sec = 0;
|
||||
timeValue->tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: ipv4 only
|
||||
int X_ConvertInetSocketAddressToSockaddr(JNIEnv* env,
|
||||
jobject objInetSocketAddress, sockaddr* sockAddr);
|
||||
|
||||
// NOTE: only ipv4
|
||||
jobject X_NewInetAddress(JNIEnv* env, jint address);
|
||||
|
||||
// NOTE: ipv4 only
|
||||
jobject X_NewInetSocketAddress(JNIEnv* env, sockaddr* sockAddr);
|
||||
|
||||
// NOTE: ipv4 only
|
||||
bool X_IsSockaddrEqualsInetSocketAddress(JNIEnv* env, sockaddr* sockAddr,
|
||||
jobject socketAddress);
|
||||
|
||||
|
||||
void UDT_ThrowExceptionUDT_Message(JNIEnv* env, const jint socketID,
|
||||
const char *comment);
|
||||
|
||||
}//extern "C"
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* JNIHELPERS_H_ */
|
|
@ -0,0 +1,186 @@
|
|||
/**
|
||||
* =================================================================================
|
||||
*
|
||||
* BSD LICENCE (http://en.wikipedia.org/wiki/BSD_licenses)
|
||||
*
|
||||
* Copyright (C) 2009-2013, Barchart, Inc. (http://www.barchart.com/)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the Barchart, Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Developers: Andrei Pozolotin, CCob
|
||||
*
|
||||
* =================================================================================
|
||||
*/
|
||||
|
||||
#include "../jni/com_barchart_udt_CCC.h"
|
||||
|
||||
#include "../jni/JNICCC.h"
|
||||
#include "../jni/JNIHelpers.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
JNICCC* getNativeJNICCC(JNIEnv* env, jobject javaCCC){
|
||||
|
||||
CHK_NUL_RET_NUL(env, "env");
|
||||
CHK_NUL_RET_NUL(env, "javaCCC");
|
||||
|
||||
JNICCC* jniCCC = reinterpret_cast<JNICCC*>( (intptr_t) env->GetLongField(javaCCC,udt_CCC_fld_nativeHandleID)) ;
|
||||
|
||||
if(jniCCC==NULL){
|
||||
UDT_ThrowExceptionUDT_Message(env,0,"illegal state, nativeHandle not set to instance of native JNICCC* class");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return jniCCC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: initNative
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_initNative (JNIEnv *env, jobject self){
|
||||
JNICCC* jniCCC = new JNICCC(env, self);
|
||||
|
||||
if(jniCCC==NULL)
|
||||
UDT_ThrowExceptionUDT_Message(env,0,"failed to allocate native JNICCC* class");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setACKTimer
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setACKTimer
|
||||
(JNIEnv * env, jobject obj, jint msINT){
|
||||
|
||||
JNICCC* jniCCC = getNativeJNICCC(env,obj);
|
||||
|
||||
if(jniCCC==NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
jniCCC->setACKTimer(msINT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setACKInterval
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setACKInterval
|
||||
(JNIEnv * env, jobject obj, jint pktINT){
|
||||
|
||||
JNICCC* jniCCC = getNativeJNICCC(env,obj);
|
||||
|
||||
if(jniCCC==NULL)
|
||||
return;
|
||||
|
||||
jniCCC->setACKInterval(pktINT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setRTO
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setRTO
|
||||
(JNIEnv * env, jobject obj, jint usRTO){
|
||||
|
||||
JNICCC* jniCCC = getNativeJNICCC(env,obj);
|
||||
|
||||
if(jniCCC==NULL)
|
||||
return;
|
||||
|
||||
jniCCC->setRTO(usRTO);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setPacketSndPeriod
|
||||
* Signature: (D)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setPacketSndPeriod
|
||||
(JNIEnv *env, jobject obj, jdouble sndPeriod){
|
||||
|
||||
JNICCC* jniCCC = getNativeJNICCC(env,obj);
|
||||
|
||||
if(jniCCC==NULL)
|
||||
return;
|
||||
|
||||
jniCCC->setPacketSndPeriod(sndPeriod);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setCWndSize
|
||||
* Signature: (D)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setCWndSize
|
||||
(JNIEnv *env, jobject obj, jdouble cWndSize){
|
||||
|
||||
JNICCC* jniCCC = getNativeJNICCC(env,obj);
|
||||
|
||||
if(jniCCC==NULL)
|
||||
return;
|
||||
|
||||
jniCCC->setCWndSize(cWndSize);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: getPerfInfo
|
||||
* Signature: ()Lcom/barchart/udt/MonitorUDT;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_barchart_udt_CCC_getPerfInfo
|
||||
(JNIEnv *env, jobject obj){
|
||||
|
||||
JNICCC* jniCCC = getNativeJNICCC(env,obj);
|
||||
|
||||
const CPerfMon* perfMon = jniCCC->getPerfInfo();
|
||||
|
||||
UNUSED(perfMon);
|
||||
|
||||
UDT_ThrowExceptionUDT_Message(env,0,"TODO: implement CPerfMon -> MonitorUDT mapping");
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
} // __cplusplus defined.
|
|
@ -0,0 +1,71 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
#include <jvmti.h>
|
||||
|
||||
/* Header for class com_barchart_udt_CCC */
|
||||
|
||||
#ifndef _Included_com_barchart_udt_CCC
|
||||
#define _Included_com_barchart_udt_CCC
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: initNative
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_initNative
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setACKTimer
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setACKTimer
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setACKInterval
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setACKInterval
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setRTO
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setRTO
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setPacketSndPeriod
|
||||
* Signature: (D)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setPacketSndPeriod
|
||||
(JNIEnv *, jobject, jdouble);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: setCWndSize
|
||||
* Signature: (D)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_CCC_setCWndSize
|
||||
(JNIEnv *, jobject, jdouble);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_CCC
|
||||
* Method: getPerfInfo
|
||||
* Signature: ()Lcom/barchart/udt/MonitorUDT;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_barchart_udt_CCC_getPerfInfo
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,416 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
#include <jvmti.h>
|
||||
/* Header for class com_barchart_udt_SocketUDT */
|
||||
|
||||
#ifndef _Included_com_barchart_udt_SocketUDT
|
||||
#define _Included_com_barchart_udt_SocketUDT
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_DEFAULT_ACCEPT_QUEUE_SIZE
|
||||
#define com_barchart_udt_SocketUDT_DEFAULT_ACCEPT_QUEUE_SIZE 256L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_DEFAULT_FILE_BLOCK_SIZE
|
||||
#define com_barchart_udt_SocketUDT_DEFAULT_FILE_BLOCK_SIZE 1048576L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_DEFAULT_MAX_SELECTOR_SIZE
|
||||
#define com_barchart_udt_SocketUDT_DEFAULT_MAX_SELECTOR_SIZE 1024L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_DEFAULT_MIN_SELECTOR_TIMEOUT
|
||||
#define com_barchart_udt_SocketUDT_DEFAULT_MIN_SELECTOR_TIMEOUT 10L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_INFINITE_TTL
|
||||
#define com_barchart_udt_SocketUDT_INFINITE_TTL -1L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_SIGNATURE_JNI
|
||||
#define com_barchart_udt_SocketUDT_SIGNATURE_JNI 20130512L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_TIMEOUT_INFINITE
|
||||
#define com_barchart_udt_SocketUDT_TIMEOUT_INFINITE -1L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_UDT_EXCEPT_INDEX
|
||||
#define com_barchart_udt_SocketUDT_UDT_EXCEPT_INDEX 2L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_UDT_READ_INDEX
|
||||
#define com_barchart_udt_SocketUDT_UDT_READ_INDEX 0L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_UDT_SIZE_COUNT
|
||||
#define com_barchart_udt_SocketUDT_UDT_SIZE_COUNT 3L
|
||||
|
||||
#undef com_barchart_udt_SocketUDT_UDT_WRITE_INDEX
|
||||
#define com_barchart_udt_SocketUDT_UDT_WRITE_INDEX 1L
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: epollAdd0
|
||||
* Signature: (III)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_epollAdd0
|
||||
(JNIEnv *, jclass, jint, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: epollCreate0
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_epollCreate0
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: epollRelease0
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_epollRelease0
|
||||
(JNIEnv *, jclass, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: epollRemove0
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_epollRemove0
|
||||
(JNIEnv *, jclass, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: epollUpdate0
|
||||
* Signature: (III)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_epollUpdate0
|
||||
(JNIEnv *, jclass, jint, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: epollVerify0
|
||||
* Signature: (II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_epollVerify0
|
||||
(JNIEnv *, jclass, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: epollWait0
|
||||
* Signature: (ILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_epollWait0
|
||||
(JNIEnv *, jclass, jint, jobject, jobject, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: getSignatureJNI0
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_getSignatureJNI0
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: initClass0
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_initClass0
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: receive0
|
||||
* Signature: (II[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_receive0
|
||||
(JNIEnv *, jclass, jint, jint, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: receive1
|
||||
* Signature: (II[BII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_receive1
|
||||
(JNIEnv *, jclass, jint, jint, jbyteArray, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: receive2
|
||||
* Signature: (IILjava/nio/ByteBuffer;II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_receive2
|
||||
(JNIEnv *, jclass, jint, jint, jobject, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: receiveFile0
|
||||
* Signature: (ILjava/lang/String;JJI)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_com_barchart_udt_SocketUDT_receiveFile0
|
||||
(JNIEnv *, jclass, jint, jstring, jlong, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: send0
|
||||
* Signature: (IIIZ[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_send0
|
||||
(JNIEnv *, jclass, jint, jint, jint, jboolean, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: send1
|
||||
* Signature: (IIIZ[BII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_send1
|
||||
(JNIEnv *, jclass, jint, jint, jint, jboolean, jbyteArray, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: send2
|
||||
* Signature: (IIIZLjava/nio/ByteBuffer;II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_send2
|
||||
(JNIEnv *, jclass, jint, jint, jint, jboolean, jobject, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: sendFile0
|
||||
* Signature: (ILjava/lang/String;JJI)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_com_barchart_udt_SocketUDT_sendFile0
|
||||
(JNIEnv *, jclass, jint, jstring, jlong, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: stopClass0
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_stopClass0
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testCrashJVM0
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testCrashJVM0
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testDirectByteBufferAccess0
|
||||
* Signature: (Ljava/nio/ByteBuffer;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testDirectByteBufferAccess0
|
||||
(JNIEnv *, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testDirectIntBufferAccess0
|
||||
* Signature: (Ljava/nio/IntBuffer;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testDirectIntBufferAccess0
|
||||
(JNIEnv *, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testDirectIntBufferLoad0
|
||||
* Signature: (Ljava/nio/IntBuffer;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testDirectIntBufferLoad0
|
||||
(JNIEnv *, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testEmptyCall0
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testEmptyCall0
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testFillArray0
|
||||
* Signature: ([B)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testFillArray0
|
||||
(JNIEnv *, jclass, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testFillBuffer0
|
||||
* Signature: (Ljava/nio/ByteBuffer;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testFillBuffer0
|
||||
(JNIEnv *, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testGetSetArray0
|
||||
* Signature: ([IZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testGetSetArray0
|
||||
(JNIEnv *, jclass, jintArray, jboolean);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testInvalidClose0
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testInvalidClose0
|
||||
(JNIEnv *, jclass, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testIterateArray0
|
||||
* Signature: ([Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testIterateArray0
|
||||
(JNIEnv *, jclass, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testIterateSet0
|
||||
* Signature: (Ljava/util/Set;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_testIterateSet0
|
||||
(JNIEnv *, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: testMakeArray0
|
||||
* Signature: (I)[I
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL Java_com_barchart_udt_SocketUDT_testMakeArray0
|
||||
(JNIEnv *, jclass, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: accept0
|
||||
* Signature: ()Lcom/barchart/udt/SocketUDT;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_barchart_udt_SocketUDT_accept0
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: bind0
|
||||
* Signature: (Ljava/net/InetSocketAddress;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_bind0
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: clearError0
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_clearError0
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: close0
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_close0
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: connect0
|
||||
* Signature: (Ljava/net/InetSocketAddress;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_connect0
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: getErrorCode0
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_getErrorCode0
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: getErrorMessage0
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_barchart_udt_SocketUDT_getErrorMessage0
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: getOption0
|
||||
* Signature: (ILjava/lang/Class;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_barchart_udt_SocketUDT_getOption0
|
||||
(JNIEnv *, jobject, jint, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: getStatus0
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_getStatus0
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: hasLoadedLocalSocketAddress
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_com_barchart_udt_SocketUDT_hasLoadedLocalSocketAddress
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: hasLoadedRemoteSocketAddress
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_com_barchart_udt_SocketUDT_hasLoadedRemoteSocketAddress
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: initInstance0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_initInstance0
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: initInstance1
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_barchart_udt_SocketUDT_initInstance1
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: listen0
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_listen0
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: setOption0
|
||||
* Signature: (ILjava/lang/Class;Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_setOption0
|
||||
(JNIEnv *, jobject, jint, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_barchart_udt_SocketUDT
|
||||
* Method: updateMonitor0
|
||||
* Signature: (Z)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_barchart_udt_SocketUDT_updateMonitor0
|
||||
(JNIEnv *, jobject, jboolean);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,703 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/22/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#include "list.h"
|
||||
|
||||
CSndLossList::CSndLossList(int size):
|
||||
m_piData1(NULL),
|
||||
m_piData2(NULL),
|
||||
m_piNext(NULL),
|
||||
m_iHead(-1),
|
||||
m_iLength(0),
|
||||
m_iSize(size),
|
||||
m_iLastInsertPos(-1),
|
||||
m_ListLock()
|
||||
{
|
||||
m_piData1 = new int32_t [m_iSize];
|
||||
m_piData2 = new int32_t [m_iSize];
|
||||
m_piNext = new int [m_iSize];
|
||||
|
||||
// -1 means there is no data in the node
|
||||
for (int i = 0; i < size; ++ i)
|
||||
{
|
||||
m_piData1[i] = -1;
|
||||
m_piData2[i] = -1;
|
||||
}
|
||||
|
||||
// sender list needs mutex protection
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_init(&m_ListLock, 0);
|
||||
#else
|
||||
m_ListLock = CreateMutex(NULL, false, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
CSndLossList::~CSndLossList()
|
||||
{
|
||||
delete [] m_piData1;
|
||||
delete [] m_piData2;
|
||||
delete [] m_piNext;
|
||||
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_destroy(&m_ListLock);
|
||||
#else
|
||||
CloseHandle(m_ListLock);
|
||||
#endif
|
||||
}
|
||||
|
||||
int CSndLossList::insert(int32_t seqno1, int32_t seqno2)
|
||||
{
|
||||
CGuard listguard(m_ListLock);
|
||||
|
||||
if (0 == m_iLength)
|
||||
{
|
||||
// insert data into an empty list
|
||||
|
||||
m_iHead = 0;
|
||||
m_piData1[m_iHead] = seqno1;
|
||||
if (seqno2 != seqno1)
|
||||
m_piData2[m_iHead] = seqno2;
|
||||
|
||||
m_piNext[m_iHead] = -1;
|
||||
m_iLastInsertPos = m_iHead;
|
||||
|
||||
m_iLength += CSeqNo::seqlen(seqno1, seqno2);
|
||||
|
||||
return m_iLength;
|
||||
}
|
||||
|
||||
// otherwise find the position where the data can be inserted
|
||||
int origlen = m_iLength;
|
||||
int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno1);
|
||||
int loc = (m_iHead + offset + m_iSize) % m_iSize;
|
||||
|
||||
if (offset < 0)
|
||||
{
|
||||
// Insert data prior to the head pointer
|
||||
|
||||
m_piData1[loc] = seqno1;
|
||||
if (seqno2 != seqno1)
|
||||
m_piData2[loc] = seqno2;
|
||||
|
||||
// new node becomes head
|
||||
m_piNext[loc] = m_iHead;
|
||||
m_iHead = loc;
|
||||
m_iLastInsertPos = loc;
|
||||
|
||||
m_iLength += CSeqNo::seqlen(seqno1, seqno2);
|
||||
}
|
||||
else if (offset > 0)
|
||||
{
|
||||
if (seqno1 == m_piData1[loc])
|
||||
{
|
||||
m_iLastInsertPos = loc;
|
||||
|
||||
// first seqno is equivlent, compare the second
|
||||
if (-1 == m_piData2[loc])
|
||||
{
|
||||
if (seqno2 != seqno1)
|
||||
{
|
||||
m_iLength += CSeqNo::seqlen(seqno1, seqno2) - 1;
|
||||
m_piData2[loc] = seqno2;
|
||||
}
|
||||
}
|
||||
else if (CSeqNo::seqcmp(seqno2, m_piData2[loc]) > 0)
|
||||
{
|
||||
// new seq pair is longer than old pair, e.g., insert [3, 7] to [3, 5], becomes [3, 7]
|
||||
m_iLength += CSeqNo::seqlen(m_piData2[loc], seqno2) - 1;
|
||||
m_piData2[loc] = seqno2;
|
||||
}
|
||||
else
|
||||
// Do nothing if it is already there
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// searching the prior node
|
||||
int i;
|
||||
if ((-1 != m_iLastInsertPos) && (CSeqNo::seqcmp(m_piData1[m_iLastInsertPos], seqno1) < 0))
|
||||
i = m_iLastInsertPos;
|
||||
else
|
||||
i = m_iHead;
|
||||
|
||||
while ((-1 != m_piNext[i]) && (CSeqNo::seqcmp(m_piData1[m_piNext[i]], seqno1) < 0))
|
||||
i = m_piNext[i];
|
||||
|
||||
if ((-1 == m_piData2[i]) || (CSeqNo::seqcmp(m_piData2[i], seqno1) < 0))
|
||||
{
|
||||
m_iLastInsertPos = loc;
|
||||
|
||||
// no overlap, create new node
|
||||
m_piData1[loc] = seqno1;
|
||||
if (seqno2 != seqno1)
|
||||
m_piData2[loc] = seqno2;
|
||||
|
||||
m_piNext[loc] = m_piNext[i];
|
||||
m_piNext[i] = loc;
|
||||
|
||||
m_iLength += CSeqNo::seqlen(seqno1, seqno2);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iLastInsertPos = i;
|
||||
|
||||
// overlap, coalesce with prior node, insert(3, 7) to [2, 5], ... becomes [2, 7]
|
||||
if (CSeqNo::seqcmp(m_piData2[i], seqno2) < 0)
|
||||
{
|
||||
m_iLength += CSeqNo::seqlen(m_piData2[i], seqno2) - 1;
|
||||
m_piData2[i] = seqno2;
|
||||
|
||||
loc = i;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iLastInsertPos = m_iHead;
|
||||
|
||||
// insert to head node
|
||||
if (seqno2 != seqno1)
|
||||
{
|
||||
if (-1 == m_piData2[loc])
|
||||
{
|
||||
m_iLength += CSeqNo::seqlen(seqno1, seqno2) - 1;
|
||||
m_piData2[loc] = seqno2;
|
||||
}
|
||||
else if (CSeqNo::seqcmp(seqno2, m_piData2[loc]) > 0)
|
||||
{
|
||||
m_iLength += CSeqNo::seqlen(m_piData2[loc], seqno2) - 1;
|
||||
m_piData2[loc] = seqno2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// coalesce with next node. E.g., [3, 7], ..., [6, 9] becomes [3, 9]
|
||||
while ((-1 != m_piNext[loc]) && (-1 != m_piData2[loc]))
|
||||
{
|
||||
int i = m_piNext[loc];
|
||||
|
||||
if (CSeqNo::seqcmp(m_piData1[i], CSeqNo::incseq(m_piData2[loc])) <= 0)
|
||||
{
|
||||
// coalesce if there is overlap
|
||||
if (-1 != m_piData2[i])
|
||||
{
|
||||
if (CSeqNo::seqcmp(m_piData2[i], m_piData2[loc]) > 0)
|
||||
{
|
||||
if (CSeqNo::seqcmp(m_piData2[loc], m_piData1[i]) >= 0)
|
||||
m_iLength -= CSeqNo::seqlen(m_piData1[i], m_piData2[loc]);
|
||||
|
||||
m_piData2[loc] = m_piData2[i];
|
||||
}
|
||||
else
|
||||
m_iLength -= CSeqNo::seqlen(m_piData1[i], m_piData2[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_piData1[i] == CSeqNo::incseq(m_piData2[loc]))
|
||||
m_piData2[loc] = m_piData1[i];
|
||||
else
|
||||
m_iLength --;
|
||||
}
|
||||
|
||||
m_piData1[i] = -1;
|
||||
m_piData2[i] = -1;
|
||||
m_piNext[loc] = m_piNext[i];
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return m_iLength - origlen;
|
||||
}
|
||||
|
||||
void CSndLossList::remove(int32_t seqno)
|
||||
{
|
||||
CGuard listguard(m_ListLock);
|
||||
|
||||
if (0 == m_iLength)
|
||||
return;
|
||||
|
||||
// Remove all from the head pointer to a node with a larger seq. no. or the list is empty
|
||||
int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno);
|
||||
int loc = (m_iHead + offset + m_iSize) % m_iSize;
|
||||
|
||||
if (0 == offset)
|
||||
{
|
||||
// It is the head. Remove the head and point to the next node
|
||||
loc = (loc + 1) % m_iSize;
|
||||
|
||||
if (-1 == m_piData2[m_iHead])
|
||||
loc = m_piNext[m_iHead];
|
||||
else
|
||||
{
|
||||
m_piData1[loc] = CSeqNo::incseq(seqno);
|
||||
if (CSeqNo::seqcmp(m_piData2[m_iHead], CSeqNo::incseq(seqno)) > 0)
|
||||
m_piData2[loc] = m_piData2[m_iHead];
|
||||
|
||||
m_piData2[m_iHead] = -1;
|
||||
|
||||
m_piNext[loc] = m_piNext[m_iHead];
|
||||
}
|
||||
|
||||
m_piData1[m_iHead] = -1;
|
||||
|
||||
if (m_iLastInsertPos == m_iHead)
|
||||
m_iLastInsertPos = -1;
|
||||
|
||||
m_iHead = loc;
|
||||
|
||||
m_iLength --;
|
||||
}
|
||||
else if (offset > 0)
|
||||
{
|
||||
int h = m_iHead;
|
||||
|
||||
if (seqno == m_piData1[loc])
|
||||
{
|
||||
// target node is not empty, remove part/all of the seqno in the node.
|
||||
int temp = loc;
|
||||
loc = (loc + 1) % m_iSize;
|
||||
|
||||
if (-1 == m_piData2[temp])
|
||||
m_iHead = m_piNext[temp];
|
||||
else
|
||||
{
|
||||
// remove part, e.g., [3, 7] becomes [], [4, 7] after remove(3)
|
||||
m_piData1[loc] = CSeqNo::incseq(seqno);
|
||||
if (CSeqNo::seqcmp(m_piData2[temp], m_piData1[loc]) > 0)
|
||||
m_piData2[loc] = m_piData2[temp];
|
||||
m_iHead = loc;
|
||||
m_piNext[loc] = m_piNext[temp];
|
||||
m_piNext[temp] = loc;
|
||||
m_piData2[temp] = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// target node is empty, check prior node
|
||||
int i = m_iHead;
|
||||
while ((-1 != m_piNext[i]) && (CSeqNo::seqcmp(m_piData1[m_piNext[i]], seqno) < 0))
|
||||
i = m_piNext[i];
|
||||
|
||||
loc = (loc + 1) % m_iSize;
|
||||
|
||||
if (-1 == m_piData2[i])
|
||||
m_iHead = m_piNext[i];
|
||||
else if (CSeqNo::seqcmp(m_piData2[i], seqno) > 0)
|
||||
{
|
||||
// remove part/all seqno in the prior node
|
||||
m_piData1[loc] = CSeqNo::incseq(seqno);
|
||||
if (CSeqNo::seqcmp(m_piData2[i], m_piData1[loc]) > 0)
|
||||
m_piData2[loc] = m_piData2[i];
|
||||
|
||||
m_piData2[i] = seqno;
|
||||
|
||||
m_piNext[loc] = m_piNext[i];
|
||||
m_piNext[i] = loc;
|
||||
|
||||
m_iHead = loc;
|
||||
}
|
||||
else
|
||||
m_iHead = m_piNext[i];
|
||||
}
|
||||
|
||||
// Remove all nodes prior to the new head
|
||||
while (h != m_iHead)
|
||||
{
|
||||
if (m_piData2[h] != -1)
|
||||
{
|
||||
m_iLength -= CSeqNo::seqlen(m_piData1[h], m_piData2[h]);
|
||||
m_piData2[h] = -1;
|
||||
}
|
||||
else
|
||||
m_iLength --;
|
||||
|
||||
m_piData1[h] = -1;
|
||||
|
||||
if (m_iLastInsertPos == h)
|
||||
m_iLastInsertPos = -1;
|
||||
|
||||
h = m_piNext[h];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CSndLossList::getLossLength()
|
||||
{
|
||||
CGuard listguard(m_ListLock);
|
||||
|
||||
return m_iLength;
|
||||
}
|
||||
|
||||
int32_t CSndLossList::getLostSeq()
|
||||
{
|
||||
if (0 == m_iLength)
|
||||
return -1;
|
||||
|
||||
CGuard listguard(m_ListLock);
|
||||
|
||||
if (0 == m_iLength)
|
||||
return -1;
|
||||
|
||||
if (m_iLastInsertPos == m_iHead)
|
||||
m_iLastInsertPos = -1;
|
||||
|
||||
// return the first loss seq. no.
|
||||
int32_t seqno = m_piData1[m_iHead];
|
||||
|
||||
// head moves to the next node
|
||||
if (-1 == m_piData2[m_iHead])
|
||||
{
|
||||
//[3, -1] becomes [], and head moves to next node in the list
|
||||
m_piData1[m_iHead] = -1;
|
||||
m_iHead = m_piNext[m_iHead];
|
||||
}
|
||||
else
|
||||
{
|
||||
// shift to next node, e.g., [3, 7] becomes [], [4, 7]
|
||||
int loc = (m_iHead + 1) % m_iSize;
|
||||
|
||||
m_piData1[loc] = CSeqNo::incseq(seqno);
|
||||
if (CSeqNo::seqcmp(m_piData2[m_iHead], m_piData1[loc]) > 0)
|
||||
m_piData2[loc] = m_piData2[m_iHead];
|
||||
|
||||
m_piData1[m_iHead] = -1;
|
||||
m_piData2[m_iHead] = -1;
|
||||
|
||||
m_piNext[loc] = m_piNext[m_iHead];
|
||||
m_iHead = loc;
|
||||
}
|
||||
|
||||
m_iLength --;
|
||||
|
||||
return seqno;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CRcvLossList::CRcvLossList(int size):
|
||||
m_piData1(NULL),
|
||||
m_piData2(NULL),
|
||||
m_piNext(NULL),
|
||||
m_piPrior(NULL),
|
||||
m_iHead(-1),
|
||||
m_iTail(-1),
|
||||
m_iLength(0),
|
||||
m_iSize(size)
|
||||
{
|
||||
m_piData1 = new int32_t [m_iSize];
|
||||
m_piData2 = new int32_t [m_iSize];
|
||||
m_piNext = new int [m_iSize];
|
||||
m_piPrior = new int [m_iSize];
|
||||
|
||||
// -1 means there is no data in the node
|
||||
for (int i = 0; i < size; ++ i)
|
||||
{
|
||||
m_piData1[i] = -1;
|
||||
m_piData2[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
CRcvLossList::~CRcvLossList()
|
||||
{
|
||||
delete [] m_piData1;
|
||||
delete [] m_piData2;
|
||||
delete [] m_piNext;
|
||||
delete [] m_piPrior;
|
||||
}
|
||||
|
||||
void CRcvLossList::insert(int32_t seqno1, int32_t seqno2)
|
||||
{
|
||||
// Data to be inserted must be larger than all those in the list
|
||||
// guaranteed by the UDT receiver
|
||||
|
||||
if (0 == m_iLength)
|
||||
{
|
||||
// insert data into an empty list
|
||||
m_iHead = 0;
|
||||
m_iTail = 0;
|
||||
m_piData1[m_iHead] = seqno1;
|
||||
if (seqno2 != seqno1)
|
||||
m_piData2[m_iHead] = seqno2;
|
||||
|
||||
m_piNext[m_iHead] = -1;
|
||||
m_piPrior[m_iHead] = -1;
|
||||
m_iLength += CSeqNo::seqlen(seqno1, seqno2);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise searching for the position where the node should be
|
||||
int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno1);
|
||||
int loc = (m_iHead + offset) % m_iSize;
|
||||
|
||||
if ((-1 != m_piData2[m_iTail]) && (CSeqNo::incseq(m_piData2[m_iTail]) == seqno1))
|
||||
{
|
||||
// coalesce with prior node, e.g., [2, 5], [6, 7] becomes [2, 7]
|
||||
loc = m_iTail;
|
||||
m_piData2[loc] = seqno2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// create new node
|
||||
m_piData1[loc] = seqno1;
|
||||
|
||||
if (seqno2 != seqno1)
|
||||
m_piData2[loc] = seqno2;
|
||||
|
||||
m_piNext[m_iTail] = loc;
|
||||
m_piPrior[loc] = m_iTail;
|
||||
m_piNext[loc] = -1;
|
||||
m_iTail = loc;
|
||||
}
|
||||
|
||||
m_iLength += CSeqNo::seqlen(seqno1, seqno2);
|
||||
}
|
||||
|
||||
bool CRcvLossList::remove(int32_t seqno)
|
||||
{
|
||||
if (0 == m_iLength)
|
||||
return false;
|
||||
|
||||
// locate the position of "seqno" in the list
|
||||
int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
int loc = (m_iHead + offset) % m_iSize;
|
||||
|
||||
if (seqno == m_piData1[loc])
|
||||
{
|
||||
// This is a seq. no. that starts the loss sequence
|
||||
|
||||
if (-1 == m_piData2[loc])
|
||||
{
|
||||
// there is only 1 loss in the sequence, delete it from the node
|
||||
if (m_iHead == loc)
|
||||
{
|
||||
m_iHead = m_piNext[m_iHead];
|
||||
if (-1 != m_iHead)
|
||||
m_piPrior[m_iHead] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_piNext[m_piPrior[loc]] = m_piNext[loc];
|
||||
if (-1 != m_piNext[loc])
|
||||
m_piPrior[m_piNext[loc]] = m_piPrior[loc];
|
||||
else
|
||||
m_iTail = m_piPrior[loc];
|
||||
}
|
||||
|
||||
m_piData1[loc] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// there are more than 1 loss in the sequence
|
||||
// move the node to the next and update the starter as the next loss inSeqNo(seqno)
|
||||
|
||||
// find next node
|
||||
int i = (loc + 1) % m_iSize;
|
||||
|
||||
// remove the "seqno" and change the starter as next seq. no.
|
||||
m_piData1[i] = CSeqNo::incseq(m_piData1[loc]);
|
||||
|
||||
// process the sequence end
|
||||
if (CSeqNo::seqcmp(m_piData2[loc], CSeqNo::incseq(m_piData1[loc])) > 0)
|
||||
m_piData2[i] = m_piData2[loc];
|
||||
|
||||
// remove the current node
|
||||
m_piData1[loc] = -1;
|
||||
m_piData2[loc] = -1;
|
||||
|
||||
// update list pointer
|
||||
m_piNext[i] = m_piNext[loc];
|
||||
m_piPrior[i] = m_piPrior[loc];
|
||||
|
||||
if (m_iHead == loc)
|
||||
m_iHead = i;
|
||||
else
|
||||
m_piNext[m_piPrior[i]] = i;
|
||||
|
||||
if (m_iTail == loc)
|
||||
m_iTail = i;
|
||||
else
|
||||
m_piPrior[m_piNext[i]] = i;
|
||||
}
|
||||
|
||||
m_iLength --;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// There is no loss sequence in the current position
|
||||
// the "seqno" may be contained in a previous node
|
||||
|
||||
// searching previous node
|
||||
int i = (loc - 1 + m_iSize) % m_iSize;
|
||||
while (-1 == m_piData1[i])
|
||||
i = (i - 1 + m_iSize) % m_iSize;
|
||||
|
||||
// not contained in this node, return
|
||||
if ((-1 == m_piData2[i]) || (CSeqNo::seqcmp(seqno, m_piData2[i]) > 0))
|
||||
return false;
|
||||
|
||||
if (seqno == m_piData2[i])
|
||||
{
|
||||
// it is the sequence end
|
||||
|
||||
if (seqno == CSeqNo::incseq(m_piData1[i]))
|
||||
m_piData2[i] = -1;
|
||||
else
|
||||
m_piData2[i] = CSeqNo::decseq(seqno);
|
||||
}
|
||||
else
|
||||
{
|
||||
// split the sequence
|
||||
|
||||
// construct the second sequence from CSeqNo::incseq(seqno) to the original sequence end
|
||||
// located at "loc + 1"
|
||||
loc = (loc + 1) % m_iSize;
|
||||
|
||||
m_piData1[loc] = CSeqNo::incseq(seqno);
|
||||
if (CSeqNo::seqcmp(m_piData2[i], m_piData1[loc]) > 0)
|
||||
m_piData2[loc] = m_piData2[i];
|
||||
|
||||
// the first (original) sequence is between the original sequence start to CSeqNo::decseq(seqno)
|
||||
if (seqno == CSeqNo::incseq(m_piData1[i]))
|
||||
m_piData2[i] = -1;
|
||||
else
|
||||
m_piData2[i] = CSeqNo::decseq(seqno);
|
||||
|
||||
// update the list pointer
|
||||
m_piNext[loc] = m_piNext[i];
|
||||
m_piNext[i] = loc;
|
||||
m_piPrior[loc] = i;
|
||||
|
||||
if (m_iTail == i)
|
||||
m_iTail = loc;
|
||||
else
|
||||
m_piPrior[m_piNext[loc]] = loc;
|
||||
}
|
||||
|
||||
m_iLength --;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRcvLossList::remove(int32_t seqno1, int32_t seqno2)
|
||||
{
|
||||
if (seqno1 <= seqno2)
|
||||
{
|
||||
for (int32_t i = seqno1; i <= seqno2; ++ i)
|
||||
remove(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int32_t j = seqno1; j < CSeqNo::m_iMaxSeqNo; ++ j)
|
||||
remove(j);
|
||||
for (int32_t k = 0; k <= seqno2; ++ k)
|
||||
remove(k);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRcvLossList::find(int32_t seqno1, int32_t seqno2) const
|
||||
{
|
||||
if (0 == m_iLength)
|
||||
return false;
|
||||
|
||||
int p = m_iHead;
|
||||
|
||||
while (-1 != p)
|
||||
{
|
||||
if ((CSeqNo::seqcmp(m_piData1[p], seqno1) == 0) ||
|
||||
((CSeqNo::seqcmp(m_piData1[p], seqno1) > 0) && (CSeqNo::seqcmp(m_piData1[p], seqno2) <= 0)) ||
|
||||
((CSeqNo::seqcmp(m_piData1[p], seqno1) < 0) && (m_piData2[p] != -1) && CSeqNo::seqcmp(m_piData2[p], seqno1) >= 0))
|
||||
return true;
|
||||
|
||||
p = m_piNext[p];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int CRcvLossList::getLossLength() const
|
||||
{
|
||||
return m_iLength;
|
||||
}
|
||||
|
||||
int CRcvLossList::getFirstLostSeq() const
|
||||
{
|
||||
if (0 == m_iLength)
|
||||
return -1;
|
||||
|
||||
return m_piData1[m_iHead];
|
||||
}
|
||||
|
||||
void CRcvLossList::getLossArray(int32_t* array, int& len, int limit)
|
||||
{
|
||||
len = 0;
|
||||
|
||||
int i = m_iHead;
|
||||
|
||||
while ((len < limit - 1) && (-1 != i))
|
||||
{
|
||||
array[len] = m_piData1[i];
|
||||
if (-1 != m_piData2[i])
|
||||
{
|
||||
// there are more than 1 loss in the sequence
|
||||
array[len] |= 0x80000000;
|
||||
++ len;
|
||||
array[len] = m_piData2[i];
|
||||
}
|
||||
|
||||
++ len;
|
||||
|
||||
i = m_piNext[i];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/22/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_LIST_H__
|
||||
#define __UDT_LIST_H__
|
||||
|
||||
|
||||
#include "udt.h"
|
||||
#include "udtCommon.h"
|
||||
|
||||
|
||||
class CSndLossList
|
||||
{
|
||||
public:
|
||||
CSndLossList(int size = 1024);
|
||||
~CSndLossList();
|
||||
|
||||
// Functionality:
|
||||
// Insert a seq. no. into the sender loss list.
|
||||
// Parameters:
|
||||
// 0) [in] seqno1: sequence number starts.
|
||||
// 1) [in] seqno2: sequence number ends.
|
||||
// Returned value:
|
||||
// number of packets that are not in the list previously.
|
||||
|
||||
int insert(int32_t seqno1, int32_t seqno2);
|
||||
|
||||
// Functionality:
|
||||
// Remove ALL the seq. no. that are not greater than the parameter.
|
||||
// Parameters:
|
||||
// 0) [in] seqno: sequence number.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void remove(int32_t seqno);
|
||||
|
||||
// Functionality:
|
||||
// Read the loss length.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// The length of the list.
|
||||
|
||||
int getLossLength();
|
||||
|
||||
// Functionality:
|
||||
// Read the first (smallest) loss seq. no. in the list and remove it.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// The seq. no. or -1 if the list is empty.
|
||||
|
||||
int32_t getLostSeq();
|
||||
|
||||
private:
|
||||
int32_t* m_piData1; // sequence number starts
|
||||
int32_t* m_piData2; // seqnence number ends
|
||||
int* m_piNext; // next node in the list
|
||||
|
||||
int m_iHead; // first node
|
||||
int m_iLength; // loss length
|
||||
int m_iSize; // size of the static array
|
||||
int m_iLastInsertPos; // position of last insert node
|
||||
|
||||
udt_pthread_mutex_t m_ListLock; // used to synchronize list operation
|
||||
|
||||
private:
|
||||
CSndLossList(const CSndLossList&);
|
||||
CSndLossList& operator=(const CSndLossList&);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CRcvLossList
|
||||
{
|
||||
public:
|
||||
CRcvLossList(int size = 1024);
|
||||
~CRcvLossList();
|
||||
|
||||
// Functionality:
|
||||
// Insert a series of loss seq. no. between "seqno1" and "seqno2" into the receiver's loss list.
|
||||
// Parameters:
|
||||
// 0) [in] seqno1: sequence number starts.
|
||||
// 1) [in] seqno2: seqeunce number ends.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void insert(int32_t seqno1, int32_t seqno2);
|
||||
|
||||
// Functionality:
|
||||
// Remove a loss seq. no. from the receiver's loss list.
|
||||
// Parameters:
|
||||
// 0) [in] seqno: sequence number.
|
||||
// Returned value:
|
||||
// if the packet is removed (true) or no such lost packet is found (false).
|
||||
|
||||
bool remove(int32_t seqno);
|
||||
|
||||
// Functionality:
|
||||
// Remove all packets between seqno1 and seqno2.
|
||||
// Parameters:
|
||||
// 0) [in] seqno1: start sequence number.
|
||||
// 1) [in] seqno2: end sequence number.
|
||||
// Returned value:
|
||||
// if the packet is removed (true) or no such lost packet is found (false).
|
||||
|
||||
bool remove(int32_t seqno1, int32_t seqno2);
|
||||
|
||||
// Functionality:
|
||||
// Find if there is any lost packets whose sequence number falling seqno1 and seqno2.
|
||||
// Parameters:
|
||||
// 0) [in] seqno1: start sequence number.
|
||||
// 1) [in] seqno2: end sequence number.
|
||||
// Returned value:
|
||||
// True if found; otherwise false.
|
||||
|
||||
bool find(int32_t seqno1, int32_t seqno2) const;
|
||||
|
||||
// Functionality:
|
||||
// Read the loss length.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// the length of the list.
|
||||
|
||||
int getLossLength() const;
|
||||
|
||||
// Functionality:
|
||||
// Read the first (smallest) seq. no. in the list.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// the sequence number or -1 if the list is empty.
|
||||
|
||||
int getFirstLostSeq() const;
|
||||
|
||||
// Functionality:
|
||||
// Get a encoded loss array for NAK report.
|
||||
// Parameters:
|
||||
// 0) [out] array: the result list of seq. no. to be included in NAK.
|
||||
// 1) [out] physical length of the result array.
|
||||
// 2) [in] limit: maximum length of the array.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void getLossArray(int32_t* array, int& len, int limit);
|
||||
|
||||
private:
|
||||
int32_t* m_piData1; // sequence number starts
|
||||
int32_t* m_piData2; // sequence number ends
|
||||
int* m_piNext; // next node in the list
|
||||
int* m_piPrior; // prior node in the list;
|
||||
|
||||
int m_iHead; // first node in the list
|
||||
int m_iTail; // last node in the list;
|
||||
int m_iLength; // loss length
|
||||
int m_iSize; // size of the static array
|
||||
|
||||
private:
|
||||
CRcvLossList(const CRcvLossList&);
|
||||
CRcvLossList& operator=(const CRcvLossList&);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
ghost@aladdin.com
|
||||
|
||||
*/
|
||||
/* $Id: md5.cpp,v 1.3 2008/01/20 22:52:04 lilyco Exp $ */
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
copyrighted.
|
||||
|
||||
The original and principal author of md5.c is L. Peter Deutsch
|
||||
<ghost@aladdin.com>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
|
||||
either statically or dynamically; added missing #include <string.h>
|
||||
in library.
|
||||
2002-03-11 lpd Corrected argument list for main(), and added int return
|
||||
type, in test program and T value program.
|
||||
2002-02-21 lpd Added missing #include <stdio.h> in test program.
|
||||
2000-07-03 lpd Patched to eliminate warnings about "constant is
|
||||
unsigned in ANSI C, signed in traditional"; made test program
|
||||
self-checking.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
#include "md5.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#ifdef ARCH_IS_BIG_ENDIAN
|
||||
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#else
|
||||
# define BYTE_ORDER 0
|
||||
#endif
|
||||
|
||||
#define T_MASK ((md5_word_t)~0)
|
||||
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
|
||||
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
|
||||
#define T3 0x242070db
|
||||
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
|
||||
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
|
||||
#define T6 0x4787c62a
|
||||
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
|
||||
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
|
||||
#define T9 0x698098d8
|
||||
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
|
||||
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
|
||||
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
|
||||
#define T13 0x6b901122
|
||||
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
|
||||
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
|
||||
#define T16 0x49b40821
|
||||
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
|
||||
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
|
||||
#define T19 0x265e5a51
|
||||
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
|
||||
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
|
||||
#define T22 0x02441453
|
||||
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
|
||||
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
|
||||
#define T25 0x21e1cde6
|
||||
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
|
||||
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
|
||||
#define T28 0x455a14ed
|
||||
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
|
||||
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
|
||||
#define T31 0x676f02d9
|
||||
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
|
||||
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
|
||||
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
|
||||
#define T35 0x6d9d6122
|
||||
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
|
||||
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
|
||||
#define T38 0x4bdecfa9
|
||||
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
|
||||
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
|
||||
#define T41 0x289b7ec6
|
||||
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
|
||||
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
|
||||
#define T44 0x04881d05
|
||||
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
|
||||
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
|
||||
#define T47 0x1fa27cf8
|
||||
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
|
||||
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
|
||||
#define T50 0x432aff97
|
||||
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
|
||||
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
|
||||
#define T53 0x655b59c3
|
||||
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
|
||||
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
|
||||
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
|
||||
#define T57 0x6fa87e4f
|
||||
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
|
||||
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
|
||||
#define T60 0x4e0811a1
|
||||
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
|
||||
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
|
||||
#define T63 0x2ad7d2bb
|
||||
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
|
||||
|
||||
|
||||
static void
|
||||
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
|
||||
{
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
md5_word_t X[16];
|
||||
#else
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
md5_word_t xbuf[16];
|
||||
const md5_word_t *X;
|
||||
#endif
|
||||
|
||||
{
|
||||
#if BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static const int w = 1;
|
||||
|
||||
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (const md5_byte_t *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (const md5_word_t *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + F(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, T1);
|
||||
SET(d, a, b, c, 1, 12, T2);
|
||||
SET(c, d, a, b, 2, 17, T3);
|
||||
SET(b, c, d, a, 3, 22, T4);
|
||||
SET(a, b, c, d, 4, 7, T5);
|
||||
SET(d, a, b, c, 5, 12, T6);
|
||||
SET(c, d, a, b, 6, 17, T7);
|
||||
SET(b, c, d, a, 7, 22, T8);
|
||||
SET(a, b, c, d, 8, 7, T9);
|
||||
SET(d, a, b, c, 9, 12, T10);
|
||||
SET(c, d, a, b, 10, 17, T11);
|
||||
SET(b, c, d, a, 11, 22, T12);
|
||||
SET(a, b, c, d, 12, 7, T13);
|
||||
SET(d, a, b, c, 13, 12, T14);
|
||||
SET(c, d, a, b, 14, 17, T15);
|
||||
SET(b, c, d, a, 15, 22, T16);
|
||||
#undef SET
|
||||
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + G(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, T17);
|
||||
SET(d, a, b, c, 6, 9, T18);
|
||||
SET(c, d, a, b, 11, 14, T19);
|
||||
SET(b, c, d, a, 0, 20, T20);
|
||||
SET(a, b, c, d, 5, 5, T21);
|
||||
SET(d, a, b, c, 10, 9, T22);
|
||||
SET(c, d, a, b, 15, 14, T23);
|
||||
SET(b, c, d, a, 4, 20, T24);
|
||||
SET(a, b, c, d, 9, 5, T25);
|
||||
SET(d, a, b, c, 14, 9, T26);
|
||||
SET(c, d, a, b, 3, 14, T27);
|
||||
SET(b, c, d, a, 8, 20, T28);
|
||||
SET(a, b, c, d, 13, 5, T29);
|
||||
SET(d, a, b, c, 2, 9, T30);
|
||||
SET(c, d, a, b, 7, 14, T31);
|
||||
SET(b, c, d, a, 12, 20, T32);
|
||||
#undef SET
|
||||
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + H(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, T33);
|
||||
SET(d, a, b, c, 8, 11, T34);
|
||||
SET(c, d, a, b, 11, 16, T35);
|
||||
SET(b, c, d, a, 14, 23, T36);
|
||||
SET(a, b, c, d, 1, 4, T37);
|
||||
SET(d, a, b, c, 4, 11, T38);
|
||||
SET(c, d, a, b, 7, 16, T39);
|
||||
SET(b, c, d, a, 10, 23, T40);
|
||||
SET(a, b, c, d, 13, 4, T41);
|
||||
SET(d, a, b, c, 0, 11, T42);
|
||||
SET(c, d, a, b, 3, 16, T43);
|
||||
SET(b, c, d, a, 6, 23, T44);
|
||||
SET(a, b, c, d, 9, 4, T45);
|
||||
SET(d, a, b, c, 12, 11, T46);
|
||||
SET(c, d, a, b, 15, 16, T47);
|
||||
SET(b, c, d, a, 2, 23, T48);
|
||||
#undef SET
|
||||
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + I(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, T49);
|
||||
SET(d, a, b, c, 7, 10, T50);
|
||||
SET(c, d, a, b, 14, 15, T51);
|
||||
SET(b, c, d, a, 5, 21, T52);
|
||||
SET(a, b, c, d, 12, 6, T53);
|
||||
SET(d, a, b, c, 3, 10, T54);
|
||||
SET(c, d, a, b, 10, 15, T55);
|
||||
SET(b, c, d, a, 1, 21, T56);
|
||||
SET(a, b, c, d, 8, 6, T57);
|
||||
SET(d, a, b, c, 15, 10, T58);
|
||||
SET(c, d, a, b, 6, 15, T59);
|
||||
SET(b, c, d, a, 13, 21, T60);
|
||||
SET(a, b, c, d, 4, 6, T61);
|
||||
SET(d, a, b, c, 11, 10, T62);
|
||||
SET(c, d, a, b, 2, 15, T63);
|
||||
SET(b, c, d, a, 9, 21, T64);
|
||||
#undef SET
|
||||
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
pms->abcd[0] += a;
|
||||
pms->abcd[1] += b;
|
||||
pms->abcd[2] += c;
|
||||
pms->abcd[3] += d;
|
||||
}
|
||||
|
||||
void
|
||||
md5_init(md5_state_t *pms)
|
||||
{
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
|
||||
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void
|
||||
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
|
||||
{
|
||||
const md5_byte_t *p = data;
|
||||
int left = nbytes;
|
||||
int offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
|
||||
memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
void
|
||||
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
|
||||
{
|
||||
static const md5_byte_t pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
ghost@aladdin.com
|
||||
|
||||
*/
|
||||
/* $Id: md5.h,v 1.2 2007/12/24 05:58:37 lilyco Exp $ */
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
copyrighted.
|
||||
|
||||
The original and principal author of md5.h is L. Peter Deutsch
|
||||
<ghost@aladdin.com>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
#ifndef md5_INCLUDED
|
||||
# define md5_INCLUDED
|
||||
|
||||
/*
|
||||
* This package supports both compile-time and run-time determination of CPU
|
||||
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
|
||||
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
|
||||
* defined as non-zero, the code will be compiled to run only on big-endian
|
||||
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
|
||||
* run on either big- or little-endian CPUs, but will run slightly less
|
||||
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
|
||||
*/
|
||||
|
||||
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
|
||||
/* Define the state of the MD5 Algorithm. */
|
||||
typedef struct md5_state_s {
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Initialize the algorithm. */
|
||||
void md5_init(md5_state_t *pms);
|
||||
|
||||
/* Append a string to the message. */
|
||||
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
|
||||
|
||||
/* Finish the message and return the digest. */
|
||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* md5_INCLUDED */
|
|
@ -0,0 +1,411 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 02/12/2011
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Packet Header |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// ~ Data / Control Information Field ~
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |0| Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |ff |o| Message Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Time Stamp |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Destination Socket ID |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// bit 0:
|
||||
// 0: Data Packet
|
||||
// 1: Control Packet
|
||||
// bit ff:
|
||||
// 11: solo message packet
|
||||
// 10: first packet of a message
|
||||
// 01: last packet of a message
|
||||
// bit o:
|
||||
// 0: in order delivery not required
|
||||
// 1: in order delivery required
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |1| Type | Reserved |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Additional Info |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Time Stamp |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Destination Socket ID |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// bit 1-15:
|
||||
// 0: Protocol Connection Handshake
|
||||
// Add. Info: Undefined
|
||||
// Control Info: Handshake information (see CHandShake)
|
||||
// 1: Keep-alive
|
||||
// Add. Info: Undefined
|
||||
// Control Info: None
|
||||
// 2: Acknowledgement (ACK)
|
||||
// Add. Info: The ACK sequence number
|
||||
// Control Info: The sequence number to which (but not include) all the previous packets have beed received
|
||||
// Optional: RTT
|
||||
// RTT Variance
|
||||
// available receiver buffer size (in bytes)
|
||||
// advertised flow window size (number of packets)
|
||||
// estimated bandwidth (number of packets per second)
|
||||
// 3: Negative Acknowledgement (NAK)
|
||||
// Add. Info: Undefined
|
||||
// Control Info: Loss list (see loss list coding below)
|
||||
// 4: Congestion/Delay Warning
|
||||
// Add. Info: Undefined
|
||||
// Control Info: None
|
||||
// 5: Shutdown
|
||||
// Add. Info: Undefined
|
||||
// Control Info: None
|
||||
// 6: Acknowledgement of Acknowledement (ACK-square)
|
||||
// Add. Info: The ACK sequence number
|
||||
// Control Info: None
|
||||
// 7: Message Drop Request
|
||||
// Add. Info: Message ID
|
||||
// Control Info: first sequence number of the message
|
||||
// last seqeunce number of the message
|
||||
// 8: Error Signal from the Peer Side
|
||||
// Add. Info: Error code
|
||||
// Control Info: None
|
||||
// 0x7FFF: Explained by bits 16 - 31
|
||||
//
|
||||
// bit 16 - 31:
|
||||
// This space is used for future expansion or user defined control packets.
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |1| Sequence Number a (first) |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |0| Sequence Number b (last) |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |0| Sequence Number (single) |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// Loss List Field Coding:
|
||||
// For any consectutive lost seqeunce numbers that the differnece between
|
||||
// the last and first is more than 1, only record the first (a) and the
|
||||
// the last (b) sequence numbers in the loss list field, and modify the
|
||||
// the first bit of a to 1.
|
||||
// For any single loss or consectutive loss less than 2 packets, use
|
||||
// the original sequence numbers in the field.
|
||||
|
||||
|
||||
#include <cstring>
|
||||
#include "packet.h"
|
||||
|
||||
|
||||
const int CPacket::m_iPktHdrSize = 16;
|
||||
const int CHandShake::m_iContentSize = 48;
|
||||
|
||||
|
||||
// Set up the aliases in the constructure
|
||||
CPacket::CPacket():
|
||||
m_iSeqNo((int32_t&)(m_nHeader[0])),
|
||||
m_iMsgNo((int32_t&)(m_nHeader[1])),
|
||||
m_iTimeStamp((int32_t&)(m_nHeader[2])),
|
||||
m_iID((int32_t&)(m_nHeader[3])),
|
||||
m_pcData((char*&)(m_PacketVector[1].iov_base)),
|
||||
__pad()
|
||||
{
|
||||
for (int i = 0; i < 4; ++ i)
|
||||
m_nHeader[i] = 0;
|
||||
m_PacketVector[0].iov_base = (char *)m_nHeader;
|
||||
m_PacketVector[0].iov_len = CPacket::m_iPktHdrSize;
|
||||
m_PacketVector[1].iov_base = NULL;
|
||||
m_PacketVector[1].iov_len = 0;
|
||||
}
|
||||
|
||||
CPacket::~CPacket()
|
||||
{
|
||||
}
|
||||
|
||||
int CPacket::getLength() const
|
||||
{
|
||||
return m_PacketVector[1].iov_len;
|
||||
}
|
||||
|
||||
void CPacket::setLength(int len)
|
||||
{
|
||||
m_PacketVector[1].iov_len = len;
|
||||
}
|
||||
|
||||
void CPacket::pack(int pkttype, void* lparam, void* rparam, int size)
|
||||
{
|
||||
// Set (bit-0 = 1) and (bit-1~15 = type)
|
||||
m_nHeader[0] = 0x80000000 | (pkttype << 16);
|
||||
|
||||
// Set additional information and control information field
|
||||
switch (pkttype)
|
||||
{
|
||||
case 2: //0010 - Acknowledgement (ACK)
|
||||
// ACK packet seq. no.
|
||||
if (NULL != lparam)
|
||||
m_nHeader[1] = *(int32_t *)lparam;
|
||||
|
||||
// data ACK seq. no.
|
||||
// optional: RTT (microsends), RTT variance (microseconds) advertised flow window size (packets), and estimated link capacity (packets per second)
|
||||
m_PacketVector[1].iov_base = (char *)rparam;
|
||||
m_PacketVector[1].iov_len = size;
|
||||
|
||||
break;
|
||||
|
||||
case 6: //0110 - Acknowledgement of Acknowledgement (ACK-2)
|
||||
// ACK packet seq. no.
|
||||
m_nHeader[1] = *(int32_t *)lparam;
|
||||
|
||||
// control info field should be none
|
||||
// but "writev" does not allow this
|
||||
m_PacketVector[1].iov_base = (char *)&__pad; //NULL;
|
||||
m_PacketVector[1].iov_len = 4; //0;
|
||||
|
||||
break;
|
||||
|
||||
case 3: //0011 - Loss Report (NAK)
|
||||
// loss list
|
||||
m_PacketVector[1].iov_base = (char *)rparam;
|
||||
m_PacketVector[1].iov_len = size;
|
||||
|
||||
break;
|
||||
|
||||
case 4: //0100 - Congestion Warning
|
||||
// control info field should be none
|
||||
// but "writev" does not allow this
|
||||
m_PacketVector[1].iov_base = (char *)&__pad; //NULL;
|
||||
m_PacketVector[1].iov_len = 4; //0;
|
||||
|
||||
break;
|
||||
|
||||
case 1: //0001 - Keep-alive
|
||||
// control info field should be none
|
||||
// but "writev" does not allow this
|
||||
m_PacketVector[1].iov_base = (char *)&__pad; //NULL;
|
||||
m_PacketVector[1].iov_len = 4; //0;
|
||||
|
||||
break;
|
||||
|
||||
case 0: //0000 - Handshake
|
||||
// control info filed is handshake info
|
||||
m_PacketVector[1].iov_base = (char *)rparam;
|
||||
m_PacketVector[1].iov_len = size; //sizeof(CHandShake);
|
||||
|
||||
break;
|
||||
|
||||
case 5: //0101 - Shutdown
|
||||
// control info field should be none
|
||||
// but "writev" does not allow this
|
||||
m_PacketVector[1].iov_base = (char *)&__pad; //NULL;
|
||||
m_PacketVector[1].iov_len = 4; //0;
|
||||
|
||||
break;
|
||||
|
||||
case 7: //0111 - Message Drop Request
|
||||
// msg id
|
||||
m_nHeader[1] = *(int32_t *)lparam;
|
||||
|
||||
//first seq no, last seq no
|
||||
m_PacketVector[1].iov_base = (char *)rparam;
|
||||
m_PacketVector[1].iov_len = size;
|
||||
|
||||
break;
|
||||
|
||||
case 8: //1000 - Error Signal from the Peer Side
|
||||
// Error type
|
||||
m_nHeader[1] = *(int32_t *)lparam;
|
||||
|
||||
// control info field should be none
|
||||
// but "writev" does not allow this
|
||||
m_PacketVector[1].iov_base = (char *)&__pad; //NULL;
|
||||
m_PacketVector[1].iov_len = 4; //0;
|
||||
|
||||
break;
|
||||
|
||||
case 32767: //0x7FFF - Reserved for user defined control packets
|
||||
// for extended control packet
|
||||
// "lparam" contains the extended type information for bit 16 - 31
|
||||
// "rparam" is the control information
|
||||
m_nHeader[0] |= *(int32_t *)lparam;
|
||||
|
||||
if (NULL != rparam)
|
||||
{
|
||||
m_PacketVector[1].iov_base = (char *)rparam;
|
||||
m_PacketVector[1].iov_len = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PacketVector[1].iov_base = (char *)&__pad;
|
||||
m_PacketVector[1].iov_len = 4;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iovec* CPacket::getPacketVector()
|
||||
{
|
||||
return m_PacketVector;
|
||||
}
|
||||
|
||||
int CPacket::getFlag() const
|
||||
{
|
||||
// read bit 0
|
||||
return m_nHeader[0] >> 31;
|
||||
}
|
||||
|
||||
int CPacket::getType() const
|
||||
{
|
||||
// read bit 1~15
|
||||
return (m_nHeader[0] >> 16) & 0x00007FFF;
|
||||
}
|
||||
|
||||
int CPacket::getExtendedType() const
|
||||
{
|
||||
// read bit 16~31
|
||||
return m_nHeader[0] & 0x0000FFFF;
|
||||
}
|
||||
|
||||
int32_t CPacket::getAckSeqNo() const
|
||||
{
|
||||
// read additional information field
|
||||
return m_nHeader[1];
|
||||
}
|
||||
|
||||
int CPacket::getMsgBoundary() const
|
||||
{
|
||||
// read [1] bit 0~1
|
||||
return m_nHeader[1] >> 30;
|
||||
}
|
||||
|
||||
bool CPacket::getMsgOrderFlag() const
|
||||
{
|
||||
// read [1] bit 2
|
||||
return (1 == ((m_nHeader[1] >> 29) & 1));
|
||||
}
|
||||
|
||||
int32_t CPacket::getMsgSeq() const
|
||||
{
|
||||
// read [1] bit 3~31
|
||||
return m_nHeader[1] & 0x1FFFFFFF;
|
||||
}
|
||||
|
||||
CPacket* CPacket::clone() const
|
||||
{
|
||||
CPacket* pkt = new CPacket;
|
||||
memcpy(pkt->m_nHeader, m_nHeader, m_iPktHdrSize);
|
||||
pkt->m_pcData = new char[m_PacketVector[1].iov_len];
|
||||
memcpy(pkt->m_pcData, m_pcData, m_PacketVector[1].iov_len);
|
||||
pkt->m_PacketVector[1].iov_len = m_PacketVector[1].iov_len;
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
CHandShake::CHandShake():
|
||||
m_iVersion(0),
|
||||
m_iType(0),
|
||||
m_iISN(0),
|
||||
m_iMSS(0),
|
||||
m_iFlightFlagSize(0),
|
||||
m_iReqType(0),
|
||||
m_iID(0),
|
||||
m_iCookie(0)
|
||||
{
|
||||
for (int i = 0; i < 4; ++ i)
|
||||
m_piPeerIP[i] = 0;
|
||||
}
|
||||
|
||||
int CHandShake::serialize(char* buf, int& size)
|
||||
{
|
||||
if (size < m_iContentSize)
|
||||
return -1;
|
||||
|
||||
int32_t* p = (int32_t*)buf;
|
||||
*p++ = m_iVersion;
|
||||
*p++ = m_iType;
|
||||
*p++ = m_iISN;
|
||||
*p++ = m_iMSS;
|
||||
*p++ = m_iFlightFlagSize;
|
||||
*p++ = m_iReqType;
|
||||
*p++ = m_iID;
|
||||
*p++ = m_iCookie;
|
||||
for (int i = 0; i < 4; ++ i)
|
||||
*p++ = m_piPeerIP[i];
|
||||
|
||||
size = m_iContentSize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CHandShake::deserialize(const char* buf, int size)
|
||||
{
|
||||
if (size < m_iContentSize)
|
||||
return -1;
|
||||
|
||||
int32_t* p = (int32_t*)buf;
|
||||
m_iVersion = *p++;
|
||||
m_iType = *p++;
|
||||
m_iISN = *p++;
|
||||
m_iMSS = *p++;
|
||||
m_iFlightFlagSize = *p++;
|
||||
m_iReqType = *p++;
|
||||
m_iID = *p++;
|
||||
m_iCookie = *p++;
|
||||
for (int i = 0; i < 4; ++ i)
|
||||
m_piPeerIP[i] = *p++;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/02/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_PACKET_H__
|
||||
#define __UDT_PACKET_H__
|
||||
|
||||
|
||||
#include "udt.h"
|
||||
|
||||
#ifdef WINDOWS
|
||||
struct iovec
|
||||
{
|
||||
int iov_len;
|
||||
char* iov_base;
|
||||
};
|
||||
#endif
|
||||
|
||||
class CChannel;
|
||||
|
||||
class CPacket
|
||||
{
|
||||
friend class CChannel;
|
||||
friend class CSndQueue;
|
||||
friend class CRcvQueue;
|
||||
|
||||
public:
|
||||
int32_t& m_iSeqNo; // alias: sequence number
|
||||
int32_t& m_iMsgNo; // alias: message number
|
||||
int32_t& m_iTimeStamp; // alias: timestamp
|
||||
int32_t& m_iID; // alias: socket ID
|
||||
char*& m_pcData; // alias: data/control information
|
||||
|
||||
static const int m_iPktHdrSize; // packet header size
|
||||
|
||||
public:
|
||||
CPacket();
|
||||
~CPacket();
|
||||
|
||||
// Functionality:
|
||||
// Get the payload or the control information field length.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// the payload or the control information field length.
|
||||
|
||||
int getLength() const;
|
||||
|
||||
// Functionality:
|
||||
// Set the payload or the control information field length.
|
||||
// Parameters:
|
||||
// 0) [in] len: the payload or the control information field length.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void setLength(int len);
|
||||
|
||||
// Functionality:
|
||||
// Pack a Control packet.
|
||||
// Parameters:
|
||||
// 0) [in] pkttype: packet type filed.
|
||||
// 1) [in] lparam: pointer to the first data structure, explained by the packet type.
|
||||
// 2) [in] rparam: pointer to the second data structure, explained by the packet type.
|
||||
// 3) [in] size: size of rparam, in number of bytes;
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void pack(int pkttype, void* lparam = NULL, void* rparam = NULL, int size = 0);
|
||||
|
||||
// Functionality:
|
||||
// Read the packet vector.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Pointer to the packet vector.
|
||||
|
||||
iovec* getPacketVector();
|
||||
|
||||
// Functionality:
|
||||
// Read the packet flag.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// packet flag (0 or 1).
|
||||
|
||||
int getFlag() const;
|
||||
|
||||
// Functionality:
|
||||
// Read the packet type.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// packet type filed (000 ~ 111).
|
||||
|
||||
int getType() const;
|
||||
|
||||
// Functionality:
|
||||
// Read the extended packet type.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// extended packet type filed (0x000 ~ 0xFFF).
|
||||
|
||||
int getExtendedType() const;
|
||||
|
||||
// Functionality:
|
||||
// Read the ACK-2 seq. no.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// packet header field (bit 16~31).
|
||||
|
||||
int32_t getAckSeqNo() const;
|
||||
|
||||
// Functionality:
|
||||
// Read the message boundary flag bit.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// packet header field [1] (bit 0~1).
|
||||
|
||||
int getMsgBoundary() const;
|
||||
|
||||
// Functionality:
|
||||
// Read the message inorder delivery flag bit.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// packet header field [1] (bit 2).
|
||||
|
||||
bool getMsgOrderFlag() const;
|
||||
|
||||
// Functionality:
|
||||
// Read the message sequence number.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// packet header field [1] (bit 3~31).
|
||||
|
||||
int32_t getMsgSeq() const;
|
||||
|
||||
// Functionality:
|
||||
// Clone this packet.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Pointer to the new packet.
|
||||
|
||||
CPacket* clone() const;
|
||||
|
||||
protected:
|
||||
uint32_t m_nHeader[4]; // The 128-bit header field
|
||||
iovec m_PacketVector[2]; // The 2-demension vector of UDT packet [header, data]
|
||||
|
||||
int32_t __pad;
|
||||
|
||||
protected:
|
||||
CPacket& operator=(const CPacket&);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CHandShake
|
||||
{
|
||||
public:
|
||||
CHandShake();
|
||||
|
||||
int serialize(char* buf, int& size);
|
||||
int deserialize(const char* buf, int size);
|
||||
|
||||
public:
|
||||
static const int m_iContentSize; // Size of hand shake data
|
||||
|
||||
public:
|
||||
int32_t m_iVersion; // UDT version
|
||||
int32_t m_iType; // UDT socket type
|
||||
int32_t m_iISN; // random initial sequence number
|
||||
int32_t m_iMSS; // maximum segment size
|
||||
int32_t m_iFlightFlagSize; // flow control window size
|
||||
int32_t m_iReqType; // connection request type: 1: regular connection request, 0: rendezvous connection request, -1/-2: response
|
||||
int32_t m_iID; // socket ID
|
||||
int32_t m_iCookie; // cookie
|
||||
uint32_t m_piPeerIP[4]; // The IP address that the peer's UDP port is bound to
|
||||
};
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,527 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/12/2011
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef __UDT_QUEUE_H__
|
||||
#define __UDT_QUEUE_H__
|
||||
|
||||
#include "channel.h"
|
||||
#include "packet.h"
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "udtCommon.h"
|
||||
|
||||
class CUDT;
|
||||
|
||||
struct CUnit
|
||||
{
|
||||
CPacket m_Packet; // packet
|
||||
int m_iFlag; // 0: free, 1: occupied, 2: msg read but not freed (out-of-order), 3: msg dropped
|
||||
};
|
||||
|
||||
class CUnitQueue
|
||||
{
|
||||
friend class CRcvQueue;
|
||||
friend class CRcvBuffer;
|
||||
|
||||
public:
|
||||
CUnitQueue();
|
||||
~CUnitQueue();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Initialize the unit queue.
|
||||
// Parameters:
|
||||
// 1) [in] size: queue size
|
||||
// 2) [in] mss: maximum segament size
|
||||
// 3) [in] version: IP version
|
||||
// Returned value:
|
||||
// 0: success, -1: failure.
|
||||
|
||||
int init(int size, int mss, int version);
|
||||
|
||||
// Functionality:
|
||||
// Increase (double) the unit queue size.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// 0: success, -1: failure.
|
||||
|
||||
int increase();
|
||||
|
||||
// Functionality:
|
||||
// Decrease (halve) the unit queue size.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// 0: success, -1: failure.
|
||||
|
||||
int shrink();
|
||||
|
||||
// Functionality:
|
||||
// find an available unit for incoming packet.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Pointer to the available unit, NULL if not found.
|
||||
|
||||
CUnit* getNextAvailUnit();
|
||||
|
||||
private:
|
||||
struct CQEntry
|
||||
{
|
||||
CUnit* m_pUnit; // unit queue
|
||||
char* m_pBuffer; // data buffer
|
||||
int m_iSize; // size of each queue
|
||||
|
||||
CQEntry* m_pNext;
|
||||
}
|
||||
*m_pQEntry, // pointer to the first unit queue
|
||||
*m_pCurrQueue, // pointer to the current available queue
|
||||
*m_pLastQueue; // pointer to the last unit queue
|
||||
|
||||
CUnit* m_pAvailUnit; // recent available unit
|
||||
|
||||
int m_iSize; // total size of the unit queue, in number of packets
|
||||
int m_iCount; // total number of valid packets in the queue
|
||||
|
||||
int m_iMSS; // unit buffer size
|
||||
int m_iIPversion; // IP version
|
||||
|
||||
private:
|
||||
CUnitQueue(const CUnitQueue&);
|
||||
CUnitQueue& operator=(const CUnitQueue&);
|
||||
};
|
||||
|
||||
struct CSNode
|
||||
{
|
||||
CUDT* m_pUDT; // Pointer to the instance of CUDT socket
|
||||
uint64_t m_llTimeStamp; // Time Stamp
|
||||
|
||||
int m_iHeapLoc; // location on the heap, -1 means not on the heap
|
||||
};
|
||||
|
||||
class CSndUList
|
||||
{
|
||||
friend class CSndQueue;
|
||||
|
||||
public:
|
||||
CSndUList();
|
||||
~CSndUList();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Insert a new UDT instance into the list.
|
||||
// Parameters:
|
||||
// 1) [in] ts: time stamp: next processing time
|
||||
// 2) [in] u: pointer to the UDT instance
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void insert(int64_t ts, const CUDT* u);
|
||||
|
||||
// Functionality:
|
||||
// Update the timestamp of the UDT instance on the list.
|
||||
// Parameters:
|
||||
// 1) [in] u: pointer to the UDT instance
|
||||
// 2) [in] resechedule: if the timestampe shoudl be rescheduled
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void update(const CUDT* u, bool reschedule = true);
|
||||
|
||||
// Functionality:
|
||||
// Retrieve the next packet and peer address from the first entry, and reschedule it in the queue.
|
||||
// Parameters:
|
||||
// 0) [out] addr: destination address of the next packet
|
||||
// 1) [out] pkt: the next packet to be sent
|
||||
// Returned value:
|
||||
// 1 if successfully retrieved, -1 if no packet found.
|
||||
|
||||
int pop(sockaddr*& addr, CPacket& pkt);
|
||||
|
||||
// Functionality:
|
||||
// Remove UDT instance from the list.
|
||||
// Parameters:
|
||||
// 1) [in] u: pointer to the UDT instance
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void remove(const CUDT* u);
|
||||
|
||||
// Functionality:
|
||||
// Retrieve the next scheduled processing time.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Scheduled processing time of the first UDT socket in the list.
|
||||
|
||||
uint64_t getNextProcTime();
|
||||
|
||||
private:
|
||||
void insert_(int64_t ts, const CUDT* u);
|
||||
void remove_(const CUDT* u);
|
||||
|
||||
private:
|
||||
CSNode** m_pHeap; // The heap array
|
||||
int m_iArrayLength; // physical length of the array
|
||||
int m_iLastEntry; // position of last entry on the heap array
|
||||
|
||||
udt_pthread_mutex_t m_ListLock;
|
||||
|
||||
udt_pthread_mutex_t* m_pWindowLock;
|
||||
udt_pthread_cond_t* m_pWindowCond;
|
||||
|
||||
CTimer* m_pTimer;
|
||||
|
||||
private:
|
||||
CSndUList(const CSndUList&);
|
||||
CSndUList& operator=(const CSndUList&);
|
||||
};
|
||||
|
||||
struct CRNode
|
||||
{
|
||||
CUDT* m_pUDT; // Pointer to the instance of CUDT socket
|
||||
uint64_t m_llTimeStamp; // Time Stamp
|
||||
|
||||
CRNode* m_pPrev; // previous link
|
||||
CRNode* m_pNext; // next link
|
||||
|
||||
bool m_bOnList; // if the node is already on the list
|
||||
};
|
||||
|
||||
class CRcvUList
|
||||
{
|
||||
public:
|
||||
CRcvUList();
|
||||
~CRcvUList();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Insert a new UDT instance to the list.
|
||||
// Parameters:
|
||||
// 1) [in] u: pointer to the UDT instance
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void insert(const CUDT* u);
|
||||
|
||||
// Functionality:
|
||||
// Remove the UDT instance from the list.
|
||||
// Parameters:
|
||||
// 1) [in] u: pointer to the UDT instance
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void remove(const CUDT* u);
|
||||
|
||||
// Functionality:
|
||||
// Move the UDT instance to the end of the list, if it already exists; otherwise, do nothing.
|
||||
// Parameters:
|
||||
// 1) [in] u: pointer to the UDT instance
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void update(const CUDT* u);
|
||||
|
||||
public:
|
||||
CRNode* m_pUList; // the head node
|
||||
|
||||
private:
|
||||
CRNode* m_pLast; // the last node
|
||||
|
||||
private:
|
||||
CRcvUList(const CRcvUList&);
|
||||
CRcvUList& operator=(const CRcvUList&);
|
||||
};
|
||||
|
||||
class CHash
|
||||
{
|
||||
public:
|
||||
CHash();
|
||||
~CHash();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Initialize the hash table.
|
||||
// Parameters:
|
||||
// 1) [in] size: hash table size
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void init(int size);
|
||||
|
||||
// Functionality:
|
||||
// Look for a UDT instance from the hash table.
|
||||
// Parameters:
|
||||
// 1) [in] id: socket ID
|
||||
// Returned value:
|
||||
// Pointer to a UDT instance, or NULL if not found.
|
||||
|
||||
CUDT* lookup(int32_t id);
|
||||
|
||||
// Functionality:
|
||||
// Insert an entry to the hash table.
|
||||
// Parameters:
|
||||
// 1) [in] id: socket ID
|
||||
// 2) [in] u: pointer to the UDT instance
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void insert(int32_t id, CUDT* u);
|
||||
|
||||
// Functionality:
|
||||
// Remove an entry from the hash table.
|
||||
// Parameters:
|
||||
// 1) [in] id: socket ID
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void remove(int32_t id);
|
||||
|
||||
private:
|
||||
struct CBucket
|
||||
{
|
||||
int32_t m_iID; // Socket ID
|
||||
CUDT* m_pUDT; // Socket instance
|
||||
|
||||
CBucket* m_pNext; // next bucket
|
||||
} **m_pBucket; // list of buckets (the hash table)
|
||||
|
||||
int m_iHashSize; // size of hash table
|
||||
|
||||
private:
|
||||
CHash(const CHash&);
|
||||
CHash& operator=(const CHash&);
|
||||
};
|
||||
|
||||
class CRendezvousQueue
|
||||
{
|
||||
public:
|
||||
CRendezvousQueue();
|
||||
~CRendezvousQueue();
|
||||
|
||||
public:
|
||||
void insert(const UDTSOCKET& id, CUDT* u, int ipv, const sockaddr* addr, uint64_t ttl);
|
||||
void remove(const UDTSOCKET& id);
|
||||
CUDT* retrieve(const sockaddr* addr, UDTSOCKET& id);
|
||||
|
||||
void updateConnStatus();
|
||||
|
||||
private:
|
||||
struct CRL
|
||||
{
|
||||
UDTSOCKET m_iID; // UDT socket ID (self)
|
||||
CUDT* m_pUDT; // UDT instance
|
||||
int m_iIPversion; // IP version
|
||||
sockaddr* m_pPeerAddr; // UDT sonnection peer address
|
||||
uint64_t m_ullTTL; // the time that this request expires
|
||||
};
|
||||
std::list<CRL> m_lRendezvousID; // The sockets currently in rendezvous mode
|
||||
|
||||
udt_pthread_mutex_t m_RIDVectorLock;
|
||||
};
|
||||
|
||||
class CSndQueue
|
||||
{
|
||||
friend class CUDT;
|
||||
friend class CUDTUnited;
|
||||
|
||||
public:
|
||||
CSndQueue();
|
||||
~CSndQueue();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Initialize the sending queue.
|
||||
// Parameters:
|
||||
// 1) [in] c: UDP channel to be associated to the queue
|
||||
// 2) [in] t: Timer
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void init(CChannel* c, CTimer* t);
|
||||
|
||||
// Functionality:
|
||||
// Send out a packet to a given address.
|
||||
// Parameters:
|
||||
// 1) [in] addr: destination address
|
||||
// 2) [in] packet: packet to be sent out
|
||||
// Returned value:
|
||||
// Size of data sent out.
|
||||
|
||||
int sendto(const sockaddr* addr, CPacket& packet);
|
||||
|
||||
private:
|
||||
#ifndef WINDOWS
|
||||
static void* worker(void* param);
|
||||
#else
|
||||
static DWORD WINAPI worker(LPVOID param);
|
||||
#endif
|
||||
|
||||
udt_pthread_t m_WorkerThread;
|
||||
|
||||
private:
|
||||
CSndUList* m_pSndUList; // List of UDT instances for data sending
|
||||
CChannel* m_pChannel; // The UDP channel for data sending
|
||||
CTimer* m_pTimer; // Timing facility
|
||||
|
||||
udt_pthread_mutex_t m_WindowLock;
|
||||
udt_pthread_cond_t m_WindowCond;
|
||||
|
||||
volatile bool m_bClosing; // closing the worker
|
||||
udt_pthread_cond_t m_ExitCond;
|
||||
|
||||
private:
|
||||
CSndQueue(const CSndQueue&);
|
||||
CSndQueue& operator=(const CSndQueue&);
|
||||
};
|
||||
|
||||
class CRcvQueue
|
||||
{
|
||||
friend class CUDT;
|
||||
friend class CUDTUnited;
|
||||
|
||||
public:
|
||||
CRcvQueue();
|
||||
~CRcvQueue();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Initialize the receiving queue.
|
||||
// Parameters:
|
||||
// 1) [in] size: queue size
|
||||
// 2) [in] mss: maximum packet size
|
||||
// 3) [in] version: IP version
|
||||
// 4) [in] hsize: hash table size
|
||||
// 5) [in] c: UDP channel to be associated to the queue
|
||||
// 6) [in] t: timer
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void init(int size, int payload, int version, int hsize, CChannel* c, CTimer* t);
|
||||
|
||||
// Functionality:
|
||||
// Read a packet for a specific UDT socket id.
|
||||
// Parameters:
|
||||
// 1) [in] id: Socket ID
|
||||
// 2) [out] packet: received packet
|
||||
// Returned value:
|
||||
// Data size of the packet
|
||||
|
||||
int recvfrom(int32_t id, CPacket& packet);
|
||||
|
||||
private:
|
||||
#ifndef WINDOWS
|
||||
static void* worker(void* param);
|
||||
#else
|
||||
static DWORD WINAPI worker(LPVOID param);
|
||||
#endif
|
||||
|
||||
udt_pthread_t m_WorkerThread;
|
||||
|
||||
private:
|
||||
CUnitQueue m_UnitQueue; // The received packet queue
|
||||
|
||||
CRcvUList* m_pRcvUList; // List of UDT instances that will read packets from the queue
|
||||
CHash* m_pHash; // Hash table for UDT socket looking up
|
||||
CChannel* m_pChannel; // UDP channel for receving packets
|
||||
CTimer* m_pTimer; // shared timer with the snd queue
|
||||
|
||||
int m_iPayloadSize; // packet payload size
|
||||
|
||||
volatile bool m_bClosing; // closing the workder
|
||||
udt_pthread_cond_t m_ExitCond;
|
||||
|
||||
private:
|
||||
int setListener(CUDT* u);
|
||||
void removeListener(const CUDT* u);
|
||||
|
||||
void registerConnector(const UDTSOCKET& id, CUDT* u, int ipv, const sockaddr* addr, uint64_t ttl);
|
||||
void removeConnector(const UDTSOCKET& id);
|
||||
|
||||
void setNewEntry(CUDT* u);
|
||||
bool ifNewEntry();
|
||||
CUDT* getNewEntry();
|
||||
|
||||
void storePkt(int32_t id, CPacket* pkt);
|
||||
|
||||
private:
|
||||
udt_pthread_mutex_t m_LSLock;
|
||||
CUDT* m_pListener; // pointer to the (unique, if any) listening UDT entity
|
||||
CRendezvousQueue* m_pRendezvousQueue; // The list of sockets in rendezvous mode
|
||||
|
||||
std::vector<CUDT*> m_vNewEntry; // newly added entries, to be inserted
|
||||
udt_pthread_mutex_t m_IDLock;
|
||||
|
||||
std::map<int32_t, std::queue<CPacket*> > m_mBuffer; // temporary buffer for rendezvous connection request
|
||||
udt_pthread_mutex_t m_PassLock;
|
||||
udt_pthread_cond_t m_PassCond;
|
||||
|
||||
private:
|
||||
CRcvQueue(const CRcvQueue&);
|
||||
CRcvQueue& operator=(const CRcvQueue&);
|
||||
};
|
||||
|
||||
struct CMultiplexer
|
||||
{
|
||||
CSndQueue* m_pSndQueue; // The sending queue
|
||||
CRcvQueue* m_pRcvQueue; // The receiving queue
|
||||
CChannel* m_pChannel; // The UDP channel for sending and receiving
|
||||
CTimer* m_pTimer; // The timer
|
||||
|
||||
int m_iPort; // The UDP port number of this multiplexer
|
||||
int m_iIPversion; // IP version
|
||||
int m_iMSS; // Maximum Segment Size
|
||||
int m_iRefCount; // number of UDT instances that are associated with this multiplexer
|
||||
bool m_bReusable; // if this one can be shared with others
|
||||
|
||||
int m_iID; // multiplexer ID
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,326 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/18/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_H__
|
||||
#define __UDT_H__
|
||||
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef WINDOWS
|
||||
typedef SOCKET SYSSOCKET;
|
||||
#define UDT_API
|
||||
#else
|
||||
typedef int SYSSOCKET;
|
||||
#define UDT_API __attribute__ ((visibility("default")))
|
||||
#endif
|
||||
|
||||
#define NO_BUSY_WAITING
|
||||
|
||||
typedef SYSSOCKET UDPSOCKET;
|
||||
typedef int UDTSOCKET;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef std::set<UDTSOCKET> ud_set;
|
||||
#define UD_CLR(u, uset) ((uset)->erase(u))
|
||||
#define UD_ISSET(u, uset) ((uset)->find(u) != (uset)->end())
|
||||
#define UD_SET(u, uset) ((uset)->insert(u))
|
||||
#define UD_ZERO(uset) ((uset)->clear())
|
||||
|
||||
enum EPOLLOpt
|
||||
{
|
||||
// this values are defined same as linux epoll.h
|
||||
// so that if system values are used by mistake, they should have the same effect
|
||||
UDT_EPOLL_IN = 0x1,
|
||||
UDT_EPOLL_OUT = 0x4,
|
||||
UDT_EPOLL_ERR = 0x8
|
||||
};
|
||||
|
||||
enum UDTSTATUS {INIT = 1, OPENED, LISTENING, CONNECTING, CONNECTED, BROKEN, CLOSING, CLOSED, NONEXIST};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum UDTOpt
|
||||
{
|
||||
UDT_MSS, // the Maximum Transfer Unit
|
||||
UDT_SNDSYN, // if sending is blocking
|
||||
UDT_RCVSYN, // if receiving is blocking
|
||||
UDT_CC, // custom congestion control algorithm
|
||||
UDT_FC, // Flight flag size (window size)
|
||||
UDT_SNDBUF, // maximum buffer in sending queue
|
||||
UDT_RCVBUF, // UDT receiving buffer size
|
||||
UDT_LINGER, // waiting for unsent data when closing
|
||||
UDP_SNDBUF, // UDP sending buffer size
|
||||
UDP_RCVBUF, // UDP receiving buffer size
|
||||
UDT_MAXMSG, // maximum datagram message size
|
||||
UDT_MSGTTL, // time-to-live of a datagram message
|
||||
UDT_RENDEZVOUS, // rendezvous connection mode
|
||||
UDT_SNDTIMEO, // send() timeout
|
||||
UDT_RCVTIMEO, // recv() timeout
|
||||
UDT_REUSEADDR, // reuse an existing port or create a new one
|
||||
UDT_MAXBW, // maximum bandwidth (bytes per second) that the connection can use
|
||||
UDT_STATE, // current socket state, see UDTSTATUS, read only
|
||||
UDT_EVENT, // current avalable events associated with the socket
|
||||
UDT_SNDDATA, // size of data in the sending buffer
|
||||
UDT_RCVDATA // size of data available for recv
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct CPerfMon
|
||||
{
|
||||
// global measurements
|
||||
int64_t msTimeStamp; // time since the UDT entity is started, in milliseconds
|
||||
int64_t pktSentTotal; // total number of sent data packets, including retransmissions
|
||||
int64_t pktRecvTotal; // total number of received packets
|
||||
int pktSndLossTotal; // total number of lost packets (sender side)
|
||||
int pktRcvLossTotal; // total number of lost packets (receiver side)
|
||||
int pktRetransTotal; // total number of retransmitted packets
|
||||
int pktSentACKTotal; // total number of sent ACK packets
|
||||
int pktRecvACKTotal; // total number of received ACK packets
|
||||
int pktSentNAKTotal; // total number of sent NAK packets
|
||||
int pktRecvNAKTotal; // total number of received NAK packets
|
||||
int64_t usSndDurationTotal; // total time duration when UDT is sending data (idle time exclusive)
|
||||
|
||||
// local measurements
|
||||
int64_t pktSent; // number of sent data packets, including retransmissions
|
||||
int64_t pktRecv; // number of received packets
|
||||
int pktSndLoss; // number of lost packets (sender side)
|
||||
int pktRcvLoss; // number of lost packets (receiver side)
|
||||
int pktRetrans; // number of retransmitted packets
|
||||
int pktSentACK; // number of sent ACK packets
|
||||
int pktRecvACK; // number of received ACK packets
|
||||
int pktSentNAK; // number of sent NAK packets
|
||||
int pktRecvNAK; // number of received NAK packets
|
||||
double mbpsSendRate; // sending rate in Mb/s
|
||||
double mbpsRecvRate; // receiving rate in Mb/s
|
||||
int64_t usSndDuration; // busy sending time (i.e., idle time exclusive)
|
||||
|
||||
// instant measurements
|
||||
double usPktSndPeriod; // packet sending period, in microseconds
|
||||
int pktFlowWindow; // flow window size, in number of packets
|
||||
int pktCongestionWindow; // congestion window size, in number of packets
|
||||
int pktFlightSize; // number of packets on flight
|
||||
double msRTT; // RTT, in milliseconds
|
||||
double mbpsBandwidth; // estimated bandwidth, in Mb/s
|
||||
int byteAvailSndBuf; // available UDT sender buffer size
|
||||
int byteAvailRcvBuf; // available UDT receiver buffer size
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class UDT_API CUDTException
|
||||
{
|
||||
public:
|
||||
CUDTException(int major = 0, int minor = 0, int err = -1);
|
||||
CUDTException(const CUDTException& e);
|
||||
virtual ~CUDTException();
|
||||
|
||||
// Functionality:
|
||||
// Get the description of the exception.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Text message for the exception description.
|
||||
|
||||
virtual const char* getErrorMessage();
|
||||
|
||||
// Functionality:
|
||||
// Get the system errno for the exception.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// errno.
|
||||
|
||||
virtual int getErrorCode() const;
|
||||
|
||||
// Functionality:
|
||||
// Clear the error code.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
virtual void clear();
|
||||
|
||||
private:
|
||||
int m_iMajor; // major exception categories
|
||||
|
||||
// 0: correct condition
|
||||
// 1: network setup exception
|
||||
// 2: network connection broken
|
||||
// 3: memory exception
|
||||
// 4: file exception
|
||||
// 5: method not supported
|
||||
// 6+: undefined error
|
||||
|
||||
int m_iMinor; // for specific error reasons
|
||||
int m_iErrno; // errno returned by the system if there is any
|
||||
std::string m_strMsg; // text error message
|
||||
|
||||
std::string m_strAPI; // the name of UDT function that returns the error
|
||||
std::string m_strDebug; // debug information, set to the original place that causes the error
|
||||
|
||||
public: // Error Code
|
||||
static const int SUCCESS;
|
||||
static const int ECONNSETUP;
|
||||
static const int ENOSERVER;
|
||||
static const int ECONNREJ;
|
||||
static const int ESOCKFAIL;
|
||||
static const int ESECFAIL;
|
||||
static const int ECONNFAIL;
|
||||
static const int ECONNLOST;
|
||||
static const int ENOCONN;
|
||||
static const int ERESOURCE;
|
||||
static const int ETHREAD;
|
||||
static const int ENOBUF;
|
||||
static const int EFILE;
|
||||
static const int EINVRDOFF;
|
||||
static const int ERDPERM;
|
||||
static const int EINVWROFF;
|
||||
static const int EWRPERM;
|
||||
static const int EINVOP;
|
||||
static const int EBOUNDSOCK;
|
||||
static const int ECONNSOCK;
|
||||
static const int EINVPARAM;
|
||||
static const int EINVSOCK;
|
||||
static const int EUNBOUNDSOCK;
|
||||
static const int ENOLISTEN;
|
||||
static const int ERDVNOSERV;
|
||||
static const int ERDVUNBOUND;
|
||||
static const int ESTREAMILL;
|
||||
static const int EDGRAMILL;
|
||||
static const int EDUPLISTEN;
|
||||
static const int ELARGEMSG;
|
||||
static const int EINVPOLLID;
|
||||
static const int EASYNCFAIL;
|
||||
static const int EASYNCSND;
|
||||
static const int EASYNCRCV;
|
||||
static const int ETIMEOUT;
|
||||
static const int EPEERERR;
|
||||
static const int EUNKNOWN;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// If you need to export these APIs to be used by a different language,
|
||||
// declare extern "C" for them, and add a "udt_" prefix to each API.
|
||||
// The following APIs: sendfile(), recvfile(), epoll_wait(), geterrormsg(),
|
||||
// include C++ specific feature, please use the corresponding sendfile2(), etc.
|
||||
|
||||
namespace UDT
|
||||
{
|
||||
|
||||
typedef CUDTException ERRORINFO;
|
||||
typedef UDTOpt SOCKOPT;
|
||||
typedef CPerfMon TRACEINFO;
|
||||
typedef ud_set UDSET;
|
||||
|
||||
UDT_API extern const UDTSOCKET INVALID_SOCK;
|
||||
#undef ERROR
|
||||
UDT_API extern const int ERROR;
|
||||
|
||||
UDT_API int startup();
|
||||
UDT_API int cleanup();
|
||||
UDT_API UDTSOCKET socket(int af, int type, int protocol);
|
||||
UDT_API int bind(UDTSOCKET u, const struct sockaddr* name, int namelen);
|
||||
UDT_API int bind2(UDTSOCKET u, UDPSOCKET udpsock);
|
||||
UDT_API int listen(UDTSOCKET u, int backlog);
|
||||
UDT_API UDTSOCKET accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen);
|
||||
UDT_API int connect(UDTSOCKET u, const struct sockaddr* name, int namelen);
|
||||
UDT_API int close(UDTSOCKET u);
|
||||
UDT_API int getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen);
|
||||
UDT_API int getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen);
|
||||
UDT_API int getsockopt(UDTSOCKET u, int level, SOCKOPT optname, void* optval, int* optlen);
|
||||
UDT_API int setsockopt(UDTSOCKET u, int level, SOCKOPT optname, const void* optval, int optlen);
|
||||
UDT_API int send(UDTSOCKET u, const char* buf, int len, int flags);
|
||||
UDT_API int recv(UDTSOCKET u, char* buf, int len, int flags);
|
||||
UDT_API int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl = -1, bool inorder = false);
|
||||
UDT_API int recvmsg(UDTSOCKET u, char* buf, int len);
|
||||
UDT_API int64_t sendfile(UDTSOCKET u, std::fstream& ifs, int64_t& offset, int64_t size, int block = 364000);
|
||||
UDT_API int64_t recvfile(UDTSOCKET u, std::fstream& ofs, int64_t& offset, int64_t size, int block = 7280000);
|
||||
UDT_API int64_t sendfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 364000);
|
||||
UDT_API int64_t recvfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 7280000);
|
||||
|
||||
// select and selectEX are DEPRECATED; please use epoll.
|
||||
UDT_API int select(int nfds, UDSET* readfds, UDSET* writefds, UDSET* exceptfds, const struct timeval* timeout);
|
||||
UDT_API int selectEx(const std::vector<UDTSOCKET>& fds, std::vector<UDTSOCKET>* readfds,
|
||||
std::vector<UDTSOCKET>* writefds, std::vector<UDTSOCKET>* exceptfds, int64_t msTimeOut);
|
||||
|
||||
// BARCHART
|
||||
UDT_API int epoll_update_usock(int eid, UDTSOCKET u, const int* events = NULL);
|
||||
// BARCHART
|
||||
UDT_API int epoll_verify_usock(int eid, UDTSOCKET u, int* events);
|
||||
|
||||
UDT_API int epoll_create();
|
||||
UDT_API int epoll_add_usock(int eid, UDTSOCKET u, const int* events = NULL);
|
||||
UDT_API int epoll_add_ssock(int eid, SYSSOCKET s, const int* events = NULL);
|
||||
UDT_API int epoll_remove_usock(int eid, UDTSOCKET u);
|
||||
UDT_API int epoll_remove_ssock(int eid, SYSSOCKET s);
|
||||
UDT_API int epoll_wait(int eid, std::set<UDTSOCKET>* readfds, std::set<UDTSOCKET>* writefds, int64_t msTimeOut,
|
||||
std::set<SYSSOCKET>* lrfds = NULL, std::set<SYSSOCKET>* wrfds = NULL);
|
||||
UDT_API int epoll_wait2(int eid, UDTSOCKET* readfds, int* rnum, UDTSOCKET* writefds, int* wnum, int64_t msTimeOut,
|
||||
SYSSOCKET* lrfds = NULL, int* lrnum = NULL, SYSSOCKET* lwfds = NULL, int* lwnum = NULL);
|
||||
UDT_API int epoll_release(int eid);
|
||||
UDT_API ERRORINFO& getlasterror();
|
||||
UDT_API int getlasterror_code();
|
||||
UDT_API const char* getlasterror_desc();
|
||||
UDT_API int perfmon(UDTSOCKET u, TRACEINFO* perf, bool clear = true);
|
||||
UDT_API UDTSTATUS getsockstate(UDTSOCKET u);
|
||||
|
||||
} // namespace UDT
|
||||
|
||||
#endif
|
|
@ -0,0 +1,759 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 07/25/2010
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <unistd.h>
|
||||
#ifdef MACOSX
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include "md5.h"
|
||||
#include "udtCommon.h"
|
||||
|
||||
bool CTimer::m_bUseMicroSecond = false;
|
||||
uint64_t CTimer::s_ullCPUFrequency = CTimer::readCPUFrequency();
|
||||
#ifndef WINDOWS
|
||||
udt_pthread_mutex_t CTimer::m_EventLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
udt_pthread_cond_t CTimer::m_EventCond = PTHREAD_COND_INITIALIZER;
|
||||
#else
|
||||
udt_pthread_mutex_t CTimer::m_EventLock = CreateMutex(NULL, false, NULL);
|
||||
udt_pthread_cond_t CTimer::m_EventCond = CreateEvent(NULL, false, false, NULL);
|
||||
#endif
|
||||
|
||||
CTimer::CTimer():
|
||||
m_ullSchedTime(),
|
||||
m_TickCond(),
|
||||
m_TickLock()
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_init(&m_TickLock, NULL);
|
||||
pthread_cond_init(&m_TickCond, NULL);
|
||||
#else
|
||||
m_TickLock = CreateMutex(NULL, false, NULL);
|
||||
m_TickCond = CreateEvent(NULL, false, false, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
CTimer::~CTimer()
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_destroy(&m_TickLock);
|
||||
pthread_cond_destroy(&m_TickCond);
|
||||
#else
|
||||
CloseHandle(m_TickLock);
|
||||
CloseHandle(m_TickCond);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CTimer::rdtsc(uint64_t &x)
|
||||
{
|
||||
if (m_bUseMicroSecond)
|
||||
{
|
||||
x = getTime();
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(LINUX) && defined(I386)
|
||||
uint32_t lval, hval;
|
||||
//asm volatile ("push %eax; push %ebx; push %ecx; push %edx");
|
||||
//asm volatile ("xor %eax, %eax; cpuid");
|
||||
asm volatile ("rdtsc" : "=a" (lval), "=d" (hval));
|
||||
//asm volatile ("pop %edx; pop %ecx; pop %ebx; pop %eax");
|
||||
x = hval;
|
||||
x = (x << 32) | lval;
|
||||
#elif defined(LINUX) && defined(AMD64)
|
||||
uint32_t lval, hval;
|
||||
asm ("rdtsc" : "=a" (lval), "=d" (hval));
|
||||
x = hval;
|
||||
x = (x << 32) | lval;
|
||||
#elif defined(WINDOWS)
|
||||
//HANDLE hCurThread = ::GetCurrentThread();
|
||||
//DWORD_PTR dwOldMask = ::SetThreadAffinityMask(hCurThread, 1);
|
||||
BOOL ret = QueryPerformanceCounter((LARGE_INTEGER *)&x);
|
||||
//SetThreadAffinityMask(hCurThread, dwOldMask);
|
||||
if (!ret)
|
||||
x = getTime() * s_ullCPUFrequency;
|
||||
#elif defined(MACOSX)
|
||||
x = mach_absolute_time();
|
||||
#else
|
||||
// use system call to read time clock for other archs
|
||||
x = getTime();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t CTimer::readCPUFrequency()
|
||||
{
|
||||
uint64_t frequency = 1; // 1 tick per microsecond.
|
||||
|
||||
#if defined(LINUX) && (defined(I386) || defined(AMD64))
|
||||
uint64_t t1, t2;
|
||||
|
||||
rdtsc(t1);
|
||||
timespec ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 100000000;
|
||||
nanosleep(&ts, NULL);
|
||||
rdtsc(t2);
|
||||
|
||||
// CPU clocks per microsecond
|
||||
frequency = (t2 - t1) / 100000;
|
||||
#elif defined(WINDOWS)
|
||||
int64_t ccf;
|
||||
if (QueryPerformanceFrequency((LARGE_INTEGER *)&ccf))
|
||||
frequency = ccf / 1000000;
|
||||
#elif defined(MACOSX)
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
frequency = info.denom * 1000ULL / info.numer;
|
||||
#endif
|
||||
|
||||
// Fall back to microsecond if the resolution is not high enough.
|
||||
if (frequency < 10)
|
||||
{
|
||||
frequency = 1;
|
||||
m_bUseMicroSecond = true;
|
||||
}
|
||||
return frequency;
|
||||
}
|
||||
|
||||
uint64_t CTimer::getCPUFrequency()
|
||||
{
|
||||
return s_ullCPUFrequency;
|
||||
}
|
||||
|
||||
void CTimer::sleep(uint64_t interval)
|
||||
{
|
||||
uint64_t t;
|
||||
rdtsc(t);
|
||||
|
||||
// sleep next "interval" time
|
||||
sleepto(t + interval);
|
||||
}
|
||||
|
||||
void CTimer::sleepto(uint64_t nexttime)
|
||||
{
|
||||
// Use class member such that the method can be interrupted by others
|
||||
m_ullSchedTime = nexttime;
|
||||
|
||||
uint64_t t;
|
||||
rdtsc(t);
|
||||
|
||||
while (t < m_ullSchedTime)
|
||||
{
|
||||
#ifndef NO_BUSY_WAITING
|
||||
#if defined(LINUX) && defined(I386)
|
||||
__asm__ volatile ("pause; rep; nop; nop; nop; nop; nop;");
|
||||
#elif defined(LINUX) && defined(AMD64)
|
||||
__asm__ volatile ("nop; nop; nop; nop; nop;");
|
||||
#endif
|
||||
#else
|
||||
#ifndef WINDOWS
|
||||
timeval now;
|
||||
timespec timeout;
|
||||
gettimeofday(&now, 0);
|
||||
if (now.tv_usec < 990000)
|
||||
{
|
||||
timeout.tv_sec = now.tv_sec;
|
||||
timeout.tv_nsec = (now.tv_usec + 10000) * 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout.tv_sec = now.tv_sec + 1;
|
||||
timeout.tv_nsec = (now.tv_usec + 10000 - 1000000) * 1000;
|
||||
}
|
||||
pthread_mutex_lock(&m_TickLock);
|
||||
pthread_cond_timedwait(&m_TickCond, &m_TickLock, &timeout);
|
||||
pthread_mutex_unlock(&m_TickLock);
|
||||
#else
|
||||
WaitForSingleObject(m_TickCond, 1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
rdtsc(t);
|
||||
}
|
||||
}
|
||||
|
||||
void CTimer::interrupt()
|
||||
{
|
||||
// schedule the sleepto time to the current CCs, so that it will stop
|
||||
rdtsc(m_ullSchedTime);
|
||||
tick();
|
||||
}
|
||||
|
||||
void CTimer::tick()
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_cond_signal(&m_TickCond);
|
||||
#else
|
||||
SetEvent(m_TickCond);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t CTimer::getTime()
|
||||
{
|
||||
//For Cygwin and other systems without microsecond level resolution, uncomment the following three lines
|
||||
//uint64_t x;
|
||||
//rdtsc(x);
|
||||
//return x / s_ullCPUFrequency;
|
||||
//Specific fix may be necessary if rdtsc is not available either.
|
||||
|
||||
#ifndef WINDOWS
|
||||
timeval t;
|
||||
gettimeofday(&t, 0);
|
||||
return t.tv_sec * 1000000ULL + t.tv_usec;
|
||||
#else
|
||||
LARGE_INTEGER ccf;
|
||||
HANDLE hCurThread = ::GetCurrentThread();
|
||||
DWORD_PTR dwOldMask = ::SetThreadAffinityMask(hCurThread, 1);
|
||||
if (QueryPerformanceFrequency(&ccf))
|
||||
{
|
||||
LARGE_INTEGER cc;
|
||||
if (QueryPerformanceCounter(&cc))
|
||||
{
|
||||
SetThreadAffinityMask(hCurThread, dwOldMask);
|
||||
return (cc.QuadPart * 1000000ULL / ccf.QuadPart);
|
||||
}
|
||||
}
|
||||
|
||||
SetThreadAffinityMask(hCurThread, dwOldMask);
|
||||
return GetTickCount() * 1000ULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CTimer::triggerEvent()
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_cond_signal(&m_EventCond);
|
||||
#else
|
||||
SetEvent(m_EventCond);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CTimer::waitForEvent()
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
timeval now;
|
||||
timespec timeout;
|
||||
gettimeofday(&now, 0);
|
||||
if (now.tv_usec < 990000)
|
||||
{
|
||||
timeout.tv_sec = now.tv_sec;
|
||||
timeout.tv_nsec = (now.tv_usec + 10000) * 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout.tv_sec = now.tv_sec + 1;
|
||||
timeout.tv_nsec = (now.tv_usec + 10000 - 1000000) * 1000;
|
||||
}
|
||||
pthread_mutex_lock(&m_EventLock);
|
||||
pthread_cond_timedwait(&m_EventCond, &m_EventLock, &timeout);
|
||||
pthread_mutex_unlock(&m_EventLock);
|
||||
#else
|
||||
WaitForSingleObject(m_EventCond, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CTimer::sleep()
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
usleep(10);
|
||||
#else
|
||||
Sleep(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Automatically lock in constructor
|
||||
CGuard::CGuard(udt_pthread_mutex_t& lock):
|
||||
m_Mutex(lock),
|
||||
m_iLocked()
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
m_iLocked = pthread_mutex_lock(&m_Mutex);
|
||||
#else
|
||||
m_iLocked = WaitForSingleObject(m_Mutex, INFINITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Automatically unlock in destructor
|
||||
CGuard::~CGuard()
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
if (0 == m_iLocked)
|
||||
pthread_mutex_unlock(&m_Mutex);
|
||||
#else
|
||||
if (WAIT_FAILED != m_iLocked)
|
||||
ReleaseMutex(m_Mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGuard::enterCS(udt_pthread_mutex_t& lock)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_lock(&lock);
|
||||
#else
|
||||
WaitForSingleObject(lock, INFINITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGuard::leaveCS(udt_pthread_mutex_t& lock)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_unlock(&lock);
|
||||
#else
|
||||
ReleaseMutex(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGuard::createMutex(udt_pthread_mutex_t& lock)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
#else
|
||||
lock = CreateMutex(NULL, false, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGuard::releaseMutex(udt_pthread_mutex_t& lock)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_mutex_destroy(&lock);
|
||||
#else
|
||||
CloseHandle(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGuard::createCond(udt_pthread_cond_t& cond)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_cond_init(&cond, NULL);
|
||||
#else
|
||||
cond = CreateEvent(NULL, false, false, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGuard::releaseCond(udt_pthread_cond_t& cond)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
pthread_cond_destroy(&cond);
|
||||
#else
|
||||
CloseHandle(cond);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
CUDTException::CUDTException(int major, int minor, int err):
|
||||
m_iMajor(major),
|
||||
m_iMinor(minor)
|
||||
{
|
||||
if (-1 == err)
|
||||
#ifndef WINDOWS
|
||||
m_iErrno = errno;
|
||||
#else
|
||||
m_iErrno = GetLastError();
|
||||
#endif
|
||||
else
|
||||
m_iErrno = err;
|
||||
}
|
||||
|
||||
CUDTException::CUDTException(const CUDTException& e):
|
||||
m_iMajor(e.m_iMajor),
|
||||
m_iMinor(e.m_iMinor),
|
||||
m_iErrno(e.m_iErrno),
|
||||
m_strMsg()
|
||||
{
|
||||
}
|
||||
|
||||
CUDTException::~CUDTException()
|
||||
{
|
||||
}
|
||||
|
||||
const char* CUDTException::getErrorMessage()
|
||||
{
|
||||
// translate "Major:Minor" code into text message.
|
||||
|
||||
switch (m_iMajor)
|
||||
{
|
||||
case 0:
|
||||
m_strMsg = "Success";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_strMsg = "Connection setup failure";
|
||||
|
||||
switch (m_iMinor)
|
||||
{
|
||||
case 1:
|
||||
m_strMsg += ": connection time out";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_strMsg += ": connection rejected";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_strMsg += ": unable to create/configure UDP socket";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
m_strMsg += ": abort for security reasons";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch (m_iMinor)
|
||||
{
|
||||
case 1:
|
||||
m_strMsg = "Connection was broken";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_strMsg = "Connection does not exist";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_strMsg = "System resource failure";
|
||||
|
||||
switch (m_iMinor)
|
||||
{
|
||||
case 1:
|
||||
m_strMsg += ": unable to create new threads";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_strMsg += ": unable to allocate buffers";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
m_strMsg = "File system failure";
|
||||
|
||||
switch (m_iMinor)
|
||||
{
|
||||
case 1:
|
||||
m_strMsg += ": cannot seek read position";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_strMsg += ": failure in read";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_strMsg += ": cannot seek write position";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
m_strMsg += ": failure in write";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 5:
|
||||
m_strMsg = "Operation not supported";
|
||||
|
||||
switch (m_iMinor)
|
||||
{
|
||||
case 1:
|
||||
m_strMsg += ": Cannot do this operation on a BOUND socket";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_strMsg += ": Cannot do this operation on a CONNECTED socket";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_strMsg += ": Bad parameters";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
m_strMsg += ": Invalid socket ID";
|
||||
break;
|
||||
|
||||
case 5:
|
||||
m_strMsg += ": Cannot do this operation on an UNBOUND socket";
|
||||
break;
|
||||
|
||||
case 6:
|
||||
m_strMsg += ": Socket is not in listening state";
|
||||
break;
|
||||
|
||||
case 7:
|
||||
m_strMsg += ": Listen/accept is not supported in rendezous connection setup";
|
||||
break;
|
||||
|
||||
case 8:
|
||||
m_strMsg += ": Cannot call connect on UNBOUND socket in rendezvous connection setup";
|
||||
break;
|
||||
|
||||
case 9:
|
||||
m_strMsg += ": This operation is not supported in SOCK_STREAM mode";
|
||||
break;
|
||||
|
||||
case 10:
|
||||
m_strMsg += ": This operation is not supported in SOCK_DGRAM mode";
|
||||
break;
|
||||
|
||||
case 11:
|
||||
m_strMsg += ": Another socket is already listening on the same port";
|
||||
break;
|
||||
|
||||
case 12:
|
||||
m_strMsg += ": Message is too large to send (it must be less than the UDT send buffer size)";
|
||||
break;
|
||||
|
||||
case 13:
|
||||
m_strMsg += ": Invalid epoll ID";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 6:
|
||||
m_strMsg = "Non-blocking call failure";
|
||||
|
||||
switch (m_iMinor)
|
||||
{
|
||||
case 1:
|
||||
m_strMsg += ": no buffer available for sending";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_strMsg += ": no data available for reading";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 7:
|
||||
m_strMsg = "The peer side has signalled an error";
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
m_strMsg = "Unknown error";
|
||||
}
|
||||
|
||||
// Adding "errno" information
|
||||
if ((0 != m_iMajor) && (0 < m_iErrno))
|
||||
{
|
||||
m_strMsg += ": ";
|
||||
#ifndef WINDOWS
|
||||
char errmsg[1024];
|
||||
if (strerror_r(m_iErrno, errmsg, 1024) == 0)
|
||||
m_strMsg += errmsg;
|
||||
#else
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, m_iErrno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
|
||||
m_strMsg += (char*)lpMsgBuf;
|
||||
LocalFree(lpMsgBuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
// period
|
||||
#ifndef WINDOWS
|
||||
m_strMsg += ".";
|
||||
#endif
|
||||
|
||||
return m_strMsg.c_str();
|
||||
}
|
||||
|
||||
int CUDTException::getErrorCode() const
|
||||
{
|
||||
return m_iMajor * 1000 + m_iMinor;
|
||||
}
|
||||
|
||||
void CUDTException::clear()
|
||||
{
|
||||
m_iMajor = 0;
|
||||
m_iMinor = 0;
|
||||
m_iErrno = 0;
|
||||
}
|
||||
|
||||
const int CUDTException::SUCCESS = 0;
|
||||
const int CUDTException::ECONNSETUP = 1000;
|
||||
const int CUDTException::ENOSERVER = 1001;
|
||||
const int CUDTException::ECONNREJ = 1002;
|
||||
const int CUDTException::ESOCKFAIL = 1003;
|
||||
const int CUDTException::ESECFAIL = 1004;
|
||||
const int CUDTException::ECONNFAIL = 2000;
|
||||
const int CUDTException::ECONNLOST = 2001;
|
||||
const int CUDTException::ENOCONN = 2002;
|
||||
const int CUDTException::ERESOURCE = 3000;
|
||||
const int CUDTException::ETHREAD = 3001;
|
||||
const int CUDTException::ENOBUF = 3002;
|
||||
const int CUDTException::EFILE = 4000;
|
||||
const int CUDTException::EINVRDOFF = 4001;
|
||||
const int CUDTException::ERDPERM = 4002;
|
||||
const int CUDTException::EINVWROFF = 4003;
|
||||
const int CUDTException::EWRPERM = 4004;
|
||||
const int CUDTException::EINVOP = 5000;
|
||||
const int CUDTException::EBOUNDSOCK = 5001;
|
||||
const int CUDTException::ECONNSOCK = 5002;
|
||||
const int CUDTException::EINVPARAM = 5003;
|
||||
const int CUDTException::EINVSOCK = 5004;
|
||||
const int CUDTException::EUNBOUNDSOCK = 5005;
|
||||
const int CUDTException::ENOLISTEN = 5006;
|
||||
const int CUDTException::ERDVNOSERV = 5007;
|
||||
const int CUDTException::ERDVUNBOUND = 5008;
|
||||
const int CUDTException::ESTREAMILL = 5009;
|
||||
const int CUDTException::EDGRAMILL = 5010;
|
||||
const int CUDTException::EDUPLISTEN = 5011;
|
||||
const int CUDTException::ELARGEMSG = 5012;
|
||||
const int CUDTException::EINVPOLLID = 5013;
|
||||
const int CUDTException::EASYNCFAIL = 6000;
|
||||
const int CUDTException::EASYNCSND = 6001;
|
||||
const int CUDTException::EASYNCRCV = 6002;
|
||||
const int CUDTException::ETIMEOUT = 6003;
|
||||
const int CUDTException::EPEERERR = 7000;
|
||||
const int CUDTException::EUNKNOWN = -1;
|
||||
|
||||
|
||||
//
|
||||
bool CIPAddress::ipcmp(const sockaddr* addr1, const sockaddr* addr2, int ver)
|
||||
{
|
||||
if (AF_INET == ver)
|
||||
{
|
||||
sockaddr_in* a1 = (sockaddr_in*)addr1;
|
||||
sockaddr_in* a2 = (sockaddr_in*)addr2;
|
||||
|
||||
if ((a1->sin_port == a2->sin_port) && (a1->sin_addr.s_addr == a2->sin_addr.s_addr))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sockaddr_in6* a1 = (sockaddr_in6*)addr1;
|
||||
sockaddr_in6* a2 = (sockaddr_in6*)addr2;
|
||||
|
||||
if (a1->sin6_port == a2->sin6_port)
|
||||
{
|
||||
for (int i = 0; i < 16; ++ i)
|
||||
if (*((char*)&(a1->sin6_addr) + i) != *((char*)&(a2->sin6_addr) + i))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CIPAddress::ntop(const sockaddr* addr, uint32_t ip[4], int ver)
|
||||
{
|
||||
if (AF_INET == ver)
|
||||
{
|
||||
sockaddr_in* a = (sockaddr_in*)addr;
|
||||
ip[0] = a->sin_addr.s_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
sockaddr_in6* a = (sockaddr_in6*)addr;
|
||||
ip[3] = (a->sin6_addr.s6_addr[15] << 24) + (a->sin6_addr.s6_addr[14] << 16) + (a->sin6_addr.s6_addr[13] << 8) + a->sin6_addr.s6_addr[12];
|
||||
ip[2] = (a->sin6_addr.s6_addr[11] << 24) + (a->sin6_addr.s6_addr[10] << 16) + (a->sin6_addr.s6_addr[9] << 8) + a->sin6_addr.s6_addr[8];
|
||||
ip[1] = (a->sin6_addr.s6_addr[7] << 24) + (a->sin6_addr.s6_addr[6] << 16) + (a->sin6_addr.s6_addr[5] << 8) + a->sin6_addr.s6_addr[4];
|
||||
ip[0] = (a->sin6_addr.s6_addr[3] << 24) + (a->sin6_addr.s6_addr[2] << 16) + (a->sin6_addr.s6_addr[1] << 8) + a->sin6_addr.s6_addr[0];
|
||||
}
|
||||
}
|
||||
|
||||
void CIPAddress::pton(sockaddr* addr, const uint32_t ip[4], int ver)
|
||||
{
|
||||
if (AF_INET == ver)
|
||||
{
|
||||
sockaddr_in* a = (sockaddr_in*)addr;
|
||||
a->sin_addr.s_addr = ip[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
sockaddr_in6* a = (sockaddr_in6*)addr;
|
||||
for (int i = 0; i < 4; ++ i)
|
||||
{
|
||||
a->sin6_addr.s6_addr[i * 4] = ip[i] & 0xFF;
|
||||
a->sin6_addr.s6_addr[i * 4 + 1] = (unsigned char)((ip[i] & 0xFF00) >> 8);
|
||||
a->sin6_addr.s6_addr[i * 4 + 2] = (unsigned char)((ip[i] & 0xFF0000) >> 16);
|
||||
a->sin6_addr.s6_addr[i * 4 + 3] = (unsigned char)((ip[i] & 0xFF000000) >> 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void CMD5::compute(const char* input, unsigned char result[16])
|
||||
{
|
||||
md5_state_t state;
|
||||
|
||||
md5_init(&state);
|
||||
md5_append(&state, (const md5_byte_t *)input, strlen(input));
|
||||
md5_finish(&state, result);
|
||||
}
|
|
@ -0,0 +1,327 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 08/01/2009
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_COMMON_H__
|
||||
#define __UDT_COMMON_H__
|
||||
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <cstdlib>
|
||||
#include "udt.h"
|
||||
|
||||
|
||||
#ifdef WINDOWS
|
||||
// Windows compatibility
|
||||
typedef HANDLE udt_pthread_t;
|
||||
typedef HANDLE udt_pthread_mutex_t;
|
||||
typedef HANDLE udt_pthread_cond_t;
|
||||
typedef DWORD udt_pthread_key_t;
|
||||
#else
|
||||
typedef pthread_t udt_pthread_t;
|
||||
typedef pthread_mutex_t udt_pthread_mutex_t;
|
||||
typedef pthread_cond_t udt_pthread_cond_t;
|
||||
typedef pthread_key_t udt_pthread_key_t;
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CTimer
|
||||
{
|
||||
public:
|
||||
CTimer();
|
||||
~CTimer();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Sleep for "interval" CCs.
|
||||
// Parameters:
|
||||
// 0) [in] interval: CCs to sleep.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void sleep(uint64_t interval);
|
||||
|
||||
// Functionality:
|
||||
// Seelp until CC "nexttime".
|
||||
// Parameters:
|
||||
// 0) [in] nexttime: next time the caller is waken up.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void sleepto(uint64_t nexttime);
|
||||
|
||||
// Functionality:
|
||||
// Stop the sleep() or sleepto() methods.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void interrupt();
|
||||
|
||||
// Functionality:
|
||||
// trigger the clock for a tick, for better granuality in no_busy_waiting timer.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void tick();
|
||||
|
||||
public:
|
||||
|
||||
// Functionality:
|
||||
// Read the CPU clock cycle into x.
|
||||
// Parameters:
|
||||
// 0) [out] x: to record cpu clock cycles.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
static void rdtsc(uint64_t &x);
|
||||
|
||||
// Functionality:
|
||||
// return the CPU frequency.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// CPU frequency.
|
||||
|
||||
static uint64_t getCPUFrequency();
|
||||
|
||||
// Functionality:
|
||||
// check the current time, 64bit, in microseconds.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// current time in microseconds.
|
||||
|
||||
static uint64_t getTime();
|
||||
|
||||
// Functionality:
|
||||
// trigger an event such as new connection, close, new data, etc. for "select" call.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
static void triggerEvent();
|
||||
|
||||
// Functionality:
|
||||
// wait for an event to br triggered by "triggerEvent".
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
static void waitForEvent();
|
||||
|
||||
// Functionality:
|
||||
// sleep for a short interval. exact sleep time does not matter
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
static void sleep();
|
||||
|
||||
private:
|
||||
uint64_t getTimeInMicroSec();
|
||||
|
||||
private:
|
||||
uint64_t m_ullSchedTime; // next schedulled time
|
||||
|
||||
pthread_cond_t m_TickCond;
|
||||
udt_pthread_mutex_t m_TickLock;
|
||||
|
||||
static udt_pthread_cond_t m_EventCond;
|
||||
static udt_pthread_mutex_t m_EventLock;
|
||||
|
||||
private:
|
||||
static uint64_t s_ullCPUFrequency; // CPU frequency : clock cycles per microsecond
|
||||
static uint64_t readCPUFrequency();
|
||||
static bool m_bUseMicroSecond; // No higher resolution timer available, use gettimeofday().
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CGuard
|
||||
{
|
||||
public:
|
||||
CGuard(udt_pthread_mutex_t& lock);
|
||||
~CGuard();
|
||||
|
||||
public:
|
||||
static void enterCS(udt_pthread_mutex_t& lock);
|
||||
static void leaveCS(udt_pthread_mutex_t& lock);
|
||||
|
||||
static void createMutex(udt_pthread_mutex_t& lock);
|
||||
static void releaseMutex(udt_pthread_mutex_t& lock);
|
||||
|
||||
static void createCond(udt_pthread_cond_t& cond);
|
||||
static void releaseCond(udt_pthread_cond_t& cond);
|
||||
|
||||
private:
|
||||
udt_pthread_mutex_t& m_Mutex; // Alias name of the mutex to be protected
|
||||
unsigned int m_iLocked; // Locking status
|
||||
|
||||
CGuard& operator=(const CGuard&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// UDT Sequence Number 0 - (2^31 - 1)
|
||||
|
||||
// seqcmp: compare two seq#, considering the wraping
|
||||
// seqlen: length from the 1st to the 2nd seq#, including both
|
||||
// seqoff: offset from the 2nd to the 1st seq#
|
||||
// incseq: increase the seq# by 1
|
||||
// decseq: decrease the seq# by 1
|
||||
// incseq: increase the seq# by a given offset
|
||||
|
||||
class CSeqNo
|
||||
{
|
||||
public:
|
||||
inline static int seqcmp(int32_t seq1, int32_t seq2)
|
||||
{return (abs(seq1 - seq2) < m_iSeqNoTH) ? (seq1 - seq2) : (seq2 - seq1);}
|
||||
|
||||
inline static int seqlen(int32_t seq1, int32_t seq2)
|
||||
{return (seq1 <= seq2) ? (seq2 - seq1 + 1) : (seq2 - seq1 + m_iMaxSeqNo + 2);}
|
||||
|
||||
inline static int seqoff(int32_t seq1, int32_t seq2)
|
||||
{
|
||||
if (abs(seq1 - seq2) < m_iSeqNoTH)
|
||||
return seq2 - seq1;
|
||||
|
||||
if (seq1 < seq2)
|
||||
return seq2 - seq1 - m_iMaxSeqNo - 1;
|
||||
|
||||
return seq2 - seq1 + m_iMaxSeqNo + 1;
|
||||
}
|
||||
|
||||
inline static int32_t incseq(int32_t seq)
|
||||
{return (seq == m_iMaxSeqNo) ? 0 : seq + 1;}
|
||||
|
||||
inline static int32_t decseq(int32_t seq)
|
||||
{return (seq == 0) ? m_iMaxSeqNo : seq - 1;}
|
||||
|
||||
inline static int32_t incseq(int32_t seq, int32_t inc)
|
||||
{return (m_iMaxSeqNo - seq >= inc) ? seq + inc : seq - m_iMaxSeqNo + inc - 1;}
|
||||
|
||||
public:
|
||||
static const int32_t m_iSeqNoTH; // threshold for comparing seq. no.
|
||||
static const int32_t m_iMaxSeqNo; // maximum sequence number used in UDT
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// UDT ACK Sub-sequence Number: 0 - (2^31 - 1)
|
||||
|
||||
class CAckNo
|
||||
{
|
||||
public:
|
||||
inline static int32_t incack(int32_t ackno)
|
||||
{return (ackno == m_iMaxAckSeqNo) ? 0 : ackno + 1;}
|
||||
|
||||
public:
|
||||
static const int32_t m_iMaxAckSeqNo; // maximum ACK sub-sequence number used in UDT
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// UDT Message Number: 0 - (2^29 - 1)
|
||||
|
||||
class CMsgNo
|
||||
{
|
||||
public:
|
||||
inline static int msgcmp(int32_t msgno1, int32_t msgno2)
|
||||
{return (abs(msgno1 - msgno2) < m_iMsgNoTH) ? (msgno1 - msgno2) : (msgno2 - msgno1);}
|
||||
|
||||
inline static int msglen(int32_t msgno1, int32_t msgno2)
|
||||
{return (msgno1 <= msgno2) ? (msgno2 - msgno1 + 1) : (msgno2 - msgno1 + m_iMaxMsgNo + 2);}
|
||||
|
||||
inline static int msgoff(int32_t msgno1, int32_t msgno2)
|
||||
{
|
||||
if (abs(msgno1 - msgno2) < m_iMsgNoTH)
|
||||
return msgno2 - msgno1;
|
||||
|
||||
if (msgno1 < msgno2)
|
||||
return msgno2 - msgno1 - m_iMaxMsgNo - 1;
|
||||
|
||||
return msgno2 - msgno1 + m_iMaxMsgNo + 1;
|
||||
}
|
||||
|
||||
inline static int32_t incmsg(int32_t msgno)
|
||||
{return (msgno == m_iMaxMsgNo) ? 0 : msgno + 1;}
|
||||
|
||||
public:
|
||||
static const int32_t m_iMsgNoTH; // threshold for comparing msg. no.
|
||||
static const int32_t m_iMaxMsgNo; // maximum message number used in UDT
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct CIPAddress
|
||||
{
|
||||
static bool ipcmp(const sockaddr* addr1, const sockaddr* addr2, int ver = AF_INET);
|
||||
static void ntop(const sockaddr* addr, uint32_t ip[4], int ver = AF_INET);
|
||||
static void pton(sockaddr* addr, const uint32_t ip[4], int ver = AF_INET);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct CMD5
|
||||
{
|
||||
static void compute(const char* input, unsigned char result[16]);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,286 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/22/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#include <cmath>
|
||||
#include "udtCommon.h"
|
||||
#include "window.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
CACKWindow::CACKWindow(int size):
|
||||
m_piACKSeqNo(NULL),
|
||||
m_piACK(NULL),
|
||||
m_pTimeStamp(NULL),
|
||||
m_iSize(size),
|
||||
m_iHead(0),
|
||||
m_iTail(0)
|
||||
{
|
||||
m_piACKSeqNo = new int32_t[m_iSize];
|
||||
m_piACK = new int32_t[m_iSize];
|
||||
m_pTimeStamp = new uint64_t[m_iSize];
|
||||
|
||||
m_piACKSeqNo[0] = -1;
|
||||
}
|
||||
|
||||
CACKWindow::~CACKWindow()
|
||||
{
|
||||
delete [] m_piACKSeqNo;
|
||||
delete [] m_piACK;
|
||||
delete [] m_pTimeStamp;
|
||||
}
|
||||
|
||||
void CACKWindow::store(int32_t seq, int32_t ack)
|
||||
{
|
||||
m_piACKSeqNo[m_iHead] = seq;
|
||||
m_piACK[m_iHead] = ack;
|
||||
m_pTimeStamp[m_iHead] = CTimer::getTime();
|
||||
|
||||
m_iHead = (m_iHead + 1) % m_iSize;
|
||||
|
||||
// overwrite the oldest ACK since it is not likely to be acknowledged
|
||||
if (m_iHead == m_iTail)
|
||||
m_iTail = (m_iTail + 1) % m_iSize;
|
||||
}
|
||||
|
||||
int CACKWindow::acknowledge(int32_t seq, int32_t& ack)
|
||||
{
|
||||
if (m_iHead >= m_iTail)
|
||||
{
|
||||
// Head has not exceeded the physical boundary of the window
|
||||
|
||||
for (int i = m_iTail, n = m_iHead; i < n; ++ i)
|
||||
{
|
||||
// looking for indentical ACK Seq. No.
|
||||
if (seq == m_piACKSeqNo[i])
|
||||
{
|
||||
// return the Data ACK it carried
|
||||
ack = m_piACK[i];
|
||||
|
||||
// calculate RTT
|
||||
int rtt = int(CTimer::getTime() - m_pTimeStamp[i]);
|
||||
|
||||
if (i + 1 == m_iHead)
|
||||
{
|
||||
m_iTail = m_iHead = 0;
|
||||
m_piACKSeqNo[0] = -1;
|
||||
}
|
||||
else
|
||||
m_iTail = (i + 1) % m_iSize;
|
||||
|
||||
return rtt;
|
||||
}
|
||||
}
|
||||
|
||||
// Bad input, the ACK node has been overwritten
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Head has exceeded the physical window boundary, so it is behind tail
|
||||
for (int j = m_iTail, n = m_iHead + m_iSize; j < n; ++ j)
|
||||
{
|
||||
// looking for indentical ACK seq. no.
|
||||
if (seq == m_piACKSeqNo[j % m_iSize])
|
||||
{
|
||||
// return Data ACK
|
||||
j %= m_iSize;
|
||||
ack = m_piACK[j];
|
||||
|
||||
// calculate RTT
|
||||
int rtt = int(CTimer::getTime() - m_pTimeStamp[j]);
|
||||
|
||||
if (j == m_iHead)
|
||||
{
|
||||
m_iTail = m_iHead = 0;
|
||||
m_piACKSeqNo[0] = -1;
|
||||
}
|
||||
else
|
||||
m_iTail = (j + 1) % m_iSize;
|
||||
|
||||
return rtt;
|
||||
}
|
||||
}
|
||||
|
||||
// bad input, the ACK node has been overwritten
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CPktTimeWindow::CPktTimeWindow(int asize, int psize):
|
||||
m_iAWSize(asize),
|
||||
m_piPktWindow(NULL),
|
||||
m_iPktWindowPtr(0),
|
||||
m_iPWSize(psize),
|
||||
m_piProbeWindow(NULL),
|
||||
m_iProbeWindowPtr(0),
|
||||
m_iLastSentTime(0),
|
||||
m_iMinPktSndInt(1000000),
|
||||
m_LastArrTime(),
|
||||
m_CurrArrTime(),
|
||||
m_ProbeTime()
|
||||
{
|
||||
m_piPktWindow = new int[m_iAWSize];
|
||||
m_piPktReplica = new int[m_iAWSize];
|
||||
m_piProbeWindow = new int[m_iPWSize];
|
||||
m_piProbeReplica = new int[m_iPWSize];
|
||||
|
||||
m_LastArrTime = CTimer::getTime();
|
||||
|
||||
for (int i = 0; i < m_iAWSize; ++ i)
|
||||
m_piPktWindow[i] = 1000000;
|
||||
|
||||
for (int k = 0; k < m_iPWSize; ++ k)
|
||||
m_piProbeWindow[k] = 1000;
|
||||
}
|
||||
|
||||
CPktTimeWindow::~CPktTimeWindow()
|
||||
{
|
||||
delete [] m_piPktWindow;
|
||||
delete [] m_piPktReplica;
|
||||
delete [] m_piProbeWindow;
|
||||
delete [] m_piProbeReplica;
|
||||
}
|
||||
|
||||
int CPktTimeWindow::getMinPktSndInt() const
|
||||
{
|
||||
return m_iMinPktSndInt;
|
||||
}
|
||||
|
||||
int CPktTimeWindow::getPktRcvSpeed() const
|
||||
{
|
||||
// get median value, but cannot change the original value order in the window
|
||||
std::copy(m_piPktWindow, m_piPktWindow + m_iAWSize - 1, m_piPktReplica);
|
||||
std::nth_element(m_piPktReplica, m_piPktReplica + (m_iAWSize / 2), m_piPktReplica + m_iAWSize - 1);
|
||||
int median = m_piPktReplica[m_iAWSize / 2];
|
||||
|
||||
int count = 0;
|
||||
int sum = 0;
|
||||
int upper = median << 3;
|
||||
int lower = median >> 3;
|
||||
|
||||
// median filtering
|
||||
int* p = m_piPktWindow;
|
||||
for (int i = 0, n = m_iAWSize; i < n; ++ i)
|
||||
{
|
||||
if ((*p < upper) && (*p > lower))
|
||||
{
|
||||
++ count;
|
||||
sum += *p;
|
||||
}
|
||||
++ p;
|
||||
}
|
||||
|
||||
// claculate speed, or return 0 if not enough valid value
|
||||
if (count > (m_iAWSize >> 1))
|
||||
return (int)ceil(1000000.0 / (sum / count));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CPktTimeWindow::getBandwidth() const
|
||||
{
|
||||
// get median value, but cannot change the original value order in the window
|
||||
std::copy(m_piProbeWindow, m_piProbeWindow + m_iPWSize - 1, m_piProbeReplica);
|
||||
std::nth_element(m_piProbeReplica, m_piProbeReplica + (m_iPWSize / 2), m_piProbeReplica + m_iPWSize - 1);
|
||||
int median = m_piProbeReplica[m_iPWSize / 2];
|
||||
|
||||
int count = 1;
|
||||
int sum = median;
|
||||
int upper = median << 3;
|
||||
int lower = median >> 3;
|
||||
|
||||
// median filtering
|
||||
int* p = m_piProbeWindow;
|
||||
for (int i = 0, n = m_iPWSize; i < n; ++ i)
|
||||
{
|
||||
if ((*p < upper) && (*p > lower))
|
||||
{
|
||||
++ count;
|
||||
sum += *p;
|
||||
}
|
||||
++ p;
|
||||
}
|
||||
|
||||
return (int)ceil(1000000.0 / (double(sum) / double(count)));
|
||||
}
|
||||
|
||||
void CPktTimeWindow::onPktSent(int currtime)
|
||||
{
|
||||
int interval = currtime - m_iLastSentTime;
|
||||
|
||||
if ((interval < m_iMinPktSndInt) && (interval > 0))
|
||||
m_iMinPktSndInt = interval;
|
||||
|
||||
m_iLastSentTime = currtime;
|
||||
}
|
||||
|
||||
void CPktTimeWindow::onPktArrival()
|
||||
{
|
||||
m_CurrArrTime = CTimer::getTime();
|
||||
|
||||
// record the packet interval between the current and the last one
|
||||
*(m_piPktWindow + m_iPktWindowPtr) = int(m_CurrArrTime - m_LastArrTime);
|
||||
|
||||
// the window is logically circular
|
||||
++ m_iPktWindowPtr;
|
||||
if (m_iPktWindowPtr == m_iAWSize)
|
||||
m_iPktWindowPtr = 0;
|
||||
|
||||
// remember last packet arrival time
|
||||
m_LastArrTime = m_CurrArrTime;
|
||||
}
|
||||
|
||||
void CPktTimeWindow::probe1Arrival()
|
||||
{
|
||||
m_ProbeTime = CTimer::getTime();
|
||||
}
|
||||
|
||||
void CPktTimeWindow::probe2Arrival()
|
||||
{
|
||||
m_CurrArrTime = CTimer::getTime();
|
||||
|
||||
// record the probing packets interval
|
||||
*(m_piProbeWindow + m_iProbeWindowPtr) = int(m_CurrArrTime - m_ProbeTime);
|
||||
// the window is logically circular
|
||||
++ m_iProbeWindowPtr;
|
||||
if (m_iProbeWindowPtr == m_iPWSize)
|
||||
m_iProbeWindowPtr = 0;
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 01/22/2011
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_WINDOW_H__
|
||||
#define __UDT_WINDOW_H__
|
||||
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include "udt.h"
|
||||
|
||||
|
||||
class CACKWindow
|
||||
{
|
||||
public:
|
||||
CACKWindow(int size = 1024);
|
||||
~CACKWindow();
|
||||
|
||||
// Functionality:
|
||||
// Write an ACK record into the window.
|
||||
// Parameters:
|
||||
// 0) [in] seq: ACK seq. no.
|
||||
// 1) [in] ack: DATA ACK no.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void store(int32_t seq, int32_t ack);
|
||||
|
||||
// Functionality:
|
||||
// Search the ACK-2 "seq" in the window, find out the DATA "ack" and caluclate RTT .
|
||||
// Parameters:
|
||||
// 0) [in] seq: ACK-2 seq. no.
|
||||
// 1) [out] ack: the DATA ACK no. that matches the ACK-2 no.
|
||||
// Returned value:
|
||||
// RTT.
|
||||
|
||||
int acknowledge(int32_t seq, int32_t& ack);
|
||||
|
||||
private:
|
||||
int32_t* m_piACKSeqNo; // Seq. No. for the ACK packet
|
||||
int32_t* m_piACK; // Data Seq. No. carried by the ACK packet
|
||||
uint64_t* m_pTimeStamp; // The timestamp when the ACK was sent
|
||||
|
||||
int m_iSize; // Size of the ACK history window
|
||||
int m_iHead; // Pointer to the lastest ACK record
|
||||
int m_iTail; // Pointer to the oldest ACK record
|
||||
|
||||
private:
|
||||
CACKWindow(const CACKWindow&);
|
||||
CACKWindow& operator=(const CACKWindow&);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CPktTimeWindow
|
||||
{
|
||||
public:
|
||||
CPktTimeWindow(int asize = 16, int psize = 16);
|
||||
~CPktTimeWindow();
|
||||
|
||||
// Functionality:
|
||||
// read the minimum packet sending interval.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// minimum packet sending interval (microseconds).
|
||||
|
||||
int getMinPktSndInt() const;
|
||||
|
||||
// Functionality:
|
||||
// Calculate the packes arrival speed.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Packet arrival speed (packets per second).
|
||||
|
||||
int getPktRcvSpeed() const;
|
||||
|
||||
// Functionality:
|
||||
// Estimate the bandwidth.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// Estimated bandwidth (packets per second).
|
||||
|
||||
int getBandwidth() const;
|
||||
|
||||
// Functionality:
|
||||
// Record time information of a packet sending.
|
||||
// Parameters:
|
||||
// 0) currtime: timestamp of the packet sending.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void onPktSent(int currtime);
|
||||
|
||||
// Functionality:
|
||||
// Record time information of an arrived packet.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void onPktArrival();
|
||||
|
||||
// Functionality:
|
||||
// Record the arrival time of the first probing packet.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void probe1Arrival();
|
||||
|
||||
// Functionality:
|
||||
// Record the arrival time of the second probing packet and the interval between packet pairs.
|
||||
// Parameters:
|
||||
// None.
|
||||
// Returned value:
|
||||
// None.
|
||||
|
||||
void probe2Arrival();
|
||||
|
||||
private:
|
||||
int m_iAWSize; // size of the packet arrival history window
|
||||
int* m_piPktWindow; // packet information window
|
||||
int* m_piPktReplica;
|
||||
int m_iPktWindowPtr; // position pointer of the packet info. window.
|
||||
|
||||
int m_iPWSize; // size of probe history window size
|
||||
int* m_piProbeWindow; // record inter-packet time for probing packet pairs
|
||||
int* m_piProbeReplica;
|
||||
int m_iProbeWindowPtr; // position pointer to the probing window
|
||||
|
||||
int m_iLastSentTime; // last packet sending time
|
||||
int m_iMinPktSndInt; // Minimum packet sending interval
|
||||
|
||||
uint64_t m_LastArrTime; // last packet arrival time
|
||||
uint64_t m_CurrArrTime; // current packet arrival time
|
||||
uint64_t m_ProbeTime; // arrival time of the first probing packet
|
||||
|
||||
private:
|
||||
CPktTimeWindow(const CPktTimeWindow&);
|
||||
CPktTimeWindow &operator=(const CPktTimeWindow&);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,73 @@
|
|||
From 60a91b17be591edad3c10df0b26d45c79dff7def Mon Sep 17 00:00:00 2001
|
||||
From: nathan <nathan@dorkbox.com>
|
||||
Date: Thu, 8 Jan 2015 23:31:27 +0100
|
||||
Subject: [PATCH 3/5] Code polish. removed unnecessary preprocessor symbols
|
||||
|
||||
---
|
||||
JavaLauncherApp/make_common.mak | 5 +----
|
||||
JavaLauncherApp/src/common.c | 10 +++++-----
|
||||
2 files changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/JavaLauncherApp/make_common.mak b/JavaLauncherApp/make_common.mak
|
||||
index 65536b0..1b55a95 100644
|
||||
--- a/JavaLauncherApp/make_common.mak
|
||||
+++ b/JavaLauncherApp/make_common.mak
|
||||
@@ -181,11 +181,8 @@ ifeq ($(COMPILE_OS_ARCH),32)
|
||||
PROGRAM_PATH+=bin/$(DIST_OS_NAME)
|
||||
endif
|
||||
|
||||
-
|
||||
- #udt config
|
||||
- FLAGS +=-DIA32
|
||||
else ifeq ($(COMPILE_OS_ARCH),64)
|
||||
- FLAGS +=-DAMD64 -D_AMD64_ -D__AMD64__
|
||||
+ FLAGS +=-DAMD64
|
||||
M_ARCH=-m64
|
||||
DIST_OS_NAME=$(COMPILE_OS)_64
|
||||
|
||||
diff --git a/JavaLauncherApp/src/common.c b/JavaLauncherApp/src/common.c
|
||||
index 20f55ee..51a0e51 100644
|
||||
--- a/JavaLauncherApp/src/common.c
|
||||
+++ b/JavaLauncherApp/src/common.c
|
||||
@@ -123,7 +123,7 @@ _TCHAR* findSymlinkCommand(_TCHAR* command, int resolve) {
|
||||
else {
|
||||
/* Get the directory PATH where executables reside. */
|
||||
path = _tgetenv(_T_STRING("PATH"));
|
||||
- #ifdef WINDOWS
|
||||
+ #ifdef WINDOWS
|
||||
/* on windows, prepend the current directory */
|
||||
if (path == NULL)
|
||||
path = _T_STRING("");
|
||||
@@ -133,7 +133,7 @@ _TCHAR* findSymlinkCommand(_TCHAR* command, int resolve) {
|
||||
ch[length] = PATH_SEPARATOR;
|
||||
_tcscpy(&ch[length + 1], path);
|
||||
path = ch;
|
||||
- #endif
|
||||
+ #endif
|
||||
if (!path) {
|
||||
return NULL;
|
||||
} else {
|
||||
@@ -306,9 +306,9 @@ _TCHAR* fixupPath(_TCHAR* path, _TCHAR* programDir, bool programDirFirst, bool a
|
||||
}
|
||||
|
||||
_TCHAR * lastDirSeparator(_TCHAR* str) {
|
||||
- #ifndef WINDOWS
|
||||
+ #ifndef WINDOWS
|
||||
return _tcsrchr(str, DIR_SEPARATOR);
|
||||
- #else
|
||||
+ #else
|
||||
int i = -1;
|
||||
_TCHAR * c = NULL;
|
||||
while (str[++i] != 0) {
|
||||
@@ -316,7 +316,7 @@ _TCHAR * lastDirSeparator(_TCHAR* str) {
|
||||
c = &str[i];
|
||||
}
|
||||
return c;
|
||||
- #endif
|
||||
+ #endif
|
||||
}
|
||||
|
||||
_TCHAR * firstDirSeparator(_TCHAR* str) {
|
||||
--
|
||||
1.9.1
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
From fc0f8e2f8f8abeae9cd71a4fe9c0244981e12d64 Mon Sep 17 00:00:00 2001
|
||||
From: nathan <nathan@dorkbox.com>
|
||||
Date: Fri, 9 Jan 2015 01:22:45 +0100
|
||||
Subject: [PATCH 4/5] Fixed unitialized variable
|
||||
|
||||
---
|
||||
JavaLauncherApp/src/udt/core.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/JavaLauncherApp/src/udt/core.cpp b/JavaLauncherApp/src/udt/core.cpp
|
||||
index c1c8d03..a5acfa7 100644
|
||||
--- a/JavaLauncherApp/src/udt/core.cpp
|
||||
+++ b/JavaLauncherApp/src/udt/core.cpp
|
||||
@@ -2285,7 +2285,7 @@ int CUDT::packData(CPacket& packet, uint64_t& ts)
|
||||
if (offset < 0)
|
||||
return 0;
|
||||
|
||||
- int msglen;
|
||||
+ int msglen = 0;
|
||||
|
||||
payload = m_pSndBuffer->readData(&(packet.m_pcData), offset, packet.m_iMsgNo, msglen);
|
||||
|
||||
--
|
||||
1.9.1
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the University of Illinois
|
||||
nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,7 @@
|
|||
DIRS = src app
|
||||
TARGETS = all clean install
|
||||
|
||||
$(TARGETS): %: $(patsubst %, %.%, $(DIRS))
|
||||
|
||||
$(foreach TGT, $(TARGETS), $(patsubst %, %.$(TGT), $(DIRS))):
|
||||
$(MAKE) -C $(subst ., , $@)
|
|
@ -0,0 +1,14 @@
|
|||
Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
|
||||
All Rights Reserved.
|
||||
Copyright (c) 2011 - 2012, Google, Inc. All Rights Reserved.
|
||||
|
||||
UDP-based Data Transfer (UDT) Library - version 4
|
||||
Author: Yunhong Gu [yunhong.gu @ gmail.com]
|
||||
|
||||
UDT version 4 is free software under BSD License. See ./LICENSE.txt.
|
||||
|
||||
============================================================================
|
||||
|
||||
UDT Website:
|
||||
http://udt.sf.net
|
||||
http://sf.net/projects/udt/
|
|
@ -0,0 +1,36 @@
|
|||
version 4.11
|
||||
|
||||
mostly bug fixes since last version.
|
||||
|
||||
version 4.10
|
||||
|
||||
added UDT_SNDDATA and UDT_RCVDATA options
|
||||
fixed a bug that causes unnecessary connection timeout
|
||||
improved epoll UDT event handling
|
||||
|
||||
version 4.9
|
||||
|
||||
asynchronous close
|
||||
asynchronous connect
|
||||
some bug fixes, especially on EPOLL
|
||||
improved cache code
|
||||
removed unnecessary NAK (reduced loss retransmission)
|
||||
receiver side error can unblock a blocked sender
|
||||
|
||||
version 4.8
|
||||
|
||||
fix a bug that may cause seg fault on concurrent close on the same socket
|
||||
add epoll support
|
||||
increase the listener's scalability to 100K concurrent connections
|
||||
fix a bug that may cause accept/select to return positively when an accepted socket is closed immediately after accept returns
|
||||
fix a bug that may cause connect to fail if the server closes listening socket immediately after accept returns
|
||||
fix recvfile fstream write status bug (e.g., when disk is full, recvfile should handle properly now)
|
||||
|
||||
version 4.7a
|
||||
|
||||
fix timeout bug introduced in 4.7
|
||||
initialize CHandShake
|
||||
|
||||
version 4.7
|
||||
|
||||
Fix several related bugs that can cause hang/memory leak/segmentation fault during cleanup()
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue