Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordmartens2009-12-03 14:35:43 -0500
committerdmartens2009-12-03 14:35:43 -0500
commitfc640cf3fdee9bc3f47c2bf91339b5918e398b00 (patch)
treec2b424a41e3bc1aa72c926dbaf8958cf748e5c36 /incubation/projects
parent04e82608b28d2f6a60cc6f9fc9227ddd65256e88 (diff)
downloadorg.eclipse.ecf-fc640cf3fdee9bc3f47c2bf91339b5918e398b00.tar.gz
org.eclipse.ecf-fc640cf3fdee9bc3f47c2bf91339b5918e398b00.tar.xz
org.eclipse.ecf-fc640cf3fdee9bc3f47c2bf91339b5918e398b00.zip
Added ECF IPC project to project in incubation.
Diffstat (limited to 'incubation/projects')
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/.project11
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.cproject1139
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.project69
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.settings/org.eclipse.cdt.core.prefs3
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/build.properties24
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/build.xml1
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/misc/epl-v10.html258
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/readme.txt36
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOImpl.c383
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOImpl.h111
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOResult.c117
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOResult.h67
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/IPCPackage.c39
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/IPCPackage.h47
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreNative.c310
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreNative.h98
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreResult.c55
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreResult.h29
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/util.c42
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/util.h12
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOImpl.c803
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOImpl.h105
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOResult.c117
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOResult.h71
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/IPCPackage.c52
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/IPCPackage.h47
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreNative.c228
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreNative.h122
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreResult.c60
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreResult.h28
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.classpath7
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.project34
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.settings/org.eclipse.pde.core.prefs4
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/META-INF/MANIFEST.MF11
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/build.properties4
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/META-INF/MANIFEST.MF10
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/about.html28
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/ipc_010.dll0
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/IPCException.java114
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/IPCPackage.java43
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/Utils.java375
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFO.java489
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOImpl.java377
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOInputStream.java132
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOOutputStream.java70
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOResult.java117
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/package-info.java122
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/Semaphore.java345
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/SemaphoreNative.java247
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/SemaphoreResult.java108
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/sharedmemory/SharedMemory.java524
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/features/org.eclipse.ecf.ipc-feature/build.properties1
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/features/org.eclipse.ecf.ipc-feature/feature.xml20
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/.project11
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/build.xml247
-rw-r--r--incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/remote.sh45
57 files changed, 7977 insertions, 0 deletions
diff --git a/incubation/projects/org.eclipse.ecf.ipc/.project b/incubation/projects/org.eclipse.ecf.ipc/.project
new file mode 100644
index 000000000..daf60532e
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>trunk</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.cproject b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.cproject
new file mode 100644
index 000000000..65d0f67b3
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.cproject
@@ -0,0 +1,1139 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject>
+<storageModule moduleId="org.eclipse.cdt.core.settings">
+<cconfiguration id="cdt.managedbuild.config.gnu.mingw.so.debug.210865893">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.so.debug.210865893" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+<externalSettings>
+<externalSetting>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/ipc shared library"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/ipc-lib"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/clipc-native"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/org.eclipse.ecf.ipc.libary-reference"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/ipc shared library/Debug"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/ipc-lib/Debug"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/clipc-native/Debug"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/org.eclipse.ecf.ipc.libary-reference/Debug"/>
+</externalSetting>
+</externalSettings>
+<extensions>
+<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactExtension="dll" artifactName="ipc_010" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mingw.so.debug.210865893" name="Debug" parent="cdt.managedbuild.config.gnu.mingw.so.debug">
+<folderInfo id="cdt.managedbuild.config.gnu.mingw.so.debug.210865893." name="/" resourcePath="">
+<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.base.794047601" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.base">
+<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.PE" id="cdt.managedbuild.target.gnu.platform.mingw.base.93843979" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.mingw.base"/>
+<builder buildPath="${workspace_loc:/clipc-native/Debug}" id="cdt.managedbuild.tool.gnu.builder.mingw.base.1255033766" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/>
+<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.base.2123389991" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.base">
+<inputType id="cdt.managedbuild.tool.gnu.assembler.input.805054199" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.368695828" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
+<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.852243034" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base">
+<option id="gnu.cpp.compiler.option.optimization.level.1219071566" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+<option id="gnu.cpp.compiler.option.debugging.level.1789715606" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.base.594789682" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.base">
+<option id="gnu.c.compiler.option.preprocessor.def.symbols.187408312" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+<listOptionValue builtIn="false" value="_JNI_IMPLEMENTATION_"/>
+</option>
+<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.1538578757" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
+<option id="gnu.c.compiler.option.debugging.level.1800340091" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+<option id="gnu.c.compiler.option.include.paths.302379843" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+<listOptionValue builtIn="false" value="&quot;${JAVA_HOME}/include&quot;"/>
+<listOptionValue builtIn="false" value="&quot;${JAVA_HOME}/include/${target.os}&quot;"/>
+</option>
+<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.388211000" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.base.244833887" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.base">
+<option defaultValue="true" id="gnu.c.link.option.shared.916948211" name="Shared (-shared)" superClass="gnu.c.link.option.shared" valueType="boolean"/>
+<option id="gnu.c.link.option.ldflags.82091924" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="-Wl,--kill-at" valueType="string"/>
+<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.2137447082" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+</inputType>
+<outputType id="cdt.managedbuild.tool.gnu.c.linker.mingw.so.output.base.1886859153" outputPrefix="" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.so.output.base"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base.233090677" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base">
+<option defaultValue="true" id="gnu.cpp.link.option.shared.1746115242" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" valueType="boolean"/>
+</tool>
+</toolChain>
+</folderInfo>
+<sourceEntries>
+<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="src/windows"/>
+</sourceEntries>
+</configuration>
+</storageModule>
+
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" 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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.210865893;cdt.managedbuild.config.gnu.mingw.so.debug.210865893.;cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.926711176;cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.1409314067">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.210865893;cdt.managedbuild.config.gnu.mingw.so.debug.210865893.;cdt.managedbuild.tool.gnu.c.compiler.base.857817593;cdt.managedbuild.tool.gnu.c.compiler.input.971929554">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.release.314936760;cdt.managedbuild.config.gnu.mingw.so.release.314936760.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release.1141640803;cdt.managedbuild.tool.gnu.c.compiler.input.1943902680">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.210865893;cdt.managedbuild.config.gnu.mingw.so.debug.210865893.;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.594789682;cdt.managedbuild.tool.gnu.c.compiler.input.388211000">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.210865893;cdt.managedbuild.config.gnu.mingw.so.debug.210865893.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug.921650772;cdt.managedbuild.tool.gnu.c.compiler.input.1737505195">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+</cconfiguration>
+<cconfiguration id="cdt.managedbuild.config.gnu.mingw.so.release.314936760">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.so.release.314936760" moduleId="org.eclipse.cdt.core.settings" name="Release">
+<externalSettings>
+<externalSetting>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/ipc shared library"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/ipc-lib"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/clipc-native"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/ipc shared library/Release"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/ipc-lib/Release"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/clipc-native/Release"/>
+</externalSetting>
+</externalSettings>
+<extensions>
+<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactExtension="dll" artifactName="ipcsharedlibrary" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mingw.so.release.314936760" name="Release" parent="cdt.managedbuild.config.gnu.mingw.so.release">
+<folderInfo id="cdt.managedbuild.config.gnu.mingw.so.release.314936760." name="/" resourcePath="">
+<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.so.release.3890528" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.so.release">
+<targetPlatform id="cdt.managedbuild.target.gnu.platform.mingw.so.release.1132543718" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.mingw.so.release"/>
+<builder buildPath="${workspace_loc:/ipc shared library/Release}" id="cdt.managedbuild.tool.gnu.builder.mingw.base.1322913713" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/>
+<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.so.release.620498011" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.so.release">
+<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1066807098" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.2006519376" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
+<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release.1082694587" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release">
+<option id="gnu.cpp.compiler.mingw.so.release.option.optimization.level.2144541347" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.so.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+<option id="gnu.cpp.compiler.mingw.so.release.option.debugging.level.949206189" name="Debug Level" superClass="gnu.cpp.compiler.mingw.so.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release.1141640803" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release">
+<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.mingw.so.release.option.optimization.level.494438497" name="Optimization Level" superClass="gnu.c.compiler.mingw.so.release.option.optimization.level" valueType="enumerated"/>
+<option id="gnu.c.compiler.mingw.so.release.option.debugging.level.1533243227" name="Debug Level" superClass="gnu.c.compiler.mingw.so.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1943902680" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.so.release.1861642583" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.so.release">
+<option defaultValue="true" id="gnu.c.link.mingw.so.release.option.shared.838995499" name="Shared (-shared)" superClass="gnu.c.link.mingw.so.release.option.shared" valueType="boolean"/>
+<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1613401006" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+</inputType>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.release.146265537" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.release">
+<option defaultValue="true" id="gnu.cpp.link.mingw.so.release.option.shared.158722932" name="Shared (-shared)" superClass="gnu.cpp.link.mingw.so.release.option.shared" valueType="boolean"/>
+</tool>
+</toolChain>
+</folderInfo>
+<sourceEntries>
+<entry excluding="src/windows|src/linux|c-src/linux/util.h|c-src/linux/util.c|c-src/linux/SemaphoreResult.h|c-src/linux/SemaphoreResult_Results.h|c-src/linux/SemaphoreResult_Results.c|c-src/linux/IPCPackage.c|c-src/linux/com_lts_ipc_semaphore_SemaphoreResult$Results.h|c-src/linux/NamedPipeResult.h|c-src/linux/NamedPipeResult.c|c-src/linux/NamedPipeImpl.c|c-src/linux/com_lts_ipc_semaphore_SemaphoreResult.h|c-src/linux/com_lts_ipc_semaphore_SemaphoreResult.c|c-src/linux/com_lts_ipc_semaphore_SemaphoreResult_Results.h|c-src/linux/com_lts_ipc_semaphore_SemaphoreNative.h|c-src/linux/com_lts_ipc_semaphore_SemaphoreNative.c|c-src/linux/com_lts_ipc_namedpipe_NamedPipeResult.h|c-src/linux/com_lts_ipc_namedpipe_NamedPipeImpl.h|c-src/linux/com_lts_ipc_namedpipe_NamedPipeImpl_PipeDirection.h|c-src/linux/com_lts_ipc_IPCPackage.h" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+</sourceEntries>
+</configuration>
+</storageModule>
+
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" 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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.210865893;cdt.managedbuild.config.gnu.mingw.so.debug.210865893.;cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.926711176;cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.1409314067">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.210865893;cdt.managedbuild.config.gnu.mingw.so.debug.210865893.;cdt.managedbuild.tool.gnu.c.compiler.base.857817593;cdt.managedbuild.tool.gnu.c.compiler.input.971929554">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.release.314936760;cdt.managedbuild.config.gnu.mingw.so.release.314936760.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release.1141640803;cdt.managedbuild.tool.gnu.c.compiler.input.1943902680">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.210865893;cdt.managedbuild.config.gnu.mingw.so.debug.210865893.;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.594789682;cdt.managedbuild.tool.gnu.c.compiler.input.388211000">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.210865893;cdt.managedbuild.config.gnu.mingw.so.debug.210865893.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug.921650772;cdt.managedbuild.tool.gnu.c.compiler.input.1737505195">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<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="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<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.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+</cconfiguration>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<project id="ipc shared library.cdt.managedbuild.target.gnu.mingw.so.1285919922" name="Shared Library" projectType="cdt.managedbuild.target.gnu.mingw.so"/>
+</storageModule>
+</cproject>
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.project b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.project
new file mode 100644
index 000000000..85c6dedbd
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.project
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.ecf.ipc.library-reference</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>?name?</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.append_environment</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildArguments</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildCommand</key>
+ <value>make</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildLocation</key>
+ <value>${workspace_loc:/clipc-native/Debug}</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.contents</key>
+ <value>org.eclipse.cdt.make.core.activeConfigSettings</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.stopOnError</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+ <value>true</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ </natures>
+</projectDescription>
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.settings/org.eclipse.cdt.core.prefs b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.settings/org.eclipse.cdt.core.prefs
new file mode 100644
index 000000000..662dd935a
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/.settings/org.eclipse.cdt.core.prefs
@@ -0,0 +1,3 @@
+#Wed Oct 21 18:16:55 CEST 2009
+eclipse.preferences.version=1
+environment/project/cdt.managedbuild.config.gnu.mingw.so.debug.210865893=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<environment append\="true" appendContributed\="true"/>\r\n
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/build.properties b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/build.properties
new file mode 100644
index 000000000..b6a54fcb7
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/build.properties
@@ -0,0 +1,24 @@
+###############################################################################
+# Copyright (c) 2009 Clark N. Hobbie
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Clark N. Hobbie - initial API and implementation
+###############################################################################
+#
+# properties for building on Windows XP
+#
+env.JAVA_HOME=C:/Java/jdk-1.6.0_13
+JAVA_HOME=C:/Java/jdk-1.6.0_13
+MINGW_HOME=C:/MinGW
+MINGW_INCLUDE=${MINGW_HOME}/include
+MINGW_BIN=${MINGW_HOME}/bin
+C_INCLUDE=${MINGW_HOME}/include;${JAVA_HOME}/include;${JAVA_HOME}/include/win32
+BUILD_DIR=c:/TEMP/java-ipc
+bin.includes = bin/
+src.includes = src/
+jars.compile.order =
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/build.xml b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/build.xml
new file mode 100644
index 000000000..e2c92aec7
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/build.xml
@@ -0,0 +1 @@
+<?xml version="1.0"?> <!-- Copyright (c) 2009 Clark N. Hobbie All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: Clark N. Hobbie - initial API and implementation --> <project name="ipc" default="build" basedir="."> <property file="build.properties"/> <property name="MINGW" value="c:\MinGW"/> <target name="header"> <exec os="Windows XP" executable="javah"> <arg value="-classpath"/> <arg value="..\clipc-java\bin"/> <arg value="-d"/> <arg value="src/windows"/> <arg value="org.eclipse.ecf.ipc.semaphore.SemaphoreNative"/> <arg value="org.eclipse.ecf.ipc.semaphore.SemaphoreResult"/> <arg value="org.eclipse.ecf.ipc.semaphore.SemaphoreResult$Results"/> <arg value="org.eclipse.ecf.ipc.namedpipe.NamedPipeImpl"/> <arg value="org.eclipse.ecf.ipc.namedpipe.NamedPipeResult"/> <arg value="org.eclipse.ecf.ipc.IPCPackage"/> </exec> <exec os="Linux" executable="javah"> <arg value="-classpath"/> <arg value="../clipc-java/bin"/> <arg value="-d"/> <arg value="src/linux"/> <arg value="org.eclipse.ecf.ipc.semaphore.SemaphoreNative"/> <arg value="org.eclipse.ecf.ipc.semaphore.SemaphoreResult"/> <arg value="org.eclipse.ecf.ipc.fifo.FIFOImpl"/> <arg value="org.eclipse.ecf.ipc.fifo.FIFOResult"/> <arg value="org.eclipse.ecf.ipc.IPCPackage"/> </exec> </target> <target name="ipc_pkg_headers"> <exec os="Windows XP" executable="javah"> <arg value="-classpath"/> <arg value="..\clipc-java\bin"/> <arg value="-d"/> <arg value="src/windows"/> <arg value="org.eclipse.ecf.ipc.namedpipe.NamedPipeImpl"/> </exec> </target> <target name="clean"> <delete dir="bin"/> <delete dir="lib"/> <delete dir="doc"/> <delete dir="Debug"/> </target> <target name="native-windows" if="os-windows"> <exec executable="${MINGW}\bin\gcc" dir="src/windows"> <env key="PATH" path="${env.PATH};${MINGW}\bin"/> <arg value="-Wall"/> <arg value="-D_JNI_IMPLEMENTATION_"/> <arg value="-Wl,--kill-at"/> <arg value="-I${env.JAVA_HOME}/include"/> <arg value="-I${env.JAVA_HOME}/include/win32"/> <arg value="-shared"/> <arg value="*.c"/> <arg line="-o ecf-ipc_010.dll"/> </exec> <mkdir dir="lib"/> <copy todir="lib"> <fileset dir="src/windows"> <include name="*.dll"/> </fileset> </copy> </target> <target name="native-linux" if="os-linux"> <mkdir dir="lib"/> <exec executable="gcc" dir="src/linux"> <arg value="-Wall"/> <arg value="-D_JNI_IMPLEMENTATION_"/> <arg value="-I${env.JAVA_HOME}/include"/> <arg value="-I${env.JAVA_HOME}/include/linux"/> <arg value="-shared"/> <arg value="IPCPackage.c"/> <arg value="FIFOImpl.c"/> <arg value="FIFOResult.c"/> <arg value="SemaphoreNative.c"/> <arg value="SemaphoreResult.c"/> <arg value="util.c"/> <arg line="-o libclipc.so"/> </exec> <move todir="lib" file="src/linux/libclipc.so"/> </target> <target name="determine-os"> <condition property="os-windows"> <os family="windows"/> </condition> <condition property="os-linux"> <os family="unix" name="Linux"/> </condition> </target> <target name="build" depends="echo-os, determine-os, native-windows, native-linux"> </target> <target name="lib" depends="build"/> <target name="echo-os"> <echo> env.JAVA_HOME ${env.JAVA_HOME} os.name ${os.name} os.family ${os.arch} os.version ${os.version} </echo> </target> <target name="source" depends="clean"> <delete file="source.zip"/> <zip basedir="." file="source.zip"> <exclude name="**/*~"/> <exclude name="**/*.dll"/> <exclude name="**/*.swp"/> </zip> </target> </project> \ No newline at end of file
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/misc/epl-v10.html b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/misc/epl-v10.html
new file mode 100644
index 000000000..832a9d448
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/misc/epl-v10.html
@@ -0,0 +1,258 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+
+
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Eclipse Public License - Version 1.0</title>
+<style type="text/css">
+ body {
+ size: 8.5in 11.0in;
+ margin: 0.25in 0.5in 0.25in 0.5in;
+ tab-interval: 0.5in;
+ }
+ p {
+ margin-left: auto;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ }
+ p.list {
+ margin-left: 0.5in;
+ margin-top: 0.05em;
+ margin-bottom: 0.05em;
+ }
+ </style>
+
+</head><body lang="EN-US">
+
+<h2>Eclipse Public License - v 1.0</h2>
+
+<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
+AGREEMENT.</p>
+
+<p><b>1. DEFINITIONS</b></p>
+
+<p>"Contribution" means:</p>
+
+<p class="list">a) in the case of the initial Contributor, the initial
+code and documentation distributed under this Agreement, and</p>
+<p class="list">b) in the case of each subsequent Contributor:</p>
+<p class="list">i) changes to the Program, and</p>
+<p class="list">ii) additions to the Program;</p>
+<p class="list">where such changes and/or additions to the Program
+originate from and are distributed by that particular Contributor. A
+Contribution 'originates' from a Contributor if it was added to the
+Program by such Contributor itself or anyone acting on such
+Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii)
+are not derivative works of the Program.</p>
+
+<p>"Contributor" means any person or entity that distributes
+the Program.</p>
+
+<p>"Licensed Patents" mean patent claims licensable by a
+Contributor which are necessarily infringed by the use or sale of its
+Contribution alone or when combined with the Program.</p>
+
+<p>"Program" means the Contributions distributed in accordance
+with this Agreement.</p>
+
+<p>"Recipient" means anyone who receives the Program under
+this Agreement, including all Contributors.</p>
+
+<p><b>2. GRANT OF RIGHTS</b></p>
+
+<p class="list">a) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free copyright license to reproduce, prepare derivative works
+of, publicly display, publicly perform, distribute and sublicense the
+Contribution of such Contributor, if any, and such derivative works, in
+source code and object code form.</p>
+
+<p class="list">b) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free patent license under Licensed Patents to make, use, sell,
+offer to sell, import and otherwise transfer the Contribution of such
+Contributor, if any, in source code and object code form. This patent
+license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor,
+such addition of the Contribution causes such combination to be covered
+by the Licensed Patents. The patent license shall not apply to any other
+combinations which include the Contribution. No hardware per se is
+licensed hereunder.</p>
+
+<p class="list">c) Recipient understands that although each Contributor
+grants the licenses to its Contributions set forth herein, no assurances
+are provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.</p>
+
+<p class="list">d) Each Contributor represents that to its knowledge it
+has sufficient copyright rights in its Contribution, if any, to grant
+the copyright license set forth in this Agreement.</p>
+
+<p><b>3. REQUIREMENTS</b></p>
+
+<p>A Contributor may choose to distribute the Program in object code
+form under its own license agreement, provided that:</p>
+
+<p class="list">a) it complies with the terms and conditions of this
+Agreement; and</p>
+
+<p class="list">b) its license agreement:</p>
+
+<p class="list">i) effectively disclaims on behalf of all Contributors
+all warranties and conditions, express and implied, including warranties
+or conditions of title and non-infringement, and implied warranties or
+conditions of merchantability and fitness for a particular purpose;</p>
+
+<p class="list">ii) effectively excludes on behalf of all Contributors
+all liability for damages, including direct, indirect, special,
+incidental and consequential damages, such as lost profits;</p>
+
+<p class="list">iii) states that any provisions which differ from this
+Agreement are offered by that Contributor alone and not by any other
+party; and</p>
+
+<p class="list">iv) states that source code for the Program is available
+from such Contributor, and informs licensees how to obtain it in a
+reasonable manner on or through a medium customarily used for software
+exchange.</p>
+
+<p>When the Program is made available in source code form:</p>
+
+<p class="list">a) it must be made available under this Agreement; and</p>
+
+<p class="list">b) a copy of this Agreement must be included with each
+copy of the Program.</p>
+
+<p>Contributors may not remove or alter any copyright notices contained
+within the Program.</p>
+
+<p>Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.</p>
+
+<p><b>4. COMMERCIAL DISTRIBUTION</b></p>
+
+<p>Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use of
+the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create
+potential liability for other Contributors. Therefore, if a Contributor
+includes the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and
+indemnify every other Contributor ("Indemnified Contributor")
+against any losses, damages and costs (collectively "Losses")
+arising from claims, lawsuits and other legal actions brought by a third
+party against the Indemnified Contributor to the extent caused by the
+acts or omissions of such Commercial Contributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In
+order to qualify, an Indemnified Contributor must: a) promptly notify
+the Commercial Contributor in writing of such claim, and b) allow the
+Commercial Contributor to control, and cooperate with the Commercial
+Contributor in, the defense and any related settlement negotiations. The
+Indemnified Contributor may participate in any such claim at its own
+expense.</p>
+
+<p>For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.</p>
+
+<p><b>5. NO WARRANTY</b></p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to
+the risks and costs of program errors, compliance with applicable laws,
+damage to or loss of data, programs or equipment, and unavailability or
+interruption of operations.</p>
+
+<p><b>6. DISCLAIMER OF LIABILITY</b></p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
+NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), 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 OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p>
+
+<p><b>7. GENERAL</b></p>
+
+<p>If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.</p>
+
+<p>If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other
+software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the
+date such litigation is filed.</p>
+
+<p>All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of time
+after becoming aware of such noncompliance. If all Recipient's rights
+under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive.</p>
+
+<p>Everyone is permitted to copy and distribute copies of this
+Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The
+Agreement Steward reserves the right to publish new versions (including
+revisions) of this Agreement from time to time. No one other than the
+Agreement Steward has the right to modify this Agreement. The Eclipse
+Foundation is the initial Agreement Steward. The Eclipse Foundation may
+assign the responsibility to serve as the Agreement Steward to a
+suitable separate entity. Each new version of the Agreement will be
+given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new version
+of the Agreement is published, Contributor may elect to distribute the
+Program (including its Contributions) under the new version. Except as
+expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
+rights or licenses to the intellectual property of any Contributor under
+this Agreement, whether expressly, by implication, estoppel or
+otherwise. All rights in the Program not expressly granted under this
+Agreement are reserved.</p>
+
+<p>This Agreement is governed by the laws of the State of New York and
+the intellectual property laws of the United States of America. No party
+to this Agreement will bring a legal action under this Agreement more
+than one year after the cause of action arose. Each party waives its
+rights to a jury trial in any resulting litigation.</p>
+
+</body></html> \ No newline at end of file
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/readme.txt b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/readme.txt
new file mode 100644
index 000000000..c3a824432
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/readme.txt
@@ -0,0 +1,36 @@
+Copyright (c) 2009 Clark N. Hobbie
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+
+Contributors:
+ Clark N. Hobbie - initial API and implementation
+
+=-=-=-=-=-=-=
+
+This directory contains the files for the native (operating system dependent)
+portion of the CLIPC library. The complete version includes the Java (OS
+independent) files as well.
+
+Any 1.6 Java compiler should suffice to build the Java files. Development
+was done using 1.6.0_12.
+
+To build the native libraries on windows you will need to get a copy of
+mingw which can be found at mingw.org The version that you are looking at
+was built with version 5.1.4.
+
+The linux version was built with the default gcc. The uname -all for that
+system was:
+
+Linux fedora 2.6.27.19-170.2.35.fc10.i686 #1 SMP Mon Feb 23 13:21:22 EST 2009 i686 i686 i386 GNU/Linux
+
+The gcc --version info (minus the licensing info) was:
+
+gcc (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)
+
+The basic development environment was Eclipse 3.4.2 with the 5.0.2 version
+of the C/C++ environment.
+
+Please send bugs/comments/etc to ltsllc@sourceforge.net and/or post to the
+project forums at https://sourceforge.net/projects/clipc
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOImpl.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOImpl.c
new file mode 100644
index 000000000..8d65a5c24
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOImpl.c
@@ -0,0 +1,383 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/**
+ * Provide native methods required by the FIFONative class.
+ */
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "FIFOImpl.h"
+#include "FIFOResult.h"
+
+
+#define MAX_TIMEOUT 0x7FFFFFFF
+#define HANDLE_TYPE int
+
+static int methodsInitialized = 0;
+
+static jmethodID methodIsCreator;
+static jmethodID methodGetHandle;
+static jmethodID methodGetActualName;
+static jmethodID methodGetBufferSize;
+
+static jmethodID methodDirection;
+
+#define NAMED_PIPE_IMPL "org/eclipse/ecf/ipc/fifo/FIFOImpl"
+#define NAMED_PIPE_RESULT "org/eclipse/ecf/ipc/fifo/FIFOResult"
+
+
+static void
+implGetActualName(JNIEnv *env, jobject this, char* buf)
+{
+ jstring value;
+ int length;
+
+ value = (*env)->CallObjectMethod(env, this, methodGetActualName);
+ length = (*env)->GetStringLength(env, value);
+ (*env)->GetStringUTFRegion(env, value, 0, length, buf);
+}
+
+void FIFOImpl_initialize(JNIEnv *env)
+{
+ jclass npiClass;
+ jclass nprClass;
+
+ if (methodsInitialized)
+ {
+ return;
+ }
+ else
+ {
+ methodsInitialized = 1;
+ }
+
+ npiClass = (*env)->FindClass(env, NAMED_PIPE_IMPL);
+ nprClass = (*env)->FindClass(env, NAMED_PIPE_RESULT);
+
+ methodIsCreator = (*env)->GetMethodID(env, npiClass, "isCreator", "()Z");
+ methodGetHandle = (*env)->GetMethodID(env, npiClass, "getHandle", "()J");
+ methodGetActualName = (*env)->GetMethodID(env, npiClass, "getActualName", "()Ljava/lang/String;");
+ methodGetBufferSize = (*env)->GetMethodID(env, npiClass, "getBufferSize", "()I");
+
+ methodDirection = (*env)->GetMethodID(env, npiClass, "getDirectionInt", "()I");
+}
+
+
+
+static int
+getDirection(JNIEnv *env, jobject this)
+{
+ jint value;
+
+ value = (*env)->CallIntMethod(env, this, methodDirection);
+ return (int) value;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_org_eclipse_ecf_ipc_fifopipe_FIFOImpl_virtualNameContainsActualNameImpl (
+ JNIEnv *env,
+ jclass class)
+{
+ return 0;
+}
+
+
+static int
+implGetHandle(JNIEnv *env, jobject this)
+{
+ jlong value;
+
+ value = (*env)->CallLongMethod(env, this, methodGetHandle);
+ return (int) ((long) value);
+}
+
+/**
+ * Connect the this process to a named pipe.
+ *
+ * On linux, a named pipe (fifo) is opened like any other file. The only piece
+ * of information needed is whether the process wants to read or to write the fifo.
+ *
+ * Note that, on linux, CLIPC *always* uses blocking mode when connecting to the
+ * FIFO and non-blocking mode for reads and writes. Non-blocking mode is used
+ * for read/write even when the client is requesting blocking mode.
+ */
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_openImpl (
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jint direction)
+{
+ int handle;
+ int flags;
+ char name[128];
+
+ implGetActualName(env, this, name);
+ switch (direction)
+ {
+ case org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_WRITER :
+ flags = O_WRONLY;
+ break;
+
+ case org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_READER :
+ flags = O_RDONLY;
+ break;
+
+ default :
+ FIFOResult_SetResultCode(env, result, -1);
+ return;
+ }
+
+ handle = open (name, flags);
+
+ if (-1 == handle)
+ {
+ FIFOResult_SetResultCode(env, result, handle);
+ }
+ else
+ {
+ int ctl_result;
+
+ ctl_result = fcntl(handle, F_SETFL, O_NDELAY);
+ if (0 == ctl_result)
+ {
+ FIFOResult_SetResultCode(env, result, 0);
+ FIFOResult_SetHandle(env, result, handle);
+ }
+ else
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT);
+ FIFOResult_SetHandle(env, result, -1);
+ FIFOResult_SetErrorCode(env, result, errno);
+ }
+ }
+}
+
+
+/**
+ * Create a new instance of a named pipe and create the named pipe itself if it
+ * doesn't already exist.
+ *
+ * In windows, the CreateFIFO system call must always be used before attempting
+ * to perform any operations on a named pipe. This is unlike POSIX, where the pipe
+ * is created once, and then clients can simply open or close the pipe like they
+ * would any other file.
+ *
+ * This method modifies the result parameter rather than returning a value. The
+ * various fields are populated according to whether or not the calls were successful.
+ *
+ * If the call was successful, result.resultCode should be 0 and result.handle
+ * should contain the value returned by the CreateFIFO system call.
+ *
+ * If the call failed, result.resultCode should contain a non-zero value that is
+ * taken from the constants defined by FIFOResult.ERROR_ In that situation,
+ * the value of result.handle is not defined.
+ */
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_createImpl (
+ JNIEnv *env,
+ jobject this,
+ jobject resultObject)
+{
+ int mode;
+ int result;
+ char name[512];
+
+ mode = 0660;
+
+ implGetActualName(env, this, name);
+
+ result = mkfifo(name, mode);
+ if (-1 == result && EEXIST == errno)
+ {
+ result = 0;
+ }
+
+ FIFOResult_SetResultCode(env, resultObject, result);
+}
+
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_writeImpl (
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jbyteArray buffer,
+ jint offset,
+ jint length,
+ jint timeoutMsec)
+{
+ jbyte *actualBuffer;
+ jbyte *ptr;
+ int returnValue;
+ int handle;
+ jboolean junk;
+
+
+ handle = implGetHandle(env, this);
+
+ Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_select(env, this, result, timeoutMsec);
+
+ if (FIFOResult_GetResultCode(env, result) != org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS)
+ {
+ return;
+ }
+
+
+ actualBuffer = (*env)->GetByteArrayElements(env, buffer, &junk);
+ ptr = actualBuffer + offset;
+
+ returnValue = write(handle, ptr, length);
+ (*env)->ReleaseByteArrayElements(env, buffer, actualBuffer, JNI_ABORT);
+
+ if (-1 != returnValue)
+ {
+ FIFOResult_SetResultCode(env, result, 0);
+ FIFOResult_SetByteCount(env, result, returnValue);
+ }
+ else
+ {
+ FIFOResult_SetResultCode(env, result, -1);
+ }
+}
+
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_readImpl (
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jbyteArray buffer,
+ jint offset,
+ jint length,
+ jint timeoutMsec)
+{
+ jbyte *actualBuffer;
+ jbyte *ptr;
+ int returnValue;
+ int handle;
+ jboolean junk;
+
+ handle = implGetHandle(env, this);
+
+ actualBuffer = (*env)->GetByteArrayElements(env, buffer, &junk);
+ ptr = actualBuffer + offset;
+
+ Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_select(env, this, result, timeoutMsec);
+
+ returnValue = read(handle, ptr, length);
+
+ (*env)->ReleaseByteArrayElements(env, buffer, actualBuffer, JNI_COMMIT);
+
+ if (-1 != returnValue)
+ {
+ FIFOResult_SetResultCode(env, result, 0);
+ FIFOResult_SetByteCount(env, result, returnValue);
+ }
+ else
+ {
+perror("error reading FIFO");
+ FIFOResult_SetResultCode(env, result, -1);
+ }
+}
+
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_select(
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jint timeoutMsec)
+{
+ fd_set read, write, error;
+ int handle;
+ struct timeval timeout;
+ struct timeval *ptimeout;
+ int rvalue;
+
+
+ if (timeoutMsec < 0)
+ {
+ ptimeout = NULL;
+ }
+ else
+ {
+ timeout.tv_sec = timeoutMsec % 1000;
+ timeoutMsec = timeoutMsec - timeout.tv_sec;
+ timeout.tv_usec = timeoutMsec * 1000;
+
+ ptimeout = &timeout;
+ }
+
+ handle = implGetHandle(env, this);
+ FD_ZERO(&read);
+ FD_ZERO(&write);
+ FD_ZERO(&error);
+
+
+ FD_SET(handle, &error);
+
+ switch(getDirection(env, this))
+ {
+ case org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_READER :
+ FD_SET(handle, &read);
+ break;
+
+ case org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_WRITER :
+ FD_SET(handle, &write);
+ break;
+ }
+
+ rvalue = select(1 + handle, &read, &write, &error, NULL);
+
+ if (0 == rvalue)
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_TIMEOUT);
+ FIFOResult_SetErrorCode(env, result, 0);
+ }
+ else if (rvalue > 0)
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS);
+ FIFOResult_SetErrorCode(env, result, 0);
+ }
+ else
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_SELECT);
+ FIFOResult_SetErrorCode(env, result, errno);
+ }
+}
+
+/**
+ * Return the actual name for for a "simple" virtual name.
+ *
+ * If the platform has naming requirements for FIFOs, then return an actual name
+ * for a short file name.
+ *
+ * If the platform has no naming requirements, then return null.
+ *
+ * On linux, there are no naming requirements, so return null.
+ */
+JNIEXPORT jstring JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_toActualName (
+ JNIEnv *env,
+ jclass class,
+ jstring name)
+{
+ return NULL;
+}
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOImpl.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOImpl.h
new file mode 100644
index 000000000..7b66ddb60
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOImpl.h
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class _ipc_fifo_FIFOImpl */
+
+#ifndef _Included_org_eclipse_ecf_ipc_fifo_FIFOImpl
+#define _Included_org_eclipse_ecf_ipc_fifo_FIFOImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_READER
+#define org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_READER 0L
+#undef org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_WRITER
+#define org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_WRITER 1L
+#undef org_eclipse_ecf_ipc_fifo_FIFOImpl_BLOCKING_MODE_BLOCKING
+#define org_eclipse_ecf_ipc_fifo_FIFOImpl_BLOCKING_MODE_BLOCKING 1L
+#undef org_eclipse_ecf_ipc_fifo_FIFOImpl_BLOCKING_MODE_NON_BLOCKING
+#define org_eclipse_ecf_ipc_fifo_FIFOImpl_BLOCKING_MODE_NON_BLOCKING 2L
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: createImpl
+ * Signature: (Lcom/lts/ipc/fifo/FIFOResult;)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_createImpl
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: writeImpl
+ * Signature: (Lcom/lts/ipc/fifo/FIFOResult;[BII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_writeImpl
+ (JNIEnv *, jobject, jobject, jbyteArray, jint, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: readImpl
+ * Signature: (Lcom/lts/ipc/fifo/FIFOResult;[BII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_readImpl
+ (JNIEnv *, jobject, jobject, jbyteArray, jint, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: openImpl
+ * Signature: (Lcom/lts/ipc/fifo/FIFOResult;I)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_openImpl
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: createNonBlocking
+ * Signature: (Lcom/lts/ipc/fifo/FIFOResult;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_createNonBlocking
+ (JNIEnv *, jobject, jobject, jstring);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: readNonBlocking
+ * Signature: (Lcom/lts/ipc/fifo/FIFOResult;[BIII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_readNonBlocking
+ (JNIEnv *, jobject, jobject, jbyteArray, jint, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: writeNonBlocking
+ * Signature: (Lcom/lts/ipc/fifo/FIFOResult;[BIII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_writeNonBlocking
+ (JNIEnv *, jobject, jobject, jbyteArray, jint, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: toActualName
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_toActualName
+ (JNIEnv *, jclass, jstring);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: connectNonBlocking
+ * Signature: (Lcom/lts/ipc/fifo/FIFOResult;)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_connectNonBlocking
+ (JNIEnv *, jobject, jobject);
+
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_select(
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jint timeoutMsec);
+
+void FIFOImpl_initialize(JNIEnv *env);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOResult.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOResult.c
new file mode 100644
index 000000000..7ec60a578
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOResult.c
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/**
+ * Provide native methods required by the FIFONative class.
+ */
+
+#include <stdio.h>
+#include "FIFOImpl.h"
+#include "FIFOResult.h"
+#include "FIFOResult.h"
+
+
+#define MAX_TIMEOUT 0x7FFFFFFF
+#define HANDLE_TYPE int
+
+static int methodsInitialized = 0;
+
+static jfieldID fieldHandle;
+static jfieldID fieldResultCode;
+static jfieldID fieldErrorCode;
+static jfieldID fieldByteCount;
+static jfieldID fieldServer;
+static jfieldID fieldSyncObject;
+
+#define NAMED_PIPE_RESULT "org/eclipse/ecf/ipc/fifo/FIFOResult"
+
+void
+FIFOResult_initialize(JNIEnv *env)
+{
+ jclass nprClass;
+
+ if (methodsInitialized)
+ {
+ return;
+ }
+ else
+ {
+ methodsInitialized = 1;
+ }
+
+ nprClass = (*env)->FindClass(env, NAMED_PIPE_RESULT);
+
+ fieldHandle = (*env)->GetFieldID(env, nprClass, "handle", "J");
+ fieldResultCode = (*env)->GetFieldID(env, nprClass, "resultCode", "I");
+ fieldErrorCode = (*env)->GetFieldID(env, nprClass, "errorCode", "I");
+ fieldByteCount = (*env)->GetFieldID(env, nprClass, "byteCount", "I");
+ fieldServer = (*env)->GetFieldID(env, nprClass, "server", "Z");
+ fieldSyncObject = (*env)->GetFieldID(env, nprClass, "syncObject", "J");
+}
+
+
+void
+FIFOResult_SetHandle(JNIEnv *env, jobject result, int handle)
+{
+ (*env)->SetLongField(env, result, fieldHandle, handle);
+}
+
+
+void
+FIFOResult_SetResultCode(JNIEnv *env, jobject result, jint value)
+{
+ (*env)->SetIntField(env, result, fieldResultCode, value);
+}
+
+int
+FIFOResult_GetResultCode(JNIEnv *env, jobject result)
+{
+ return (int) (*env)->GetIntField(env, result, fieldResultCode);
+}
+
+
+void
+FIFOResult_SetErrorCode(JNIEnv *env, jobject result, int errorCode)
+{
+ jint value;
+
+ value = (jint) errorCode;
+ (*env)->SetIntField(env, result, fieldErrorCode, value);
+}
+
+
+void
+FIFOResult_SetByteCount(JNIEnv *env, jobject result, int byteCount)
+{
+ jint value = (jint) byteCount;
+ (*env)->SetIntField(env, result, fieldByteCount, value);
+}
+
+int
+FIFOResult_isServer(JNIEnv *env, jobject result)
+{
+ jboolean value = (*env)->GetBooleanField(env, result, fieldServer);
+ return (int) value;
+}
+
+jlong
+FIFOResult_GetSyncObject(JNIEnv *env, jobject result)
+{
+ jlong value = (*env)->GetLongField(env, result, fieldSyncObject);
+ return value;
+}
+
+
+void
+FIFOResult_SetSyncObject(JNIEnv *env, jobject result, jlong value)
+{
+ (*env)->SetLongField(env, result, fieldSyncObject, value);
+}
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOResult.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOResult.h
new file mode 100644
index 000000000..0b395c383
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/FIFOResult.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/**
+ * Utility routines for setting the fields in FIFOResult
+ */
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_eclipse_ecf_ipc_fifo_FIFOResult */
+
+#ifndef _Included_org_eclipse_ecf_ipc_fifo_FIFOResult
+#define _Included_org_eclipse_ecf_ipc_fifo_FIFOResult
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_UNKNOWN
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_UNKNOWN -1L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS 0L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_ACCESS_DENIED
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_ACCESS_DENIED 1L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_INVALID_HANDLE
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_INVALID_HANDLE 2L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_BUSY
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_BUSY 3L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_NOT_FOUND
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_NOT_FOUND 4L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_CLOSED
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_CLOSED 5L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT 6L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_READ
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_READ 7L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_TIMEOUT
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_TIMEOUT 8L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_SELECT
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_SELECT 9L
+
+void FIFOResult_initialize(JNIEnv *env);
+void FIFOResult_SetHandle(JNIEnv *env, jobject result, int handle);
+void FIFOResult_SetResultCode(JNIEnv *env, jobject result, jint value);
+int FIFOResult_GetResultCode(JNIEnv *env, jobject result);
+void FIFOResult_SetErrorCode(JNIEnv *env, jobject result, int errorCode);
+void FIFOResult_SetByteCount(JNIEnv *env, jobject result, int byteCount);
+int FIFOResult_isServer(JNIEnv *env, jobject result);
+jlong FIFOResult_GetSyncObject(JNIEnv *env, jobject result);
+void FIFOResult_SetSyncObject(JNIEnv *env, jobject result, jlong value);
+
+
+
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/IPCPackage.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/IPCPackage.c
new file mode 100644
index 000000000..fd2fa9d8b
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/IPCPackage.c
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/*
+ * IPCPackage.c
+ *
+ * Created on: Mar 5, 2009
+ * Author: cnh
+ */
+
+#include "IPCPackage.h"
+#include "SemaphoreResult.h"
+#include "FIFOResult.h"
+#include "FIFOImpl.h"
+
+extern void NamedPipeImpl_initialize(JNIEnv *env);
+
+
+static int initialized = 0;
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_IPCPackage_initializeNative(JNIEnv *env, jclass thisClass)
+{
+ if (initialized)
+ return;
+
+ FIFOImpl_initialize(env);
+ FIFOResult_initialize(env);
+ SemaphoreResult_initialize(env);
+
+ initialized = 1;
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/IPCPackage.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/IPCPackage.h
new file mode 100644
index 000000000..35b3eb5e4
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/IPCPackage.h
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_eclipse_ecf_ipc_IPCPackage */
+
+#ifndef _Included_org_eclipse_ecf_ipc_IPCPackage
+#define _Included_org_eclipse_ecf_ipc_IPCPackage
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: org_eclipse_ecf_ipc_IPCPackage
+ * Method: initializeNative
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_IPCPackage_initializeNative
+ (JNIEnv *, jclass);
+
+/*
+ * Class: org_eclipse_ecf_ipc_IPCPackage
+ * Method: setValue
+ * Signature: ([B)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_IPCPackage_setValue
+ (JNIEnv *, jclass, jbyteArray);
+
+/*
+ * Class: org_eclipse_ecf_ipc_IPCPackage
+ * Method: createBuffer
+ * Signature: (I)Ljava/nio/ByteBuffer;
+ */
+JNIEXPORT jobject JNICALL Java_org_eclipse_ecf_ipc_IPCPackage_createBuffer
+ (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreNative.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreNative.c
new file mode 100644
index 000000000..f61bad481
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreNative.c
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include "SemaphoreNative.h"
+#include "SemaphoreResult.h"
+
+
+static int performSemop(JNIEnv *env, jobject resultObject, int semid, int value);
+static void setResults(int outcome, JNIEnv *env, jobject result, int semid);
+
+union semun {
+ int val; /* Value for SETVAL */
+ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
+ unsigned short *array; /* Array for GETALL, SETALL */
+ struct seminfo *__buf; /* Buffer for IPC_INFO
+ (Linux-specific) */
+};
+
+/**
+ * Convert a Java supplied string to a key_t that is suitable for use in identifying
+ * a semaphore.
+ *
+ * The function uses the constant PROJID in the ftok function to come up with the
+ * identifying value.
+ */
+static key_t
+jstringToKey(JNIEnv *env, jstring s)
+{
+ char name[512];
+ int length;
+ key_t key;
+
+
+ length = (*env)->GetStringLength(env, s);
+ (*env)->GetStringUTFRegion(env, s, 0, length, name);
+
+ key = ftok(name, 1);
+
+ return key;
+}
+
+
+/**
+ * Perform an increment/decrement/wait operation.
+ *
+ * This method performs one of three operations, depending on the value of the
+ * value parameter.
+ *
+ * If value is zero, then the process will block until the semaphore becomes zero
+ * as well. If the semaphore is already zero, then the function returns immediately.
+ *
+ * If value is one or more, then the process will increase the semaphore by value.
+ * This may cause processes that are waiting for the semaphore to be woken.
+ *
+ * If the value is less than zero, the process will attempt to decrease the semaphore.
+ * If the result of this would cause the semaphore to become less than 0, the caller
+ * will block.
+ *
+ * PARAMETERS
+ * env
+ * A pointer to the JNI environment. This is required to set the values of the
+ * resultObject parameter.
+ *
+ * resultObject
+ * An instance of SemaphoreResult whose fields will be set based on the results
+ * of this function.
+ *
+ * semid
+ * An identifier for the semaphore being operated on.
+ *
+ * value
+ * The value being used in the operation as described above.
+ *
+ * RETURN VALUE
+ *
+ * The function returns 0 for success, -1 for failure.
+ */
+static int performSemop(JNIEnv *env, jobject resultObject, int semid, int value)
+{
+ struct sembuf buffer;
+ int result;
+
+ buffer.sem_num = 0;
+ buffer.sem_op = value;
+ buffer.sem_flg = 0;
+
+ result = semop(semid, &buffer, 1);
+ setResults(result, env, resultObject, semid);
+ return result;
+}
+
+/**
+ * Connect to an existing semaphore.
+ *
+ * This function simply tries to connect to the semaphore specified by the key parameter.
+ * It recodes the outcome in the supplied result object.
+ */
+static int connect(JNIEnv *env, jobject result, key_t key)
+{
+ int flags;
+ int semid;
+
+ flags = 0660;
+ semid = semget(key, 1, flags);
+ setResults(semid, env, result, semid);
+ return semid;
+}
+
+
+/**
+ * Set the contents of a SemaphoreResult object depending on the values passed into
+ * this function.
+ *
+ * If the result code signifies failure (-1), then set the result code in the result
+ * object to the value of errno, and set the value of the handle field to -1.
+ *
+ * Otherwise, set the result field in the result object to 0 and set the handle field
+ * to the value of the semaphore ID.
+ *
+ * PARAMS
+ *
+ * outcome
+ * Whether the caller wants to signify success or failure. A value of -1 signifies
+ * failure, while any other code signifies success.
+ *
+ * env
+ * The JNI environment. Required to be able to set the fields of the result object.
+ *
+ * result
+ * The result object. This is the thing that the function sets.
+ *
+ * semid
+ * The identifier for a semaphore. In success cases, this should be a non-
+ * negative integer value.
+ */
+static void setResults(int outcome, JNIEnv *env, jobject result, int semid)
+{
+ if (-1 == outcome)
+ {
+ SemaphoreResult_setResult(env, result, errno);
+ SemaphoreResult_setHandle(env, result, -1);
+ }
+ else
+ {
+ SemaphoreResult_setResult(env, result, 0);
+ SemaphoreResult_setHandle(env, result, semid);
+ }
+}
+
+/**
+ * Attempt to create and initialize a semaphore.
+ *
+ * This function will try to create a new semaphore. On successfully creating
+ * a semaphore, the function will set the initial value of the semaphore to the
+ * value passed to the function.
+ *
+ * The function will fail if the semaphore already exists. It does not try to
+ * do anything else in such a failure scenario, though it will set the contents
+ * of the result object in such a situation.
+ *
+ * PARAMETERS
+ * env
+ * A pointer to the JNI environment. This is required when setting the
+ * contents of the result object.
+ *
+ * result
+ * A SemaphoreResult object that holds failure codes and the like if the
+ * attempt to create a new semaphore fails.
+ *
+ * key
+ * The key used to identify which semaphore to create or initialize. This
+ * is usually obtained via ftok.
+ *
+ * initialValue
+ * The initial value for the semaphore.
+ *
+ * RETURN VALUE
+ *
+ * The function returns -1 to signal that it could not create the semaphore, or
+ * that it could not initialize the semaphore once created. On success, the
+ * return value is the semaphore ID for the newly created semaphore.
+ */
+static int create(JNIEnv *env, jobject result, key_t key, jint initialValue)
+{
+ int flags;
+ int semid;
+ int returnCode;
+
+ //
+ // Create the semaphore
+ //
+ flags = 0660; // r/w by user/group, nothing for others
+ flags = flags | IPC_CREAT | IPC_EXCL;
+ semid = semget(key, 1, flags);
+
+ //
+ // If we failed, stop here
+ //
+ if (-1 == semid)
+ {
+ setResults(semid, env, result, semid);
+ returnCode = -1;
+ }
+ else
+ {
+ union semun argument;
+
+ argument.val = initialValue;
+
+ returnCode = semctl(semid, 0, SETVAL, argument);
+
+ if (0 == returnCode)
+ {
+ setResults(semid, env, result, semid);
+ returnCode = semid;
+ }
+ }
+
+ return returnCode;
+}
+
+
+/**
+ * Connect to the semaphore, creating it if it does not already exist.
+ */
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_connect (
+ JNIEnv *env,
+ jclass clazz,
+ jobject resultObject,
+ jstring semaphoreName,
+ jint initialValue)
+{
+ key_t key;
+ int semid;
+
+ key = jstringToKey(env, semaphoreName);
+
+ //
+ // Try to create the semaphore. If that succeeds then we are done.
+ //
+ semid = create(env, resultObject, key, initialValue);
+
+ //
+ // If the attempt fails because the semaphore already exists, then try to connect
+ // to it. Accept the outcode of the connect as the outcome to this method.
+ //
+ if (-1 == semid && EEXIST == errno)
+ {
+ semid = connect(env, resultObject, key);
+ }
+}
+
+/**
+ * Increment the semaphore, possibly causing processes that are waiting for it to
+ * wake up.
+ */
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_increment (
+ JNIEnv *env,
+ jclass clazz,
+ jobject result,
+ jlong handle)
+{
+ int semid;
+
+ semid = handle;
+ performSemop(env, result, semid, 1);
+}
+
+/**
+ * Decrement the semaphore, possibly causing the calling process to block waiting
+ * for it to become available.
+ */
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_decrement (
+ JNIEnv *env,
+ jclass clazz,
+ jobject result,
+ jlong handle,
+ jlong msecTimeout)
+{
+ int semid;
+
+ semid = (int) handle;
+ performSemop(env, result, semid, -1);
+}
+
+
+JNIEXPORT jint JNICALL
+Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_getNamingMethod
+ (JNIEnv *env, jclass clazz)
+{
+ return 1;
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreNative.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreNative.h
new file mode 100644
index 000000000..95f3d3a7e
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreNative.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_eclipse_ecf_ipc_semaphore_SemaphoreNative */
+
+#ifndef _Included_org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+#define _Included_org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: connect
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;Ljava/lang/String;II)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_connect
+ (JNIEnv *, jclass, jobject, jstring, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: increment
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;J)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_increment
+ (JNIEnv *, jclass, jobject, jlong);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: decrement
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_decrement
+ (JNIEnv *, jclass, jobject, jlong, jlong);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: getValue
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;J)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_getValue
+ (JNIEnv *, jclass, jobject, jlong);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: supportsGetValue
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_supportsGetValue
+ (JNIEnv *, jclass);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: setValue
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;JI)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_setValue
+ (JNIEnv *, jclass, jobject, jlong, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: supportsSetValue
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_supportsSetValue
+ (JNIEnv *, jclass);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: createResult
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;Ljava/lang/String;II)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_createResult
+ (JNIEnv *, jclass, jobject, jstring, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: linkTest
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_linkTest
+ (JNIEnv *, jclass);
+
+JNIEXPORT jint JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_getNamingMethod
+ (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreResult.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreResult.c
new file mode 100644
index 000000000..547b7050a
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreResult.c
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/*
+ * Accessor methods for the SemaphoreResult class.
+ *
+ * Created on: Mar 5, 2009
+ * Author: cnh
+ */
+
+#include <jni.h>
+#include <errno.h>
+
+#include "SemaphoreResult.h"
+
+static jfieldID handleField;
+static jfieldID errorCodeField;
+static jfieldID resultCodeField;
+
+#define CLASS_NAME "org/eclipse/ecf/ipc/semaphore/SemaphoreResult"
+#define RESULT_SIGNATURE "Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult$Results;"
+
+void SemaphoreResult_initialize(JNIEnv *env)
+{
+ jclass clazz;
+
+ clazz = (*env)->FindClass(env, CLASS_NAME);
+
+ handleField = (*env)->GetFieldID(env, clazz, "handle", "J");
+ resultCodeField = (*env)->GetFieldID(env, clazz, "resultCode", "I");
+ errorCodeField = (*env)->GetFieldID(env, clazz, "errorCode", "I");
+}
+
+
+void SemaphoreResult_setResult(JNIEnv *env, jobject this, int rawCode)
+{
+ (*env)->SetIntField(env, this, errorCodeField, rawCode);
+}
+
+
+void SemaphoreResult_setHandle(JNIEnv *env, jobject this, int semid)
+{
+ jlong value;
+
+ value = (jlong) ((int) semid);
+ (*env)->SetLongField(env, this, handleField, value);
+}
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreResult.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreResult.h
new file mode 100644
index 000000000..82780d9f2
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/SemaphoreResult.h
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/*
+ * SemaphoreResult.h
+ *
+ * Created on: Mar 5, 2009
+ * Author: cnh
+ */
+#include <jni.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <semaphore.h>
+
+#ifndef SEMAPHORERESULT_H_
+#define SEMAPHORERESULT_H_
+
+extern void SemaphoreResult_setResult(JNIEnv *env, jobject this, int code);
+extern void SemaphoreResult_setHandle(JNIEnv *env, jobject this, int id);
+extern void SemaphoreResult_initialize(JNIEnv *env);
+
+#endif /* SEMAPHORERESULT_H_ */
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/util.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/util.c
new file mode 100644
index 000000000..43c8f7a15
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/util.c
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <jni.h>
+
+//
+// The neighbor of the beast
+//
+#define PROJID 668
+
+/**
+ * Convert a Java supplied string to a key_t that is suitable for use in identifying
+ * a semaphore.
+ *
+ * The function uses the constant PROJID in the ftok function to come up with the
+ * identifying value.
+ */
+key_t jstringToKey(JNIEnv *env, jstring s)
+{
+ char name[512];
+ int length;
+ key_t key;
+
+
+ length = (*env)->GetStringLength(env, s);
+ (*env)->GetStringUTFRegion(env, s, 0, length, name);
+ key = ftok(name, PROJID);
+
+ return key;
+}
+
+
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/util.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/util.h
new file mode 100644
index 000000000..bfbf2a5de
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/linux/util.h
@@ -0,0 +1,12 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+extern key_t jstringToKey(JNIEnv *env, jstring s);
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOImpl.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOImpl.c
new file mode 100644
index 000000000..c6a7ba875
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOImpl.c
@@ -0,0 +1,803 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/**
+ * Provide native methods required by the FIFONative class.
+ */
+
+#include <windows.h>
+#include <stdio.h>
+#include "FIFOImpl.h"
+#include "FIFOResult.h"
+#include "FIFOResult.h"
+
+
+#define MAX_TIMEOUT 0x7FFFFFFF
+#define HANDLE_TYPE int
+
+static int methodsInitialized = 0;
+
+static jmethodID methodIsCreator;
+static jmethodID methodGetHandle;
+static jmethodID methodGetActualName;
+static jmethodID methodGetBufferSize;
+
+#define NAMED_PIPE_IMPL "org/eclipse/ecf/ipc/fifo/FIFOImpl"
+#define NAMED_PIPE_RESULT "org/eclipse/ecf/ipc/fifo/FIFOResult"
+
+
+static HANDLE
+getSyncHandle(JNIEnv *env, jobject result)
+{
+ DWORD temp;
+
+ temp = (DWORD) FIFOResult_GetSyncObject(env, result);
+ return (HANDLE) temp;
+}
+
+
+static void
+setSyncHandle(JNIEnv *env, jobject result, HANDLE value)
+{
+ DWORD temp;
+
+ temp = (DWORD) value;
+ FIFOResult_SetSyncObject(env, result, (jlong) temp);
+}
+
+
+static void
+convertToTSTR(const char* s, TCHAR *buf)
+{
+ int index;
+
+ index = 0;
+ while (s[index] != '\0')
+ {
+ buf[index] = s[index];
+ index++;
+ }
+
+ buf[index] = '\0';
+}
+
+
+static void
+jstringToTString(JNIEnv *env, jstring s, TCHAR *buff)
+{
+ int len;
+ char localBuffer[256];
+
+
+ len = (*env)->GetStringLength(env, s);
+ (*env)->GetStringUTFRegion(env, s, 0, len, localBuffer);
+ convertToTSTR(localBuffer, buff);
+}
+
+
+static void
+jstringToString(JNIEnv *env, jstring s, char *buff)
+{
+ int len;
+
+ len = (*env)->GetStringLength(env, s);
+ (*env)->GetStringUTFRegion(env, s, 0, len, buff);
+}
+
+static void
+implGetActualName(JNIEnv *env, jobject this, TCHAR *buf)
+{
+ jstring value;
+
+ value = (*env)->CallObjectMethod(env, this, methodGetActualName);
+ jstringToTString(env, value, buf);
+}
+
+static DWORD
+implGetBufferSize(JNIEnv *env, jobject this)
+{
+ jint value;
+ long temp;
+
+ value = (*env)->CallIntMethod(env, this, methodGetBufferSize);
+ temp = (long) value;
+ return (DWORD) temp;
+}
+
+void
+FIFOImpl_initialize(JNIEnv *env)
+{
+ jclass npiClass;
+ jclass nprClass;
+
+ if (methodsInitialized)
+ {
+ return;
+ }
+ else
+ {
+ methodsInitialized = 1;
+ }
+
+ npiClass = (*env)->FindClass(env, NAMED_PIPE_IMPL);
+ nprClass = (*env)->FindClass(env, NAMED_PIPE_RESULT);
+
+ methodIsCreator = (*env)->GetMethodID(env, npiClass, "isCreator", "()Z");
+ methodGetHandle = (*env)->GetMethodID(env, npiClass, "getHandle", "()J");
+ methodGetActualName = (*env)->GetMethodID(env, npiClass, "getActualName", "()Ljava/lang/String;");
+ methodGetBufferSize = (*env)->GetMethodID(env, npiClass, "getBufferSize", "()I");
+}
+
+
+
+
+JNIEXPORT jboolean JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_virtualNameContainsActualNameImpl (
+ JNIEnv *env,
+ jclass class)
+{
+ jboolean result = 1;
+ return result;
+}
+
+
+static int
+implIsCreator(JNIEnv *env, jobject this)
+{
+ jint value;
+
+ value = (*env)->CallBooleanMethod(env, this, methodIsCreator);
+ return (int) value;
+}
+
+static HANDLE
+implGetHandle(JNIEnv *env, jobject this)
+{
+ jlong value;
+
+ value = (*env)->CallLongMethod(env, this, methodGetHandle);
+ return (HANDLE) ((long) value);
+}
+
+
+void
+openServer(JNIEnv *env, jobject this, jobject result)
+{
+ HANDLE nph;
+ BOOL success;
+ jint resultCode;
+
+
+ nph = implGetHandle(env, this);
+ success = ConnectNamedPipe(nph, NULL);
+
+ if (success || ERROR_PIPE_CONNECTED == GetLastError())
+ {
+ resultCode = org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS;
+ FIFOResult_SetHandle(env, result, nph);
+ }
+ else
+ {
+ switch(GetLastError())
+ {
+ case ERROR_NO_DATA :
+ {
+ resultCode = org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_INVALID_HANDLE;
+ break;
+ }
+
+ default :
+ {
+ resultCode = org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_UNKNOWN;
+ break;
+ }
+ }
+ }
+
+ FIFOResult_SetResultCode(env, result, resultCode);
+}
+
+
+void
+openClient (JNIEnv *env, jobject this, jobject result)
+{
+ HANDLE handle;
+ TCHAR name[256];
+ DWORD readWriteMode;
+ jint resultCode;
+ DWORD errorCode;
+
+ readWriteMode = PIPE_ACCESS_DUPLEX | PIPE_TYPE_BYTE | PIPE_WAIT;
+ implGetActualName(env, this, name);
+
+ handle = CreateFile(
+ name, // pipe name
+ readWriteMode, // read and write access
+ 0, // no sharing
+ NULL, // default security attributes
+ OPEN_EXISTING, // opens existing pipe
+ 0, // default attributes
+ NULL); // no template file
+
+ if (INVALID_HANDLE_VALUE != handle)
+ {
+ resultCode = 0;
+ errorCode = 0;
+ FIFOResult_SetHandle(env, result, handle);
+ }
+ else
+ {
+ errorCode = GetLastError();
+ switch(GetLastError())
+ {
+ case ERROR_ACCESS_DENIED :
+ resultCode = (jint) org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_ACCESS_DENIED;
+ break;
+
+ case ERROR_PIPE_BUSY :
+ resultCode = (jint) org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_BUSY;
+ break;
+
+ default :
+ resultCode = (jint) org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_UNKNOWN;
+ break;
+ }
+ }
+
+ FIFOResult_SetResultCode(env, result, resultCode);
+ FIFOResult_SetErrorCode(env, result, errorCode);
+}
+
+
+/**
+ * Connect the named pipe to another process.
+ *
+ * Windows requires that the connectiong process know if it is the "client" or the
+ * "server" when connecting, so we care about the creator parameter.
+ *
+ * All Windows named pipes, however, are bidirectional, so ignore the direction
+ * parameter.
+ */
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_openImpl (
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jint direction)
+{
+ int isCreatorValue;
+ HANDLE handle;
+
+ isCreatorValue = implIsCreator(env, this);
+ handle = implGetHandle(env, this);
+
+ if (isCreatorValue)
+ {
+ openServer(env, this, result);
+ }
+ else
+ {
+ openClient(env, this, result);
+ }
+}
+
+
+/**
+ * Create a new instance of a named pipe and create the named pipe itself if it
+ * doesn't already exist.
+ *
+ * In windows, the CreateNamedPipe system call must always be used before attempting
+ * to perform any operations on a named pipe. This is unlike POSIX, where the pipe
+ * is created once, and then clients can simply open or close the pipe like they
+ * would any other file.
+ *
+ * This method modifies the result parameter rather than returning a value. The
+ * various fields are populated according to whether or not the calls were successful.
+ *
+ * If the call was successful, result.resultCode should be 0 and result.handle
+ * should contain the value returned by the CreateNamedPipe system call.
+ *
+ * If the call failed, result.resultCode should contain a non-zero value that is
+ * taken from the constants defined by FIFOResult.ERROR_ In that situation,
+ * the value of result.handle is not defined.
+ */
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_createImpl (
+ JNIEnv *env,
+ jobject this,
+ jobject result)
+{
+ jint resultCodeValue;
+ HANDLE handle;
+ DWORD dwOpenMode;
+ TCHAR tstring[256];
+ DWORD bufferSize;
+ DWORD dwPipeMode;
+ DWORD nDefaultTimeout;
+
+ dwOpenMode = PIPE_ACCESS_DUPLEX;
+ dwPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
+ nDefaultTimeout = NMPWAIT_USE_DEFAULT_WAIT;
+
+ implGetActualName(env, this, tstring);
+ bufferSize = implGetBufferSize(env, this);
+
+
+ handle = CreateNamedPipe(
+ tstring, // pipe name
+ dwOpenMode, // open modes
+ dwPipeMode, // pipe mode (stream oriented, blocking)
+ PIPE_UNLIMITED_INSTANCES, // create as many as you want
+ (DWORD) bufferSize, // outgoing buffer size
+ (DWORD) bufferSize, // incoming buffer size
+ nDefaultTimeout, // no default timeout
+ NULL); // default security
+
+ if (INVALID_HANDLE_VALUE != handle)
+ {
+ resultCodeValue = 0;
+ FIFOResult_SetHandle(env, result, handle);
+ }
+ else
+ {
+ if (ERROR_ACCESS_DENIED == GetLastError())
+ {
+ resultCodeValue = (jint) org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_ACCESS_DENIED;
+ }
+ else
+ {
+ resultCodeValue = (jint) org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_UNKNOWN;
+ }
+ }
+
+ FIFOResult_SetResultCode(env, result, resultCodeValue);
+}
+
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_writeImpl (
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jbyteArray buffer,
+ jint offset,
+ jint length)
+{
+ BOOL success;
+ jboolean isCopy;
+ HANDLE handle;
+ jbyte *actualBuffer;
+ DWORD actualCount;
+ jbyte *bptr;
+
+ handle = implGetHandle(env, this);
+
+ actualBuffer = (*env)->GetByteArrayElements(env, buffer, &isCopy);
+ bptr = actualBuffer + offset;
+
+ success = WriteFile(handle, bptr, length, &actualCount, NULL);
+
+ (*env)->ReleaseByteArrayElements(env, buffer, actualBuffer, JNI_ABORT);
+
+ FIFOResult_SetHandle(env, result, handle);
+ if (success)
+ {
+ FIFOResult_SetResultCode(env, result, 0);
+ FIFOResult_SetErrorCode(env, result, 0);
+ FIFOResult_SetByteCount(env, result, actualCount);
+ }
+ else
+ {
+ FIFOResult_SetResultCode(env, result, -1);
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ }
+}
+
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_readImpl (
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jbyteArray buffer,
+ jint offset,
+ jint length)
+{
+ BOOL success;
+ jboolean junk;
+ HANDLE handle;
+ jbyte *actualBuffer;
+ jbyte *ptr;
+ DWORD actualCount;
+
+ FIFOResult_initialize(env);
+
+ handle = implGetHandle(env, this);
+
+ actualBuffer = (*env)->GetByteArrayElements(env, buffer, &junk);
+ ptr = actualBuffer + offset;
+
+ success = ReadFile(handle, ptr, length, &actualCount, NULL);
+
+ (*env)->ReleaseByteArrayElements(env, buffer, actualBuffer, JNI_COMMIT);
+
+ FIFOResult_SetHandle(env, result, handle);
+ if (success)
+ {
+ FIFOResult_SetResultCode(env, result, 0);
+ FIFOResult_SetErrorCode(env, result, 0);
+ FIFOResult_SetByteCount(env, result, actualCount);
+ }
+ else
+ {
+ FIFOResult_SetResultCode(env, result, -1);
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ }
+}
+
+void createNonBlockingServer(
+ JNIEnv *env,
+ jobject result)
+{
+ jint resultCodeValue;
+ HANDLE handle;
+ DWORD dwOpenMode;
+ TCHAR tstring[256];
+ DWORD dwPipeMode;
+ dwOpenMode = PIPE_ACCESS_DUPLEX;
+ dwOpenMode = dwOpenMode | FILE_FLAG_OVERLAPPED;
+ dwPipeMode = PIPE_TYPE_BYTE;
+ dwPipeMode = dwPipeMode | PIPE_WAIT;
+
+ handle = CreateNamedPipe(
+ tstring, // pipe name
+ dwOpenMode, // open modes
+ dwPipeMode, // pipe mode (stream oriented, blocking)
+ PIPE_UNLIMITED_INSTANCES, // create as many as you want
+ (DWORD) 1024, // outgoing buffer size
+ (DWORD) 1024, // incoming buffer size
+ NMPWAIT_USE_DEFAULT_WAIT, // no default timeout
+ NULL);
+
+ if (INVALID_HANDLE_VALUE != handle)
+ {
+ resultCodeValue = 0;
+ FIFOResult_SetHandle(env, result, handle);
+ }
+ else if (ERROR_ACCESS_DENIED == GetLastError())
+ {
+ resultCodeValue = (jint) org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_ACCESS_DENIED;
+ }
+ else
+ {
+ resultCodeValue = (jint) org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_UNKNOWN;
+ }
+
+ FIFOResult_SetResultCode(env, result, resultCodeValue);
+}
+
+static void
+closeNonBlockingError(JNIEnv *env, jobject result, int resultCode)
+{
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ FIFOResult_SetResultCode(env, result, (jint) org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT);
+ CloseHandle(getSyncHandle(env, result));
+}
+
+static void
+connectNonBlockingServer(JNIEnv *env, jobject this, jobject result)
+{
+ HANDLE handle;
+ BOOL success;
+ OVERLAPPED over;
+ DWORD waitResult;
+
+ over.Offset = 0;
+ over.OffsetHigh = 0;
+ over.hEvent = CreateEvent(NULL, TRUE, TRUE, "pipeReady");
+
+ //
+ // Note that the connect call SHOULD FAIL at this point.
+ //
+ handle = implGetHandle(env, this);
+ success = ConnectNamedPipe(handle, &over);
+
+ if (success || ERROR_IO_PENDING != GetLastError())
+ {
+ closeNonBlockingError(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT);
+ return;
+ }
+
+ //
+ // Despite being non-blocking, the caller will wait indefinitely for someone
+ // to connect
+ //
+ waitResult = WaitForSingleObject(over.hEvent, INFINITE);
+ if (WAIT_OBJECT_0 != waitResult)
+ {
+ closeNonBlockingError(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT);
+ return;
+ }
+
+ //
+ // otherwise, we now have a connection
+ //
+ FIFOResult_SetErrorCode(env, result, 0);
+ FIFOResult_SetResultCode(env, result, 0);
+ FIFOResult_SetHandle(env, result, handle);
+ setSyncHandle(env, result, over.hEvent);
+}
+
+static void
+connectNonBlockingClient (
+ JNIEnv *env,
+ jobject this,
+ jobject result)
+{
+ HANDLE file;
+ TCHAR actual[512];
+ DWORD mode;
+
+ mode = GENERIC_READ | GENERIC_WRITE;
+
+ implGetActualName(env, this, actual);
+
+ file = CreateFile(
+ actual, // name
+ mode, // easiest to just to read/write
+ 0, // no sharing
+ NULL, // default security
+ OPEN_EXISTING, // open existing pipe
+ FILE_FLAG_OVERLAPPED, // async I/O
+ NULL); // no template file
+
+ if (INVALID_HANDLE_VALUE == file)
+ {
+ closeNonBlockingError(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT);
+ return;
+ }
+ else
+ {
+ HANDLE eventObj;
+ eventObj = CreateEvent(NULL, TRUE, TRUE, "pipeReady");
+ setSyncHandle(env, result, eventObj);
+ FIFOResult_SetErrorCode(env, result, 0);
+ FIFOResult_SetResultCode(env, result, 0);
+ FIFOResult_SetHandle(env, result, file);
+ setSyncHandle(env, result, eventObj);
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_connectNonBlocking (
+ JNIEnv *env,
+ jobject this,
+ jobject result)
+{
+ if (FIFOResult_isServer(env, result))
+ {
+ connectNonBlockingServer(env, this, result);
+ }
+ else
+ {
+ connectNonBlockingClient(env, this, result);
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_createNonBlocking (
+ JNIEnv *env,
+ jclass class,
+ jobject result,
+ jstring name)
+{
+ HANDLE eventHandle;
+
+ if (FIFOResult_isServer(env, result))
+ {
+ createNonBlockingServer(env, result);
+ }
+
+ eventHandle = CreateEvent(NULL, TRUE, TRUE, "pipeReady");
+
+ setSyncHandle(env, result, eventHandle);
+}
+
+static void
+performNonBlockingRead(
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ VOID* ptr,
+ DWORD length,
+ DWORD timeoutMsec)
+{
+ OVERLAPPED over;
+ DWORD bytesRead;
+ BOOL success;
+
+ over.Offset = 0;
+ over.OffsetHigh = 0;
+ over.hEvent = getSyncHandle(env, result);
+
+
+ success = ReadFile(
+ implGetHandle(env, this),
+ ptr,
+ (DWORD) length,
+ &bytesRead,
+ &over);
+
+ if (success || GetLastError() != ERROR_IO_PENDING)
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_READ);
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ return;
+ }
+
+ DWORD resultCode;
+ DWORD timeout;
+
+ if (timeoutMsec < 0)
+ {
+ timeout = INFINITE;
+ }
+
+ resultCode = WaitForSingleObject(
+ getSyncHandle(env, result),
+ (DWORD) timeoutMsec);
+
+ if (WAIT_TIMEOUT == resultCode)
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_TIMEOUT);
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ return;
+ }
+ else if (WAIT_OBJECT_0 != resultCode)
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_READ);
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ return;
+ }
+
+ GetOverlappedResult(
+ implGetHandle(env, this),
+ &over,
+ &bytesRead,
+ FALSE);
+
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS);
+ FIFOResult_SetErrorCode(env, result, ERROR_SUCCESS);
+ FIFOResult_SetByteCount(env, result, bytesRead);
+}
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_readNonBlocking (
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jbyteArray buffer,
+ jint start,
+ jint length,
+ jint timeoutMsec)
+{
+ VOID *actualBuffer;
+ VOID *ptr;
+
+ actualBuffer = (*env)->GetByteArrayElements(env, buffer, NULL);
+ ptr = actualBuffer + start;
+
+ performNonBlockingRead(env, this, result, ptr, length, timeoutMsec);
+
+ (*env)->ReleaseByteArrayElements(env, buffer, actualBuffer, JNI_COMMIT);
+}
+
+
+static void
+nonBlockingWrite(
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ VOID* ptr,
+ DWORD length,
+ DWORD timeoutMsec)
+{
+ OVERLAPPED over;
+ DWORD bytesWritten;
+ BOOL success;
+ DWORD resultCode;
+
+
+ over.Offset = 0;
+ over.OffsetHigh = 0;
+ over.hEvent = getSyncHandle(env, result);
+
+ success = WriteFile(
+ implGetHandle(env, this),
+ ptr,
+ (DWORD) length,
+ &bytesWritten,
+ &over);
+
+ if (success || GetLastError() != ERROR_IO_PENDING)
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_READ);
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ return;
+ }
+
+ if (timeoutMsec < 0)
+ {
+ timeoutMsec = INFINITE;
+ }
+
+ resultCode = WaitForSingleObject(
+ getSyncHandle(env, result),
+ timeoutMsec);
+
+ if (WAIT_TIMEOUT == resultCode)
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_TIMEOUT);
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ return;
+ }
+ else if (WAIT_OBJECT_0 != resultCode)
+ {
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_READ);
+ FIFOResult_SetErrorCode(env, result, GetLastError());
+ return;
+ }
+
+ GetOverlappedResult(
+ implGetHandle(env, this),
+ &over,
+ &bytesWritten,
+ FALSE);
+
+ FIFOResult_SetResultCode(env, result, org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS);
+ FIFOResult_SetErrorCode(env, result, ERROR_SUCCESS);
+ FIFOResult_SetByteCount(env, result, bytesWritten);
+}
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_writeNonBlocking (
+ JNIEnv *env,
+ jobject this,
+ jobject result,
+ jbyteArray buffer,
+ jint start,
+ jint length,
+ jint timeoutMsec)
+{
+ VOID *actualBuffer;
+ VOID *ptr;
+
+ actualBuffer = (*env)->GetByteArrayElements(env, buffer, NULL);
+ ptr = actualBuffer + start;
+
+ nonBlockingWrite(env, this, result, ptr, length, timeoutMsec);
+
+ (*env)->ReleaseByteArrayElements(env, buffer, actualBuffer, JNI_COMMIT);
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_toActualName(
+ JNIEnv *env,
+ jclass class,
+ jstring suffix)
+{
+ char strSuffix[512];
+ char buffer[512];
+
+
+ jstringToString(env, suffix, strSuffix);
+ sprintf(buffer, "\\\\.\\pipe\\%s", strSuffix);
+ return (*env)->NewStringUTF(env, buffer);
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOImpl.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOImpl.h
new file mode 100644
index 000000000..b423e9d60
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOImpl.h
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_lts_ipc_fifo_FIFOImpl */
+
+#ifndef _Included_org_eclipse_ecf_ipc_fifo_FIFOImpl
+#define _Included_org_eclipse_ecf_ipc_fifo_FIFOImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_READER
+#define org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_READER 0L
+#undef org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_WRITER
+#define org_eclipse_ecf_ipc_fifo_FIFOImpl_DIRECTION_WRITER 1L
+#undef org_eclipse_ecf_ipc_fifo_FIFOImpl_BLOCKING_MODE_BLOCKING
+#define org_eclipse_ecf_ipc_fifo_FIFOImpl_BLOCKING_MODE_BLOCKING 1L
+#undef org_eclipse_ecf_ipc_fifo_FIFOImpl_BLOCKING_MODE_NON_BLOCKING
+#define org_eclipse_ecf_ipc_fifo_FIFOImpl_BLOCKING_MODE_NON_BLOCKING 2L
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: createImpl
+ * Signature: (Lorg/eclipse/ecf/ipc/fifo/FIFOResult;)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_createImpl
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: writeImpl
+ * Signature: (Lorg/eclipse/ecf/ipc/fifo/FIFOResult;[BII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_writeImpl
+ (JNIEnv *, jobject, jobject, jbyteArray, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: readImpl
+ * Signature: (Lorg/eclipse/ecf/ipc/fifo/FIFOResult;[BII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_readImpl
+ (JNIEnv *, jobject, jobject, jbyteArray, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: openImpl
+ * Signature: (Lorg/eclipse/ecf/ipc/fifo/FIFOResult;I)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_openImpl
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: createNonBlocking
+ * Signature: (Lorg/eclipse/ecf/ipc/fifo/FIFOResult;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_createNonBlocking
+ (JNIEnv *, jobject, jobject, jstring);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: readNonBlocking
+ * Signature: (Lorg/eclipse/ecf/ipc/fifo/FIFOResult;[BIII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_readNonBlocking
+ (JNIEnv *, jobject, jobject, jbyteArray, jint, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: writeNonBlocking
+ * Signature: (Lorg/eclipse/ecf/ipc/fifo/FIFOResult;[BIII)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_writeNonBlocking
+ (JNIEnv *, jobject, jobject, jbyteArray, jint, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: toActualName
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_toActualName
+ (JNIEnv *, jclass, jstring);
+
+/*
+ * Class: org_eclipse_ecf_ipc_fifo_FIFOImpl
+ * Method: connectNonBlocking
+ * Signature: (Lorg/eclipse/ecf/ipc/fifo/FIFOResult;)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_fifo_FIFOImpl_connectNonBlocking
+ (JNIEnv *, jobject, jobject);
+
+void FIFOImpl_initialize(JNIEnv *env);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOResult.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOResult.c
new file mode 100644
index 000000000..e0610bb3d
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOResult.c
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/**
+ * Provide native methods required by the FIFONative class.
+ */
+
+#include <windows.h>
+#include <stdio.h>
+#include "FIFOImpl.h"
+#include "FIFOResult.h"
+#include "FIFOResult.h"
+
+
+#define MAX_TIMEOUT 0x7FFFFFFF
+#define HANDLE_TYPE int
+
+static int methodsInitialized = 0;
+
+static jfieldID fieldHandle;
+static jfieldID fieldResultCode;
+static jfieldID fieldErrorCode;
+static jfieldID fieldByteCount;
+static jfieldID fieldServer;
+static jfieldID fieldSyncObject;
+
+#define NAMED_PIPE_RESULT "org/eclipse/ecf/ipc/fifo/FIFOResult"
+
+void
+FIFOResult_initialize(JNIEnv *env)
+{
+ jclass nprClass;
+
+ if (methodsInitialized)
+ {
+ return;
+ }
+ else
+ {
+ methodsInitialized = 1;
+ }
+
+ nprClass = (*env)->FindClass(env, NAMED_PIPE_RESULT);
+
+ fieldHandle = (*env)->GetFieldID(env, nprClass, "handle", "J");
+ fieldResultCode = (*env)->GetFieldID(env, nprClass, "resultCode", "I");
+ fieldErrorCode = (*env)->GetFieldID(env, nprClass, "errorCode", "I");
+ fieldByteCount = (*env)->GetFieldID(env, nprClass, "byteCount", "I");
+ fieldServer = (*env)->GetFieldID(env, nprClass, "server", "Z");
+ fieldSyncObject = (*env)->GetFieldID(env, nprClass, "syncObject", "J");
+}
+
+
+void
+FIFOResult_SetHandle(JNIEnv *env, jobject result, HANDLE handle)
+{
+ jlong value;
+ DWORD dword;
+
+ dword = (DWORD) handle;
+ value = dword;
+ (*env)->SetLongField(env, result, fieldHandle, value);
+}
+
+
+void
+FIFOResult_SetResultCode(JNIEnv *env, jobject result, jint value)
+{
+ (*env)->SetIntField(env, result, fieldResultCode, value);
+}
+
+
+void
+FIFOResult_SetErrorCode(JNIEnv *env, jobject result, DWORD errorCode)
+{
+ jint value;
+
+ value = (jint) errorCode;
+ (*env)->SetIntField(env, result, fieldErrorCode, value);
+}
+
+
+void
+FIFOResult_SetByteCount(JNIEnv *env, jobject result, DWORD byteCount)
+{
+ jint value = (jint) byteCount;
+ (*env)->SetIntField(env, result, fieldByteCount, value);
+}
+
+int
+FIFOResult_isServer(JNIEnv *env, jobject result)
+{
+ jboolean value = (*env)->GetBooleanField(env, result, fieldServer);
+ return (int) value;
+}
+
+jlong
+FIFOResult_GetSyncObject(JNIEnv *env, jobject result)
+{
+ jlong value = (*env)->GetLongField(env, result, fieldSyncObject);
+ return value;
+}
+
+
+void
+FIFOResult_SetSyncObject(JNIEnv *env, jobject result, jlong value)
+{
+ (*env)->SetLongField(env, result, fieldSyncObject, value);
+}
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOResult.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOResult.h
new file mode 100644
index 000000000..61f5e44db
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/FIFOResult.h
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/**
+ * Utility routines for setting the fields in FIFOResult
+ */
+#ifndef _Included_org_eclipse_ecf_ipc_fifo_FIFOResult
+#define _Included_org_eclipse_ecf_ipc_fifo_FIFOResult
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_UNKNOWN
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_UNKNOWN -1L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_SUCCESS 0L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_ACCESS_DENIED
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_ACCESS_DENIED 1L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_INVALID_HANDLE
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_INVALID_HANDLE 2L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_BUSY
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_BUSY 3L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_NOT_FOUND
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_NOT_FOUND 4L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_CLOSED
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_PIPE_CLOSED 5L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_CONNECT 6L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_READ
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_ERROR_READ 7L
+#undef org_eclipse_ecf_ipc_fifo_FIFOResult_TIMEOUT
+#define org_eclipse_ecf_ipc_fifo_FIFOResult_TIMEOUT 8L
+
+
+
+extern void
+FIFOResult_SetHandle(JNIEnv *env, jobject result, HANDLE handle);
+
+extern void
+FIFOResult_SetResultCode(JNIEnv *env, jobject result, jint value);
+
+extern void
+FIFOResult_SetErrorCode(JNIEnv *env, jobject result, DWORD errorCode);
+
+extern void
+FIFOResult_SetByteCount(JNIEnv *env, jobject result, DWORD byteCount);
+
+extern int
+FIFOResult_isServer(JNIEnv * env, jobject result);
+
+extern void
+FIFOResult_initialize(JNIEnv *env);
+
+extern jlong
+FIFOResult_GetSyncObject(JNIEnv *env, jobject result);
+
+extern void
+FIFOResult_SetSyncObject(JNIEnv *env, jobject result, jlong value);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/IPCPackage.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/IPCPackage.c
new file mode 100644
index 000000000..fc33634ed
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/IPCPackage.c
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/*
+ * IPCPackage.c
+ *
+ * Created on: Mar 5, 2009
+ * Author: cnh
+ */
+
+#include <jni.h>
+#include <windows.h>
+#include <stdio.h>
+#include "IPCPackage.h"
+#include "SemaphoreResult.h"
+#include "FIFOImpl.h"
+#include "FIFOResult.h"
+
+static int initialized = 0;
+
+JNIEXPORT void JNICALL
+Java_org_eclipse_ecf_ipc_IPCPackage_initializeNative(JNIEnv *env, jclass thisClass)
+{
+ if (initialized)
+ return;
+
+ SemaphoreResult_initialize(env);
+ FIFOImpl_initialize(env);
+ FIFOResult_initialize(env);
+
+ initialized = 1;
+}
+
+
+JNIEXPORT jobject JNICALL
+Java_org_eclipse_ecf_ipc_IPCPackage_createBuffer(JNIEnv *env, jclass clazz, jint size)
+{
+ void *buff;
+ jobject bb;
+
+ buff = malloc(size);
+ bb = (*env)->NewDirectByteBuffer(env, buff, size);
+ return bb;
+}
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/IPCPackage.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/IPCPackage.h
new file mode 100644
index 000000000..90c785b3b
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/IPCPackage.h
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_lts_ipc_IPCPackage */
+
+#ifndef _Included_org_eclipse_ecf_ipc_IPCPackage
+#define _Included_org_eclipse_ecf_ipc_IPCPackage
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: org_eclipse_ecf_ipc_IPCPackage
+ * Method: initializeNative
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_IPCPackage_initializeNative
+ (JNIEnv *, jclass);
+
+/*
+ * Class: org_eclipse_ecf_ipc_IPCPackage
+ * Method: setValue
+ * Signature: ([B)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_IPCPackage_setValue
+ (JNIEnv *, jclass, jbyteArray);
+
+/*
+ * Class: org_eclipse_ecf_ipc_IPCPackage
+ * Method: createBuffer
+ * Signature: (I)Ljava/nio/ByteBuffer;
+ */
+JNIEXPORT jobject JNICALL Java_org_eclipse_ecf_ipc_IPCPackage_createBuffer
+ (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreNative.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreNative.c
new file mode 100644
index 000000000..c13e53fc2
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreNative.c
@@ -0,0 +1,228 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+#include <windows.h>
+#include <stdio.h>
+#include "SemaphoreNative.h"
+#include "SemaphoreResult.h"
+
+static int errorToReturnCode();
+
+#define MAX_TIMEOUT 0x7FFFFFFF
+#define HANDLE_TYPE int
+
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_connect(
+ JNIEnv *env,
+ jclass clazz,
+ jobject resultObject,
+ jstring name,
+ jint initialValue)
+{
+ HANDLE sem;
+ const char *s;
+ LONG msInitialValue, msMaxValue;
+
+ msInitialValue = (LONG) initialValue;
+ s = (*env)->GetStringUTFChars(env, name, NULL);
+
+ sem = CreateSemaphore(
+ NULL, // default security attributes
+ msInitialValue, // initial value
+ msMaxValue, // max value
+ s // name
+ );
+
+ (*env)->ReleaseStringUTFChars(env, name, s);
+
+ if (NULL == sem)
+ {
+ int errorCode = errorToReturnCode();
+ SemaphoreResult_setResultCode(env, resultObject, errorCode);
+ SemaphoreResult_setErrorCode(env, resultObject, GetLastError());
+ sem = (HANDLE) -1;
+ SemaphoreResult_setHandle(env, resultObject, (int) sem);
+ }
+ else
+ {
+ SemaphoreResult_setResultCode(env, resultObject, org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_SUCCESS);
+ SemaphoreResult_setErrorCode(env, resultObject, 0);
+ SemaphoreResult_setHandle(env, resultObject, (int) sem);
+ }
+}
+
+/*
+ * Convert a Windows error code returned from GetErrorCode into something that
+ * is defined by our interface.
+ */
+static int errorToReturnCode()
+{
+ DWORD errorCode;
+ int returnCode;
+
+ errorCode = GetLastError();
+
+ switch(errorCode)
+ {
+ case ERROR_SUCCESS :
+ returnCode = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_SUCCESS;
+ break;
+
+ case ERROR_ACCESS_DENIED :
+ returnCode = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_ACCESS_DENIED;
+ break;
+
+ case ERROR_INVALID_HANDLE :
+ returnCode = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_UNKNOWN_HANDLE;
+ break;
+
+ case ERROR_SEM_TIMEOUT :
+ returnCode = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_TIMEOUT;
+ break;
+
+ case ERROR_TOO_MANY_POSTS :
+ returnCode = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_TOO_MANY_INCREMENTS;
+ break;
+
+ default :
+ returnCode = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_UNKNOWN_ERROR;
+ break;
+ }
+
+ return returnCode;
+}
+
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_increment(
+ JNIEnv *env,
+ jclass this,
+ jobject resultObject,
+ jlong sem
+)
+{
+ HANDLE handle;
+ BOOL result;
+ long previous;
+
+ //
+ // The compiler will whine about how we're converting an integer to a
+ // pointer, and that the pointer size (32 bits) is different from the
+ // integer size (64 bits). This makes it hard to find the real errors in
+ // the output, hence this bit of code.
+ //
+ handle = (HANDLE) ((HANDLE_TYPE)sem);
+ result = ReleaseSemaphore(handle, 1, &previous);
+}
+
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: decrement
+ * Signature: (JJJ)I
+ *
+ * The timeout is the time we should wait if the semaphore is not available.
+ *
+ * The timeout is in nanoseconds.
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_decrement(
+ JNIEnv *env,
+ jclass clazz,
+ jobject resultObject,
+ jlong sem,
+ jlong timeout
+)
+{
+ DWORD result, msec;
+ HANDLE handle;
+ int code;
+
+ if (0 > timeout || timeout > MAX_TIMEOUT)
+ {
+ msec = INFINITE;
+ }
+ else
+ {
+ msec = timeout;
+ }
+
+ //
+ // The compiler will whine about how we're converting an integer to a
+ // pointer, and that the pointer size (32 bits) is different from the
+ // integer size (64 bits). This makes it hard to find the real errors in
+ // the output, hence this bit of code.
+ //
+ handle = (HANDLE) ((int) sem);
+
+ result = WaitForSingleObject(handle, msec);
+
+ switch (result)
+ {
+ case WAIT_OBJECT_0 :
+ code = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_SUCCESS;
+ break;
+
+ case WAIT_TIMEOUT :
+ code = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_TIMEOUT;
+ break;
+
+ case WAIT_ABANDONED :
+ code = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_PLATFORM_ERROR;
+ break;
+
+ case WAIT_FAILED :
+ code = errorToReturnCode();
+ break;
+
+ default :
+ code = org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_UNKNOWN_ERROR;
+ break;
+ }
+
+ SemaphoreResult_setErrorCode(env, resultObject, GetLastError());
+ SemaphoreResult_setHandle(env, resultObject, (int) handle);
+ SemaphoreResult_setResultCode(env, resultObject, code);
+}
+
+
+JNIEXPORT jboolean JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_supportsGetValue
+ (JNIEnv *env, jclass this)
+{
+ return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_supportsSetValue
+ (JNIEnv *env, jclass this)
+{
+ return JNI_FALSE;
+}
+
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: createResult
+ * Signature: ()Lorg/eclipse/ecf/ipc/SemaphoreNative/ConnectResult;
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_createResult
+ (JNIEnv *env, jclass this, jobject obj, jstring name, jint maxValue, jint initialValue)
+{
+}
+
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_linkTest
+ (JNIEnv *env, jclass this)
+{
+ return;
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_getNamingMethod
+ (JNIEnv *env, jclass this)
+{
+ return org_eclipse_ecf_ipc_semaphore_SemaphoreNative_METHOD_INTEGER;
+}
+
+
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreNative.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreNative.h
new file mode 100644
index 000000000..69b86f705
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreNative.h
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_eclipse_ecf_ipc_semaphore_SemaphoreNative */
+
+#ifndef _Included_org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+#define _Included_org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_SUCCESS
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_SUCCESS 0L
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_UNKNOWN_ERROR
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_UNKNOWN_ERROR 1L
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_PLATFORM_ERROR
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_PLATFORM_ERROR 2L
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_UNKNOWN_HANDLE
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_UNKNOWN_HANDLE 3L
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_TIMEOUT
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_TIMEOUT 4L
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_ACCESS_DENIED
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_ACCESS_DENIED 5L
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_NOT_IMPLEMENTED
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_NOT_IMPLEMENTED 6L
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_TOO_MANY_INCREMENTS
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_RESULT_TOO_MANY_INCREMENTS 7L
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_METHOD_INTEGER
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_METHOD_INTEGER 0
+#undef org_eclipse_ecf_ipc_semaphore_SemaphoreNative_METHOD_FILE_NAME
+#define org_eclipse_ecf_ipc_semaphore_SemaphoreNative_METHOD_FILE_NAME 1
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: connect
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_connect
+ (JNIEnv *, jclass, jobject, jstring, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: increment
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;J)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_increment
+ (JNIEnv *, jclass, jobject, jlong);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: decrement
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_decrement
+ (JNIEnv *, jclass, jobject, jlong, jlong);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: getValue
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;J)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_getValue
+ (JNIEnv *, jclass, jobject, jlong);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: supportsGetValue
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_supportsGetValue
+ (JNIEnv *, jclass);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: setValue
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;JI)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_setValue
+ (JNIEnv *, jclass, jobject, jlong, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: supportsSetValue
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_supportsSetValue
+ (JNIEnv *, jclass);
+
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: createResult
+ * Signature: (Lorg/eclipse/ecf/ipc/semaphore/SemaphoreResult;Ljava/lang/String;II)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_createResult
+ (JNIEnv *, jclass, jobject, jstring, jint, jint);
+
+/*
+ * Class: org_eclipse_ecf_ipc_semaphore_SemaphoreNative
+ * Method: linkTest
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_linkTest
+ (JNIEnv *, jclass);
+
+
+JNIEXPORT jint JNICALL Java_org_eclipse_ecf_ipc_semaphore_SemaphoreNative_getNamingMethod
+ (JNIEnv *, jclass);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreResult.c b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreResult.c
new file mode 100644
index 000000000..584baca52
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreResult.c
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/*
+ * SemaphoreResult.c
+ *
+ * Accessor methods for the SemaphoreResult class.
+ *
+ * Created on: Mar 5, 2009
+ * Author: cnh
+ */
+
+#include <windows.h>
+#include "SemaphoreResult.h"
+
+static jfieldID resultCodeField;
+static jfieldID handleField;
+static jfieldID errorCodeField;
+
+#define CLASS_NAME "org/eclipse/ecf/ipc/semaphore/SemaphoreResult"
+
+void SemaphoreResult_initialize(JNIEnv *env)
+{
+ jclass clazz;
+
+ clazz = (*env)->FindClass(env, CLASS_NAME);
+
+ handleField = (*env)->GetFieldID(env, clazz, "handle", "J");
+ errorCodeField = (*env)->GetFieldID(env, clazz, "errorCode", "I");
+ resultCodeField = (*env)->GetFieldID(env, clazz, "resultCode", "I");
+}
+
+
+
+void SemaphoreResult_setResultCode(JNIEnv *env, jobject this, int code)
+{
+ (*env)->SetIntField(env, this, resultCodeField, (jint) code);
+}
+
+
+void SemaphoreResult_setErrorCode(JNIEnv *env, jobject this, int code)
+{
+ (*env)->SetIntField(env, this, errorCodeField, (int) code);
+}
+
+
+void SemaphoreResult_setHandle(JNIEnv *env, jobject this, int id)
+{
+ jlong value;
+
+ value = (jlong) ((int) id);
+ (*env)->SetLongField(env, this, handleField, value);
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreResult.h b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreResult.h
new file mode 100644
index 000000000..35136fa46
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc.library/src/windows/SemaphoreResult.h
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/*
+ * SemaphoreResult.h
+ *
+ * Created on: Mar 5, 2009
+ * Author: cnh
+ */
+#include <windows.h>
+#include <jni.h>
+
+#ifndef SEMAPHORERESULT_H_
+#define SEMAPHORERESULT_H_
+
+extern void SemaphoreResult_setResultCode(JNIEnv *env, jobject this, int code);
+extern void SemaphoreResult_setErrorCode(JNIEnv *env, jobject this, int code);
+extern void SemaphoreResult_setHandle(JNIEnv *env, jobject this, int handle);
+extern void SemaphoreResult_initialize(JNIEnv *env);
+
+#endif /* SEMAPHORERESULT_H_ */
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.classpath b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.classpath
new file mode 100644
index 000000000..ad32c83a7
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.project b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.project
new file mode 100644
index 000000000..cd8d9a5a6
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.ecf.ipc</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.settings/org.eclipse.jdt.core.prefs b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..4c63ff126
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Tue Sep 08 21:00:47 CEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.settings/org.eclipse.pde.core.prefs b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 000000000..218ed3e25
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Tue Sep 08 21:00:47 CEST 2009
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/META-INF/MANIFEST.MF b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..f8b1e4591
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: ECF IPC API Bundle
+Bundle-SymbolicName: org.eclipse.ecf.ipc;singleton:=true
+Bundle-Version: 0.1.0.qualifier
+Bundle-Vendor: Eclipse ECF
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: org.eclipse.ecf.ipc,
+ org.eclipse.ecf.ipc.fifo,
+ org.eclipse.ecf.ipc.semaphore,
+ org.eclipse.ecf.ipc.sharedmemory
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/build.properties b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/build.properties
new file mode 100644
index 000000000..34d2e4d2d
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/META-INF/MANIFEST.MF b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..3f3e18dff
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-SymbolicName: org.eclipse.ecf.ipc.win32.x86;singleton:=true
+Bundle-Version: 0.1.0.qualifier
+Fragment-Host: org.eclipse.ecf.ipc;bundle-version="0.1.0"
+Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86))
+Bundle-Localization: ipc.win32.win32.x86
+Eclipse-BundleShape: dir
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/about.html b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/about.html
new file mode 100644
index 000000000..395df3ba9
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor&rsquo;s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/ipc_010.dll b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/ipc_010.dll
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/fragments/org.eclipse.ecf.ipc.win32.x86/ipc_010.dll
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/IPCException.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/IPCException.java
new file mode 100644
index 000000000..c618d40c1
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/IPCException.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc;
+
+/**
+ * A problem occurred while trying to use an IPC mechanism.
+ *
+ * <P>
+ * This class allows clients to distinguish between exceptions generated by the classes
+ * in this package and exceptions from other sources. The exact nature of the exception
+ * should be denoted by the message, which should be taken from one of the constants
+ * defined in the {@link Messages} class.
+ *
+ * @author Clark N. Hobbie
+ */
+@SuppressWarnings("serial")
+public class IPCException extends Exception
+{
+ public static final String MSG_ALREADY_CONNECTED
+ = "The system is already connected to the shared memory segment";
+
+ public static final String MSG_ERROR_OPENING_MAPPING_FILE
+ = "Caught an exception while trying to open the underlying file for the segment";
+
+ public static final String MSG_ERROR_CREATING_MAP
+ = "Caught an exception while trying to obtain a map from the underlying file channel";
+
+ public static final String MSG_NOT_CONNECTED
+ = "Attempt to access the segment before connecting to it.";
+
+ public static final String MSG_PERMISSIONS =
+ "The process is not allowed to manipulate the semaphore";
+
+ public static final String MSG_UNKNOWN =
+ "An unknown/unanticipated error occurred while trying ot manipulate the semaphore";
+
+ public static final String MSG_EXCEPTION_CREATING_FILE =
+ "Caught an exception while trying to create a file associated with the IPC mechanism";
+
+ public static final String MSG_TIMEOUT =
+ "A timeout occurred while waiting for the resource to become available";
+
+ public enum Errors
+ {
+ AlreadyConnected(MSG_ALREADY_CONNECTED),
+ ErrorOpeningMappingFile(MSG_ERROR_OPENING_MAPPING_FILE),
+ ErrorCreatingMap(MSG_ERROR_CREATING_MAP),
+ NotConnected(MSG_NOT_CONNECTED),
+ Permissions(MSG_PERMISSIONS),
+ Unknown(MSG_UNKNOWN),
+ ExceptionCreatingFile(MSG_EXCEPTION_CREATING_FILE),
+ Timeout(MSG_TIMEOUT),
+ ;
+
+ public String message;
+
+ private Errors(String msg)
+ {
+ message = msg;
+ }
+ }
+
+ private Errors myError;
+
+ public Errors getError()
+ {
+ return myError;
+ }
+
+ public void setError(Errors error)
+ {
+ myError = error;
+ }
+
+
+ public IPCException()
+ {}
+
+ public IPCException (String msg)
+ {
+ super(msg);
+ }
+
+ public IPCException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ public IPCException (String msg, Throwable cause)
+ {
+ super(msg, cause);
+ }
+
+ public IPCException(Errors error)
+ {
+ super(error.message);
+ setError(error);
+ }
+
+
+ public IPCException(Errors error, Throwable t)
+ {
+ super(error.message, t);
+ setError(error);
+ }
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/IPCPackage.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/IPCPackage.java
new file mode 100644
index 000000000..031c50062
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/IPCPackage.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc;
+
+import java.nio.ByteBuffer;
+
+public class IPCPackage
+{
+ public static final String LIBRARY_NAME = "ipc_010";
+
+ public static native void initializeNative();
+ public static native void setValue(byte[] buf);
+ public static native ByteBuffer createBuffer(int size);
+
+ private static boolean ourPackageInitialized;
+
+ public static void initializePackage()
+ {
+ if (ourPackageInitialized)
+ return;
+ else
+ basicInitializePackage();
+ }
+
+
+ private static synchronized void basicInitializePackage()
+ {
+ if (ourPackageInitialized)
+ return;
+
+ System.loadLibrary(LIBRARY_NAME);
+ initializeNative();
+ ourPackageInitialized = true;
+ }
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/Utils.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/Utils.java
new file mode 100644
index 000000000..485224ad3
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/Utils.java
@@ -0,0 +1,375 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+
+/**
+ * An internal class that provides utility methods common to IPC classes.
+ *
+ * @author Clark N. Hobbie
+ */
+public class Utils
+{
+
+ public static long toMilliseconds(long seconds, long nanos)
+ {
+ long result = seconds * 1000;
+ result += nanos / 1000000;
+ long temp = nanos % 1000000;
+ if (temp > 0)
+ result++;
+
+ return result;
+ }
+
+ public static long toNanoseconds(long sec, long nanos)
+ {
+ long result = nanos;
+ result = result + 1000000000 * sec;
+ return result;
+ }
+
+ public static void closeNoExceptions(Reader reader)
+ {
+ if (null == reader)
+ return;
+
+ try
+ {
+ reader.close();
+ }
+ catch (IOException e)
+ {
+ ; // ignore exceptions
+ }
+ }
+
+ public static void closeNoExceptions(BufferedReader reader)
+ {
+ if (null == reader)
+ return;
+
+ try
+ {
+ reader.close();
+ }
+ catch (IOException e)
+ {
+ ; // this method is supposed to ignore exceptions
+ }
+ }
+
+ public static void closeNoExceptions(InputStream istream)
+ {
+ if (null == istream)
+ return;
+
+ try
+ {
+ istream.close();
+ }
+ catch (IOException e)
+ {
+ ; // this method is supposed to ignore exceptions
+ }
+ }
+
+ public static String readFile(File file) throws IOException
+ {
+ FileReader reader = null;
+
+ try
+ {
+ reader = new FileReader(file);
+ StringWriter sw = new StringWriter(1024);
+ for (int c = reader.read(); c != -1; c = reader.read())
+ {
+ sw.write(c);
+ }
+
+ return sw.toString();
+ }
+ catch (FileNotFoundException e)
+ {
+ return null;
+ }
+ finally
+ {
+ Utils.closeNoExceptions(reader);
+ }
+ }
+
+ public static String readFile(String name) throws IOException
+ {
+ File file = new File(name);
+ return readFile(file);
+ }
+
+ public static void writeFile(File file, String contents) throws IOException
+ {
+ FileWriter writer = null;
+
+ try
+ {
+ writer = new FileWriter(file);
+ writer.write(contents);
+ }
+ finally
+ {
+ Utils.closeNoExceptions(writer);
+ }
+ }
+
+ public static void writeFile(String name, String contents) throws IOException
+ {
+ File file = new File(name);
+ writeFile(file, contents);
+ }
+
+ public static void closeNoExceptions(FileWriter writer)
+ {
+ if (null == writer)
+ return;
+
+ try
+ {
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ ; // the point of this method is to avoid throwing exceptions
+ }
+ }
+
+ /**
+ * Find the enum tag that matches a string without regards to case.
+ * <P>
+ * This method is intended to be used like so:
+ * </P>
+ * <P>
+ * <CODE>
+ * <PRE>
+ * enum Foo {
+ * One,Two,Three,Four;
+ * public static Foo toValueIgnoreCase(String s) {
+ * return (Foo) Utils.toValueIgnoreCase(Foo.values(), s);
+ * }
+ * }
+ * </PRE>
+ * </CODE>
+ * </P>
+ *
+ * @param values
+ * The enum tag values.
+ * @param s
+ * The string we are trying to convert.
+ * @return The matching enum tag.
+ * @throws RuntimeException
+ * If there is no match.
+ */
+ public static Object toValueIgnoreCase(Object[] values, String s)
+ {
+ Object result = matchIgnoreCase(values, s);
+
+ if (null == result)
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter out = new PrintWriter(sw);
+ out.println(s + " does not match any tag name.");
+ out.println("Available tag names are:");
+ for (Object o : values)
+ {
+ String value = o.toString();
+ out.println(value);
+ }
+
+ out.close();
+ String msg = sw.toString();
+ throw new RuntimeException(msg);
+ }
+
+ return result;
+ }
+
+ public static Object matchIgnoreCase(Object[] values, String s)
+ {
+ for (Object tag : values)
+ {
+ if (s.equalsIgnoreCase(tag.toString()))
+ return tag;
+ }
+
+ return null;
+ }
+
+ public static void closeNoExceptions(OutputStream ostream)
+ {
+ try
+ {
+ ostream.close();
+ }
+ catch (IOException e)
+ {
+ ;
+ }
+ }
+
+ static public void fillArrayWith(byte[] dest, byte[] pattern)
+ {
+ int count = 0;
+ while (count < dest.length)
+ {
+ for (int i = 0; i < pattern.length; i++)
+ {
+ dest[count] = pattern[i];
+ count++;
+ }
+ }
+ }
+
+ /**
+ * Create a byte array that is populated with a particular string.
+ * <P>
+ * Useful when initializing shared memory.
+ * </P>
+ *
+ * @param size
+ * The size of the returned array.
+ * @param pattern
+ * The pattern to use to populate the array.
+ * @return The populated array.
+ */
+ static public byte[] createAndFillWith(int size, String pattern)
+ {
+ byte[] buffer = new byte[size];
+ byte[] pat = pattern.getBytes();
+ fillArrayWith(buffer, pat);
+ return buffer;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void listProperties()
+ {
+ Collection col = System.getProperties().keySet();
+ List<String> list = new ArrayList(col);
+ Collections.sort(list);
+ for (String key : list)
+ {
+ String value = System.getProperty(key);
+ System.out.println(key + " = " + value);
+ }
+ }
+
+ /**
+ * Read or create a file.
+ * <P>
+ * This method opens the named text file and returns its contents, assuming the file
+ * exists.
+ * </P>
+ * <P>
+ * If the file does not exist, then it creates it and writes the supplied string into
+ * it. This operation happens in an "atomic" fashion, so that another thread or
+ * process that if another process or thread attempts to write the same file at the
+ * same time, only one of them will succeed.
+ * </P>
+ *
+ * @param file
+ * The file to read or create.
+ * @param contents
+ * If the file needs to be created, the contents of the file.
+ * @throws IOException
+ * If a problem exists while trying to read or write the file.
+ * @return The contents of the file. If the file does not exist, this will simply
+ * return the supplied string.
+ */
+ public static String readOrCreate(File file, String contents) throws IOException
+ {
+ //
+ // if the file exists, return its contents
+ //
+ if (file.exists())
+ {
+ return readFile(file);
+ }
+ //
+ // otherwise, write the supplied string to the file using an "atomic"
+ // operation
+ //
+ else
+ {
+ //
+ // create a temp file and write the contents to it.
+ //
+ File parent = file.getParentFile();
+ File temp = File.createTempFile("tempfile", null, parent);
+ Utils.writeFile(temp, contents);
+
+ //
+ // rename the temp file to the desired name. If the destination does
+ // not exist, this should succeed.
+ //
+ if (temp.renameTo(file))
+ {
+ return contents;
+ }
+ //
+ // otherwise, someone created the file before we did. Return its
+ // contents
+ //
+ else
+ {
+ return readFile(file);
+ }
+ }
+ }
+
+
+ public static String readOrCreate(String name, String contents) throws IOException
+ {
+ File file = new File(name);
+ return readOrCreate(file, contents);
+ }
+
+ public static void printEnv()
+ {
+ Properties props = System.getProperties();
+ List<String> list = new ArrayList<String>();
+ for (Object o : props.keySet())
+ {
+ list.add((String) o);
+ }
+
+ for (String name : list)
+ {
+ String value = props.getProperty(name);
+ System.out.println(name + " = " + value);
+ }
+
+ System.out.flush();
+ }
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFO.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFO.java
new file mode 100644
index 000000000..8d612ee86
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFO.java
@@ -0,0 +1,489 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.fifo;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.ecf.ipc.IPCException;
+import org.eclipse.ecf.ipc.Utils;
+import org.eclipse.ecf.ipc.fifo.FIFOImpl.PipeDirection;
+
+
+/**
+ * A one-way interprocess communications channel.
+ * <UL>
+ * <LI><A href="#note">Note</A></LI>
+ * <LI><A href="#quickstart">Quickstart</A></LI>
+ * <LI><A href="#description">Description</A></LI>
+ * </UL>
+ * <A name="note"><H2>NOTE</H2></A> Because of the way that Windows implements named
+ * pipes, one process must call the {@link #create()} method before the named pipe can be
+ * used. This is in addition to whether that process will be exclusively reading from or
+ * writing to the pipe.
+ * <P>
+ * On Linux, a named pipe (FIFO) will persist after the process that created it
+ * terminates, allowing subsequent clients to use it without taking on a client or role.
+ * </P>
+ * <P>
+ * Unfortunately, using this information will introduce a platform dependency in the
+ * system.
+ * </P>
+ * <A name="quickstart"><H2>Quickstart</H2></A> <H3>Creator/Writer Process</H3>
+ * <P>
+ * <CODE>
+ * <PRE>
+ * byte[] buffer;
+ * String name;
+ * // create an instance for buffer and fill it with data
+ * // set name to a valid file name
+ * ...
+ * NamedPipe pipe = new NamedPipe(name);
+ * pipe.create();
+ * pipe.openWriter();
+ * pipe.write(buffer);
+ * </PRE>
+ * </CODE>
+ * <P>
+ * <H3>Reader Process</H3>
+ * <P>
+ * <CODE>
+ * <PRE>
+ * byte[] buffer;
+ * String name;
+ * // create an instance for buffer
+ * // set name to the same name as the writer is using
+ * ...
+ * NamedPipe pipe = new NamedPipe(name);
+ * pipe.openReader();
+ * int count = pipe.read(buffer);
+ * // process the data received
+ * ...
+ * </PRE>
+ * </CODE>
+ * </P>
+ * <A name="description"><H2>Description</H2></A> <A href="#note">Please see the note on
+ * client/server roles before using this class</A>
+ * <P>
+ * This class provides a named pipe IPC primitive. These are sometimes referred to as
+ * FIFOs or message queues.
+ * </P>
+ * <P>
+ * In this context a named pipe provides a one-way, synchronous communications channel
+ * between two processes. Note that this class only allows one-way communications even if
+ * the underlying mechanism the operating system supports is two-way.
+ * </P>
+ * <P>
+ * The class uses file naming <A href="../package-summary.html#file_naming"> as explained
+ * in the package description.</A> In the case of this class, the file name will refer to
+ * an operating system file. On Linux, this will be the name of the FIFO that is a file in
+ * the file system that implements the pipe. On windows, this will be a file that contains
+ * the actual name of the pipe.
+ * </P>
+ * <P>
+ * Before using an instance of the class, the {@link #openReader()} or
+ * {@link #openWriter()} method should be used to establish the role it will be taking
+ * when communicating. Attempting to use an instance without properly initializing may
+ * result in unpredictable behavior.
+ * </P>
+ * <P>
+ * Once the role has been established the {@link #read(byte[])},
+ * {@link #read(byte[], int, int)}, {@link #write(byte[])} and
+ * {@link #write(byte[], int, int)} methods, as appropriate, can be used to send or
+ * receive information.
+ * </P>
+ * <A name="virtual_file"><H2>Virtual File Name</H3></A>
+ * <P>
+ * This class uses virtual and
+ * actual files to implement the underlying primitive. On platforms such as Linux, the
+ * virtual and actual file names are the same and both refer to a special file on the
+ * system that represents the communications channel.
+ * </P>
+ * <P>
+ * In the case of Windows, named pipes must use a special file name of the form: {@code
+ * \\.\pipe\<name>}. Such file names cannot be used on Linux.
+ * </P>
+ * <P>
+ * In order to provide a reasonably platform independent solution, the Windows
+ * implementation of named pipes uses two file names for the pipe: a virtual name name and
+ * an actual name.
+ * </P>
+ * <P>
+ * The virtual name is basically any valid file name on the system. The file identified in
+ * the virtual name corresponds to an actual file in the system, which contains the actual
+ * name of the named pipe.
+ * </P>
+ * <P>
+ * The actual name is then used to identify the named pipe to Windows.
+ * </P>
+ *
+ * @author Clark N. Hobbie
+ */
+public class FIFO
+{
+ public enum BlockingMode
+ {
+ Blocking,
+ NonBlocking;
+
+ public static BlockingMode toValueIgnoreCase(String s)
+ {
+ return (BlockingMode) Utils.toValueIgnoreCase(values(), s);
+ }
+ }
+
+
+ public static final int DEFAULT_BUFFER_SIZE = 1024;
+
+ private BlockingMode myBlockingMode;
+
+ public BlockingMode getBlockingMode()
+ {
+ return myBlockingMode;
+ }
+
+ public void setBlockingMode(BlockingMode blockingMode)
+ {
+ myBlockingMode = blockingMode;
+ }
+
+ private PipeDirection myDirection;
+
+
+ private int myTimeoutMsec;
+
+ private FIFOImpl myImpl;
+
+
+ public int getTimeoutMsec()
+ {
+ return myTimeoutMsec;
+ }
+
+ public void setTimeoutMsec(int timeout)
+ {
+ myTimeoutMsec = timeout;
+ }
+
+
+ protected FIFOImpl getImpl()
+ {
+ return myImpl;
+ }
+
+ protected void setImpl(FIFOImpl impl)
+ {
+ myImpl = impl;
+ }
+
+ /**
+ * Create a named pipe with the specified virtual name.
+ *
+ * @param virtualName
+ * The file to be used for the named pipe. See the class description for
+ * details about <A href="#virtual_file"> how and why the virtual file name is
+ * used. </A>
+ */
+ public FIFO(String virtualName)
+ {
+ initialize(virtualName, DEFAULT_BUFFER_SIZE, -1);
+ }
+
+ public FIFO(String virtualName, int timeoutMsec)
+ {
+ initialize(virtualName, DEFAULT_BUFFER_SIZE, timeoutMsec);
+ }
+
+ protected void initialize(String virtualName)
+ {
+ initialize(virtualName, DEFAULT_BUFFER_SIZE, -1);
+ }
+
+ private void initialize(String virtualName, int bufferSize, int timeoutMsec)
+ {
+ FIFOImpl impl = new FIFOImpl(virtualName);
+ setTimeoutMsec(timeoutMsec);
+ impl.setBufferSize(bufferSize);
+ setImpl(impl);
+ }
+
+ public void create() throws IPCException
+ {
+ FIFOResult result = getImpl().create();
+ processCreateResult(result);
+ }
+
+ private void processCreateResult(FIFOResult result) throws IPCException
+ {
+ if (FIFOResult.SUCCESS != result.resultCode)
+ {
+ String msg = null;
+
+ switch (result.resultCode)
+ {
+ case FIFOResult.ERROR_ACCESS_DENIED:
+ msg = "access to the FIFO was denied";
+ break;
+
+ case FIFOResult.ERROR_UNKNOWN:
+ default:
+ msg = "An unknown error was encountered while trying to create the named pipe";
+ break;
+ }
+
+ throw new IPCException(msg);
+ }
+ }
+
+ protected String readActualName(String virtualName) throws IPCException
+ {
+ try
+ {
+ String s = Utils.readFile(virtualName);
+ return s;
+ }
+ catch (IOException e)
+ {
+ String msg = "An error was encountered while trying to read the actual "
+ + "name of a named pipe from its virtual name.";
+
+ throw new IPCException(msg, e);
+ }
+ }
+
+ /**
+ * Open the named pipe, taking on the role of reader or writer.
+ * <P>
+ * On Linux, users of named pipes need to either read or write to a named pipe, they
+ * should not do both. Therefore this method establishes how the client is going to
+ * use the pipe and then connects to it.
+ * </P>
+ *
+ * @param direction
+ * The role the client wants to take on: reader or writer.
+ * @throws IPCException
+ * If a problem is encountered while trying to connect to the pipe.
+ */
+ public void open(PipeDirection direction) throws IPCException
+ {
+ FIFOResult result = getImpl().open(direction);
+ processOpenResult(result);
+ }
+
+ private void processOpenResult(FIFOResult result) throws IPCException
+ {
+ if (FIFOResult.SUCCESS != result.resultCode)
+ {
+ switch (result.resultCode)
+ {
+ case FIFOResult.ERROR_INVALID_HANDLE:
+ {
+ String msg = "Attempt to listen to an unconnected named pipe. "
+ + "Error code = " + result.errorCode;
+
+ throw new IPCException(msg);
+ }
+
+ default:
+ {
+ String msg = "An unknown error was encountered while trying to listen "
+ + "for a client. " + "Error code = " + result.errorCode;
+
+ throw new IPCException(msg);
+ }
+ }
+ }
+ }
+
+ /**
+ * Connect to the named pipe, taking on the role of writer.
+ * <P>
+ * This method is equivalent to calling {@link #open(PipeDirection)} with an argument
+ * of {@link PipeDirection#Writer}.
+ * </P>
+ *
+ * @throws IPCException
+ * If a problem is encountered while trying to connect to the pipe.
+ * @see #open(PipeDirection)
+ */
+ public void openWriter() throws IPCException
+ {
+ setDirection(PipeDirection.Writer);
+ open(PipeDirection.Writer);
+ }
+
+ /**
+ * Connect to the named pipe, taking on the role of reader.
+ * <P>
+ * This method is equivalent to calling {@link #open(PipeDirection)} with an argument
+ * of {@link PipeDirection#Reader}.
+ * </P>
+ *
+ * @throws IPCException
+ * If a problem is encountered while trying to connect to the pipe.
+ * @see #open(PipeDirection)
+ */
+ public void openReader() throws IPCException
+ {
+ setDirection(PipeDirection.Reader);
+ open(PipeDirection.Reader);
+ }
+
+ protected PipeDirection getDirection()
+ {
+ return myDirection;
+ }
+
+ protected void setDirection(PipeDirection direction)
+ {
+ myDirection = direction;
+ }
+
+ protected String getActualName()
+ {
+ return getImpl().getActualName();
+ }
+
+ /**
+ * Read from the named pipe, blocking until data becomes available.
+ * <P>
+ * This method is equivalent to calling {@linkplain #read(byte[], int, int)
+ * read(buffer, 0, buff.length)}. See that class for additional details.
+ * </P>
+ *
+ * @param buffer
+ * The buffer where the data read from the pipe should be placed.
+ * @return The number of bytes actually read.
+ * @throws IPCException
+ * If a problem is encountered while reading from the named pipe.
+ * @see #read(byte[], int, int)
+ */
+ public int read(byte[] buffer) throws IPCException
+ {
+ return read(buffer, 0, buffer.length);
+ }
+
+ /**
+ * Read some data from the named pipe, blocking if the data is not available.
+ * <P>
+ * This method will block if data is not available when it is called. The method may
+ * read less than the specified amount of data.
+ * </P>
+ * <P>
+ * It is an error on some platforms to read from a pipe that has been opened for
+ * writing.
+ * </P>
+ *
+ * @param buffer
+ * The buffer where the data read should be placed.
+ * @param offset
+ * Where the data should start in the buffer.
+ * @param length
+ * The size of the buffer, in bytes.
+ * @return The number of bytes read.
+ * @throws IPCException
+ * If a problem is encountered while trying to read from the pipe.
+ */
+ public int read(byte[] buffer, int offset, int length) throws IPCException
+ {
+ return getImpl().read(buffer, offset, length);
+ }
+
+ /**
+ * Write some data to the named pipe.
+ * <P>
+ * This method is equivalent to calling {@linkplain #write(byte[], int, int)
+ * write(buffer, 0, buffer.length)}. Please see that method for additional details.
+ * </P>
+ *
+ * @param buffer
+ * The buffer that contains the data.
+ * @return The number of bytes actually written.
+ * @throws IPCException
+ * If a problem is encountered while writing the data.
+ */
+ public int write(byte[] buffer) throws IPCException
+ {
+ return write(buffer, 0, buffer.length);
+ }
+
+ /**
+ * Write some data to the named pipe.
+ * <P>
+ * This method writes data to the named pipe and will block if the pipe is currently
+ * full.
+ * </P>
+ * <P>
+ * It is an error to write to a named pipe that the client opened as a reader.
+ * </P>
+ * <P>
+ * The method may perform a partial write, in which case only some of the data in
+ * the buffer was actually written. In that case, the return value will be
+ * less than the length parameter.
+ * </P>
+ *
+ * @param buffer
+ * The buffer that contains the data to write.
+ * @param offset
+ * Where in the buffer that the data starts.
+ * @param length
+ * The number of bytes of data to write.
+ * @return The number of bytes of data that were actually written.
+ * @throws IPCException
+ * If a problem is encountered while trying to write the data.
+ */
+ public int write(byte[] buffer, int offset, int length) throws IPCException
+ {
+ return getImpl().write(buffer, offset, length, getTimeoutMsec());
+ }
+
+
+
+ public InputStream getInputStream(int timeoutMsec) throws IOException
+ {
+ try
+ {
+ open(PipeDirection.Reader);
+ return new FIFOInputStream(this, timeoutMsec);
+ }
+ catch (IPCException e)
+ {
+ throw new IOException("Error opening pipe", e);
+ }
+ }
+
+
+ public InputStream getInputStream() throws IOException
+ {
+ return getInputStream(-1);
+ }
+
+ public OutputStream getOutputStream() throws IOException
+ {
+ try
+ {
+ open(PipeDirection.Writer);
+ return new FIFOOutputStream(this);
+ }
+ catch (IPCException e)
+ {
+ throw new IOException("Error opening pipe", e);
+ }
+ }
+
+ public String getVirtualName()
+ {
+ return getImpl().getVirtualName();
+ }
+
+ public native void selectForWriting(int timeoutMsec);
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOImpl.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOImpl.java
new file mode 100644
index 000000000..c737d408e
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOImpl.java
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.fifo;
+
+import java.io.IOException;
+
+import org.eclipse.ecf.ipc.IPCException;
+import org.eclipse.ecf.ipc.IPCPackage;
+import org.eclipse.ecf.ipc.Utils;
+
+
+/**
+ * An internal class that provides the underlying system calls needed to implement
+ * named pipes.
+ * <P>
+ * This class is implementation dependent and not intended for general use.
+ * </P>
+ *
+ * @author Clark N. Hobbie
+ */
+public class FIFOImpl
+{
+ static {
+ IPCPackage.initializePackage();
+ }
+
+ public static final int DIRECTION_READER = 0;
+ public static final int DIRECTION_WRITER = 1;
+
+ public static final int BLOCKING_MODE_BLOCKING = 1;
+ public static final int BLOCKING_MODE_NON_BLOCKING = 2;
+
+ public static final int SELECT_READING = 1;
+ public static final int SELECT_WRITING = 2;
+ public static final int SELECT_BOTH = 3;
+
+ /**
+ * The role a client is taking (reader/writer) when using a named pipe. <H2>NOTE</H2>
+ * This class really belongs in {@link FIFO} and will probably be moved there in
+ * the near future.
+ *
+ * @author Clark N. Hobbie
+ */
+ public enum PipeDirection
+ {
+ Reader(DIRECTION_READER), Writer(DIRECTION_WRITER);
+
+ public int jniValue;
+
+ private PipeDirection(int direction)
+ {
+ jniValue = direction;
+ }
+ }
+
+ public FIFOImpl(String virtualName)
+ {
+ initialize(virtualName);
+ }
+
+ protected void initialize(String virtualName)
+ {
+ setVirtualName(virtualName);
+ }
+
+
+ private native void createImpl(FIFOResult result);
+
+ public FIFOResult create() throws IPCException
+ {
+ setCreator(true);
+
+ processVirtualActualFile();
+ FIFOResult result = new FIFOResult();
+ createImpl(result);
+
+ if (result.resultCode == FIFOResult.SUCCESS)
+ {
+ setHandle(result.handle);
+ }
+
+ return result;
+ }
+
+ private void processVirtualActualFile() throws IPCException
+ {
+ String suffix = Long.toString(System.currentTimeMillis());
+
+ //
+ // if the platform DOES NOT have any particular requirements for the name
+ // of a pipe, then use the virtual name as the actual name.
+ //
+ String actual = toActualName(suffix);
+ if (null == actual)
+ {
+ actual = getVirtualName();
+ }
+
+ //
+ // otherwise, write the actual name into the virtual file.
+ //
+ else
+ {
+ try
+ {
+ actual = Utils.readOrCreate(getVirtualName(), actual);
+ }
+ catch (IOException e)
+ {
+ String msg =
+ "Error trying to read/write virtual file: " + getVirtualName();
+ throw new IPCException(msg,e);
+ }
+ }
+
+ setActualName(actual);
+ }
+
+ private native void writeImpl(FIFOResult result, byte[] buffer, int offset,
+ int length, int timeoutMsec);
+
+ /**
+ * Try to write a buffer of data within the specified time frame.
+ * <P>
+ * It is possible for a FIFO to have enough data written to it that it runs
+ * out of buffer space. When that happens the writer must wait until the
+ * reader reads enough of the data to free up some more buffer space.
+ * </P>
+ *
+ * <P>
+ * The timeout specifies how long the caller is willing to wait for buffer
+ * space to free up. A value of less than 0 means that the caller will wait
+ * "forever." A value of 0 means that the caller will not wait at all --- if
+ * it is not possible to write immediately, then throw a timeout.
+ * </P>
+ *
+ * <P>
+ * Any other value specifies the number of milliseconds that the caller will
+ * wait for the space to free up.
+ * </P>
+ *
+ * <P>
+ * Note that a wait will only occur if the FIFO is full --- in all other
+ * situations, the write will complete without delay.
+ * </P>
+ *
+ * @param buffer
+ * The buffer that contains the data to write.
+ * @param offset
+ * The offset within the buffer that the data starts.
+ * @param length
+ * The number of bytes to try and write.
+ * @param timeoutMsec
+ * See description. The number of milliseconds to wait for a
+ * write to become possible.
+ * @return The number of bytes actually written.
+ * @throws IPCException
+ * If the caller specified a wait time and this elapsed before
+ * anything could be written, then this exception is thrown.
+ */
+ public int write(byte[] buffer, int offset, int length, int timeoutMsec) throws IPCException
+ {
+ if (getDirection() != PipeDirection.Writer)
+ {
+ throw new IPCException("Attempt to write to a read-only pipe.");
+ }
+
+ FIFOResult result = new FIFOResult();
+ writeImpl(result, buffer, offset, length, timeoutMsec);
+ if (result.resultCode != FIFOResult.SUCCESS)
+ {
+ String msg = "Error writing named pipe, error code = " + result.errorCode;
+
+ throw new IPCException(msg);
+ }
+
+ return result.byteCount;
+ }
+
+ private native void readImpl(FIFOResult result, byte[] buffer, int offset,
+ int length, int timeoutMsec);
+
+ public int read(byte[] buffer, int offset, int length) throws IPCException
+ {
+ return read(buffer, offset, length, -1);
+ }
+
+
+ public int read(byte[] buffer, int offset, int length, int timeoutMsec) throws IPCException
+ {
+ if (PipeDirection.Reader != getDirection())
+ {
+ throw new IPCException("Attempt to read a write-only pipe.");
+ }
+
+ FIFOResult result = new FIFOResult();
+ readImpl(result, buffer, offset, length, timeoutMsec);
+
+ if (result.resultCode == FIFOResult.ERROR_PIPE_CLOSED)
+ {
+ return -1;
+ }
+
+ if (result.resultCode != FIFOResult.SUCCESS)
+ {
+ String msg = "Error reading named pipe, code = " + result.errorCode;
+ throw new IPCException(msg);
+ }
+
+ return result.byteCount;
+ }
+
+ private native void openImpl(FIFOResult result, int direction);
+
+ public FIFOResult open(PipeDirection direction) throws IPCException
+ {
+ setDirection(direction);
+ if (null == getActualName())
+ {
+ processVirtualActualFile();
+ }
+ FIFOResult result = new FIFOResult();
+ openImpl(result, direction.jniValue);
+ setHandle(result.handle);
+ return result;
+ }
+
+ private String myActualName;
+
+ private boolean myCreator;
+
+ private PipeDirection myDirection;
+
+ private long myHandle;
+
+ private int myBufferSize;
+
+ private String myVirtualName;
+
+ public String getVirtualName()
+ {
+ return myVirtualName;
+ }
+
+ public void setVirtualName(String virtualName)
+ {
+ myVirtualName = virtualName;
+ }
+
+ protected int getBufferSize()
+ {
+ return myBufferSize;
+ }
+
+ protected void setBufferSize(int bufferSize)
+ {
+ myBufferSize = bufferSize;
+ }
+
+ protected String getActualName()
+ {
+ return myActualName;
+ }
+
+ protected PipeDirection getDirection()
+ {
+ return myDirection;
+ }
+
+ protected int getDirectionInt()
+ {
+ return myDirection.jniValue;
+ }
+
+ protected long getHandle()
+ {
+ return myHandle;
+ }
+
+ protected void setActualName(String actualName)
+ {
+ myActualName = actualName;
+ }
+
+ public void setCreator(boolean creator)
+ {
+ myCreator = creator;
+ }
+
+ protected void setDirection(PipeDirection direction)
+ {
+ myDirection = direction;
+ }
+
+ protected void setHandle(long handle)
+ {
+ myHandle = handle;
+ }
+
+ protected boolean isCreator()
+ {
+ return myCreator;
+ }
+
+
+ public native void createNonBlocking(FIFOResult result, String name);
+ public native void readNonBlocking(FIFOResult result, byte[] buffer, int start, int length, int timeoutMsec);
+ public native void writeNonBlocking(FIFOResult result, byte[] buffer, int start, int length, int timeoutMsec);
+
+ /**
+ * Return a name that the underlying OS can use for a named pipe, given a string
+ * that is more or less unique.
+ * <P>
+ * Currently, all platforms that support named pipes use a file name to identify
+ * the named pipe. This method does several things. First of all, it signals
+ * to ECF IPC whether or not the OS uses special names for pipes.
+ * </P>
+ * <P>
+ * Windows, for example, requires that all named pipes occur in the directory,
+ * "\\.\pipe" whereas linux has no such requirement.
+ * </P>
+ * <P>
+ * If the underlying OS has a special naming requirement, then it should return
+ * a name that it can use, given a suffix string.
+ * </P>
+ * <P>
+ * On windows, for example, if one were to supply "123456" as the suffix, the method
+ * should return "\\.\pipe\123456"
+ * </P>
+ * <P>
+ * If the underlying OS does not have a special naming requirement, then it should
+ * return null. Therefore on linux, this method should return null.
+ * </P>
+ *
+ * @param suffix A string that the actual name should be based on. See description for
+ * details.
+ * @return A suitable name if the platform requires that named pipes use a particular
+ * format, otherwise null.
+ */
+ public static native String toActualName(String virtualName);
+
+ /**
+ * Connect to the underlying FIFO.
+ */
+ public native void connectNonBlocking(FIFOResult result);
+
+
+ /**
+ * Determine if the FIFO is ready for reading, writing, or both.
+ * <P>
+ * This method is similar to the old Unix select system call, which would look
+ * for file handles read to read/write.
+ * </P>
+ * <P>
+ * The call takes the amount of time the caller wants to wait for I/O to
+ * be ready on the FIFO. A value of less than 0 means wait until ready.
+ * A value of 0 means poll the FIFO but do not wait. Any other value is
+ * the number of milliseconds to wait for the FIFO to be ready.
+ * </P>
+ * <P>
+ * If the client is the reader, then the method will wait until data is
+ * ready. If the client is a writer, it will wait for writing to become
+ * non-blocking.
+ * </P>
+ *
+ * @param timeouitMsec
+ */
+ public native void select(FIFOResult result, int timeoutMsec);
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOInputStream.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOInputStream.java
new file mode 100644
index 000000000..c9fa04f26
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOInputStream.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.fifo;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.ecf.ipc.IPCException;
+
+
+public class FIFOInputStream extends InputStream
+{
+ private FIFO myPipe;
+ private byte[] myBuffer;
+ private int myIndex;
+ private boolean myEndOfFile;
+ private int myDataSize;
+ private int myTimeout;
+
+ public boolean isEndOfFile()
+ {
+ return myEndOfFile;
+ }
+
+ public void setEndOfFile(boolean endOfFile)
+ {
+ myEndOfFile = endOfFile;
+ }
+
+ public FIFOInputStream(FIFO pipe)
+ {
+ initialize(pipe, -1);
+ }
+
+ public FIFOInputStream(FIFO fifo, int timeoutMsec)
+ {
+ initialize(fifo, timeoutMsec);
+ }
+
+ protected void initialize(FIFO pipe, int timeoutMsec)
+ {
+ myPipe = pipe;
+ myBuffer = new byte[8192];
+ myIndex = -1;
+ setEndOfFile(false);
+ myTimeout = timeoutMsec;
+ }
+
+
+ public int read() throws IOException
+ {
+ if (isEndOfFile())
+ return -1;
+
+ if (-1 == myIndex || myIndex >= myDataSize)
+ {
+ loadBuffer();
+ }
+
+ if (isEndOfFile())
+ return -1;
+
+ int bvalue = myBuffer[myIndex];
+ myIndex++;
+ return bvalue;
+ }
+
+ protected int bytesAvailable()
+ {
+ if (myIndex < 0)
+ return 0;
+
+ return myDataSize - myIndex;
+ }
+
+ public int read(byte[] buffer, int offset, int length) throws IOException
+ {
+ if (isEndOfFile())
+ return -1;
+
+ //
+ // if we don't currently have any data, load some
+ //
+ if (bytesAvailable() < 1)
+ loadBuffer();
+
+ if (isEndOfFile())
+ return -1;
+
+ int count = bytesAvailable();
+ int index = 0;
+ while (index < count && index < length && index < buffer.length)
+ {
+ buffer[index + offset] = (byte) read();
+ index++;
+ }
+
+ return count;
+ }
+
+ protected void loadBuffer() throws IOException
+ {
+ try
+ {
+ if (-1 == myTimeout)
+ {
+ myDataSize = myPipe.read(myBuffer);
+ }
+ else
+ {
+ }
+ myIndex = 0;
+
+ if (-1 == myDataSize)
+ {
+ setEndOfFile(true);
+ }
+ }
+ catch (IPCException e)
+ {
+ throw new IOException("Error reading data from pipe", e);
+ }
+ }
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOOutputStream.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOOutputStream.java
new file mode 100644
index 000000000..aceecb441
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOOutputStream.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.fifo;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.eclipse.ecf.ipc.IPCException;
+
+
+public class FIFOOutputStream extends OutputStream
+{
+ private byte[] myBuffer;
+ private int myNumberOfBytes;
+ private FIFO myNamedPipe;
+ public FIFOOutputStream(FIFO pipe)
+ {
+ initialize(pipe);
+ }
+
+
+ public void initialize(FIFO pipe)
+ {
+ myNamedPipe = pipe;
+ myBuffer = new byte[8192];
+ myNumberOfBytes = 0;
+ }
+
+
+ @Override
+ public void write(int b) throws IOException
+ {
+ if (myNumberOfBytes >= myBuffer.length)
+ {
+ flush();
+ }
+
+ myBuffer[myNumberOfBytes] = (byte) b;
+ myNumberOfBytes++;
+ }
+
+ @Override
+ public void flush() throws IOException
+ {
+ try
+ {
+ myNamedPipe.write(myBuffer, 0, myNumberOfBytes);
+ myNumberOfBytes = 0;
+ }
+ catch (IPCException e)
+ {
+ throw new IOException("Error writing out data", e);
+ }
+ }
+
+
+ @Override
+ public void close() throws IOException
+ {
+ flush();
+ }
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOResult.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOResult.java
new file mode 100644
index 000000000..af101ad86
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/fifo/FIFOResult.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.fifo;
+
+/**
+ * <P>
+ * An internal class to hold the results of a call to a JNI method.
+ * </P>
+ * <H2>NOTE</H2>
+ * <P>
+ * This is an internal class and not intended for general use.
+ * </P>
+ * <H2>Description</H2>
+ * <P>
+ * This class is used to pass multiple results between the JNI layer and the Java layer of
+ * named pipes. JNI calls can only return a single result, so to overcome that limitation,
+ * an instance of this class is passed back instead.
+ * </P>
+ * <H2>Properties</H2>
+ * <UL>
+ * <LI>handle - an integer value the operating system uses to identify the named pipe</LI>
+ * <LI>errorCode - a value the native method uses to communicate a problem with the
+ * operation. The codes are defined by the ERROR_ constants that this class defines.</LI>
+ * <LI>resultCode - The Java level result code. Generally a value of 0 means that the call
+ * succeeded whereas a non-zero code means that there was a problem.</LI>
+ * <LI>byteCount - For operations like read and write, this property specifies the number
+ * of bytes actually read or written by the underlying operation.</LI>
+ * </UL>
+ *
+ * @author Clark N. Hobbie
+ */
+public class FIFOResult
+{
+ public static final int ERROR_UNKNOWN = -1;
+
+ public static final int SUCCESS = 0;
+
+ public static final int ERROR_ACCESS_DENIED = 1;
+
+ /**
+ * An attempt was made to perform some operation such as listening or writing to a
+ * named pipe when the client did not have a valid pipe handle.
+ */
+ public static final int ERROR_INVALID_HANDLE = 2;
+
+ /**
+ * An attempt was made to connect to a named pipe, but failed because all the
+ * instances were already connected to other clients.
+ */
+ public static final int ERROR_PIPE_BUSY = 3;
+
+ /**
+ * An attempt was made to open a file, but either a component of the path to the file
+ * or the file itself does not exist.
+ */
+ public static final int ERROR_NOT_FOUND = 4;
+
+ public static final int ERROR_PIPE_CLOSED = 5;
+
+ /**
+ * An attempt to connect to a FIFO failed.
+ */
+ public static final int ERROR_CONNECT = 6;
+
+ /**
+ * A generic problem occurred while trying to read from the FIFO.
+ */
+ public static final int ERROR_READ = 7;
+
+ /**
+ * Timeout while waiting for something.
+ */
+ public static final int TIMEOUT = 8;
+
+ /**
+ * An error was encountered while making a call to wait for an IPC
+ * mechanism to become ready (e.g., select or WaitForSingleObject).
+ */
+ public static final int ERROR_SELECT = 9;
+
+ public int resultCode;
+
+ public long handle;
+
+ public int errorCode;
+
+ public int byteCount;
+
+ /**
+ * Is the FIFO a server?
+ *
+ * <P>
+ * A value of true indicates that whoever is using the FIFO is the server.
+ * A value of false means that the user is not the server.
+ * </P>
+ *
+ * <P>
+ * This is only relevant for the Windows platform, where a different system
+ * call must be used depending on whether this is the client or the server.
+ * </P>
+ */
+ public boolean server;
+
+
+ /**
+ * A windows-specific object required when using non-blocking FIFOs.
+ */
+ public long syncObject;
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/package-info.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/package-info.java
new file mode 100644
index 000000000..b30c9ce01
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/package-info.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+/**
+ * <P>
+ * A package that supports interprocess communications.
+ * </P>
+ *
+ * <H2>Table of Contents</H2>
+ * <UL>
+ * <LI><A href="#intro">Introduction</A></LI>
+ * <LI><A href="#named_pipe">Named Pipes</A></LI>
+ * <LI><A href="#semaphore">Semaphores</A></LI>
+ * <LI><A href="#shared_memory">Shared Memory</A></LI>
+ * <LI><A href="#socket">Sockets</A></LI>
+ * </UL>
+ *
+ * <A name="intro"><H2>Introduction</H2></A>
+ * This package documents the Eclipse IPC library. Eclipse IPC provides support
+ * for communication primitives that do not exist in the JRE, such as semaphores
+ * and named pipes, or improve support for primitives that exist but may not be
+ * as clear, such as shared memory.
+ *
+ * <A name="named_pipe"><H2>Named Pipes</H2></A>
+ * Named Pipes also refer to FIFOs or Message Queues. In the context of Eclipse IPC, a
+ * named pipe is an one-way IPC mechanism that appears on the underlying file system.
+ *
+ * <P>
+ * In terms of speed and bandwith, named pipes appear to fall somewhere between
+ * sockets and shared memory.
+ * </P>
+ *
+ * <P>
+ * The underlying mechanism may or may not directly use the file created by this
+ * class. On Linux, for example, the file is the actual named pipe --- a FIFO.
+ * On Windows, the file is the logical name for the named pipe. The actual name
+ * exists in a Windows specific namespace.
+ * </P>
+ *
+ * <A name="semaphore"><H2>Semaphores</H2></A>
+ * A Eclipse IPC {@link org.eclipse.ecf.ipc.semaphore.Semaphore}
+ * is the traditional synchronization primitive that allow processes to
+ * signal each other. The Eclipse IPC implementation is an "n-ary" semaphore that also
+ * a file for use in allowing processes to identify the semaphore.
+ *
+ * <P>
+ * Eclipse IPC semaphores appear to be the faster than the other primitives in terms of
+ * synchronization, but of course do not provide any data exchange beyond that.
+ * </P>
+ *
+ * <A name="shared_memory"><H2>Shared Memory</H2></A>
+ * The {@link org.eclipse.ecf.ipc.sharedmemory.SharedMemory}
+ * class is a more user-friendly implementation of the JRE
+ * mechanism for accessing shared memory: {@link java.io.RandomAccessFile},
+ * {@link java.nio.channels.FileChannel} and {@link java.nio.MappedByteBuffer}.
+ *
+ * <P>
+ * Should the JRE classes end up using some other mechanism that is unstuitable
+ * for for IPC, the intention is to change the Eclipse IPC version so that it keeps
+ * supporting shared memory.
+ * </P>
+ *
+ * <P>
+ * Eclipse IPC shared memory appears to have the greatest bandwidth of all the Eclipse IPC
+ * IPC mechanisms.
+ * </P>
+ *
+ * <P>
+ * Eclipse IPC shared memory exploits the underlying JRE support for synchronization
+ * via file locking to provide synchronization. This implementation appears
+ * to be roughly equal to the speed of named pipes and sockets, but significantly
+ * slower than that provided by semaphores.
+ * </P>
+ *
+ * <A name="socket"><H2>Sockets</H2></A>
+ * The Eclipse IPC {@link org.eclipse.ecf.ipc.socket} package is a collection of utilities for
+ * use with regular JRE sockets. Eclipse IPC does not try to provide a replacement for
+ * JRE sockets since they are good enough as is.
+ *
+ * <A name="file_naming"><H2>File Naming</H2></A>
+ * Eclipse IPC uses files and file names to allow processes to identify instances of
+ * various IPC mechanisms that do not have a standard means for such identification
+ * across supported platforms. When creating an instance of Semaphore or
+ * NamedPipe, for example, the developer supplies a file name to identify it.
+ *
+ * <P>
+ * The idea is that all processes that use the same file name will be connected to
+ * the same mechanism. Two processes that both use "/foo/bar" as the name with
+ * the Semaphore class, for example, will be connected to the same semaphore.
+ * </P>
+ *
+ * <P>
+ * The use of file names is functional as well as symbolic. On Linux and Windows,
+ * the name supplied is created and populated with the underlying name or handle
+ * that is used to access the primitive.
+ * </P>
+ *
+ * <P>
+ * For example, on Windows the file name provided for a shared queue will contain
+ * the actual name that windows uses to identify the queue. For semaphores, the
+ * Windows file will contain an integer value that is passed to semaphore-related
+ * operations to identify the semaphore being operated on.
+ * </P>
+ *
+ * <P>
+ * The manner in which files are used is similar to the way that shared memory
+ * operates.
+ * </P>
+ *
+ * @see org.eclipse.ecf.ipc.namedpipe.NamedPipe
+ * @see org.eclipse.ecf.ipc.semaphore.Semaphore
+ * @see org.eclipse.ecf.ipc.sharedmemory.SharedMemory
+ */
+package org.eclipse.ecf.ipc;
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/Semaphore.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/Semaphore.java
new file mode 100644
index 000000000..f61333cf2
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/Semaphore.java
@@ -0,0 +1,345 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.semaphore;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.ecf.ipc.IPCException;
+import org.eclipse.ecf.ipc.Utils;
+import org.eclipse.ecf.ipc.IPCException.Errors;
+import org.eclipse.ecf.ipc.semaphore.SemaphoreResult.Results;
+
+
+/**
+ * An inter-process, n-ary semaphore. <H2>Description</H2> An instance of this class
+ * presents an implementation of a general semaphore that is capable of spanning more than
+ * one process. Briefly, a semaphore has an integer value associated with it that is
+ * supposed to always be zero or more. Calling the increment method tries to decrease the
+ * value by 1, but if the value is already less than 1, the calling process waits until
+ * some other process changes the value to 1 or greater before continuing. The increment
+ * method increases the semaphore value by 1 and never blocks.
+ * <P>
+ * This class was created because standard java does not provide any mechanism for
+ * communication between java VMs other than sockets, etc. Those methods are fine, but
+ * semaphores, etc. can be hundreds of times faster.
+ * </P>
+ * <P>
+ * The class uses file naming <A href="../package-summary.html#file_naming"> as explained
+ * in the package description.</A> In the case of this class, the file name will refer to
+ * an operating system file whose contents are a string that is the numeric "handle" that
+ * the system uses to identify the semaphore in system calls.
+ * </P>
+ * <P>
+ * The class assumes that the primary reason for using this class is speed, and therefore
+ * most other issues are ignored in favor of speed. For this reason, some methods that
+ * could throw a more descriptive exception, such as increment when the semaphore is not
+ * connected, throw things like NullPointerException.
+ * </P>
+ * <H2>Native Methods</H2>
+ * <P>
+ * This class uses native methods, specifically the methods defined in the
+ * {@link SemaphoreNative} class. This is an inherent security issue that really cannot be
+ * avoided if clients want to use this class. The name of the library used is defined by
+ * {@link org.eclipse.ecf.ipc.semaphore.SemaphoreNative#LIBRARY_NAME}. The library is not loaded
+ * until an instance of this class actually tries to connect or create an underlying
+ * semaphore; so clients have a bit of control over error handling.
+ * </P>
+ * <H2>Implementation</H2>
+ * <P>
+ * The implementation of this class depends on the notion that a semaphore can be
+ * identified by a long integer "handle." This is the convention used by POSIX and
+ * Windows, but if it is not in fact the case for the platform, the class will not
+ * function. Of course if this is the case, the native methods should fail to load before
+ * a Semaphore can be used, but that's another issue.
+ * </P>
+ *
+ * <H2>Virtual and Actual Names</H2>
+ * <P>
+ * In keeping with the virtual file approach to naming, each semaphore is associated
+ * with a file. The file may or may not be required by the underlying operating
+ * system, see the {@link SemaphoreNative} class for details.
+ * </P>
+ *
+ * <P>
+ * The contents of the file is a string that is used to identify the semaphore to
+ * the operating system in some way. It is possible that the string is the same as
+ * the file name itself.
+ * </P>
+ *
+ * @author Clark N. Hobbie
+ */
+public class Semaphore
+{
+ /**
+ * The underlying operating system handle for the semaphore.
+ */
+ protected long myHandle = -1;
+
+ public long getHandle()
+ {
+ return myHandle;
+ }
+
+ public void setHandle(long handle)
+ {
+ myHandle = handle;
+ }
+
+ private String myActualName;
+
+ public String getActualName()
+ {
+ return myActualName;
+ }
+
+ public void setActualName(String s)
+ {
+ myActualName = s;
+ }
+
+
+ static private int ourNextActualName;
+
+ static {
+ long temp = System.currentTimeMillis();
+ ourNextActualName = (int) temp & 0x0fffffff;
+ }
+
+ synchronized static protected int generateNextActualName()
+ {
+ int temp = ourNextActualName;
+ ourNextActualName++;
+ return temp;
+ }
+
+
+ /**
+ * Create a semaphore without actually doing anything at the operating system level.
+ * <P>
+ * A call should be made to {@link #connect(String, int)} before attempting to use
+ * other methods, otherwise NullPointerExceptions will be thrown.
+ */
+ public Semaphore()
+ {
+ }
+
+ public Semaphore(String name) throws IPCException
+ {
+ connect(name, 1, 1);
+ }
+
+
+ /**
+ * Create a semaphore and attach to the underlying operating system construct.
+ * <P>
+ * This method is equivalent to calling the no-arg constructor, followed by calling
+ * the {@link #connect(String, int)} method.
+ *
+ * @param name
+ * The name of the semaphore.
+ * @param initialValue
+ * The initial value of the semaphore.
+ */
+ public Semaphore(String name, int initialValue) throws IPCException
+ {
+
+ connect(name, initialValue, initialValue);
+ }
+
+ /**
+ * Connect to the underlying operating system resource, creating it if it does not
+ * exist.
+ * <P>
+ * Calling this method when the instance is already connected has no effect.
+ * </P>
+ * <P>
+ * A side effect of this method is that it creates a file whose name is the value
+ * of the name parameter. The contents of the file is the actual name of the
+ * semaphore that is used when creating the semaphore.
+ * </P>
+ *
+ * @param name
+ * The name of the semaphore.
+ * @param initialValue
+ * The initial value for the semaphore.
+ *
+ */
+ public void connect(String name, int maxValue, int initialValue) throws IPCException
+ {
+ determineActualName(name);
+
+ SemaphoreResult result = new SemaphoreResult();
+ SemaphoreNative.connect(result, getActualName(), initialValue);
+ result.convertResultCode();
+
+ switch (result.result)
+ {
+ case Success:
+ break;
+
+ case InsufficientPermissions:
+ throw new IPCException(Errors.Permissions);
+
+ default:
+ throw new IPCException(Errors.Unknown);
+ }
+
+ setHandle(result.handle);
+ }
+
+ /**
+ *
+ * @param name
+ * @throws IPCException
+ */
+ private void determineActualName(String name) throws IPCException
+ {
+ String actualName = null;
+
+ int method;
+ method = SemaphoreNative.getNamingMethod();
+
+ switch (method)
+ {
+ case SemaphoreNative.METHOD_FILE_NAME :
+ {
+ File file = new File(name);
+ actualName = file.toString();
+ break;
+ }
+
+ case SemaphoreNative.METHOD_INTEGER :
+ {
+ actualName = Integer.toString(generateNextActualName());
+ break;
+ }
+
+ default :
+ throw new IPCException("Impossible case");
+ }
+
+ try
+ {
+ actualName = Utils.readOrCreate(name, actualName);
+ setActualName(actualName);
+ }
+ catch (IOException e)
+ {
+ throw new IPCException("Error trying to create or read virtual file for semaphore", e);
+ }
+ }
+
+ /**
+ * Connect to the underlying semaphore.
+ * <P>
+ * This method will attempt to connect to the underlying semaphore, creating it if it
+ * does not exist.
+ * </P>
+ * <P>
+ * The initialValue parameter is ignored if the semaphore already exists. In the
+ * situation where the semaphore is created, the initialValue argument is used to set
+ * the starting value
+ * </P>
+ *
+ * @param name The name of the semaphore. See class documentation for details.
+ * @param initialValue The initial value for the semaphore if it needs to be created.
+ * @throws IPCException If there is a problem creating the semaphore.
+ */
+ public void connect(String name, int initialValue) throws IPCException
+ {
+ connect(name, initialValue, initialValue);
+ }
+
+ protected void convertReturnCode(SemaphoreResult result)
+ {
+ result.result = Results.toResult(result.resultCode);
+ }
+
+ /**
+ * Increment the value of the semaphore.
+ * <P>
+ * Calling this method when the semaphore is not connected will result in a
+ * NullPointerException being thrown.
+ * </P>
+ */
+ public void increment() throws IPCException
+ {
+ SemaphoreResult result = new SemaphoreResult();
+ SemaphoreNative.increment(result, getHandle());
+ result.convertResultCode();
+
+ if (Results.Success != result.result)
+ {
+ throw new IPCException(result.result.message);
+ }
+ }
+
+ /**
+ * <P>
+ * Try to decrement the semaphore, waiting at least until the specified time to do so
+ * if the semaphore is already at 0 or below.
+ * </P>
+ * <P>
+ * Note that time is relative to {@link System#nanoTime()}. If that method returns a
+ * value that is greater than the value passed to us, then the method will not wait
+ * for the semaphore to become available.
+ * <P>
+ * The method always tries at least once to decrement the semaphore. The only question
+ * is whether or not the method will wait if it cannot immediately perform its
+ * operation.
+ *
+ * @param stopTime
+ * The time, relative to {@link System#nanoTime()}, after which the method will
+ * not wait for the semaphore to become available. Passing a negative value
+ * will cause the method to wait until the semaphore is available instead of
+ * timing out.
+ * @return true if the semaphore was reserved, false if it timed out.
+ * @throws IPCException
+ * If the call times out.
+ */
+ public void decrement(long timeout) throws IPCException
+ {
+ SemaphoreResult result = new SemaphoreResult();
+
+ SemaphoreNative.decrement(result, getHandle(), timeout);
+ result.convertResultCode();
+
+ switch (result.result)
+ {
+ case Success:
+ break;
+
+ case Timeout:
+ throw new IPCException(Errors.Timeout);
+
+ default:
+ throw new IPCException(result.result.message);
+ }
+ }
+
+ /**
+ * Decrement the semaphore by 1, blocking if required.
+ * <P>
+ * This method is equivalent to calling {@linkplain #decrement(long) decrement(-1)}.
+ * See that method for details.
+ * </P>
+ *
+ * @return Whether the decrement succeeded. This version of the method should always
+ * return true.
+ * @throws IPCException
+ * If a problem is encountered while trying to perform this operation.
+ */
+ public void decrement() throws IPCException
+ {
+ decrement(-1);
+ }
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/SemaphoreNative.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/SemaphoreNative.java
new file mode 100644
index 000000000..fcbea8f06
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/SemaphoreNative.java
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.semaphore;
+
+import org.eclipse.ecf.ipc.IPCPackage;
+
+/**
+ * <P>
+ * An internal class that provides an interface into the system for implementing
+ * semaphores.
+ * </P>
+ * <H2>Exceptions</H2>
+ * <P>
+ * To keep the native methods as simple as possible, the exceptions thrown in
+ * response to error conditions signal the nature of the error using integer
+ * codes. The codes are defined by the class constants whose names start with
+ * "ERROR_". For example, ERROR_UNKNOWN_HANDLE is used if the platform does not
+ * recognize the handle passed to it.
+ * </P>
+ *
+ * <H2>Virtual Files</H2>
+ * <P>
+ * Each semaphore is associated with a file in the file system. That file may
+ * or may not be required by the underlying operating system.
+ * </P>
+ *
+ * <P>
+ * In the case of Linux, the contents of this file will be the absolute path of
+ * the file.
+ * </P>
+ *
+ * <P>
+ * In the case of Windows, the contents of the file will be an integer value
+ * uniquely identifies the semaphore.
+ * </P>
+ *
+ * @author Clark N. Hobbie
+ */
+public class SemaphoreNative {
+ static {
+ IPCPackage.initializePackage();
+ }
+ /**
+ * Does this particular native implementation support getting a semaphore's
+ * value?
+ */
+ protected static Boolean ourSupportsGetValue;
+
+ /**
+ * Does this particular native implementation support setting a semaphore's
+ * value other than calling decrement methods?
+ */
+ protected static Boolean ourSupportsSetValue;
+
+ /**
+ * Native routines should return this to signal that the routine executed
+ * without problems.
+ */
+ public static final int RESULT_SUCCESS = 0;
+
+ /**
+ * The semaphore operation failed for an unanticipated reason.
+ */
+ public static final int RESULT_UNKNOWN_ERROR = 1;
+
+ /**
+ * The semaphore operation failed for a reason that is specific to the
+ * platform.
+ */
+ public static final int RESULT_PLATFORM_ERROR = 2;
+
+ /**
+ * The semaphore operation failed because the native platform does not
+ * recognize the handle used.
+ */
+ public static final int RESULT_UNKNOWN_HANDLE = 3;
+
+ /**
+ * A value returned by the decrement method to signal that the method failed
+ * because the semaphore value was less than 1 and the specified timeout
+ * elapsed.
+ */
+ public static final int RESULT_TIMEOUT = 4;
+
+ /**
+ * Access to the semaphore was denied when a particular operation was
+ * attempted.
+ */
+ public static final int RESULT_ACCESS_DENIED = 5;
+
+ /**
+ * The requested method is not implemented by the native layer.
+ */
+ public static final int RESULT_NOT_IMPLEMENTED = 6;
+
+ /**
+ * The semaphore has been incremented too many times.
+ */
+ public static final int RESULT_TOO_MANY_INCREMENTS = 7;
+
+ /**
+ * Denotes that the actual name for a semaphore should be an integer value.
+ */
+ public static final int METHOD_INTEGER = 0;
+
+ /**
+ * Denotes that the actual name for a semaphore should be absolute path to
+ * the virtual file.
+ */
+ public static final int METHOD_FILE_NAME = 1;
+
+ /**
+ * Connect to the underlying semaphore, creating it if it does not already
+ * exist.
+ * <P>
+ * The return value will be greater than 0 if the method was successful.
+ * This indicates that the value can be used in future calls to this classes
+ * methods.
+ * <P>
+ * If the return value is less than 0, then the native method failed.
+ * Multiplying the return value by -1 should produce a result that
+ * corresponds to one of the return codes defined by this class. That is,
+ * the absolute value should match one of the RESULT_ constants.
+ * <P>
+ * The return value should never be equal to 0.
+ *
+ * @param name
+ * The logical name of the semaphore.
+ * @param initialValue
+ * The initial value of the semaphore.
+ * @return See description. A value greater than 0 means success, a value
+ * less than 0 means failure. The return value should not be equal
+ * to zero.
+ */
+ public static native void connect(SemaphoreResult result, String name,
+ int initialValue);
+
+ /**
+ * Increase the value of the semaphore by 1.
+ *
+ * @param handle
+ * A logical value that the operating system uses to identify the
+ * semaphore.
+ * @return 0 if successful, otherwise -1.
+ */
+ public static native void increment(SemaphoreResult result, long handle);
+
+ /**
+ * Decrease the value of the semaphore by 1 if it is available; if not
+ * available wait at least the specified period of time for it to become
+ * available.
+ * <P>
+ * The value used for handle should be one that is returned by the connect
+ * method.
+ * <P>
+ * The native method always checks to see if the semaphore is available. The
+ * only question is whether or not the method will wait for the semaphore if
+ * it is not currently available.
+ * <P>
+ * If the timeout is less than or equal to zero, the method will not wait
+ * for the semaphore to become available. If the semaphore is currently
+ * available, then it will decrement it, but if it is not available then the
+ * method returns immediately with a return code of {@link #RESULT_TIMEOUT}.
+ * <P>
+ * If the timeout is greater than zero, the method will wait some
+ * unspecified period of time that is greater than or equal to the specified
+ * timeout for the semaphore to become available. If the semaphore is
+ * currently available, the method decrements it and returns. If the
+ * semaphore is not available, then the method waits some unspecified period
+ * of time for it to become available. If the semaphore becomes available,
+ * the method decrements it and returns {@link #RESULT_SUCCESS}. If the
+ * semaphore does not become available in the period of time, the method
+ * returns {@link #RESULT_TIMEOUT}.
+ * <P>
+ * The underlying operating system may not provide the requested resolution
+ * for nanoseconds. Generally speaking, the resolution should be at least 1
+ * millisecond.
+ * <P>
+ * At present, the method returns some value other than DECREMENT_TIMEOUT if
+ * it fails for some other reason, such as the semaphore does not exist.
+ *
+ * @param handle
+ * Which semaphore to use.
+ * @param timeout
+ * The amount of time, in nanoseconds, to wait for the semaphore
+ * to become available if it is not currently available.
+ * @return {@link #RESULT_SUCCESS} if the method decrements the semaphore,
+ * otherwise some other RESULT_ code is returned.
+ */
+ public static native void decrement(SemaphoreResult result, long handle,
+ long timeout);
+
+ /**
+ * Gets the current value of the semaphore.
+ * <P>
+ * The method returns 0 or greater on success and a negative value on
+ * failure. If the value indicates success, the return value is also the
+ * value of the semaphore. If negative, the absolute value corresponds to
+ * one the the RESULT_ constants.
+ *
+ * @param handle
+ * The semaphore to query.
+ * @return See description.
+ */
+ public static native int getValue(SemaphoreResult result, long handle);
+
+ public static native boolean supportsGetValue();
+
+ /**
+ * Set the value of the semaphore, without regards to other processes.
+ * <P>
+ * This method replaces whatever value the semaphore had with the value
+ * passed to the method.
+ *
+ * @param handle
+ * The handle corresponding the semaphore to modify.
+ * @param value
+ * The new value for the semaphore.
+ * @return {@link #RESULT_SUCCESS} on success, otherwise a different RESULT_
+ * code.
+ */
+ public static native int setValue(SemaphoreResult result, long handle,
+ int value);
+
+ public static native boolean supportsSetValue();
+
+ public static native void createResult(SemaphoreResult result, String name,
+ int maxValue, int initialValue);
+
+ public static native void linkTest();
+
+ /**
+ * Return the method that this platform uses in order to create a name for a
+ * semaphore.
+ *
+ * @return This method should return one of the METHOD_ constants.
+ */
+ public static native int getNamingMethod();
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/SemaphoreResult.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/SemaphoreResult.java
new file mode 100644
index 000000000..6ef5ea271
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/semaphore/SemaphoreResult.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.semaphore;
+
+/**
+ * <P>
+ * An internal class that contains the results from a native system call.
+ * </P>
+ * <P>
+ * Calls to the underlying operation system will often have sever pieces of information
+ * instead of just success and failure. This class allows clients to get back all the
+ * information at once.
+ * </P>
+ * <P>
+ * The RESULT_ constants are defined to make life easier for the JNI: accessing enum tags
+ * in JNI is somewhat difficult.
+ * </P>
+ *
+ * @author Clark N. Hobbie
+ */
+public class SemaphoreResult
+{
+ public static final int RESULT_SUCCESS = 0;
+
+ public static final int RESULT_INSUFFICIENT_PERMISSIONS = 1;
+
+ public static final int RESULT_DOES_NOT_EXIST = 2;
+
+ public static final int RESULT_UNKNOWN_ERROR = 3;
+
+ public static final int RESULT_TIMEOUT = 4;
+
+ public static final int RESULT_UNKNOWN_HANDLE = 5;
+
+ public static final String MSG_INSUFFICIENT_PERMISSIONS = "Insufficient permissions to access the semaphore";
+
+ public static final String MSG_SUCCESS = "success";
+
+ public static final String MSG_DOES_NOT_EXIST = "The semaphore does not exist";
+
+ public static final String MSG_UNKNOWN_ERROR = "An unknown error occurred while trying to access the semaphore";
+
+ public static final String MSG_TIMEOUT = "The specified period of timeout elapsed before the semaphore became available";
+
+ public static final String MSG_UNKNOWN_HANDLE = "The specified handle was not recognized as a semaphore handle by the OS";
+
+ public enum Results
+ {
+ Success(RESULT_SUCCESS, MSG_SUCCESS),
+ InsufficientPermissions(RESULT_INSUFFICIENT_PERMISSIONS, MSG_INSUFFICIENT_PERMISSIONS),
+ DoesNotExist(RESULT_DOES_NOT_EXIST, MSG_DOES_NOT_EXIST),
+ UnknownError(RESULT_UNKNOWN_ERROR, MSG_UNKNOWN_ERROR),
+ Timeout(RESULT_TIMEOUT, MSG_TIMEOUT),
+ UnknownHandle(RESULT_UNKNOWN_HANDLE, MSG_UNKNOWN_HANDLE);
+
+ public String message;
+
+ public int code;
+
+ private Results(int resultCode, String theMessage)
+ {
+ code = resultCode;
+ message = theMessage;
+ }
+
+ public static Results toResult(int code)
+ {
+ Results result = UnknownError;
+
+ for (Results r : values())
+ {
+ if (code == r.code)
+ {
+ result = r;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ public static int foo()
+ {
+ return -1;
+ }
+ }
+
+ public void convertResultCode()
+ {
+ result = Results.toResult(resultCode);
+ }
+
+ public int resultCode;
+
+ public Results result;
+
+ public int errorCode;
+
+ public long handle;
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/sharedmemory/SharedMemory.java b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/sharedmemory/SharedMemory.java
new file mode 100644
index 000000000..76000233c
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/bundles/org.eclipse.ecf.ipc/src/org/eclipse/ecf/ipc/sharedmemory/SharedMemory.java
@@ -0,0 +1,524 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Clark N. Hobbie
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Clark N. Hobbie - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.ipc.sharedmemory;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.FileChannel.MapMode;
+import java.nio.charset.Charset;
+
+import org.eclipse.ecf.ipc.IPCException;
+import org.eclipse.ecf.ipc.IPCException.Errors;
+
+
+
+/**
+ * <P>
+ * A shared memory segment.
+ * </P>
+ * <H2>Description</H2>
+ * <P>
+ * This class wraps the {@link java.nio.MappedByteBuffer} class to make it a little easier
+ * to use.
+ * </P>
+ * <P>
+ * {@link #quickstart}
+ * </P>
+ * <P>
+ * Instances of this class must correspond to a file on the host system that is read/write
+ * to the running process. <A name="quickstart">
+ * <H2>Quickstart</H2> </A>
+ * <UL>
+ * <LI>Create or connect to an existing segment via {@link #SharedMemory(String, int)}.</LI>
+ * </LI>
+ * <LI>Read from the segment via {@link #read(byte[], int, int, int)}.</LI>
+ * <LI>Write to the segment via {@link #write(byte[], int, int, int)}.</LI>
+ * <LI>You do not need to explicitly close your connection.</LI>
+ * </UL>
+ *
+ * @see java.nio.MappedByteBuffer
+ * @author Clark N. Hobbie
+ */
+public class SharedMemory
+{
+ protected File segmentFile;
+
+ protected MappedByteBuffer byteBuffer;
+
+ protected int size;
+
+ protected FileChannel channel;
+
+ private FileLock myLock;
+
+ private boolean myFileCreator;
+
+ public boolean isFileCreator()
+ {
+ return myFileCreator;
+ }
+
+ public void setFileCreator(boolean fileCreator)
+ {
+ myFileCreator = fileCreator;
+ }
+
+ public MappedByteBuffer getByteBuffer()
+ {
+ return byteBuffer;
+ }
+
+ public void setByteBuffer(MappedByteBuffer byteBuffer)
+ {
+ this.byteBuffer = byteBuffer;
+ }
+
+ public boolean isConnected()
+ {
+ return byteBuffer != null;
+ }
+
+ public File getSegmentFile()
+ {
+ return segmentFile;
+ }
+
+ public int getSize()
+ {
+ return size;
+ }
+
+ public SharedMemory()
+ {
+ }
+
+ public SharedMemory(File file, int size) throws IPCException
+ {
+ connect(file, size);
+ }
+
+ public SharedMemory(String fileName, int size) throws IPCException
+ {
+ connect(fileName, size);
+ }
+
+ /**
+ * Connect this segment to the underlying shared memory segment.
+ *
+ * @param name
+ * The name of the file for the segment.
+ * @param size
+ * The size of the segment.
+ */
+ public void connect(File file, int size) throws IPCException
+ {
+ if (null != this.byteBuffer)
+ {
+ throw new IPCException(Errors.AlreadyConnected);
+ }
+
+ myFileCreator = false;
+ try
+ {
+ myFileCreator = file.createNewFile();
+ }
+ catch (IOException e)
+ {
+ throw new IPCException(Errors.ExceptionCreatingFile, e);
+ }
+
+ RandomAccessFile raf = null;
+ try
+ {
+ raf = new RandomAccessFile(file, "rw");
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new IPCException(Errors.ErrorOpeningMappingFile, e);
+ }
+
+ channel = raf.getChannel();
+ try
+ {
+ this.byteBuffer = channel.map(MapMode.READ_WRITE, 0, size);
+ }
+ catch (IOException e)
+ {
+ throw new IPCException(Errors.ErrorCreatingMap, e);
+ }
+
+ this.segmentFile = file;
+ this.size = size;
+ }
+
+ public void connect(String fileName, int size) throws IPCException
+ {
+ File file = new File(fileName);
+ connect(file, size);
+ }
+
+ /**
+ * Write an array of bytes into a specified location in the segment, starting with a
+ * particular byte in the buffer and continuing for a specified number of bytes.
+ *
+ * @param buf
+ * The data to write.
+ * @param buffOffset
+ * The location, relative to the start of the buffer, where the data should be
+ * obtained.
+ * @param bufLength
+ * The number of bytes to write.
+ * @param segmentOffset
+ * The location in the buffer where the data should be written.
+ * @throws IPCException
+ * The method will throw this exception if the segment is not actually
+ * connected to the underlying shared memory block.
+ */
+ public void write(byte[] buf, int buffOffset, int bufLength, int segmentOffset)
+ throws IPCException
+ {
+ try
+ {
+ if (null == this.byteBuffer)
+ {
+ throw new IPCException(Errors.NotConnected);
+ }
+
+ this.byteBuffer.position(segmentOffset);
+ this.byteBuffer.put(buf, buffOffset, bufLength);
+ }
+ catch (java.nio.BufferOverflowException e)
+ {
+ System.out.println("segment size = " + this.size + ", segmentOffset = "
+ + segmentOffset + ", length = " + bufLength);
+ throw e;
+ }
+ }
+
+ public void write(byte value, int offset)
+ {
+ this.byteBuffer.position(offset);
+ this.byteBuffer.put(value);
+ }
+
+ public void write(byte[] buf) throws IPCException
+ {
+ write(buf, 0, buf.length, 0);
+ }
+
+ public void write(int value, int offset)
+ {
+ byte b = (byte) value;
+ write(b, offset);
+ }
+
+ public void write(byte[] buf, int segmentOffset) throws IPCException
+ {
+ write(buf, 0, buf.length, segmentOffset);
+ }
+
+ /**
+ * <P>
+ * Read bytes up to a specified number of bytes into the provided buffer.
+ * </P>
+ * <P>
+ * This method returns the number of bytes that were actually read. If fewer bytes are
+ * left in the segment than requested, then the method returns the number of bytes
+ * read.
+ * </P>
+ *
+ * @param buf
+ * The buffer where the bytes read should be stored.
+ * @param boffset
+ * The offset into buf where the bytes should be placed.
+ * @param length
+ * The number of bytes to try to read.
+ * @param soffset
+ * The offset within the segment where the read should start.
+ * @return The number of bytes actually read. See description for details.
+ * @throws IPCException
+ * This method throws this exception with the error set to
+ * {@link Errors#NotConnected} if the instance has not been connected
+ * to a segment yet.
+ */
+ public int read(int soffset, byte[] buf, int boffset, int length) throws IPCException
+ {
+ if (null == byteBuffer)
+ {
+ throw new IPCException(Errors.NotConnected);
+ }
+
+ if (length > byteBuffer.remaining())
+ length = byteBuffer.remaining();
+
+ byteBuffer.position(soffset);
+ byteBuffer.get(buf, boffset, length);
+
+ return length;
+ }
+
+ /**
+ * <P>
+ * Read bytes from the segment into a buffer, storing them in a location offset from
+ * the start of the buffer.
+ * </P>
+ * <P>
+ * This method is equivalent to calling:
+ * </P>
+ * <CODE>
+ * <PRE>
+ * read(0, buf, bufferOffset, buf.length);
+ * </PRE>
+ * </CODE>
+ *
+ * @param buf
+ * The buffer where the bytes read should be placed.
+ * @param bufferOffset
+ * The location in the buffer where the bytes read should start.
+ * @return The number of bytes actually read.
+ * @throws IPCException
+ * {@link #read(int, byte[], int, int)}.
+ * @see #read(int, byte[], int, int)
+ */
+ public int read(byte[] buf, int bufferOffset) throws IPCException
+ {
+ return read(0, buf, bufferOffset, buf.length);
+ }
+
+ /**
+ * Read bytes from the start of the segment.
+ * <P>
+ * This method is equivalent to calling
+ * </P>
+ * <CODE>
+ * <PRE>
+ * read(0, buf, 0, buf.length);
+ * </PRE>
+ * </CODE>
+ * <P>
+ * See that method for details.
+ * </P>
+ *
+ * @param buf
+ * The buffer where bytes read should be placed.
+ * @return The number of bytes read.
+ * @throws IPCException
+ * see {@link #read(int, byte[], int, int)}.
+ * @see {@link #read(int, byte[], int, int)}
+ */
+ public int read(byte[] buf) throws IPCException
+ {
+ return read(0, buf, 0, buf.length);
+ }
+
+ /**
+ * Read in data from the segment, starting at a particular location in the segment.
+ * <P>
+ * This method is equivalent to calling
+ * </P>
+ * <CODE>
+ * <PRE>
+ * read(segmentOffset, buf, 0, buf.length);
+ * </PRE>
+ * </CODE>
+ * <P>
+ * See that method for details.
+ * </P>
+ *
+ * @param segmentOffset
+ * The byte index into the segment where reading should start.
+ * @param buf
+ * Where the bytes read should be placed.
+ * @return The number of bytes actually read.
+ * @throws IPCException
+ * see {@link #read(int, byte[], int, int)}
+ * @see #read(int, byte[], int, int)
+ */
+ public int read(int segmentOffset, byte[] buf) throws IPCException
+ {
+ return read(segmentOffset, buf, 0, buf.length);
+ }
+
+ /**
+ * Return the byte at a particular location in the segment.
+ *
+ * @param offset
+ * The location of the byte in the segment.
+ * @return The value of the byte.
+ * @throws IndexOutOfBoundsException
+ * If offset is negative or larger than the size of the segment minus 1.
+ */
+ public byte getByte(int offset) throws IPCException
+ {
+ return byteBuffer.get(offset);
+ }
+
+ /**
+ * Reserve the shared memory segment.
+ * <P>
+ * It is not clear from the JRE documentation whether or not locking the segment will
+ * stop modifications to the segment or not. {@linkplain FileChannel#lock() for
+ * details.}
+ *
+ * @throws IOException
+ */
+ public void lock() throws IOException
+ {
+ myLock = channel.lock();
+ }
+
+ public void unlock() throws IOException
+ {
+ myLock.release();
+ }
+
+ /**
+ * Put some data at a location.
+ * <P>
+ * The entire contents of the buffer are written to a position in the segment defined
+ * by the offset parameter. If the amount of data exceeds the size of the segment, the
+ * method throws an exception.
+ * </P>
+ *
+ * @param offset
+ * The location in the segment, in bytes, where the data will be written.
+ * @param data
+ * The data to write. The contents of the array will be written.
+ * @throws IPCException
+ */
+ public void put(int offset, byte[] data) throws IPCException
+ {
+ write(data, offset);
+ }
+
+ /**
+ * <P>
+ * Retrieve a line of text from the segment.
+ * </P>
+ * <P>
+ * This method goes to the specified location in the segment and tries to read in
+ * characters. It continues until it hits the end of the segment, or it encounters the
+ * end of the string. The end of a string is denoted by any of the following sequences
+ * of characters:
+ * </P>
+ * <UL>
+ * <LI>'\n'</LI>
+ * <LI>'\r'</LI>
+ * <LI>'\n\r'</LI>
+ * </UL>
+ * <P>
+ * The method uses the underlying character set as defined by
+ * {@link Charset#defaultCharset()}
+ * </P>
+ * <P>
+ * The supplied buffer is used to determine the maximum length of the string in that,
+ * if no line termination has been encountered before a number of bytes equal to the
+ * size of the buffer are read, then the characters accumulated so far are returned.
+ * </P>
+ * <P>
+ * Any line termination character(s) are not included in the string returned.
+ * </P>
+ *
+ * @param offset
+ * The location in the segment to start reading.
+ * @param buffer
+ * A buffer to contain the bytes from the shared memory segment.
+ * @return The resulting string.
+ * @throws IOException
+ * If the method tries to read past the end of the segment, either because it
+ * started outside the segment or because the string did not have any line
+ * termination.
+ * @throws IPCException
+ * This exception is thrown if the object is not currently connected to a
+ * shared memory segment.
+ */
+ public String getLine(int offset, byte[] buffer) throws IOException, IPCException
+ {
+ StringBuffer sb = new StringBuffer();
+
+ //
+ // For the sake of efficiency, try to read a block of 256 bytes
+ //
+ int count = read(offset, buffer);
+ ByteBuffer bb = ByteBuffer.wrap(buffer, 0, count);
+ CharBuffer cb = Charset.defaultCharset().decode(bb);
+ int charCount = cb.length();
+
+ for (int index = 0; index < charCount; index++)
+ {
+ char c = cb.get();
+ if (c == '\n' || c == '\r')
+ break;
+
+ sb.append(c);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Return a string from the specified location in the segment; the string may only
+ * take the specified number of bytes.
+ * <P>
+ * This method is equivalent to calling
+ * </P>
+ * <CODE>
+ * <PRE>
+ * byte[] buf = new byte[maxBytes];
+ * getLine(offset, buf);
+ * </PRE>
+ * </CODE>
+ * <P>
+ * See that method for details.
+ * </P>
+ * <P>
+ * If the underlying string does not end after maxBytes, the method returns the
+ * substring that takes up that number of bytes.
+ * </P>
+ *
+ * @param offset
+ * The location within the segment where the string starts.
+ * @param maxBytes
+ * The maximum number of bytes for the string.
+ * @return The string found.
+ * @throws IOException
+ * See {@link #getLine(int, byte[])}.
+ * @throws IPCException
+ * See {@link #getLine(int, byte[])}.
+ * @see #getLine(int, byte[])
+ */
+ public String getLine(int offset, int maxBytes) throws IOException, IPCException
+ {
+ byte[] buffer = new byte[maxBytes];
+ return getLine(offset, buffer);
+ }
+
+
+ public void putString(int offset, String s)
+ {
+ byte[] buff = s.getBytes();
+ byteBuffer.position(offset);
+ byteBuffer.put(buff);
+ }
+
+ public void putLine(int offset, String s)
+ {
+ s = s + '\n';
+ putString(offset, s);
+ }
+}
diff --git a/incubation/projects/org.eclipse.ecf.ipc/features/org.eclipse.ecf.ipc-feature/build.properties b/incubation/projects/org.eclipse.ecf.ipc/features/org.eclipse.ecf.ipc-feature/build.properties
new file mode 100644
index 000000000..64f93a9f0
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/features/org.eclipse.ecf.ipc-feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/incubation/projects/org.eclipse.ecf.ipc/features/org.eclipse.ecf.ipc-feature/feature.xml b/incubation/projects/org.eclipse.ecf.ipc/features/org.eclipse.ecf.ipc-feature/feature.xml
new file mode 100644
index 000000000..f5b0c1ce7
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/features/org.eclipse.ecf.ipc-feature/feature.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.ecf.ipc_feature"
+ label="ECF IPC Feature"
+ version="0.1.0.qualifier"
+ provider-name="Eclipse.org">
+
+ <description url="http://www.example.com/description">
+ [Enter Feature Description here.]
+ </description>
+
+ <copyright url="http://www.example.com/copyright">
+ [Enter Copyright Description here.]
+ </copyright>
+
+ <license url="http://www.example.com/license">
+ [Enter License Description here.]
+ </license>
+
+</feature>
diff --git a/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/.project b/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/.project
new file mode 100644
index 000000000..8433d045d
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.launcher.releng</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
diff --git a/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/build.xml b/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/build.xml
new file mode 100644
index 000000000..66de760a8
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/build.xml
@@ -0,0 +1,247 @@
+<!--
+ Copyright (c) 2009 IBM Corporation and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ IBM Corporation - initial API and implementation
+ -->
+<project name="ECF IPC" basedir="." default="build">
+
+ <property name="cvsRoot" value=":pserver:anonymous@dev.eclipse.org:/cvsroot/rt" />
+ <property name="cvsExecutablePath" value="org.eclipse.equinox/framework/bundles/org.eclipse.equinox.executable" />
+ <property name="cvsTag" value="HEAD" />
+
+ <!-- Macro for execing scp -->
+ <macrodef name="SCP">
+ <attribute name="dir" />
+ <attribute name="source"/>
+ <attribute name="destination" />
+ <attribute name="failonerror" default="true" />
+ <sequential>
+ <echo message="Copying @{source} to @{destination}."/>
+ <exec dir="@{dir}" executable="scp" failonerror="@{failonerror}">
+ <arg value="-q"/>
+ <arg line="@{source}" />
+ <arg value="@{destination}" />
+ </exec>
+ </sequential>
+ </macrodef>
+
+ <!-- macro to resolve properties because we can't do ${${prop}} -->
+ <macrodef name="resolveProperty">
+ <attribute name="name" />
+ <attribute name="value" />
+ <sequential>
+ <condition property="@{name}" value="${@{value}}" >
+ <isset property="@{value}"/>
+ </condition>
+ </sequential>
+ </macrodef>
+
+ <target name="init_exeFolder" >
+ <!-- set to "bin" or "contributed" according to which folder under org.eclipse.equinox.executable to store the built eclipse -->
+ <condition property="exeFolder" value="contributed" else="bin">
+ <or>
+ <equals arg1="s390" arg2="${arch}" />
+ <equals arg1="s390x" arg2="${arch}" />
+ <equals arg1="motif.sparc" arg2="${ws}.${arch}" />
+ <equals arg1="win32.ia64" arg2="${ws}.${arch}" />
+ </or>
+ </condition>
+ </target>
+
+ <target name="init_fragment" >
+ <!-- set to "contributed" or "fragments" according to which folder under org.eclipse.equinox.launcher to find the fragment -->
+ <condition property="subFolder" value="contributed" else="fragments">
+ <or>
+ <equals arg1="s390" arg2="${arch}" />
+ <equals arg1="s390x" arg2="${arch}" />
+ <equals arg1="solaris.x86" arg2="${os}.${arch}" />
+ </or>
+ </condition>
+ <!-- mac only has arch in fragment name for x86_64 -->
+ <condition property="fragmentFolder" value="${subFolder}/org.eclipse.equinox.launcher.${ws}.${os}.${arch}"
+ else="${subFolder}/org.eclipse.equinox.launcher.${ws}.${os}" >
+ <not>
+ <and>
+ <equals arg1="macosx" arg2="${os}"/>
+ <not> <equals arg1="x86_64" arg2="${arch}"/> </not>
+ </and>
+ </not>
+ </condition>
+ </target>
+
+ <target name="fetchExecutableSource" >
+ <!-- fetch the source and put it in a folder unique to this platform so we don't interfere with other
+ compiles if the working folder is shared accross multiple machines -->
+ <delete dir="${basedir}/${os}.${ws}.${arch}/library" failonerror="false"/>
+ <cvs command="export -d ${os}.${ws}.${arch}/library" tag="${cvsTag}" package="${cvsExecutablePath}/library" cvsRoot="${cvsRoot}" dest="${basedir}" quiet="true" failonerror="true"/>
+ </target>
+
+ <target name="buildNix" if="buildNix">
+ <!-- exec the build.sh for flavors of unix -->
+ <exec dir="${libraryFolder}/${ws}" executable="sh" failonerror="true">
+ <arg value="build.sh"/>
+ <arg line="-ws ${ws} -os ${os} -arch ${arch}"/>
+ <arg line="-java ${javaHome}"/>
+ <arg value="clean all" />
+ <env key="PATH" value="/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin" />
+ </exec>
+
+ <!-- copy the resulting executable and .so -->
+ <SCP dir="${libraryFolder}/${ws}" source="eclipse" destination="${resultsBaseFolder}/org.eclipse.equinox.executable/${exeFolder}/${ws}/${os}/${arch}" />
+ <SCP dir="${libraryFolder}/${ws}" source="eclipse_${maj_ver}${min_ver}.so" destination="${resultsBaseFolder}/org.eclipse.equinox.launcher/${fragmentFolder}" />
+ </target>
+
+ <target name="buildWindows" if="buildWindows">
+ <!-- exec the batch file to build on windows -->
+ <exec dir="${libraryFolder}/${ws}" executable="cmd" failonerror="true">
+ <arg value="/c" />
+ <arg value="build.bat" />
+ <arg line="${arch}"/>
+ <arg value="-java"/>
+ <arg value="${javaHome}"/>
+ <arg line="clean all" />
+ </exec>
+
+ <SCP dir="${libraryFolder}/${ws}" source="eclipse.exe eclipsec.exe" destination="${resultsBaseFolder}/org.eclipse.equinox.executable/${exeFolder}/${ws}/${os}/${arch}" />
+ <SCP dir="${libraryFolder}/${ws}" source="eclipse_${maj_ver}${min_ver}.dll" destination="${resultsBaseFolder}/org.eclipse.equinox.launcher/${fragmentFolder}" />
+ <condition property="copyWPF">
+ <equals arg1="${ws}" arg2="wpf" />
+ </condition>
+ <antcall target="copyWPF" />
+ </target>
+
+ <target name="copyWPF" if="copyWPF" >
+ <SCP dir="${libraryFolder}/${ws}" source="com_${maj_ver}${min_ver}.dll" destination="${resultsBaseFolder}/org.eclipse.equinox.launcher/${fragmentFolder}" failonerror="false" />
+ </target>
+
+ <target name="buildMac" if="buildMac">
+ <exec dir="${libraryFolder}/carbon" executable="sh" failonerror="true">
+ <arg value="build.sh"/>
+ <arg line="-ws ${ws} -arch ${arch}"/>
+ <arg value="clean all" />
+ <env key="PATH" value="/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:${extraPath}" />
+ </exec>
+
+ <SCP dir="${libraryFolder}/carbon" source="eclipse" destination="${resultsBaseFolder}/org.eclipse.equinox.executable/${exeFolder}/${ws}/${os}/${arch}/Eclipse.app/Contents/MacOS" />
+ <SCP dir="${libraryFolder}/carbon" source="eclipse_${maj_ver}${min_ver}.so" destination="${resultsBaseFolder}/org.eclipse.equinox.launcher/${fragmentFolder}" />
+ <!-- x86 and ppc are the same universal binary, copy to both under the executable feature -->
+ <condition property="copyMacPPC">
+ <equals arg1="${arch}" arg2="x86" />
+ </condition>
+ <antcall target="copyMacPPC" />
+ </target>
+
+ <target name="copyMacPPC" if="copyMacPPC" >
+ <SCP dir="${libraryFolder}/carbon" source="eclipse" destination="${resultsBaseFolder}/org.eclipse.equinox.executable/${exeFolder}/${ws}/${os}/ppc/Eclipse.app/Contents/MacOS" />
+ </target>
+
+ <target name="determineBuild" >
+ <condition property="buildWindows" >
+ <equals arg1="${os}" arg2="win32"/>
+ </condition>
+ <condition property="buildMac" >
+ <equals arg1="${os}" arg2="macosx" />
+ </condition>
+ <condition property="buildNix" >
+ <not><or>
+ <isset property="buildWindows" />
+ <isset property="buildMac" />
+ </or></not>
+ </condition>
+ </target>
+
+ <target name="initProperties" >
+ <property name="ws" value="${env.ws}"/>
+ <property name="os" value="${env.os}" />
+ <property name="arch" value="${env.arch}" />
+
+ <resolveProperty name="machine" value="m_${os}.${arch}" />
+ <resolveProperty name="javaArg" value="j_${os}.${arch}" />
+ <resolveProperty name="userName" value="u_${os}.${arch}" />
+
+ <!-- windows is built locally, everything else is remote -->
+ <condition property="local" >
+ <equals arg1="${os}" arg2="win32"/>
+ </condition>
+ <condition property="remote" >
+ <not> <isset property="local"/> </not>
+ </condition>
+
+ <!-- working directory defaults for our machines. Others should
+ pass in workspace as a property on the command line -->
+ <condition property="workspace" value="/Users/swtbuild/build/equinox" >
+ <equals arg1="${os}" arg2="macosx"/>
+ </condition>
+ <condition property="workspace" value="~/equinox" >
+ <equals arg1="${os}.${arch}" arg2="solaris.x86" />
+ </condition>
+ <property name="workspace" value="/bluebird/teamswt/equinox" />
+ </target>
+
+
+ <!--
+ Main entry point. We expect the following properties:
+ os, ws, arch - to be passed as ant properties or set as environment variables.
+ resultsBaseFolder - location to scp the resulting binaries to, usually a workspace containing the executable & launcher projects (eg: user@machine:~/workspace)
+ m_<os>.<arch> - name of a machine to ssh to for this os & arch
+ u_<os>.<arch> - optional user on the machine for this platform
+ j_<os>.<arch> - location of a jdk we can compile against
+ We expect ssh keys to be set up so that we don't need passwords
+
+ The j_<os>.<arch> properties work together with remote.sh, and are either
+ -javaHome /path/to/jdk
+ or -java relative/path/to/jdk
+ -->
+ <target name="build" depends="initProperties">
+ <echo message="Building for ${os}, ${ws}, ${arch}"/>
+ <antcall target="buildLocal" />
+ <antcall target="buildRemote" />
+ </target>
+
+ <target name="buildLocal" if="local" >
+ <condition property="javaHome" value="${j_win32}" else="${java.home}" >
+ <isset property="j_win32"/>
+ </condition>
+ <antcall target="buildConfig" />
+ </target>
+
+ <target name="buildRemote" if="remote">
+ <echo message="Machine: ${machine}" />
+ <condition property="scpDest" value="${userName}@${machine}" else="${machine}" >
+ <isset property="userName" />
+ </condition>
+ <condition property="sshUser" value="-l ${userName}" else="" >
+ <isset property="userName" />
+ </condition>
+ <SCP dir="${basedir}" source="remote.sh build.xml" destination="${scpDest}:${workspace}" />
+ <echo message="Execing ssh ${machine}" />
+ <exec executable="ssh" failonerror="true" >
+ <arg line="${sshUser} ${machine}" />
+ <arg line="sh ${workspace}/remote.sh" />
+ <arg line="${javaArg}" />
+ <arg line="-Dos=${os} -Dws=${ws} -Darch=${arch}" />
+ <arg value="-DresultsBaseFolder=${resultsBaseFolder}" />
+ </exec>
+ </target>
+
+ <target name="buildConfig" depends="init_exeFolder,init_fragment,determineBuild" >
+ <antcall target="fetchExecutableSource" />
+ <property name="javaHome" value="${java.home}/.." />
+ <property name="libraryFolder" value="${basedir}/${os}.${ws}.${arch}/library" />
+ <property file="${libraryFolder}/make_version.mak" />
+
+ <antcall target="buildNix" />
+ <antcall target="buildWindows" />
+ <antcall target="buildMac" />
+ </target>
+
+</project>
+
+
+
+
diff --git a/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/remote.sh b/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/remote.sh
new file mode 100644
index 000000000..6dde35a36
--- /dev/null
+++ b/incubation/projects/org.eclipse.ecf.ipc/releng/org.eclipse.ecf.ipc.releng/remote.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+#the directory containing this script
+scriptDir=`dirname "$0"`
+
+ANT_HOME=/bluebird/teamswt/swt-builddir/build/apache-ant-1.7.1
+extraArgs=""
+
+while [ "$1" != "" ]; do
+ if [ "$1" = "-java" ] && [ "$2" != "" ]; then
+ JAVA_HOME=/bluebird/teamswt/swt-builddir/build/JRE/$2
+ shift
+ elif [ "$1" = "-javaHome" ] && [ "$2" != "" ]; then
+ JAVA_HOME="$2"
+ shift
+ elif [ "$1" = "-antHome" ] && [ "$2" != "" ]; then
+ ANT_HOME="$2"
+ shift
+ else
+ extraArgs="$extraArgs $1"
+ fi
+ shift
+done
+
+OS=`uname -s`
+case $OS in
+ "SunOS")
+ if [ "$PROC" = "" ]; then
+ PROC=`uname -p`
+ fi
+ case ${PROC} in
+ "i386")
+ ANT_HOME=~/equinox/apache-ant-1.7.1
+ ;;
+ esac
+ ;;
+esac
+
+PATH=$JAVA_HOME/jre/bin:$ANT_HOME/bin:$PATH
+
+export JAVA_HOME ANT_HOME PATH
+echo JAVA_HOME = $JAVA_HOME
+echo ANT_HOME = $ANT_HOME
+echo ant -f ${scriptDir}/build.xml buildConfig $extraArgs
+ant -f ${scriptDir}/build.xml buildConfig $extraArgs

Back to the top