├── .gitignore ├── .gitmodules ├── Makefile ├── README.md ├── build.sh ├── examples ├── org │ └── accelio │ │ └── jxio │ │ ├── helloworld │ │ ├── HelloClient.java │ │ └── HelloServer.java │ │ ├── log4j.properties.jxio │ │ ├── simpletest │ │ ├── SimpleClient.java │ │ └── SimpleServer.java │ │ └── tests │ │ ├── benchmarks │ │ ├── ClientWorker.java │ │ ├── DataPathTest.java │ │ ├── DataPathTestClient.java │ │ ├── DataPathTestServer.java │ │ ├── ServerPortalWorker.java │ │ ├── ServerSessionHandle.java │ │ ├── StatClientSession.java │ │ ├── StatMTMain.java │ │ ├── StatMain.java │ │ ├── StatTest.java │ │ ├── jxioConnection │ │ │ ├── StreamClient.java │ │ │ ├── StreamServer.java │ │ │ └── UserServerCallbacks.java │ │ ├── xio_client_stat.c │ │ ├── xio_mt_client_stat.c │ │ └── xio_server.c │ │ └── log4j.properties.jxiotest ├── runCBenchmarkClientTest.sh ├── runCBenchmarkServer.sh ├── runHelloWorld.sh ├── runJBenchmarkTest.py ├── runJxioConnectionTest.sh └── runSimpleTest.sh ├── manifest.template └── src ├── c ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile.am ├── NEWS ├── README ├── autogen.sh ├── configure.ac └── src │ ├── Bridge.cc │ ├── Bridge.h │ ├── CallbackFunctionsClient.cc │ ├── CallbackFunctionsClient.h │ ├── CallbackFunctionsServer.cc │ ├── CallbackFunctionsServer.h │ ├── Client.cc │ ├── Client.h │ ├── Context.cc │ ├── Context.h │ ├── EventQueue.cc │ ├── EventQueue.h │ ├── Events.cc │ ├── Events.h │ ├── Makefile.am │ ├── Msg.cc │ ├── Msg.h │ ├── MsgPool.cc │ ├── MsgPool.h │ ├── MsgPools.cc │ ├── MsgPools.h │ ├── ServerPortal.cc │ ├── ServerPortal.h │ ├── ServerSession.cc │ ├── ServerSession.h │ ├── Utils.cc │ ├── Utils.h │ └── bullseye.h ├── java └── org │ ├── accelio │ └── jxio │ │ ├── ClientSession.java │ │ ├── EventName.java │ │ ├── EventQueueHandler.java │ │ ├── EventReason.java │ │ ├── Msg.java │ │ ├── MsgPool.java │ │ ├── ServerPortal.java │ │ ├── ServerSession.java │ │ ├── WorkerCache.java │ │ ├── exceptions │ │ ├── JxioGeneralException.java │ │ ├── JxioQueueOverflowException.java │ │ └── JxioSessionClosedException.java │ │ ├── impl │ │ ├── Bridge.java │ │ ├── ElapsedTimeMeasurement.java │ │ ├── Event.java │ │ ├── EventMsgError.java │ │ ├── EventNameImpl.java │ │ ├── EventNewMsg.java │ │ ├── EventNewSession.java │ │ ├── EventSession.java │ │ ├── EventSessionEstablished.java │ │ └── LoadLibrary.java │ │ └── jxioConnection │ │ ├── Constants.java │ │ ├── JxioConnection.java │ │ ├── JxioConnectionServer.java │ │ └── impl │ │ ├── BufferManager.java │ │ ├── BufferSupplier.java │ │ ├── JxioResourceManager.java │ │ ├── MultiBufOutputStream.java │ │ ├── MultiBuffInputStream.java │ │ ├── ServerWorker.java │ │ └── SimpleConnection.java │ └── apache │ └── lucene │ └── facet │ └── taxonomy │ └── LRUHashMap.java └── lib ├── commons-logging-1.2.jar ├── commons-logging.jar └── log4j-1.2.15.jar /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.lo 4 | *.la 5 | 6 | # Libraries 7 | .libs 8 | *.lib 9 | *.a 10 | 11 | # Shared objects 12 | *.so 13 | *.so.* 14 | 15 | # Dependencies 16 | .dirstamp 17 | .deps 18 | 19 | # Automake 20 | Makefile.in 21 | Makefile 22 | aclocal.m4 23 | autom4te.cache/ 24 | config.h 25 | config.h.in 26 | config.guess 27 | config.log 28 | config.sub 29 | config.status 30 | config/ 31 | configure 32 | ltmain.sh 33 | libtool 34 | depcomp 35 | install-sh 36 | missing 37 | m4/ 38 | 39 | # Project/Eclipse 40 | .cproject 41 | .project 42 | .classpath 43 | 44 | # Java class 45 | *.class 46 | 47 | # Accellio specific 48 | 49 | # JX specific 50 | /bin 51 | /docs 52 | manifest.txt 53 | version 54 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/accelio"] 2 | path = src/accelio 3 | url = https://github.com/accelio/accelio.git 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Configuring Running Directory 3 | TOP_DIR=. 4 | 5 | GIT_VERSION=`git describe --long --tags --always --dirty` 6 | 7 | # Configuring Parameters 8 | TARGET=jxio.jar 9 | BIN_FOLDER=$(TOP_DIR)/bin 10 | LIB_FOLDER=$(TOP_DIR)/src/lib 11 | SRC_JAVA_FOLDER=$(TOP_DIR)/src/java 12 | SRC_JAVA_FILES=$(SRC_JAVA_FOLDER)/org/accelio/jxio/*.java $(SRC_JAVA_FOLDER)/org/accelio/jxio/exceptions/*.java $(SRC_JAVA_FOLDER)/org/accelio/jxio/impl/*.java $(SRC_JAVA_FOLDER)/org/accelio/jxio/jxioConnection/*.java $(SRC_JAVA_FOLDER)/org/accelio/jxio/jxioConnection/impl/*.java $(SRC_JAVA_FOLDER)/org/apache/lucene/facet/taxonomy/LRUHashMap.java 13 | 14 | NATIVE_LIBS=libjxio.so libxio.so 15 | 16 | STRIP_COMMAND=touch #do not strip libraries from symbols 17 | 18 | ifndef DONT_STRIP 19 | STRIP_COMMAND=strip -s 20 | endif 21 | 22 | all: $(TARGET) 23 | 24 | $(TARGET):$(SRC_JAVA_FILES) 25 | rm -rf $(BIN_FOLDER)/*; mkdir -p $(BIN_FOLDER) 26 | (cd src/accelio/; make -s) 27 | cp src/accelio/src/usr/.libs/libxio.so $(BIN_FOLDER) 28 | $(STRIP_COMMAND) $(BIN_FOLDER)/libxio.so 29 | (cd src/c; make -s) 30 | cp src/c/src/.libs/libjxio.so $(BIN_FOLDER) 31 | $(STRIP_COMMAND) $(BIN_FOLDER)/libjxio.so 32 | javac -cp $(LIB_FOLDER)/commons-logging.jar -d $(BIN_FOLDER) $(SRC_JAVA_FILES) 33 | (echo $(GIT_VERSION) > version) 34 | (cp manifest.template manifest.txt; sed -i "s/Implementation-Version: .*/Implementation-Version: $(GIT_VERSION)/" manifest.txt) 35 | (echo "Implementation-Version-AccelIO: `cd src/accelio; git describe --long --tags --always --dirty; cd ../..`" >> manifest.txt) 36 | (cd $(BIN_FOLDER); jar -cfm $(TARGET) ../manifest.txt org $(NATIVE_LIBS)) 37 | 38 | clean: 39 | (cd src/c; make clean -s) 40 | rm -rf $(BIN_FOLDER)/* 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

JXIO

2 | 3 | JXIO is Java API over AccelIO (C library).
4 | AccelIO (http://www.accelio.org/) is a high-performance asynchronous reliable messaging and RPC library optimized for hardware acceleration. RDMA and TCP/IP transport are implemented, and other transports, such as shared-memory can take advantage of efficient and convenient API. 5 | 6 | 7 |

Build instructions:

8 | 1. Download: git clone https://github.com/accelio/JXIO.git
9 | 2. Move into folder: cd JXIO
10 | 3. Set JAVA_HOME: export JAVA_HOME=/usr/java/jdk1.7.0_25/
11 | 4. Build: ./build.sh (this pulls the relevant C level Accelio library and builds everything you need)
12 | 13 |

Examples:

14 | In examples folder there is HelloWorld example. Both client and server are single threaded. Client sends a single message 15 | to Server and exits after receiving a response.
16 | 17 | 1. Run Server side: ./examples/runHelloWorld.sh server 36.0.0.120 1234
18 | LD library is: /.autodirect/mtrswgwork/katyak/tmp/jxio/examples
19 | Compiling JAVA files....
20 | Running Server side test
21 | 2014-02-16 11:17:35,013 main INFO HelloServer:44 waiting for JXIO incoming connections
22 | 2014-02-16 11:17:46,576 main INFO HelloServer:90 [SUCCESS] Got event onSessionNew from 36.0.0.121, URI='rdma://36.0.0.120:1234/'
23 | 2014-02-16 11:17:46,578 main INFO HelloServer:108 [SUCCESS] Got a message request! Prepare the champagne!
24 | 2014-02-16 11:17:46,579 main INFO HelloServer:116 msg is: 'Hello Server'
25 | 2014-02-16 11:17:46,583 main INFO HelloServer:135 [EVENT] Got event SESSION_CLOSED
26 | 27 | 2. Run Client side: ./examples/runHelloWorld.sh client 36.0.0.120 1234
28 | LD library is: /.autodirect/mtrswgwork/katyak/tmp/jxio/examples
29 | Compiling JAVA files....
30 | Running Client side test...
31 | 2014-02-16 11:17:46,552 main INFO HelloClient:68 Try to establish a new session to 'rdma://36.0.0.120:1234/'
32 | 2014-02-16 11:17:46,580 main INFO HelloClient:102 [SUCCESS] Session established! Hurray !
33 | 2014-02-16 11:17:46,581 main INFO HelloClient:106 [SUCCESS] Got a message! Bring the champagne!
34 | 2014-02-16 11:17:46,582 main INFO HelloClient:114 msg is: 'Hello to you too, Client'
35 | 2014-02-16 11:17:46,582 main INFO HelloClient:118 Closing the session...
36 | 2014-02-16 11:17:46,585 main INFO HelloClient:126 [EVENT] Got event SESSION_CLOSED
37 | 2014-02-16 11:17:46,586 main INFO HelloClient:57 Client is releasing JXIO resources and exiting
38 | 39 | 40 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Configuring Running Directory 4 | TOP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | cd $TOP_DIR 6 | echo -e "\nThe JXIO top directory is $TOP_DIR\n" 7 | 8 | GIT_VERSION=`git describe --long --tags --always --dirty` 9 | echo "JXIO git version: $GIT_VERSION" 10 | 11 | TARGET=${TARGET:-jxio.jar} 12 | BIN_FOLDER=${BIN_FOLDER:-$TOP_DIR/bin} 13 | LIB_FOLDER=${LIB_FOLDER:-$TOP_DIR/src/lib} 14 | DOCS_FOLDER=${DOCS_FOLDER:-$TOP_DIR/docs} 15 | SRC_JAVA_FOLDER=${SRC_JAVA_FOLDER:-$TOP_DIR/src/java} 16 | SRC_JAVA_FILES="$SRC_JAVA_FOLDER/org/accelio/jxio/*.java $SRC_JAVA_FOLDER/org/accelio/jxio/exceptions/*.java $SRC_JAVA_FOLDER/org/accelio/jxio/impl/*.java $SRC_JAVA_FOLDER/org/accelio/jxio/jxioConnection/*.java $SRC_JAVA_FOLDER/org/accelio/jxio/jxioConnection/impl/*.java $SRC_JAVA_FOLDER/org/apache/lucene/facet/taxonomy/LRUHashMap.java" 17 | NATIVE_LIBS="libjxio.so libxio.so" 18 | if [ -z "$DONT_STRIP" ]; then 19 | STRIP_COMMAND="strip -s" 20 | else 21 | STRIP_COMMAND="touch" #do not strip libraries from symbols 22 | fi 23 | 24 | ## Clean 25 | rm -fr $BIN_FOLDER 26 | mkdir -p $BIN_FOLDER 27 | 28 | ## Build Accelio 29 | echo "Build Accelio... libxio C code" 30 | cd $TOP_DIR 31 | git submodule update --init 32 | GIT_VERSION_XIO=`cd src/accelio; git describe --long --tags --always --dirty` 33 | echo "AccelIO git version: $GIT_VERSION_XIO" 34 | cd src/accelio/ && make distclean -si > /dev/null 2>&1; 35 | ./autogen.sh && ./configure --silent --disable-raio-build --enable-silent-rules --enable-performance && make -s && cp -f src/usr/.libs/libxio.so $BIN_FOLDER && $STRIP_COMMAND $BIN_FOLDER/libxio.so 36 | if [[ $? != 0 ]] ; then 37 | echo "FAILURE! stopped JXIO build" 38 | exit 1 39 | fi 40 | 41 | ## Build JXIO 42 | ## Build JXIO C code 43 | echo "Build JXIO C code" 44 | cd $TOP_DIR 45 | cd src/c/ && ./autogen.sh && ./configure --silent && make clean -s 46 | status=$? 47 | make -s 48 | if [[ $? != 0 ]] || [[ $status != 0 ]]; then 49 | echo "FAILURE! stopped JXIO build" 50 | exit 1 51 | fi 52 | cp -f src/.libs/libjxio.so $BIN_FOLDER && $STRIP_COMMAND $BIN_FOLDER/libjxio.so 53 | ## Build JXIO JAVA code 54 | echo "Build JXIO Java code" 55 | cd $TOP_DIR 56 | javac -cp $LIB_FOLDER/commons-logging.jar -d $BIN_FOLDER $SRC_JAVA_FILES 57 | if [[ $? != 0 ]] ; then 58 | echo "FAILURE! stopped JXIO build" 59 | exit 1 60 | fi 61 | ## Create JXIO Java docs 62 | echo "Creating JXIO Java docs" 63 | javadoc -quiet -classpath $LIB_FOLDER/commons-logging.jar -d $DOCS_FOLDER -sourcepath src/java/ org.accelio.jxio 64 | if [[ $? != 0 ]] ; then 65 | echo "FAILURE! stopped JXIO build" 66 | exit 1 67 | fi 68 | 69 | ## Prepare jar MANIFEST file 70 | cd $TOP_DIR 71 | cp manifest.template ${TOP_DIR}/manifest.txt 72 | sed -i "s/Implementation-Version: .*/Implementation-Version: $GIT_VERSION/" ${TOP_DIR}/manifest.txt 73 | echo "Implementation-Version-AccelIO: $GIT_VERSION_XIO" >> ${TOP_DIR}/manifest.txt 74 | 75 | ## Create JXIO Jar 76 | echo "Creating JXIO jar..." 77 | cd $BIN_FOLDER && jar -cfm $TARGET ${TOP_DIR}/manifest.txt org $NATIVE_LIBS 78 | if [[ $? != 0 ]] ; then 79 | echo "FAILURE! stopped JXIO build" 80 | exit 1 81 | fi 82 | 83 | ## Print Version details 84 | cd $TOP_DIR 85 | echo "JXIO git version: $GIT_VERSION" > version 86 | echo "AccelIO git version: $GIT_VERSION_XIO" >> version 87 | echo ""; cat $TOP_DIR/version 88 | 89 | echo -e "\nJXIO Build completed SUCCESSFULLY!\n" 90 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/helloworld/HelloClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.helloworld; 18 | 19 | import java.io.UnsupportedEncodingException; 20 | import java.net.URI; 21 | import java.net.URISyntaxException; 22 | 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | 26 | import java.io.IOException; 27 | 28 | import org.accelio.jxio.Msg; 29 | import org.accelio.jxio.MsgPool; 30 | import org.accelio.jxio.EventName; 31 | import org.accelio.jxio.EventReason; 32 | import org.accelio.jxio.ClientSession; 33 | import org.accelio.jxio.EventQueueHandler; 34 | 35 | public class HelloClient { 36 | 37 | private final static Log LOG = LogFactory.getLog(HelloClient.class.getCanonicalName()); 38 | private final MsgPool mp; 39 | private final EventQueueHandler eqh; 40 | private ClientSession client; 41 | public int exitStatus = 1; 42 | 43 | public static void main(String[] args) { 44 | if (args.length < 2) { 45 | usage(); 46 | return; 47 | } 48 | 49 | final String serverhostname = args[0]; 50 | final int port = Integer.parseInt(args[1]); 51 | 52 | URI uri = null; 53 | try { 54 | uri = new URI("rdma://" + serverhostname + ":" + port + "/"); 55 | } catch (URISyntaxException e) { 56 | e.printStackTrace(); 57 | return; 58 | } 59 | 60 | HelloClient client = new HelloClient(); 61 | client.connect(uri); 62 | client.run(); 63 | 64 | LOG.info("Client is releasing JXIO resources and exiting"); 65 | client.releaseResources(); 66 | System.exit(client.exitStatus); 67 | } 68 | 69 | HelloClient() { 70 | this.eqh = new EventQueueHandler(null); 71 | this.mp = new MsgPool(256, 100, 100); 72 | } 73 | 74 | public void connect(URI uri) { 75 | LOG.info("Try to establish a new session to '" + uri + "'"); 76 | this.client = new ClientSession(eqh, uri, new MyClientCallbacks(this)); 77 | 78 | Msg msg = this.mp.getMsg(); 79 | try { 80 | msg.getOut().put("Hello Server".getBytes("UTF-8")); 81 | } catch (UnsupportedEncodingException e) { 82 | // Just suppress the exception handling in this demo code 83 | } 84 | try { 85 | client.sendRequest(msg); 86 | } catch (IOException e) { 87 | //all exceptions thrown extend IOException 88 | LOG.error(e.toString()); 89 | } 90 | } 91 | 92 | public void run() { 93 | // block for JXIO incoming event 94 | eqh.run(); 95 | } 96 | 97 | public void releaseResources() { 98 | mp.deleteMsgPool(); 99 | eqh.close(); 100 | } 101 | 102 | public static void usage() { 103 | LOG.info("Usage: ./runHelloServer.sh []"); 104 | } 105 | 106 | class MyClientCallbacks implements ClientSession.Callbacks { 107 | private final HelloClient client; 108 | 109 | MyClientCallbacks(HelloClient client) { 110 | this.client = client; 111 | } 112 | 113 | public void onSessionEstablished() { 114 | LOG.info("[SUCCESS] Session established! Hurray !"); 115 | } 116 | 117 | public void onResponse(Msg msg) { 118 | LOG.info("[SUCCESS] Got a message! Bring the champagne!"); 119 | 120 | // Read reply message String 121 | byte ch; 122 | StringBuffer buffer = new StringBuffer(); 123 | while (msg.getIn().hasRemaining() && ((ch = msg.getIn().get()) > -1)) { 124 | buffer.append((char) ch); 125 | } 126 | LOG.info("msg is: '" + buffer.toString() + "'"); 127 | 128 | msg.returnToParentPool(); 129 | 130 | LOG.info("Closing the session..."); 131 | this.client.client.close(); 132 | 133 | exitStatus = 0; // Success, we got our message response back 134 | } 135 | 136 | public void onSessionEvent(EventName event, EventReason reason) { 137 | String str = "[EVENT] Got event " + event + " because of " + reason; 138 | if (event == EventName.SESSION_CLOSED) { // normal exit 139 | LOG.info(str); 140 | } else { 141 | this.client.exitStatus = 1; // Failure on any kind of error 142 | LOG.error(str); 143 | } 144 | this.client.eqh.stop(); 145 | } 146 | 147 | public void onMsgError(Msg msg, EventReason reason) { 148 | LOG.info("[ERROR] onMsgErrorCallback. reason=" + reason); 149 | if (reason == EventReason.MSG_FLUSHED) { 150 | LOG.info("[STATUS] getIsClosing() = " + this.client.client.getIsClosing()); 151 | } 152 | msg.returnToParentPool(); 153 | this.client.exitStatus = 1; // Failure on any kind of error 154 | System.exit(exitStatus); 155 | } 156 | } 157 | } -------------------------------------------------------------------------------- /examples/org/accelio/jxio/helloworld/HelloServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.helloworld; 18 | 19 | import java.io.UnsupportedEncodingException; 20 | import java.io.IOException; 21 | import java.net.URI; 22 | import java.net.URISyntaxException; 23 | 24 | import org.apache.commons.logging.Log; 25 | import org.apache.commons.logging.LogFactory; 26 | 27 | import org.accelio.jxio.Msg; 28 | import org.accelio.jxio.MsgPool; 29 | import org.accelio.jxio.EventName; 30 | import org.accelio.jxio.EventReason; 31 | import org.accelio.jxio.ServerPortal; 32 | import org.accelio.jxio.ServerSession; 33 | import org.accelio.jxio.EventQueueHandler; 34 | import org.accelio.jxio.WorkerCache.Worker; 35 | 36 | public class HelloServer { 37 | 38 | private final static Log LOG = LogFactory.getLog(HelloServer.class.getCanonicalName()); 39 | private final MsgPool mp; 40 | private final ServerPortal server; 41 | private final EventQueueHandler eqh; 42 | private ServerSession session; 43 | 44 | HelloServer(URI uri) { 45 | this.eqh = new EventQueueHandler(null); 46 | this.mp = new MsgPool(256, 100, 100); 47 | eqh.bindMsgPool(mp); 48 | this.server = new ServerPortal(eqh, uri, new MyPortalCallbacks(this)); 49 | } 50 | 51 | public void run() { 52 | LOG.info("waiting for JXIO incoming connections"); 53 | eqh.run(); 54 | } 55 | 56 | public void releaseResources() { 57 | eqh.releaseMsgPool(mp); 58 | mp.deleteMsgPool(); 59 | eqh.close(); 60 | } 61 | 62 | public static void main(String[] args) { 63 | if (args.length < 2) { 64 | usage(); 65 | return; 66 | } 67 | 68 | final String serverhostname = args[0]; 69 | final int port = Integer.parseInt(args[1]); 70 | 71 | URI uri = null; 72 | try { 73 | uri = new URI("rdma://" + serverhostname + ":" + port + "/"); 74 | } catch (URISyntaxException e) { 75 | e.printStackTrace(); 76 | return; 77 | } 78 | 79 | HelloServer server = new HelloServer(uri); 80 | server.run(); 81 | 82 | LOG.info("Server is releasing JXIO resources and exiting"); 83 | server.releaseResources(); 84 | } 85 | 86 | public static void usage() { 87 | LOG.info("Usage: ./runHelloServer.sh []"); 88 | } 89 | 90 | class MyPortalCallbacks implements ServerPortal.Callbacks { 91 | private final HelloServer server; 92 | 93 | MyPortalCallbacks(HelloServer server) { 94 | this.server = server; 95 | } 96 | 97 | public void onSessionNew(ServerSession.SessionKey sesID, String srcIP, Worker hint) { 98 | LOG.info("[SUCCESS] Got event onSessionNew from " + srcIP + ", URI='" + sesID.getUri() + "'"); 99 | this.server.session = new ServerSession(sesID, new MySessionCallbacks(server)); 100 | this.server.server.accept(session); 101 | } 102 | 103 | public void onSessionEvent(EventName event, EventReason reason) { 104 | LOG.info("[EVENT] Got event " + event + " because of " + reason); 105 | } 106 | } 107 | 108 | class MySessionCallbacks implements ServerSession.Callbacks { 109 | private final HelloServer server; 110 | 111 | MySessionCallbacks(HelloServer server) { 112 | this.server = server; 113 | } 114 | 115 | public void onRequest(Msg msg) { 116 | LOG.info("[SUCCESS] Got a message request! Prepare the champagne!"); 117 | 118 | // Read message String 119 | byte ch; 120 | StringBuffer buffer = new StringBuffer(); 121 | while (msg.getIn().hasRemaining() && ((ch = msg.getIn().get()) > -1)) { 122 | buffer.append((char)ch); 123 | } 124 | LOG.info("msg is: '" + buffer.toString() + "'"); 125 | 126 | // Write response 127 | try { 128 | msg.getOut().put("Hello to you too, Client".getBytes("UTF-8")); 129 | } catch (UnsupportedEncodingException e) { 130 | // Just suppress the exception handling in this demo code 131 | } 132 | 133 | // Send the response 134 | try { 135 | this.server.session.sendResponse(msg); 136 | } catch (IOException e) { 137 | // all exceptions thrown extend IOException 138 | LOG.error(e.toString()); 139 | } 140 | 141 | // Un-comment here if case you want to close the connection from Server side... 142 | // LOG.info("Closing the session..."); 143 | // this.server.session.close(); 144 | } 145 | 146 | public void onSessionEvent(EventName event, EventReason reason) { 147 | String str = "[EVENT] Got event " + event + " because of " + reason; 148 | if (event == EventName.SESSION_CLOSED) { // normal exit 149 | LOG.info(str); 150 | } else { 151 | LOG.error(str); 152 | } 153 | // Comment here if case you don't want to exit the server, stop the EQH 154 | LOG.info("Stopping the main EQH loop..."); 155 | eqh.stop(); 156 | } 157 | 158 | public boolean onMsgError(Msg msg, EventReason reason) { 159 | LOG.info("[ERROR] onMsgErrorCallback. reason=" + reason); 160 | return true; 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/log4j.properties.jxio: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, CONSOLE 3 | 4 | #log4j.logger.org.accelio.jxio=file 5 | 6 | #change log threshold and appender of Bridge logger 7 | log4j.logger.LogFromNative=INFO, Clog 8 | #Bridge logger will be printed only to bridge appender. 9 | log4j.additivity.LogFromNative=false 10 | 11 | # Direct log messages to a log file 12 | log4j.appender.file=org.apache.log4j.DailyRollingFileAppender 13 | log4j.appender.file.File=jxio.log 14 | log4j.appender.file.layout=org.apache.log4j.PatternLayout 15 | log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %t %-5p %c{1}:%L %m%n 16 | log4j.appender.file.Append=false 17 | log4j.appender.file.Threshold=INFO 18 | 19 | 20 | log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 21 | log4j.appender.CONSOLE.Target=System.out 22 | log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 23 | log4j.appender.CONSOLE.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %t %-5p %c{1}:%L %m%n 24 | 25 | 26 | #log4j.appender.Clog=org.apache.log4j.DailyRollingFileAppender 27 | #log4j.appender.Clog.File=jxio.log 28 | log4j.appender.Clog=org.apache.log4j.ConsoleAppender 29 | log4j.appender.Clog.Target=System.out 30 | log4j.appender.Clog.layout=org.apache.log4j.PatternLayout 31 | log4j.appender.Clog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %t %-5p %m 32 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/simpletest/SimpleClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.simpletest; 18 | 19 | import java.io.UnsupportedEncodingException; 20 | import java.net.URI; 21 | import java.net.URISyntaxException; 22 | 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | 26 | import java.io.IOException; 27 | 28 | import org.accelio.jxio.Msg; 29 | import org.accelio.jxio.MsgPool; 30 | import org.accelio.jxio.EventName; 31 | import org.accelio.jxio.EventReason; 32 | import org.accelio.jxio.ClientSession; 33 | import org.accelio.jxio.EventQueueHandler; 34 | 35 | public class SimpleClient { 36 | 37 | private final static Log LOG = LogFactory.getLog(SimpleClient.class.getCanonicalName()); 38 | private final MsgPool mp; 39 | private final EventQueueHandler eqh; 40 | private ClientSession client; 41 | public int exitStatus = 1; 42 | 43 | public static long numberofReqs = 0; 44 | public static long numberofRsps = 0; 45 | public static long maxNumberofReqs = 600000; 46 | public static long PRINT_COUNTER = 10000; 47 | 48 | public static void main(String[] args) { 49 | if (args.length < 2) { 50 | usage(); 51 | return; 52 | } 53 | 54 | final String serverhostname = args[0]; 55 | final int port = Integer.parseInt(args[1]); 56 | if (args.length > 2) 57 | maxNumberofReqs = Long.parseLong(args[2]); 58 | if (args.length > 3) 59 | PRINT_COUNTER = Long.parseLong(args[3]); 60 | 61 | URI uri = null; 62 | try { 63 | uri = new URI("rdma://" + serverhostname + ":" + port + "/"); 64 | } catch (URISyntaxException e) { 65 | e.printStackTrace(); 66 | return; 67 | } 68 | 69 | SimpleClient client = new SimpleClient(); 70 | // Connect 71 | client.connect(uri); 72 | // Wait for a single connection response 73 | client.run(); 74 | // Send 75 | for (numberofReqs = 1; numberofReqs <= maxNumberofReqs; ++numberofReqs){ 76 | LOG.trace("sending req " + numberofReqs); 77 | client.send(); 78 | client.run(); 79 | } 80 | // Finish 81 | LOG.info("Closing the session..."); 82 | client.close(); 83 | LOG.info("Client is releasing JXIO resources and exiting"); 84 | client.releaseResources(); 85 | System.exit(client.exitStatus); 86 | } 87 | 88 | SimpleClient() { 89 | this.eqh = new EventQueueHandler(null); 90 | this.mp = new MsgPool(256, 100, 100); 91 | } 92 | 93 | public void connect(URI uri) { 94 | LOG.info("Try to establish a new session to '" + uri + "'"); 95 | this.client = new ClientSession(eqh, uri, new MyClientCallbacks(this)); 96 | } 97 | 98 | public void send(){ 99 | Msg msg = this.mp.getMsg(); 100 | try { 101 | msg.getOut().put("Simple request".getBytes("UTF-8")); 102 | } catch (UnsupportedEncodingException e) { 103 | // Just suppress the exception handling in this demo code 104 | } 105 | try { 106 | client.sendRequest(msg); 107 | } catch (IOException e) { 108 | //all exceptions thrown extend IOException 109 | LOG.error(e.toString()); 110 | } 111 | } 112 | 113 | public void run() { 114 | // block for a single JXIO incoming event 115 | eqh.runEventLoop(1, -1); 116 | } 117 | 118 | public void close(){ 119 | client.close(); 120 | } 121 | 122 | public void releaseResources() { 123 | mp.deleteMsgPool(); 124 | eqh.close(); 125 | } 126 | 127 | public static void usage() { 128 | LOG.info("Usage: ./runSimpleClient.sh [NUMBER_OF_REQS] [PRINT_COUNTER]"); 129 | } 130 | 131 | class MyClientCallbacks implements ClientSession.Callbacks { 132 | private final SimpleClient client; 133 | 134 | MyClientCallbacks(SimpleClient client) { 135 | this.client = client; 136 | } 137 | 138 | public void onSessionEstablished() { 139 | LOG.info("[SUCCESS] Session established! Hurray !"); 140 | } 141 | 142 | public void onResponse(Msg msg) { 143 | ++numberofRsps; 144 | 145 | if (numberofRsps % PRINT_COUNTER == 0){ 146 | // Read reply message String 147 | byte ch; 148 | StringBuffer buffer = new StringBuffer(); 149 | while (msg.getIn().hasRemaining() && ((ch = msg.getIn().get()) > -1)) { 150 | buffer.append((char) ch); 151 | } 152 | LOG.info("Got message response " + numberofRsps + ": '" + buffer.toString() + "'"); 153 | } 154 | 155 | msg.returnToParentPool(); 156 | exitStatus = 0; // Success, we got our message response back 157 | } 158 | 159 | public void onSessionEvent(EventName event, EventReason reason) { 160 | String str = "[EVENT] Got event " + event + " because of " + reason; 161 | if (event == EventName.SESSION_CLOSED) { // normal exit 162 | LOG.info(str); 163 | } else { 164 | this.client.exitStatus = 1; // Failure on any kind of error 165 | LOG.error(str); 166 | } 167 | this.client.eqh.stop(); 168 | } 169 | 170 | public void onMsgError(Msg msg, EventReason reason) { 171 | LOG.info("[ERROR] onMsgErrorCallback. reason=" + reason); 172 | if (reason == EventReason.MSG_FLUSHED) { 173 | LOG.info("[STATUS] getIsClosing() = " + this.client.client.getIsClosing()); 174 | } 175 | msg.returnToParentPool(); 176 | this.client.exitStatus = 1; // Failure on any kind of error 177 | System.exit(exitStatus); 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/simpletest/SimpleServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.simpletest; 18 | 19 | import java.io.UnsupportedEncodingException; 20 | import java.io.IOException; 21 | import java.net.URI; 22 | import java.net.URISyntaxException; 23 | 24 | import org.apache.commons.logging.Log; 25 | import org.apache.commons.logging.LogFactory; 26 | import org.accelio.jxio.Msg; 27 | import org.accelio.jxio.MsgPool; 28 | import org.accelio.jxio.EventName; 29 | import org.accelio.jxio.EventReason; 30 | import org.accelio.jxio.ServerPortal; 31 | import org.accelio.jxio.ServerSession; 32 | import org.accelio.jxio.EventQueueHandler; 33 | import org.accelio.jxio.WorkerCache.Worker; 34 | 35 | public class SimpleServer { 36 | 37 | private final static Log LOG = LogFactory.getLog(SimpleServer.class.getCanonicalName()); 38 | private final MsgPool mp; 39 | private final ServerPortal server; 40 | private final EventQueueHandler eqh; 41 | private ServerSession session; 42 | 43 | public static long numberofRsps = 0; 44 | public static long numberofReqs = 0; 45 | public static long maxNumberofRsps = 600000; 46 | public static long PRINT_COUNTER = 10000; 47 | 48 | SimpleServer(URI uri) { 49 | this.eqh = new EventQueueHandler(null); 50 | this.mp = new MsgPool(256, 100, 100); 51 | eqh.bindMsgPool(mp); 52 | this.server = new ServerPortal(eqh, uri, new MyPortalCallbacks(this)); 53 | } 54 | 55 | public void run() { 56 | LOG.info("waiting for JXIO incoming connections"); 57 | eqh.run(); 58 | } 59 | 60 | public void releaseResources() { 61 | eqh.releaseMsgPool(mp); 62 | mp.deleteMsgPool(); 63 | eqh.close(); 64 | } 65 | 66 | public static void main(String[] args) { 67 | if (args.length < 2) { 68 | usage(); 69 | return; 70 | } 71 | 72 | final String serverhostname = args[0]; 73 | final int port = Integer.parseInt(args[1]); 74 | if (args.length > 2) 75 | maxNumberofRsps = Long.parseLong(args[2]); 76 | if (args.length > 3) 77 | PRINT_COUNTER = Long.parseLong(args[3]); 78 | 79 | URI uri = null; 80 | try { 81 | uri = new URI("rdma://" + serverhostname + ":" + port + "/"); 82 | } catch (URISyntaxException e) { 83 | e.printStackTrace(); 84 | return; 85 | } 86 | 87 | SimpleServer server = new SimpleServer(uri); 88 | server.run(); 89 | 90 | LOG.info("Server is releasing JXIO resources and exiting"); 91 | server.releaseResources(); 92 | } 93 | 94 | public static void usage() { 95 | LOG.info("Usage: ./runSimpleServer.sh [PRINT_COUNTER]"); 96 | } 97 | 98 | class MyPortalCallbacks implements ServerPortal.Callbacks { 99 | private final SimpleServer server; 100 | 101 | MyPortalCallbacks(SimpleServer server) { 102 | this.server = server; 103 | } 104 | 105 | public void onSessionNew(ServerSession.SessionKey sesID, String srcIP, Worker hint) { 106 | LOG.info("[SUCCESS] Got event onSessionNew from " + srcIP + ", URI='" + sesID.getUri() + "'"); 107 | this.server.session = new ServerSession(sesID, new MySessionCallbacks(server)); 108 | this.server.server.accept(session); 109 | } 110 | 111 | public void onSessionEvent(EventName event, EventReason reason) { 112 | LOG.info("[EVENT] Got event " + event + " because of " + reason); 113 | } 114 | } 115 | 116 | class MySessionCallbacks implements ServerSession.Callbacks { 117 | private final SimpleServer server; 118 | 119 | MySessionCallbacks(SimpleServer server) { 120 | this.server = server; 121 | } 122 | 123 | public void onRequest(Msg msg) { 124 | ++numberofReqs; 125 | 126 | if (numberofReqs % PRINT_COUNTER == 0){ 127 | // Read message String 128 | byte ch; 129 | StringBuffer buffer = new StringBuffer(); 130 | while (msg.getIn().hasRemaining() && ((ch = msg.getIn().get()) > -1)) { 131 | buffer.append((char)ch); 132 | } 133 | LOG.info("Got message request " + numberofReqs + " : '" + buffer.toString() + "'"); 134 | } 135 | 136 | // Write response 137 | try { 138 | msg.getOut().put("Simple response".getBytes("UTF-8")); 139 | } catch (UnsupportedEncodingException e) { 140 | // Just suppress the exception handling in this demo code 141 | } 142 | 143 | // Send the response 144 | try { 145 | ++numberofRsps; 146 | LOG.trace("sending rsp " + numberofRsps); 147 | this.server.session.sendResponse(msg); 148 | } catch (IOException e) { 149 | // all exceptions thrown extend IOException 150 | LOG.error(e.toString()); 151 | } 152 | 153 | // Un-comment here if case you want to close the connection from Server side... 154 | // if (numberofRsps == maxNumberofRsps){ 155 | // LOG.info("Closing the session..."); 156 | // this.server.session.close(); 157 | // } 158 | } 159 | 160 | public void onSessionEvent(EventName event, EventReason reason) { 161 | String str = "[EVENT] Got event " + event + " because of " + reason; 162 | if (event == EventName.SESSION_CLOSED) { // normal exit 163 | LOG.info(str); 164 | } else { 165 | LOG.error(str); 166 | } 167 | // Comment here if case you don't want to exit the server, stop the EQH 168 | LOG.info("Stopping the main EQH loop..."); 169 | eqh.stop(); 170 | } 171 | 172 | public boolean onMsgError(Msg msg, EventReason reason) { 173 | LOG.info("[ERROR] onMsgErrorCallback. reason=" + reason); 174 | return true; 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/tests/benchmarks/ClientWorker.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.tests.benchmarks; 18 | 19 | import java.net.URI; 20 | import java.util.concurrent.Callable; 21 | 22 | import org.apache.commons.logging.Log; 23 | import org.apache.commons.logging.LogFactory; 24 | 25 | import org.accelio.jxio.Msg; 26 | import org.accelio.jxio.MsgPool; 27 | import org.accelio.jxio.EventName; 28 | import org.accelio.jxio.EventReason; 29 | import org.accelio.jxio.ClientSession; 30 | import org.accelio.jxio.EventQueueHandler; 31 | import org.accelio.jxio.exceptions.JxioGeneralException; 32 | import org.accelio.jxio.exceptions.JxioQueueOverflowException; 33 | import org.accelio.jxio.exceptions.JxioSessionClosedException; 34 | 35 | public class ClientWorker implements Callable { 36 | private final ClientSession cs; 37 | private final EventQueueHandler eqh; 38 | private final MsgPool pool; 39 | private final int in_msgSize; 40 | private final int out_msgSize; 41 | // calculation members 42 | private boolean firstTime; 43 | private long startTime; 44 | private long cnt; 45 | private int sample_cnt; 46 | private int res_array_index = 0; 47 | private int burst_size; 48 | 49 | // results array (in the form of [tps1,bw1,tp2,bw2...] 50 | public double[] results; 51 | 52 | // logger 53 | private static Log LOG = LogFactory.getLog(ClientWorker.class.getCanonicalName()); 54 | 55 | // cTor 56 | public ClientWorker(int inMsg_size, int outMsg_size, URI uri, int burst_size, double[] res) { 57 | eqh = new EventQueueHandler(new ClientEQHCallbacks()); 58 | pool = new MsgPool(burst_size, inMsg_size, outMsg_size); 59 | results = res; 60 | cs = new ClientSession(eqh, uri, new ClientWorkerCallbacks()); 61 | in_msgSize = inMsg_size; 62 | out_msgSize = outMsg_size; 63 | this.burst_size = burst_size; 64 | int msgKSize = ((inMsg_size > outMsg_size) ? inMsg_size : outMsg_size) / 1024; 65 | if (msgKSize == 0) { 66 | sample_cnt = 40000; 67 | } else { 68 | sample_cnt = 40000 / msgKSize; 69 | } 70 | cnt = 0; 71 | firstTime = true; 72 | } 73 | 74 | public void close() { 75 | LOG.debug("closing client session"); 76 | cs.close(); 77 | } 78 | 79 | public double[] call() { 80 | for (int i = 0; i < burst_size; i++) { 81 | Msg msg = pool.getMsg(); 82 | if (msg == null) { 83 | LOG.error("Cannot get new message"); 84 | break; 85 | } 86 | msg.getOut().position(msg.getOut().capacity()); // simulate 'out_msgSize' was written into buffer 87 | try { 88 | cs.sendRequest(msg); 89 | } catch (JxioGeneralException e) { 90 | LOG.error("Error sending: " + e.toString()); 91 | pool.releaseMsg(msg); 92 | } catch (JxioSessionClosedException e) { 93 | LOG.error("Error sending: session closed " + e.toString()); 94 | pool.releaseMsg(msg); 95 | } catch (JxioQueueOverflowException e) { 96 | LOG.error("Error sending: queue overflow " + e.toString()); 97 | pool.releaseMsg(msg); 98 | } 99 | } 100 | eqh.run(); 101 | eqh.close(); 102 | LOG.debug("deleting message pool"); 103 | pool.deleteMsgPool(); 104 | return results; 105 | } 106 | 107 | // callbacks for the Client's event queue handler 108 | public class ClientEQHCallbacks implements EventQueueHandler.Callbacks { 109 | // this method should return an unbinded MsgPool. 110 | public MsgPool getAdditionalMsgPool(int inSize, int outSize) { 111 | System.out.println("Messages in Client's message pool ran out, Aborting test"); 112 | return null; 113 | } 114 | } 115 | 116 | class ClientWorkerCallbacks implements ClientSession.Callbacks { 117 | 118 | public void onMsgError(Msg msg, EventReason reason) { 119 | if (ClientWorker.this.cs.getIsClosing()) { 120 | LOG.debug("On Message Error while closing. Reason is=" + reason); 121 | } else { 122 | LOG.error("On Message Error. Reason is=" + reason); 123 | } 124 | msg.returnToParentPool(); 125 | } 126 | 127 | public void onSessionEstablished() { 128 | LOG.debug("Session established"); 129 | } 130 | 131 | public void onSessionEvent(EventName event, EventReason reason) { 132 | if (event == EventName.SESSION_CLOSED) { 133 | LOG.debug("closing eqh"); 134 | eqh.stop(); 135 | } 136 | } 137 | 138 | public void onResponse(Msg msg) { 139 | if (firstTime) { 140 | startTime = System.nanoTime(); 141 | firstTime = false; 142 | } 143 | 144 | cnt++; 145 | if (cnt == sample_cnt) { 146 | long delta = System.nanoTime() - startTime; 147 | // multiply by 10^9 because result is in seconds 148 | long pps = (cnt * 1000000000) / delta; 149 | // divide by (1024*1024) in order to get BW in MB 150 | double out_bw = (1.0 * pps * out_msgSize / (1024 * 1024)); 151 | double in_bw = (1.0 * pps * in_msgSize / (1024 * 1024)); 152 | results[res_array_index] = pps; 153 | results[res_array_index + 1] = out_bw; 154 | results[res_array_index + 2] = in_bw; 155 | res_array_index += 3; 156 | if (res_array_index == results.length) { 157 | ClientWorker.this.close(); 158 | return; 159 | } 160 | cnt = 0; 161 | startTime = System.nanoTime(); 162 | } 163 | if (!ClientWorker.this.cs.getIsClosing()) { 164 | try { 165 | cs.sendRequest(msg); 166 | } catch (JxioGeneralException e) { 167 | LOG.error("Error sending: " + e.toString()); 168 | pool.releaseMsg(msg); 169 | } catch (JxioSessionClosedException e) { 170 | LOG.error("Error sending: session closed " + e.toString()); 171 | pool.releaseMsg(msg); 172 | } catch (JxioQueueOverflowException e) { 173 | LOG.error("Error sending: queue overflow " + e.toString()); 174 | pool.releaseMsg(msg); 175 | } 176 | } 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/tests/benchmarks/DataPathTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | package org.accelio.jxio.tests.benchmarks; 19 | 20 | import java.io.BufferedWriter; 21 | import java.io.FileWriter; 22 | import java.net.URI; 23 | import java.net.URISyntaxException; 24 | 25 | import org.apache.commons.logging.Log; 26 | import org.apache.commons.logging.LogFactory; 27 | 28 | public abstract class DataPathTest { 29 | 30 | // command line args 31 | protected int num_of_threads; 32 | protected int outMsg_size; 33 | protected int inMsg_size; 34 | protected int burst_size; 35 | protected String test_type; 36 | protected String server_ip; 37 | protected String server_port; 38 | protected String file_path; 39 | 40 | // uri for connection 41 | protected final URI uri; 42 | 43 | // file members 44 | protected FileWriter fstream; 45 | protected BufferedWriter out; 46 | 47 | // logger 48 | private final static Log LOG = LogFactory.getLog(DataPathTestClient.class.getCanonicalName()); 49 | 50 | protected DataPathTest(String args[]) { 51 | this.parseCommandArgs(args); 52 | uri = generateUri(); 53 | if (uri == null) { 54 | System.out.println("Bad URI, Aborting test..."); 55 | System.exit(0); 56 | } 57 | } 58 | 59 | // build URI from command line parameters 60 | protected URI generateUri() { 61 | String url_string = "rdma://" + server_ip + ":" + server_port; 62 | try { 63 | return new URI(url_string); 64 | } catch (URISyntaxException e) { 65 | System.out.println("Bad URI given\n"); 66 | LOG.error("Bad URI given"); 67 | e.printStackTrace(); 68 | } 69 | return null; 70 | } 71 | 72 | public void stopTest() { 73 | LOG.debug("finishing test"); 74 | } 75 | 76 | // parse command line parameters into class members 77 | protected void parseCommandArgs(String[] args) { 78 | server_ip = args[0]; 79 | server_port = args[1]; 80 | num_of_threads = Integer.parseInt(args[2]); 81 | inMsg_size = Integer.parseInt(args[3]); 82 | outMsg_size = Integer.parseInt(args[4]); 83 | burst_size = Integer.parseInt(args[5]); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/tests/benchmarks/DataPathTestClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.tests.benchmarks; 18 | 19 | import java.io.BufferedWriter; 20 | import java.io.FileWriter; 21 | import java.io.IOException; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | import java.util.concurrent.ExecutionException; 25 | import java.util.concurrent.ExecutorService; 26 | import java.util.concurrent.Executors; 27 | import java.util.concurrent.FutureTask; 28 | 29 | import org.apache.commons.logging.Log; 30 | import org.apache.commons.logging.LogFactory; 31 | 32 | import org.accelio.jxio.tests.benchmarks.ClientWorker; 33 | import org.accelio.jxio.tests.benchmarks.DataPathTest; 34 | 35 | public class DataPathTestClient extends DataPathTest { 36 | 37 | private int test_iterations; 38 | 39 | // workers list (each worker is a future task that will run in a separate thread) 40 | protected final List> workers; 41 | 42 | // future tasks executer 43 | protected final ExecutorService executor; 44 | 45 | // calculation members 46 | double totalBTW = 0; 47 | int totalCnt = 0; 48 | int totalPPS = 0; 49 | 50 | // results matrix 51 | private double results[][]; 52 | 53 | // logger 54 | private final static Log LOG = LogFactory.getLog(DataPathTestClient.class.getCanonicalName()); 55 | 56 | private boolean write_to_file = false; 57 | 58 | // cTor 59 | public DataPathTestClient(String[] args) { 60 | super(args); 61 | test_iterations = Integer.parseInt(args[7]); 62 | file_path = args[6]; 63 | results = new double[num_of_threads][test_iterations * 3]; 64 | workers = new ArrayList>(num_of_threads); 65 | executor = Executors.newFixedThreadPool(num_of_threads); 66 | 67 | for (int i = 0; i < num_of_threads; i++) { 68 | ClientWorker cw = new ClientWorker(inMsg_size, outMsg_size, uri, burst_size, results[i]); 69 | workers.add(new FutureTask(cw)); 70 | } 71 | // Create/Open file 72 | if (!file_path.equals("no_file")) { 73 | write_to_file = true; 74 | try { 75 | fstream = new FileWriter(file_path, true); 76 | out = new BufferedWriter(fstream); 77 | } catch (Exception e) { 78 | LOG.error("Error in opening the results file"); 79 | e.printStackTrace(); 80 | } 81 | } 82 | } 83 | 84 | public void runTest() { 85 | for (int i = 0; i < workers.size(); i++) { 86 | System.out.println("running client task number " + (i + 1)); 87 | executor.execute(workers.get(i)); 88 | } 89 | for (int i = 0; i < workers.size(); i++) { 90 | try { 91 | System.out.println("gathering results from tasks"); 92 | results[i] = workers.get(i).get(); 93 | } catch (InterruptedException e) { 94 | LOG.error("Thread was interrupted before returning results"); 95 | e.printStackTrace(); 96 | } catch (ExecutionException e) { 97 | LOG.error("Thread was aborted, no results available"); 98 | e.printStackTrace(); 99 | } 100 | } 101 | // process results from threads and write them to file 102 | this.processResults(); 103 | // shutdown all threads 104 | this.executor.shutdown(); 105 | } 106 | 107 | private void processResults() { 108 | try { 109 | System.out.println("processing results"); 110 | double totalTPS[] = new double[test_iterations]; 111 | double totalOutBW[] = new double[test_iterations]; 112 | double totalInBW[] = new double[test_iterations]; 113 | double av_TPS = 0; 114 | double av_OutBW = 0; 115 | double av_InBW = 0; 116 | //for(int i=0; i SPWorkers; 43 | 44 | // logger 45 | private final static Log LOG = LogFactory.getLog(DataPathTestServer.class.getCanonicalName()); 46 | 47 | // cTor 48 | public DataPathTestServer(String args[]) { 49 | super(args); 50 | listen_eqh = new EventQueueHandler(null); 51 | tsc = new TestServerCallbacks(); 52 | listener = new ServerPortal(listen_eqh, uri, tsc, this); 53 | SPWorkers = new PriorityQueue(num_of_threads); 54 | //adding 64 to num_of_buffers_per_thread due to ACCELLIO demand 55 | for (int i = 0; i < num_of_threads; i++) { 56 | SPWorkers.add(new ServerPortalWorker(i, inMsg_size, outMsg_size, listener.getUriForServer(), burst_size + 64, tsc)); 57 | } 58 | } 59 | 60 | public void run_test() { 61 | System.out.println("Starting server portal workers"); 62 | for (int i = 0; i < num_of_threads; i++) { 63 | for (ServerPortalWorker spw : SPWorkers) { 64 | spw.start(); 65 | } 66 | listen_eqh.run(); 67 | } 68 | } 69 | 70 | private synchronized static ServerPortalWorker getNextWorker() { 71 | // retrieve next spw and update its position in the queue 72 | ServerPortalWorker s = SPWorkers.poll(); 73 | s.incrNumOfSessions(); 74 | SPWorkers.add(s); 75 | return s; 76 | } 77 | 78 | public synchronized static void updateWorkers(ServerPortalWorker s) { 79 | // remove & add the ServerPortalWorker in order. 80 | SPWorkers.remove(s); 81 | SPWorkers.add(s); 82 | } 83 | 84 | // callbacks for the listener server portal 85 | public class TestServerCallbacks implements ServerPortal.Callbacks { 86 | 87 | public void onSessionNew(ServerSession.SessionKey sesKey, String srcIP, Worker hint) { 88 | if (hint == null) { 89 | listener.reject(sesKey, EventReason.CONNECT_ERROR, "No worker was found"); 90 | return; 91 | } 92 | LOG.debug("New session created, forwarding to the next Server Portal"); 93 | // forward the created session to the ServerPortal 94 | ServerPortalWorker spw = (ServerPortalWorker)hint; 95 | listener.forward(spw.getPortal(), (new ServerSessionHandle(sesKey, spw)).getSession()); 96 | } 97 | 98 | public void onSessionEvent(EventName event, EventReason reason) { 99 | LOG.debug("GOT EVENT " + event.toString() + "because of " + reason.toString()); 100 | } 101 | } 102 | 103 | // main 104 | public static void main(String[] args) { 105 | DataPathTestServer test = new DataPathTestServer(args); 106 | test.run_test(); 107 | } 108 | 109 | @Override 110 | public Worker getWorker() { 111 | return getNextWorker(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/tests/benchmarks/ServerPortalWorker.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.tests.benchmarks; 18 | 19 | import java.net.URI; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | 22 | import org.apache.commons.logging.Log; 23 | import org.apache.commons.logging.LogFactory; 24 | 25 | import org.accelio.jxio.MsgPool; 26 | import org.accelio.jxio.ServerPortal; 27 | import org.accelio.jxio.EventQueueHandler; 28 | import org.accelio.jxio.WorkerCache.Worker; 29 | import org.accelio.jxio.tests.benchmarks.DataPathTestServer; 30 | 31 | public class ServerPortalWorker extends Thread implements Comparable, Worker { 32 | 33 | private final ServerPortal sp; 34 | private final EventQueueHandler eqh; 35 | private final MsgPool pool; 36 | private final int portal_index; 37 | private AtomicInteger num_of_sessions; 38 | 39 | // logger 40 | private final static Log LOG = LogFactory.getLog(ServerPortalWorker.class.getCanonicalName()); 41 | 42 | // cTor 43 | public ServerPortalWorker(int index, int inMsg_size, int outMsg_size, URI uri, int num_of_buffers, ServerPortal.Callbacks c) { 44 | portal_index = index; 45 | eqh = new EventQueueHandler(new ServerEQHCallbacks()); 46 | pool = new MsgPool(num_of_buffers, inMsg_size, outMsg_size); 47 | eqh.bindMsgPool(pool); 48 | sp = new ServerPortal(eqh, uri, c); 49 | num_of_sessions = new AtomicInteger(0); 50 | } 51 | 52 | public void run() { 53 | System.out.println("Server worker number " + (portal_index + 1) + " is up and waiting for requests"); 54 | // start running the event loop 55 | LOG.debug("starting eqh number " + portal_index + 1); 56 | eqh.run(); 57 | } 58 | 59 | public ServerPortal getPortal() { 60 | return sp; 61 | } 62 | 63 | public void incrNumOfSessions() { 64 | num_of_sessions.incrementAndGet(); 65 | System.out.println("Server worker number " + (portal_index + 1) + " got new Session, now handling " + num_of_sessions + " sessions"); 66 | } 67 | 68 | private void decrNumOfSessions() { 69 | num_of_sessions.decrementAndGet(); 70 | System.out.println("Server worker number " + (portal_index + 1) + " disconnected from a Session, now handling " + num_of_sessions 71 | + " sessions"); 72 | DataPathTestServer.updateWorkers(this); 73 | } 74 | 75 | public void sessionClosed() { 76 | decrNumOfSessions(); 77 | } 78 | 79 | // callbacks for the Server's event queue handler 80 | public class ServerEQHCallbacks implements EventQueueHandler.Callbacks { 81 | // this method should return an unbinded MsgPool. 82 | public MsgPool getAdditionalMsgPool(int inSize, int outSize) { 83 | System.out.println("Messages in Client's message pool ran out, Aborting test"); 84 | return null; 85 | } 86 | } 87 | 88 | @Override 89 | public int compareTo(ServerPortalWorker s) { 90 | if (this.num_of_sessions.get() <= s.num_of_sessions.get()) { 91 | return -1; 92 | } else { 93 | return 1; 94 | } 95 | } 96 | 97 | @Override 98 | public boolean isFree() { 99 | return true; 100 | } 101 | } -------------------------------------------------------------------------------- /examples/org/accelio/jxio/tests/benchmarks/ServerSessionHandle.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.tests.benchmarks; 18 | 19 | import org.apache.commons.logging.Log; 20 | import org.apache.commons.logging.LogFactory; 21 | 22 | import org.accelio.jxio.Msg; 23 | import org.accelio.jxio.EventName; 24 | import org.accelio.jxio.EventReason; 25 | import org.accelio.jxio.ServerSession; 26 | import org.accelio.jxio.exceptions.JxioGeneralException; 27 | import org.accelio.jxio.exceptions.JxioSessionClosedException; 28 | import org.accelio.jxio.tests.benchmarks.ServerPortalWorker; 29 | 30 | public class ServerSessionHandle { 31 | 32 | // the server session 33 | private final ServerSession ss; 34 | 35 | // the thread that will run the server portal 36 | private final ServerPortalWorker spw; 37 | 38 | // logger 39 | private final static Log LOG = LogFactory.getLog(ServerSessionHandle.class.getCanonicalName()); 40 | 41 | // cTor 42 | public ServerSessionHandle(ServerSession.SessionKey sesKey, ServerPortalWorker s) { 43 | ss = new ServerSession(sesKey, new SessionServerCallbacks()); 44 | spw = s; 45 | } 46 | 47 | public ServerSession getSession() { 48 | return ss; 49 | } 50 | 51 | // session callbacks 52 | public class SessionServerCallbacks implements ServerSession.Callbacks { 53 | 54 | public void onRequest(Msg msg) { 55 | // answer back with the same message that was received 56 | msg.getOut().position(msg.getOut().capacity()); // simulate 'out_msgSize' was written into buffer 57 | try { 58 | ss.sendResponse(msg); 59 | } catch (JxioSessionClosedException e) { 60 | LOG.error("request was not handled. session already closed!"); 61 | } catch (JxioGeneralException e) { 62 | LOG.error("request was not handled: " + e.toString()); 63 | } 64 | } 65 | 66 | public void onSessionEvent(EventName event, EventReason reason) { 67 | LOG.debug("got event " + event.toString() + ", the reason is " + reason.toString()); 68 | System.out.println("got event " + event.toString() + ", the reason is " + reason.toString()); 69 | if (event == EventName.SESSION_CLOSED) { 70 | spw.sessionClosed(); 71 | } 72 | } 73 | 74 | public boolean onMsgError(Msg msg, EventReason reason) { 75 | if (ServerSessionHandle.this.ss.getIsClosing()) { 76 | LOG.debug("On Message Error while closing. Reason is=" + reason); 77 | } else { 78 | LOG.error("On Message Error. Reason is=" + reason); 79 | } 80 | return true; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/tests/benchmarks/StatClientSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.tests.benchmarks; 18 | 19 | import java.net.URI; 20 | import java.net.URISyntaxException; 21 | 22 | import org.apache.commons.logging.Log; 23 | import org.apache.commons.logging.LogFactory; 24 | 25 | import org.accelio.jxio.Msg; 26 | import org.accelio.jxio.EventName; 27 | import org.accelio.jxio.EventReason; 28 | import org.accelio.jxio.ClientSession; 29 | import org.accelio.jxio.EventQueueHandler; 30 | import org.accelio.jxio.tests.benchmarks.StatTest; 31 | 32 | public class StatClientSession { 33 | private final static Log LOG = LogFactory.getLog(StatTest.class.getCanonicalName()); 34 | 35 | EventQueueHandler eqh = null; 36 | int clients_count; 37 | ClientSession clients[]; 38 | 39 | public StatClientSession(EventQueueHandler eqh, String uriString, int num_clients) { 40 | this.clients_count = 0; 41 | this.eqh = eqh; 42 | this.clients = new ClientSession[num_clients]; 43 | 44 | URI uri = null; 45 | try { 46 | uri = new URI(uriString); 47 | } catch (URISyntaxException e) { 48 | // TODO Auto-generated catch block 49 | e.printStackTrace(); 50 | } 51 | 52 | for (int i = 0; i < num_clients; i++) { 53 | this.clients[i] = new ClientSession(eqh, uri, new StatSesClientCallbacks(i)); 54 | } 55 | } 56 | 57 | public void close() { 58 | for (ClientSession cs : clients) { 59 | cs.close(); 60 | } 61 | } 62 | 63 | public void print(String str) { 64 | LOG.debug("********" + str); 65 | } 66 | 67 | class StatSesClientCallbacks implements ClientSession.Callbacks { 68 | int session_num; 69 | 70 | public StatSesClientCallbacks(int index) { 71 | this.session_num = index; 72 | } 73 | 74 | public void onMsgError() { 75 | // logger.log(Level.debug, "onMsgErrorCallback"); 76 | print("onMsgErrorCallback"); 77 | } 78 | 79 | public void onSessionEstablished() { 80 | // logger.log(Level.debug, "[SUCCESS] Session Established! Bring the champagne!"); 81 | print(session_num + " Session Established"); 82 | clients[session_num].close(); 83 | } 84 | 85 | public void onSessionEvent(EventName event, EventReason reason) { 86 | if (event == EventName.SESSION_TEARDOWN) { 87 | print(session_num + " Session Teardown"); 88 | clients_count++; 89 | if (clients_count == clients.length) { 90 | print(session_num + " Stopping Event Loop"); 91 | eqh.breakEventLoop(); 92 | } 93 | } 94 | print(session_num + "GOT EVENT " + event.toString() + " because of " + reason.toString()); 95 | } 96 | 97 | public void onResponse(Msg msg) { 98 | 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /examples/org/accelio/jxio/tests/benchmarks/StatMTMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.tests.benchmarks; 18 | 19 | public class StatMTMain { 20 | 21 | public static void main(String[] args) { 22 | if (args.length < 4) { 23 | System.out.println("StatMTMain $IP $PORT $NUM_SESSIONS $NUM_THREADS"); 24 | return; 25 | } 26 | 27 | String IP = args[0]; 28 | int port = Integer.parseInt(args[1]); 29 | int num_sessions = Integer.parseInt(args[2]); 30 | int num_threads = Integer.parseInt(args[3]); 31 | Thread[] t_arr = new Thread[num_threads]; 32 | StatTest[] mt_arr = new StatTest[num_threads]; 33 | 34 | for (int i=0; i 2 | 3 | -------------------------------------------------------------------------------- /src/c/COPYING: -------------------------------------------------------------------------------- 1 | 2 | New BSD License" or "Modified BSD License" 3 | 4 | 5 | Copyright (c) 2012 Mellanox Technologies Ltd. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions 10 | are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 2. Redistributions in binary form must reproduce the above copyright 15 | notice, this list of conditions and the following disclaimer in 16 | the documentation and/or other materials provided with the 17 | distribution. 18 | 3. Neither the name of the Mellanox Technologies Ltd nor the names 19 | of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written 21 | permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | -------------------------------------------------------------------------------- /src/c/ChangeLog: -------------------------------------------------------------------------------- 1 | 2 | version 2.0 3 | 4 | - configure.ac revisited 5 | 6 | version 1.0 7 | 8 | - simple lib with one class and one depending binary 9 | -------------------------------------------------------------------------------- /src/c/Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | # the subdirectories of the project to go into 4 | SUBDIRS = \ 5 | src 6 | -------------------------------------------------------------------------------- /src/c/NEWS: -------------------------------------------------------------------------------- 1 | We are going to distribute something with autotools! 2 | 3 | Have a look into the Changelog file for latest changes ... 4 | -------------------------------------------------------------------------------- /src/c/README: -------------------------------------------------------------------------------- 1 | 2 | This project is part of the omx library from 3 | 4 | http://www.mellanox.com 5 | 6 | by Mellanox Technologies (c) 2012 7 | 8 | 9 | The following steps are needed now: 10 | - run ./configure 11 | - run make 12 | - follow examples in ./examples/ 13 | 14 | Examples: 15 | The following examples are provided: 16 | 17 | 1. hello world - a minimal single process, single thread "hello world" 18 | server and client. 19 | 20 | 2. hello world mt - a multithreaded client, and multithreaded server 21 | demonstrating how to scale and work in multi 22 | threaded environment. 23 | 24 | 3. RAIO - Linux's Remote AIO API over libomx. the example contains 25 | a DSO library, a server application and simple clients 26 | the client demontrates reading of files from the server. 27 | the interface to the library is libraio.h. 28 | 29 | 4. fio - a new engine for fio application demonstrating the 30 | use of libraio 31 | -------------------------------------------------------------------------------- /src/c/autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | libtoolize \ 4 | && aclocal \ 5 | && automake --gnu --add-missing \ 6 | && autoconf 7 | -------------------------------------------------------------------------------- /src/c/configure.ac: -------------------------------------------------------------------------------- 1 | # initial information about the project 2 | AC_INIT([libjxio],[1.0],[]) 3 | 4 | AC_CONFIG_MACRO_DIR([m4]) 5 | 6 | # Checks for programs 7 | AC_PROG_LIBTOOL 8 | 9 | # check for C compiler and the library compiler 10 | AC_PROG_CC([gcc]) 11 | AC_PROG_CXX([g++]) 12 | 13 | AM_INIT_AUTOMAKE([1.11]) 14 | AM_SILENT_RULES([yes]) 15 | 16 | # use the C compiler for the following checks 17 | AC_LANG([C],[C++]) 18 | 19 | # --> set these variables instead of CFLAGS or LDFLAGS 20 | AC_SUBST([AM_CFLAGS]) 21 | AC_SUBST([AM_LDFLAGS]) 22 | AC_SUBST([LIBS]) 23 | 24 | # files to generate via autotools (.am or .in source files) 25 | AC_CONFIG_FILES([Makefile]) 26 | AC_CONFIG_FILES([src/Makefile]) 27 | 28 | AC_OUTPUT 29 | 30 | -------------------------------------------------------------------------------- /src/c/src/Bridge.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #ifndef Bridge__H___ 18 | #define Bridge__H___ 19 | 20 | class Context; 21 | 22 | void Bridge_invoke_logToJava_callback(const int severity, const char* log_message); 23 | void Bridge_invoke_requestForBoundMsgPool_callback(Context* ctx, int inSize, int outSize); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/c/src/CallbackFunctionsClient.cc: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #include "CallbackFunctionsClient.h" 18 | 19 | // 20 | // implementation of the XIO callbacks for client 21 | // 22 | 23 | 24 | int on_msg_callback_client(struct xio_session *session, struct xio_msg *msg, 25 | int more_in_batch, void *cb_prv_data) 26 | { 27 | const int msg_in_size = get_xio_msg_in_size(msg); 28 | const int msg_out_size = get_xio_msg_out_size(msg); 29 | 30 | LOG_TRACE("on_msg_callback client=%p, num_iov=%d, len: in=%d out=%d, msg=%p", msg->user_context, msg->in.data_iov.nents, msg_in_size, msg_out_size, msg); 31 | Client *client = (Client*)cb_prv_data; 32 | Context *ctx = client->get_ctx_class(); 33 | struct xio_iovec_ex *sglist = vmsg_sglist(&msg->in); 34 | 35 | char* buf = ctx->get_buffer(); 36 | int sizeWritten = ctx->events.writeOnResponseReceivedEvent(buf, msg->user_context, msg_in_size); 37 | ctx->done_event_creating(sizeWritten); 38 | xio_release_response(msg); 39 | 40 | return 0; 41 | } 42 | 43 | int on_msg_error_callback_client(struct xio_session *session, enum xio_status error, 44 | enum xio_msg_direction direction, struct xio_msg *msg, void *cb_prv_data) 45 | { 46 | LOG_DBG("got on_msg_error_callback for msg=%p, direction=%d. error status is %d", msg->user_context, direction, error); 47 | Client *client = (Client*)cb_prv_data; 48 | Context *ctx = client->get_ctx_class(); 49 | 50 | char* buf = ctx->get_buffer(); 51 | //this is client side - send of the request failed 52 | int sizeWritten = ctx->events.writeOnMsgErrorEventClient(buf, msg->user_context, error); 53 | ctx->done_event_creating(sizeWritten); 54 | 55 | return 0; 56 | } 57 | 58 | int on_session_established_callback(struct xio_session *session, 59 | struct xio_new_session_rsp *rsp, void *cb_prv_data) 60 | { 61 | LOG_DBG("got on_session_established_callback"); 62 | Client *client = (Client*)cb_prv_data; 63 | Context *ctx = client->get_ctx_class(); 64 | 65 | char* buf = ctx->get_buffer(); 66 | int sizeWritten = ctx->events.writeOnSessionEstablishedEvent(buf, client, session, rsp); 67 | ctx->done_event_creating(sizeWritten); 68 | 69 | return 0; 70 | } 71 | 72 | int on_session_event_callback_client(struct xio_session *session, 73 | struct xio_session_event_data *event_data, void *cb_prv_data) 74 | { 75 | LOG_DBG("got on_session_event_callback. event=%d, cb_prv_data=%p, session=%p, conn=%p", 76 | event_data->event, cb_prv_data, session, event_data->conn); 77 | Client *client = (Client*)cb_prv_data; 78 | 79 | Context *ctx = client->ctxForSessionEvent(event_data, session); 80 | if (ctx) { 81 | /*in case it is a client, the java object is represented by cb_prv_data */ 82 | char* buf = ctx->get_buffer(); 83 | int sizeWritten = ctx->events.writeOnSessionErrorEvent(buf, client, event_data); 84 | ctx->done_event_creating(sizeWritten); 85 | } 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /src/c/src/CallbackFunctionsClient.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #ifndef CallbackFunctions__H___ 19 | #define CallbackFunctions__H___ 20 | 21 | #include 22 | #include 23 | #include "Context.h" 24 | #include "Client.h" 25 | 26 | 27 | /* 28 | * this callback is called by xio library once a client recieves new msg. 29 | * @cb_prv_data: represents client that holds pointer to context class. 30 | * Through it we can access buffer which is shared with Java. 31 | */ 32 | int on_msg_callback_client(struct xio_session *session, 33 | struct xio_msg *msg, 34 | int more_in_batch, 35 | void *cb_prv_data); 36 | /* 37 | * this callback is called by xio library once there is msg error. 38 | * @conn_user_context: represents client that holds pointer to context class. 39 | * Through it we can access buffer which is shared with Java. 40 | */ 41 | int on_msg_error_callback_client(struct xio_session *session, 42 | enum xio_status error, 43 | enum xio_msg_direction direction, 44 | struct xio_msg *msg, 45 | void *cb_prv_data); 46 | /* 47 | * this callback is called by xio library once a client receives notice that a session is established 48 | * with the server. 49 | * @cb_prv_data: represents client that holds pointer to context class. 50 | * Through it we can access buffer which is shared with Java. 51 | */ 52 | int on_session_established_callback(struct xio_session *session, 53 | struct xio_new_session_rsp *rsp, 54 | void *cb_prv_data); 55 | /* 56 | * this callback is called by xio library once client recieves session event. 57 | * @cb_prv_data: represents client that holds pointer to context class. 58 | * Through it we can access buffer which is shared with Java. 59 | */ 60 | int on_session_event_callback_client(struct xio_session *session, 61 | struct xio_session_event_data *event_data, 62 | void *cb_prv_data); 63 | 64 | 65 | 66 | #endif // ! CallbackFunctions__H___ 67 | -------------------------------------------------------------------------------- /src/c/src/CallbackFunctionsServer.cc: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #include "bullseye.h" 18 | #include "CallbackFunctionsServer.h" 19 | 20 | // 21 | // implementation of the XIO callbacks for server 22 | // 23 | 24 | int on_new_session_callback(struct xio_session *xio_session, struct xio_new_session_req *req, void *cb_prv_data) 25 | { 26 | LOG_DBG("got on_new_session_callback for session=%p", xio_session); 27 | 28 | ServerPortal *portal = (ServerPortal*) cb_prv_data; 29 | Context *ctx = portal->get_ctx_class(); 30 | 31 | ServerSession *jxio_session = new ServerSession(xio_session, portal, portal->get_ctx_class()); 32 | 33 | /*modifying private data of the session, so we would be able to retrive the 34 | * ServerSession when events are received 35 | */ 36 | struct xio_session_attr ses_attr; 37 | ses_attr.user_context = jxio_session; 38 | BULLSEYE_EXCLUDE_BLOCK_START 39 | if (xio_modify_session(xio_session, &ses_attr, XIO_SESSION_ATTR_USER_CTX)) { 40 | LOG_ERR("xio_modify_session for session=%p failed", xio_session); 41 | } 42 | BULLSEYE_EXCLUDE_BLOCK_END 43 | LOG_DBG("xio_modify_session for session=%p to %p", xio_session, jxio_session); 44 | 45 | char* buf = ctx->get_buffer(); 46 | int sizeWritten = ctx->events.writeOnNewSessionEvent(buf, portal, jxio_session, req); 47 | ctx->done_event_creating(sizeWritten); 48 | return 0; 49 | } 50 | 51 | int on_msg_send_complete_callback(struct xio_session *xio_session, struct xio_msg *msg, void *cb_prv_data) 52 | { 53 | LOG_TRACE("got on_msg_send_complete_callback for msg=%p", msg->user_context); 54 | 55 | //must release the message 56 | Msg *msg_from_pool = (Msg*) msg->user_context; 57 | msg_from_pool->release_to_pool(); 58 | LOG_TRACE("finished on_msg_send_complete_callback for msg=%p", msg->user_context); 59 | return 0; 60 | } 61 | 62 | int on_msg_callback_server(struct xio_session *xio_session, struct xio_msg *msg, int more_in_batch, void *cb_prv_data) 63 | { 64 | const int msg_in_size = get_xio_msg_in_size(msg); 65 | const int msg_out_size = get_xio_msg_out_size(msg); 66 | 67 | LOG_TRACE("on_msg_callback portal=%p, num_iov=%d, len: in=%d out=%d, msg=%p", msg->user_context, msg->in.data_iov.nents, msg_in_size, msg_out_size, msg); 68 | 69 | ServerSession *jxio_session = (ServerSession*) cb_prv_data; 70 | ServerPortal *portal = jxio_session->get_portal_msg_event(); 71 | 72 | Context *ctx = portal->get_ctx_class(); 73 | struct xio_iovec_ex *sglist = vmsg_sglist(&msg->in); 74 | 75 | //checking if it's a request with a small buffer on server side 76 | 77 | bool need_copy = false; 78 | Msg* msg_from_pool; 79 | if (msg->user_context == NULL) { 80 | //first time ever that this xio_msg is received - 81 | //assign was not called 82 | need_copy = true; 83 | msg_from_pool = ctx->msg_pools.get_msg_from_pool(msg_in_size, msg_out_size); 84 | } else { 85 | msg_from_pool = (Msg*) msg->user_context; 86 | need_copy = !(msg_from_pool->was_assign_called()); 87 | } 88 | if (need_copy) { 89 | if (msg_in_size > 0) 90 | memcpy(msg_from_pool->get_buf(), sglist[0].iov_base, msg_in_size); 91 | msg->user_context = msg_from_pool; 92 | msg_from_pool->set_xio_msg_req(msg); 93 | } 94 | 95 | char* buf = ctx->get_buffer(); 96 | int sizeWritten = ctx->events.writeOnRequestReceivedEvent(buf, msg->user_context, msg_in_size, msg_out_size, jxio_session); 97 | 98 | ctx->done_event_creating(sizeWritten); 99 | 100 | return 0; 101 | } 102 | 103 | int on_msg_error_callback_server(struct xio_session *xio_session, enum xio_status error, enum xio_msg_direction direction, struct xio_msg *msg, void *cb_prv_data) 104 | { 105 | LOG_DBG("got on_msg_error_callback for msg=%p, direction=%d. error status is %d", msg->user_context, direction, error); 106 | ServerSession *jxio_session = (ServerSession*) cb_prv_data; 107 | 108 | if (error == XIO_E_MSG_DISCARDED) { 109 | //since user discarded this msg, he does not need this notification 110 | Msg* msg_from_pool = (Msg*)msg->user_context; 111 | msg_from_pool->release_to_pool(); 112 | return 0; 113 | } 114 | 115 | ServerPortal *portal = jxio_session->get_portal_msg_event(); 116 | 117 | Context *ctx = portal->get_ctx_class(); 118 | 119 | char* buf = ctx->get_buffer(); 120 | //this is server side - send of the response failed 121 | int sizeWritten = ctx->events.writeOnMsgErrorEventServer(buf, msg->user_context, jxio_session, error); 122 | ctx->done_event_creating(sizeWritten); 123 | 124 | return 0; 125 | } 126 | 127 | int on_session_event_callback_server(struct xio_session *xio_session, struct xio_session_event_data *event_data, void *cb_prv_data) { 128 | 129 | LOG_DBG("got on_session_event_callback. event=%d, reason=%d, cb_prv_data=%p, session=%p, conn=%p", 130 | event_data->event, event_data->reason, cb_prv_data, xio_session, event_data->conn); 131 | BULLSEYE_EXCLUDE_BLOCK_START 132 | if (cb_prv_data == NULL) { 133 | LOG_ERR("cb_prv_data is NULL making jxio_session of type ServerSession NULL"); 134 | return 1; 135 | } 136 | BULLSEYE_EXCLUDE_BLOCK_END 137 | ServerSession *jxio_session = (ServerSession*) cb_prv_data; 138 | ServerPortal *portal = jxio_session->get_portal_session_event(event_data->conn_user_context, event_data->conn, event_data->event); 139 | Context *ctx = portal->ctxForSessionEvent(event_data, jxio_session); 140 | if (ctx) { 141 | char* buf = ctx->get_buffer(); 142 | int sizeWritten = ctx->events.writeOnSessionErrorEvent(buf, jxio_session, event_data); 143 | ctx->done_event_creating(sizeWritten); 144 | if (portal->flag_to_delete) { 145 | portal->deleteObject(); 146 | } 147 | } 148 | return 0; 149 | } 150 | 151 | int on_buffer_request_callback(struct xio_msg *msg, void *cb_user_context) 152 | { 153 | LOG_TRACE("got on_buffer_request_callback for msg=%p, user_context=%p", msg, cb_user_context); 154 | ServerSession *jxio_session = (ServerSession*) cb_user_context; 155 | ServerPortal *portal = jxio_session->get_portal_msg_event(); 156 | Context *ctx = portal->get_ctx_class(); 157 | const int msg_in_size = get_xio_msg_in_size(msg); 158 | const int msg_out_size = get_xio_msg_out_size(msg); 159 | Msg* msg_from_pool = ctx->msg_pools.get_msg_from_pool(msg_in_size, msg_out_size); 160 | msg_from_pool->set_xio_msg_fields_for_assign(msg); 161 | return 0; 162 | } 163 | -------------------------------------------------------------------------------- /src/c/src/CallbackFunctionsServer.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #ifndef CallbackFunctions__H___ 19 | #define CallbackFunctions__H___ 20 | 21 | #include 22 | #include 23 | #include "Context.h" 24 | #include "ServerPortal.h" 25 | #include "ServerSession.h" 26 | 27 | 28 | /* 29 | * this callback is called by xio library once a server recieves new session request. 30 | * @cb_prv_data: represents portal that holds pointer to cJXCtx class. 31 | * Through it we can access buffer which is shared with Java. 32 | */ 33 | int on_new_session_callback(struct xio_session *session, 34 | struct xio_new_session_req *req, 35 | void *cb_prv_data); 36 | 37 | /* 38 | * this callback is called by xio library once server finishes sending a msg. 39 | * @cb_prv_data: represents portal that holds pointer to cJXCtx class. 40 | * Through it we can access buffer which is shared with Java. 41 | */ 42 | int on_msg_send_complete_callback(struct xio_session *session, 43 | struct xio_msg *msg, 44 | void *cb_prv_data); 45 | /* 46 | * this callback is called by xio library once a server/client recieves new msg. 47 | * @cb_prv_data: represents portal that holds pointer to cJXCtx class. 48 | * Through it we can access buffer which is shared with Java. 49 | */ 50 | int on_msg_callback_server(struct xio_session *session, 51 | struct xio_msg *msg, 52 | int more_in_batch, 53 | void *cb_prv_data); 54 | /* 55 | * this callback is called by xio library once there is msg error. 56 | * @conn_user_context: represents portal that holds pointer to cJXCtx class. 57 | * Through it we can access buffer which is shared with Java. 58 | */ 59 | int on_msg_error_callback_server(struct xio_session *session, 60 | enum xio_status error, 61 | enum xio_msg_direction direction, 62 | struct xio_msg *msg, 63 | void *cb_prv_data); 64 | 65 | /* 66 | * this callback is called by xio library once a server/client recieve session event. 67 | * @cb_prv_data: represents class implementing portal that holds pointer to cJXCtx class. 68 | * Through it we can access buffer which is shared with Java. 69 | */ 70 | int on_session_event_callback_server(struct xio_session *session, 71 | struct xio_session_event_data *event_data, 72 | void *cb_prv_data); 73 | 74 | /* this callback is called by server side when a request is received from client side and 75 | * it needs to be supplied with buffer 76 | */ 77 | int on_buffer_request_callback (struct xio_msg *msg, 78 | void *cb_user_context); 79 | 80 | 81 | 82 | #endif // ! CallbackFunctions__H___ 83 | -------------------------------------------------------------------------------- /src/c/src/Client.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #ifndef Client__H___ 18 | #define Client__H___ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "CallbackFunctionsClient.h" 25 | #include "Context.h" 26 | #include "Msg.h" 27 | 28 | class Client { 29 | public: 30 | struct xio_session* session; 31 | struct xio_connection* con; 32 | 33 | bool is_closing; 34 | //to move some to private? 35 | Client(const char* url, long ptrCtx); 36 | ~Client(); 37 | bool create_connection(); 38 | bool close_connection(); 39 | int send_msg(Msg *msg, const int out_size, const int in_size, const bool is_mirror); 40 | 41 | Context* ctxForSessionEvent(struct xio_session_event_data * event, 42 | struct xio_session *session); 43 | Context* get_ctx_class() {return ctx_class;} 44 | private: 45 | Context *ctx_class; 46 | }; 47 | 48 | #endif // ! Client__H___ 49 | -------------------------------------------------------------------------------- /src/c/src/Context.cc: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #include "bullseye.h" 19 | #include "Utils.h" 20 | #include "Context.h" 21 | #include "ServerPortal.h" 22 | 23 | #define MODULE_NAME "Context" 24 | #define CONTEXT_LOG_ERR(log_fmt, log_args...) LOG_BY_MODULE(lsERROR, log_fmt, ##log_args) 25 | #define CONTEXT_LOG_DBG(log_fmt, log_args...) LOG_BY_MODULE(lsDEBUG, log_fmt, ##log_args) 26 | #define CONTEXT_LOG_TRACE(log_fmt, log_args...) LOG_BY_MODULE(lsTRACE, log_fmt, ##log_args) 27 | 28 | Context::Context(size_t events_queue_size) : events_queue(events_queue_size) 29 | { 30 | CONTEXT_LOG_DBG("CTOR start"); 31 | 32 | staging_scheduled_event_buffer = new char[(sizeof(scheduled_event_t) + EVENTQUEUE_HEADROOM_BUFFER)]; 33 | staging_scheduled_event_in_use = false; 34 | 35 | this->ctx = xio_context_create(NULL, 0, -1); 36 | BULLSEYE_EXCLUDE_BLOCK_START 37 | if (ctx == NULL) { 38 | CONTEXT_LOG_ERR("ERROR on xio_context_create() (errno=%d '%s')", xio_errno(), xio_strerror(xio_errno())); 39 | delete[] staging_scheduled_event_buffer; 40 | throw std::bad_alloc(); 41 | } 42 | BULLSEYE_EXCLUDE_BLOCK_END 43 | 44 | this->msg_pools.setCtx(this); 45 | 46 | CONTEXT_LOG_DBG("CTOR done"); 47 | return; 48 | } 49 | 50 | Context::~Context() 51 | { 52 | while (scheduled_events_count() > 0) { 53 | delete this->scheduled_events_queue.front().queued_event; 54 | this->scheduled_events_queue.pop_front(); 55 | } 56 | delete[] staging_scheduled_event_buffer; 57 | 58 | xio_context_destroy(ctx); 59 | 60 | CONTEXT_LOG_DBG("DTOR done"); 61 | } 62 | 63 | int Context::run_event_loop(long timeout_micro_sec) 64 | { 65 | reset_events_counters(); 66 | 67 | if (scheduled_events_count() == 0) { 68 | 69 | int timeout_msec = -1; // infinite timeout as default 70 | if (timeout_micro_sec == -1) { 71 | CONTEXT_LOG_TRACE("before ev_loop_run. requested infinite timeout"); 72 | } else { 73 | timeout_msec = timeout_micro_sec/1000; 74 | CONTEXT_LOG_TRACE("before ev_loop_run. requested timeout is %d msec", timeout_msec); 75 | } 76 | 77 | // enter Accelio's event loop 78 | xio_context_run_loop(this->ctx, timeout_msec); 79 | } 80 | 81 | scheduled_events_process(); 82 | 83 | CONTEXT_LOG_TRACE("after ev_loop_run. there are %d events", get_events_count()); 84 | return get_events_count(); 85 | } 86 | 87 | void Context::break_event_loop() 88 | { 89 | CONTEXT_LOG_TRACE("before break event loop"); 90 | xio_context_stop_loop(this->ctx); 91 | CONTEXT_LOG_TRACE("after break event loop"); 92 | } 93 | 94 | void Context::add_msg_pool(MsgPool* msg_pool) 95 | { 96 | CONTEXT_LOG_DBG("adding msg pool=%p", msg_pool); 97 | this->msg_pools.add_msg_pool(msg_pool); 98 | } 99 | 100 | char* Context::get_buffer_raw() 101 | { 102 | return events_queue.get_buffer(); 103 | } 104 | 105 | char* Context::get_buffer(bool force_scheduled /*=false*/) 106 | { 107 | char* buf = NULL; 108 | if (force_scheduled != true) 109 | buf = events_queue.get_buffer_offset(); 110 | if (buf == NULL) { 111 | staging_scheduled_event_in_use = true; 112 | return staging_scheduled_event_buffer; 113 | } 114 | return buf; 115 | } 116 | 117 | void Context::done_event_creating(int size_written) 118 | { 119 | if (staging_scheduled_event_in_use == true) { 120 | staging_scheduled_event_in_use = false; 121 | 122 | scheduled_event_t scheduled_event; 123 | scheduled_event.queued_event = new char[size_written]; 124 | scheduled_event.size = size_written; 125 | memcpy(scheduled_event.queued_event, staging_scheduled_event_buffer, size_written); 126 | scheduled_events_add(scheduled_event); 127 | } 128 | else { 129 | this->events_queue.increase_offset(size_written); 130 | 131 | // need to stop the event queue only if this is the first callback 132 | if (get_events_count() == 1) { 133 | CONTEXT_LOG_TRACE("inside a callback - stopping the event queue"); 134 | this->break_event_loop(); 135 | } 136 | } 137 | } 138 | 139 | void Context::scheduled_events_add(scheduled_event_t& scheduled_event) 140 | { 141 | CONTEXT_LOG_TRACE("adding scheduled event (queue size = %d)", scheduled_events_count()); 142 | this->scheduled_events_queue.push_back(scheduled_event); 143 | this->break_event_loop(); 144 | } 145 | 146 | int Context::scheduled_events_process() 147 | { 148 | CONTEXT_LOG_TRACE("going to process %d scheduled events from queue", scheduled_events_count()); 149 | char* events_queue_buf = NULL; 150 | while (scheduled_events_count() > 0 && ((events_queue_buf = events_queue.get_buffer_offset()) != NULL)) { 151 | 152 | scheduled_event_t scheduled_event = this->scheduled_events_queue.front(); 153 | 154 | // Write internal events to event queue 155 | memcpy(events_queue_buf, scheduled_event.queued_event, scheduled_event.size); 156 | this->events_queue.increase_offset(scheduled_event.size); 157 | 158 | delete scheduled_event.queued_event; 159 | this->scheduled_events_queue.pop_front(); 160 | } 161 | return get_events_count(); 162 | } 163 | -------------------------------------------------------------------------------- /src/c/src/Context.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #ifndef Context__H___ 18 | #define Context__H___ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "EventQueue.h" 25 | #include "Events.h" 26 | #include "MsgPools.h" 27 | 28 | class Client; 29 | class MsgPool; 30 | 31 | struct __attribute__ ((packed)) scheduled_event_t { 32 | char* queued_event; 33 | size_t size; 34 | }; 35 | 36 | class Context { 37 | public: 38 | //to move some to private? 39 | Context(size_t events_queue_size); 40 | ~Context(); 41 | 42 | inline xio_context* get_xio_context() { return ctx; }; 43 | 44 | int run_event_loop(long timeout_micro_sec); 45 | void break_event_loop(); 46 | 47 | void add_msg_pool(MsgPool* msg_pool); 48 | 49 | char* get_buffer_raw(); 50 | char* get_buffer(bool force_scheduled = false); 51 | void done_event_creating(int size_written); 52 | inline int get_events_count() { return events_queue.get_count(); }; 53 | void reset_events_counters() { this->events_queue.reset(); }; 54 | 55 | inline int scheduled_events_count() { return this->scheduled_events_queue.size(); }; 56 | void scheduled_events_add(scheduled_event_t& scheduled_event); 57 | int scheduled_events_process(); 58 | 59 | static void on_event_loop_handler(int fd, int events, void *priv_data); 60 | 61 | Events events; 62 | MsgPools msg_pools; 63 | 64 | private: 65 | struct xio_context *ctx; 66 | EventQueue events_queue; 67 | bool staging_scheduled_event_in_use; 68 | char* staging_scheduled_event_buffer; 69 | std::deque scheduled_events_queue; 70 | }; 71 | 72 | #endif // ! Context__H___ 73 | -------------------------------------------------------------------------------- /src/c/src/EventQueue.cc: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #include 19 | 20 | #include "bullseye.h" 21 | #include "Utils.h" 22 | #include "EventQueue.h" 23 | 24 | EventQueue::EventQueue(size_t size) : size(size) 25 | { 26 | this->buffer = new char[size]; // might throw a std::bad_alloc() exception 27 | reset(); 28 | } 29 | 30 | EventQueue::~EventQueue() 31 | { 32 | reset(); 33 | delete this->buffer; 34 | } 35 | 36 | void EventQueue::reset() 37 | { 38 | //update offset to 0: for indication if this is the first callback called 39 | this->offset = 0; 40 | this->count = 0; 41 | } 42 | 43 | char* EventQueue::get_buffer_offset() 44 | { 45 | if (this->offset + EVENTQUEUE_HEADROOM_BUFFER > this->size) { 46 | return NULL; 47 | } 48 | return this->buffer + this->offset; 49 | }; 50 | 51 | void EventQueue::increase_offset(int increase) 52 | { 53 | this->offset += increase; 54 | BULLSEYE_EXCLUDE_BLOCK_START 55 | if (this->offset > this->size) { 56 | char fatalErrorStr[256]; 57 | sprintf(fatalErrorStr, "EventQueue buffer overflow ERROR (there are already %d events in queue). Aborting!!!", get_count()); 58 | LOG_FATAL("%s", fatalErrorStr); 59 | throw std::overflow_error(fatalErrorStr); 60 | } 61 | BULLSEYE_EXCLUDE_BLOCK_END 62 | this->count++; 63 | } 64 | -------------------------------------------------------------------------------- /src/c/src/EventQueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | 19 | #ifndef EventQueue__H___ 20 | #define EventQueue__H___ 21 | 22 | #include 23 | #include 24 | 25 | #define EVENTQUEUE_HEADROOM_BUFFER (1024) 26 | 27 | class EventQueue { 28 | public: 29 | EventQueue(size_t size); 30 | ~EventQueue(); 31 | char* get_buffer() { return buffer; }; 32 | char* get_buffer_offset(); 33 | void reset(); 34 | void increase_offset(int increase); 35 | inline int get_count() { return count; } 36 | 37 | private: 38 | const size_t size; 39 | char* buffer; 40 | int offset; 41 | int count; 42 | }; 43 | 44 | #endif // ! EventQueue__H___ 45 | -------------------------------------------------------------------------------- /src/c/src/Events.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | 19 | #ifndef Events__H___ 20 | #define Events__H___ 21 | 22 | #include 23 | #include 24 | #include 25 | #include "Utils.h" 26 | 27 | 28 | struct event_new_session { 29 | int64_t ptr_session; 30 | int32_t uri_len; 31 | char uri_str[0]; //to indicate that string uri is written to buffer 32 | int32_t ip_len; 33 | char ip_str[0]; //to indicate that ip string is written to buffer 34 | } __attribute__ ((packed)); 35 | 36 | struct __attribute__ ((packed)) event_session_established { 37 | }; 38 | 39 | struct __attribute__ ((packed)) event_session_error { 40 | 41 | int32_t error_type; 42 | int32_t error_reason; 43 | }; 44 | 45 | struct __attribute__ ((packed)) event_msg_complete { 46 | }; 47 | 48 | struct __attribute__ ((packed)) event_msg_error_server { 49 | int64_t ptr_session; 50 | //use the ptr inside event_struct for passing the pointer to msg class in java 51 | int32_t error_reason; 52 | }; 53 | 54 | struct __attribute__ ((packed)) event_msg_error_client { 55 | int32_t error_reason; 56 | }; 57 | 58 | struct __attribute__ ((packed)) event_req_received { 59 | int32_t msg_in_size; 60 | int32_t msg_out_size; 61 | int64_t ptr_session; 62 | //use the ptr inside event_struct for passing the pointer to msg class in java 63 | }; 64 | 65 | struct __attribute__ ((packed)) event_res_received { 66 | int32_t msg_size; 67 | }; 68 | 69 | struct __attribute__ ((packed)) event_fd_ready { 70 | int32_t fd; 71 | int32_t epoll_event; 72 | }; 73 | 74 | struct __attribute__ ((packed)) queued_event_t { 75 | int32_t type; 76 | int64_t ptr;//this will indicate on which session the event arrived 77 | union { 78 | struct event_new_session new_session; 79 | struct event_session_established session_established; 80 | struct event_session_error session_error; 81 | struct event_msg_complete msg_complete; 82 | struct event_msg_error_server msg_error_server; 83 | struct event_msg_error_client msg_error_client; 84 | struct event_req_received req_received; 85 | struct event_res_received res_received; 86 | struct event_fd_ready fd_ready; 87 | } event_specific; 88 | }; 89 | 90 | 91 | 92 | class Events { 93 | public: 94 | int size; 95 | 96 | Events(); 97 | 98 | int writeOnSessionErrorEvent(char *buf, void *ptrForJava, struct xio_session_event_data *event_data); 99 | int writeOnSessionEstablishedEvent (char *buf, void *ptrForJava, struct xio_session *session, 100 | struct xio_new_session_rsp *rsp); 101 | int writeOnNewSessionEvent(char *buf, void *ptrForJava, void *serverSession, 102 | struct xio_new_session_req *req); 103 | int writeOnMsgErrorEventServer(char *buf, void *ptrForJavaMsg, void *ptrForJavaSession, 104 | enum xio_status error); 105 | int writeOnMsgErrorEventClient(char *buf, void *ptrForJava, enum xio_status error); 106 | int writeOnRequestReceivedEvent(char *buf, void *ptrForJavaMsg, const int32_t msg_in_size, const int32_t msg_out_size, void *ptrForJavaSession); 107 | int writeOnResponseReceivedEvent(char *buf, void *ptrForJavaMsg, const int32_t msg_in_size); 108 | int writeOnFdReadyEvent(char *buf, int fd, int event); 109 | 110 | }; 111 | 112 | #endif // ! Events__H___ 113 | -------------------------------------------------------------------------------- /src/c/src/Makefile.am: -------------------------------------------------------------------------------- 1 | JDK = $(JAVA_HOME) 2 | topdir=../../ 3 | 4 | # additional include paths necessary to compile the C library 5 | AM_CPPFLAGS = -fPIC -DPIC -DGIT_VERSION=\"`git describe --long --tags --always --dirty`\" -Werror \ 6 | -I$(JDK)/include -I$(JDK)/include/linux \ 7 | -I$(topdir)/accelio/include 8 | 9 | ############################################################################### 10 | # THE LIBRARIES TO BUILD 11 | ############################################################################### 12 | 13 | lib_LTLIBRARIES = libjxio.la 14 | 15 | libjxio_la_SOURCES = Utils.cc EventQueue.cc Events.cc CallbackFunctionsServer.cc CallbackFunctionsClient.cc ServerPortal.cc Client.cc Context.cc Msg.cc MsgPool.cc MsgPools.cc ServerSession.cc Bridge.cc 16 | 17 | libjxio_la_LDFLAGS = -shared -rdynamic 18 | 19 | libjxio_la_LIBADD = -lxio -L$(topdir)accelio/src/usr 20 | 21 | libjxio_la_DEPENDENCIES = Makefile.am Makefile.in Makefile 22 | 23 | cov: 24 | PATH=/.autodirect/app/Coverity/cov-analysis-linux64-7.0.1/bin:$$PATH && rm -rf $(PWD)/cov-build && make clean && cov-build --dir $(PWD)/cov-build make all && cov-analyze --dir $(PWD)/cov-build && cov-format-errors --dir $(PWD)/cov-build --html-output $(PWD)/cov-build/c/output/errors/ 25 | 26 | clean: 27 | rm -rf *.o *.lo *.la 28 | 29 | ############################################################################### 30 | -------------------------------------------------------------------------------- /src/c/src/Msg.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #ifndef Msg__H___ 18 | #define Msg__H___ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | class MsgPool; 25 | 26 | #define vmsg_sglist(vmsg) \ 27 | (((vmsg)->sgl_type == XIO_SGL_TYPE_IOV) ? \ 28 | (vmsg)->data_iov.sglist : \ 29 | (((vmsg)->sgl_type == XIO_SGL_TYPE_IOV_PTR) ? \ 30 | (vmsg)->pdata_iov.sglist : NULL)) 31 | 32 | 33 | class Msg { 34 | public: 35 | Msg(char * buf, struct xio_mr *xio_mr, int in_buf_size, int out_buf_size, MsgPool* pool); 36 | ~Msg(); 37 | void set_xio_msg_client_fields(); //this method is used by client side 38 | void set_xio_msg_mirror_fields(); 39 | void set_xio_msg_server_fields(); 40 | void set_xio_msg_fields_for_assign(struct xio_msg *msg); //used when assign_buffer callback is called 41 | void set_xio_msg_req(struct xio_msg *msg); //this method is used by server side 42 | void set_xio_msg_out_size(struct xio_msg *xio_msg, const int out_size); 43 | void set_xio_msg_in_size(struct xio_msg *xio_msg, const int in_size); 44 | void release_to_pool(); 45 | void* get_buf() { return buf; } 46 | struct xio_msg* get_xio_msg() { return &xio_msg; } 47 | struct xio_msg* get_mirror_xio_msg() { return &xio_msg_mirror; } 48 | int send_response(const int size); 49 | int get_in_size() { return this->in_buf_size; } 50 | int get_out_size() { return this->out_buf_size; } 51 | bool was_assign_called() { return this->assign_called; } 52 | void dump(struct xio_msg *m); //func for debugging only 53 | 54 | private: 55 | char * buf; 56 | char * buf_out; 57 | struct xio_mr *xio_mr; 58 | struct xio_msg xio_msg; 59 | struct xio_msg xio_msg_mirror; 60 | int in_buf_size; 61 | int out_buf_size; 62 | MsgPool* pool; 63 | bool assign_called; 64 | }; 65 | 66 | 67 | 68 | inline const int get_xio_msg_in_size(struct xio_msg *msg) 69 | { 70 | struct xio_iovec_ex *sglist = vmsg_sglist(&msg->in); 71 | const int msg_in_size = (msg->in.data_iov.nents > 0) ? sglist[0].iov_len : 0; 72 | return msg_in_size; 73 | } 74 | 75 | inline const int get_xio_msg_out_size(struct xio_msg *msg) 76 | { 77 | struct xio_iovec_ex *sglist = vmsg_sglist(&msg->out); 78 | const int msg_out_size = (msg->out.data_iov.nents > 0) ? sglist[0].iov_len : 0; 79 | return msg_out_size; 80 | } 81 | 82 | 83 | #endif // ! Msg__H___ 84 | -------------------------------------------------------------------------------- /src/c/src/MsgPool.cc: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #include "bullseye.h" 19 | #include "Utils.h" 20 | #include "MsgPool.h" 21 | 22 | //TODO: make sure that in and out size are aligned to 64!!!! 23 | 24 | #define MODULE_NAME "MsgPool" 25 | #define MSGPOOL_LOG_ERR(log_fmt, log_args...) LOG_BY_MODULE(lsERROR, log_fmt, ##log_args) 26 | #define MSGPOOL_LOG_WARN(log_fmt, log_args...) LOG_BY_MODULE(lsWARN, log_fmt, ##log_args) 27 | #define MSGPOOL_LOG_DBG(log_fmt, log_args...) LOG_BY_MODULE(lsDEBUG, log_fmt, ##log_args) 28 | 29 | 30 | MsgPool::MsgPool(int msg_num, int in_size, int out_size) 31 | { 32 | Msg* msg = NULL; 33 | this->in_size = in_size; 34 | this->out_size = out_size; 35 | this->msg_num = msg_num; 36 | this->msg_ptrs = NULL; 37 | this->buf_size = (long)msg_num * (in_size + out_size); 38 | 39 | BULLSEYE_EXCLUDE_BLOCK_START 40 | if (xio_mem_alloc(buf_size, &this->reg_mem)){ 41 | MSGPOOL_LOG_ERR("allocating & registering memory failed with xio_mem_alloc(buf=%p, buf_size=%d) (errno=%d '%s')", this->reg_mem, this->buf_size, xio_errno(), xio_strerror(xio_errno())); 42 | throw std::bad_alloc(); 43 | } 44 | this->buf = (char*) this->reg_mem.addr; 45 | 46 | BULLSEYE_EXCLUDE_BLOCK_END 47 | 48 | msg_ptrs = new Msg*[msg_num]; 49 | 50 | for (int i = 0; i < msg_num; i++) { 51 | msg = new Msg((char*) buf + i * (in_size + out_size), this->reg_mem.mr, in_size, out_size, this); 52 | add_msg_to_pool(msg); 53 | msg_ptrs[i] = msg; 54 | } 55 | 56 | MSGPOOL_LOG_DBG("CTOR done. allocated msg pool: num_msgs=%d, in_size=%d, out_size=%d", msg_num, in_size, out_size); 57 | return; 58 | } 59 | 60 | MsgPool::~MsgPool() 61 | { 62 | Msg* msg = NULL; 63 | while ((msg = get_msg_from_pool()) != NULL) { 64 | delete msg; 65 | } 66 | 67 | BULLSEYE_EXCLUDE_BLOCK_START 68 | if (xio_mem_free(&this->reg_mem)) { 69 | MSGPOOL_LOG_DBG("Error xio_mem_free failed: '%s' (%d)", xio_strerror(xio_errno()), xio_errno()); 70 | } 71 | BULLSEYE_EXCLUDE_BLOCK_END 72 | 73 | delete[] msg_ptrs; 74 | MSGPOOL_LOG_DBG("DTOR done"); 75 | } 76 | 77 | Msg* MsgPool::get_msg_from_pool() 78 | { 79 | if (msg_list.empty()) { 80 | return NULL; 81 | } 82 | Msg* msg = msg_list.front(); 83 | msg_list.pop_front(); 84 | return msg; 85 | } 86 | 87 | void MsgPool::add_msg_to_pool(Msg* msg) 88 | { 89 | msg_list.push_front(msg); 90 | } 91 | -------------------------------------------------------------------------------- /src/c/src/MsgPool.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #ifndef MsgPool__H___ 18 | #define MsgPool__H___ 19 | 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include "Msg.h" 27 | #include "Bridge.h" 28 | 29 | 30 | class MsgPool { 31 | public: 32 | MsgPool (int msg_num, int in_size, int out_size); 33 | ~MsgPool(); 34 | 35 | Msg* get_msg_from_pool(); 36 | void add_msg_to_pool(Msg* msg); 37 | bool is_empty() { return msg_list.empty(); } 38 | int get_in_size() { return in_size; } 39 | int get_out_size() { return out_size; } 40 | 41 | long buf_size; 42 | char* buf; 43 | Msg** msg_ptrs; 44 | 45 | private: 46 | int msg_num; 47 | int in_size; 48 | int out_size; 49 | struct xio_reg_mem reg_mem; 50 | std::list msg_list; 51 | }; 52 | 53 | #endif // ! MsgPool__H___ 54 | -------------------------------------------------------------------------------- /src/c/src/MsgPools.cc: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #include 19 | 20 | #include "bullseye.h" 21 | #include "MsgPools.h" 22 | 23 | MsgPools::MsgPools() 24 | { 25 | this->in_size = 0; 26 | this->out_size = 0; 27 | this->first_time = true; 28 | this->ctx = NULL; 29 | } 30 | 31 | void MsgPools::setCtx(Context* ctx) 32 | { 33 | this->ctx = ctx; 34 | } 35 | 36 | MsgPools::~MsgPools() 37 | { 38 | } 39 | 40 | bool MsgPools::add_msg_pool(MsgPool* pool) 41 | { 42 | if (this->first_time) { 43 | this->in_size = pool->get_in_size(); 44 | this->out_size = pool->get_out_size(); 45 | } else { 46 | BULLSEYE_EXCLUDE_BLOCK_START 47 | if (this->in_size != pool->get_in_size() || this->out_size != pool->get_out_size()) { 48 | char fatalErrorStr[256]; 49 | sprintf(fatalErrorStr, "New pool is not of the same size!!! should be in=%d, out=%d and it is in=%d, out=%d. Aborting!!!", this->in_size, this->out_size, pool->get_in_size(), pool->get_out_size()); 50 | LOG_FATAL("%s", fatalErrorStr); 51 | throw std::overflow_error(fatalErrorStr); 52 | } 53 | BULLSEYE_EXCLUDE_BLOCK_END 54 | } 55 | msg_pool_list.push_front(pool); 56 | this->first_time = false; 57 | return true; 58 | } 59 | 60 | Msg* MsgPools::get_msg_from_pool(int in_size, int out_size) 61 | { 62 | while (this->first_time == true) { 63 | LOG_DBG("no MsgPools binded in msgPools=%p, invoking callback", this); 64 | Bridge_invoke_requestForBoundMsgPool_callback(this->ctx, in_size, out_size); 65 | 66 | } 67 | BULLSEYE_EXCLUDE_BLOCK_START 68 | //currently all msgPools have the same message sizes 69 | if (this->in_size < in_size) { 70 | char fatalErrorStr[256]; 71 | sprintf(fatalErrorStr, "Can not allocate msg with in=%d, while msgPools [%p] is in=%d. Aborting!!!", in_size, this, this->in_size); 72 | LOG_FATAL("%s", fatalErrorStr); 73 | throw std::overflow_error(fatalErrorStr); 74 | } 75 | BULLSEYE_EXCLUDE_BLOCK_END 76 | while (true) { 77 | list_pools::iterator it = msg_pool_list.begin(); 78 | while (it != msg_pool_list.end()) { 79 | MsgPool* pool = *it; 80 | if (!pool->is_empty()) { 81 | return pool->get_msg_from_pool(); 82 | } 83 | it++; 84 | } 85 | LOG_DBG("there are no more buffers in MsgPools. calling the user to allocate pool with in_size=%d, out_size=%d", in_size, out_size); 86 | Bridge_invoke_requestForBoundMsgPool_callback(this->ctx, in_size, out_size); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/c/src/MsgPools.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #ifndef MsgPools__H___ 18 | #define MsgPools__H___ 19 | 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "Utils.h" 26 | #include "MsgPool.h" 27 | 28 | class Context; 29 | 30 | typedef std::list list_pools; 31 | 32 | class MsgPools { 33 | public: 34 | MsgPools (); 35 | ~MsgPools(); 36 | //returns true if msg was allocated successfully and false otherwise 37 | bool add_msg_pool(MsgPool *p); 38 | Msg * get_msg_from_pool(int in_size, int out_size); 39 | list_pools msg_pool_list; 40 | void setCtx(Context* ctx); 41 | 42 | private: 43 | int in_size; 44 | int out_size; 45 | bool first_time; 46 | Context* ctx; 47 | 48 | }; 49 | 50 | #endif // ! MsgPools__H___ 51 | -------------------------------------------------------------------------------- /src/c/src/ServerPortal.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #ifndef ServerPortal__H___ 19 | #define ServerPortal__H___ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | #include "CallbackFunctionsServer.h" 27 | #include "Events.h" 28 | class Context; 29 | 30 | 31 | class ServerPortal { 32 | public: 33 | //to move some to private? 34 | ServerPortal(const char *url, long ptrCtx); 35 | ~ServerPortal(); 36 | 37 | //this method will return ctx if the event should be written to event queue. Otherwise will return null 38 | Context* ctxForSessionEvent(struct xio_session_event_data * event, 39 | ServerSession* ses); 40 | void deleteObject(); 41 | //this method writes that the portal was closed to the event queue and deletes this 42 | void writeEventAndDelete(bool force_scheduled = false); 43 | void scheduleWriteEventAndDelete(); 44 | void writeEventForwardCompleted(ServerSession* ses); 45 | struct xio_server* server; 46 | bool is_closing; 47 | int sessions; //indicates how many sessions are listening on this server 48 | uint16_t port; //indicates the actual port on which the server listens 49 | bool flag_to_delete; 50 | Context* get_ctx_class() {return ctx_class;} 51 | private: 52 | Context *ctx_class; 53 | }; 54 | 55 | #endif // ! ServerManager 56 | -------------------------------------------------------------------------------- /src/c/src/ServerSession.cc: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #include "ServerSession.h" 19 | #include "Utils.h" 20 | 21 | #define MODULE_NAME "ServerSession" 22 | #define SRVSESSION_LOG_ERR(log_fmt, log_args...) LOG_BY_MODULE(lsERROR, log_fmt, ##log_args) 23 | #define SRVSESSION_LOG_DBG(log_fmt, log_args...) LOG_BY_MODULE(lsDEBUG, log_fmt, ##log_args) 24 | 25 | ServerSession::ServerSession(xio_session * session, ServerPortal* portal, Context * ctx) 26 | { 27 | this->is_closing = false; 28 | this->session = session; 29 | this->forwarder = portal; 30 | this->ctx_forwarder = ctx; 31 | this->delete_after_teardown = false; 32 | this->forward_mode = false; 33 | this->first_conn = NULL; 34 | this->second_conn = NULL; 35 | this->reject_mode = false; 36 | this->forwardee = NULL; 37 | } 38 | 39 | ServerSession::~ServerSession() {} 40 | 41 | bool ServerSession::ignore_disconnect(ServerPortal* portal) 42 | { 43 | if (!forward_mode) { 44 | return false; // in accept mode 45 | } 46 | // in forward mode 47 | if (this->forwardee == portal) 48 | return false; 49 | return true; 50 | } 51 | 52 | struct xio_connection* ServerSession::get_xio_connection() 53 | { 54 | if (forward_mode) 55 | return this->second_conn; 56 | return this->first_conn; 57 | } 58 | 59 | void ServerSession::set_xio_connection(struct xio_connection* con, ServerPortal* portal) 60 | { 61 | if (this->forwarder == portal) 62 | this->first_conn = con; 63 | else 64 | this->second_conn = con; 65 | } 66 | 67 | ServerPortal * ServerSession::get_portal_session_event(void * conn_user_context, struct xio_connection* con, enum xio_session_event event) 68 | { 69 | if (event == XIO_SESSION_TEARDOWN_EVENT) { 70 | if (this->forwardee) 71 | return this->forwardee; 72 | else 73 | return this->forwarder; 74 | } 75 | if (event == XIO_SESSION_NEW_CONNECTION_EVENT) 76 | return (ServerPortal*) conn_user_context; 77 | 78 | if (this->second_conn == con) 79 | return this->forwardee; 80 | else 81 | return this->forwarder; 82 | } 83 | 84 | ServerPortal * ServerSession::get_portal_msg_event() 85 | { 86 | if (forward_mode) 87 | return this->forwardee; 88 | return this->forwarder; 89 | } 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/c/src/ServerSession.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #ifndef ServerSession__H___ 19 | #define ServerSession__H___ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | class Context; 28 | class ServerPortal; 29 | 30 | 31 | class ServerSession { 32 | public: 33 | ServerSession(xio_session * session, ServerPortal* portal, Context * ctx); 34 | ~ServerSession(); 35 | 36 | //inline functions 37 | void set_portal(ServerPortal *p) {this->forwardee = p;} 38 | struct xio_session* get_xio_session() {return session;} 39 | bool get_is_closing() {return is_closing;} 40 | void set_is_closing(bool b) {is_closing = b;} 41 | void set_forward(bool forward) {forward_mode = forward;} 42 | void set_reject() {reject_mode = true;} 43 | bool is_reject() {return reject_mode;} 44 | Context *get_ctx_forwarder() {return ctx_forwarder;} 45 | 46 | //when user chooses to forward the session, connection_disconnected event is received 47 | bool ignore_disconnect(ServerPortal* portal); 48 | //when user chooses to reject the session, the event is not passed to Java, therefore after 49 | //session teardown the ServerSession needs to be deleted 50 | bool delete_after_teardown; 51 | struct xio_connection* get_xio_connection(); 52 | void set_xio_connection(struct xio_connection* con, ServerPortal* portal); 53 | ServerPortal * get_portal_session_event(void * conn_user_context, struct xio_connection* con, enum xio_session_event event); 54 | ServerPortal * get_portal_msg_event(); 55 | private: 56 | struct xio_session* session; 57 | struct xio_connection* first_conn; 58 | struct xio_connection* second_conn; 59 | ServerPortal *forwarder; //or accepter in case of accept 60 | ServerPortal *forwardee; //will be null in case of accept 61 | Context* ctx_forwarder; 62 | bool is_closing; 63 | bool forward_mode; 64 | bool reject_mode; 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/c/src/Utils.cc: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | #include "bullseye.h" 19 | #include "Utils.h" 20 | #include "Bridge.h" 21 | #include 22 | 23 | log_severity_t g_log_threshold = DEFAULT_LOG_THRESHOLD; 24 | log_severity_t g_xio_log_level_to_jxio_severity[XIO_LOG_LEVEL_LAST]; 25 | 26 | void log_set_threshold(log_severity_t threshold) 27 | { 28 | BULLSEYE_EXCLUDE_BLOCK_START 29 | g_log_threshold = (lsNONE <= threshold && threshold <= lsTRACE) ? threshold : DEFAULT_LOG_THRESHOLD; 30 | BULLSEYE_EXCLUDE_BLOCK_END 31 | } 32 | 33 | void log_func(log_severity_t severity, const char *log_fmt, ...) 34 | { 35 | const int SIZE = 2048; 36 | char _str_[SIZE]; 37 | va_list ap; 38 | va_start(ap, log_fmt); 39 | int m = vsnprintf(_str_, SIZE, log_fmt, ap); 40 | va_end(ap); 41 | BULLSEYE_EXCLUDE_BLOCK_START 42 | if (m < 0) { 43 | return; /*error*/ 44 | } 45 | BULLSEYE_EXCLUDE_BLOCK_END 46 | _str_[SIZE-1] = '\0'; 47 | Bridge_invoke_logToJava_callback(severity, _str_); 48 | } 49 | 50 | void logs_from_xio_callback(const char *file, unsigned line, const char *func, unsigned level, const char *log_fmt, ...) 51 | { 52 | log_severity_t severity = g_xio_log_level_to_jxio_severity[level]; 53 | if (severity > g_log_threshold) 54 | return; 55 | 56 | const int SIZE = 2048; 57 | char _str_[SIZE]; 58 | int n = snprintf(_str_, SIZE, MODULE_FILE_INFO, file, line, func); 59 | BULLSEYE_EXCLUDE_BLOCK_START 60 | if (n < 0) { 61 | return; /*error*/ 62 | } 63 | if (n < SIZE) { 64 | va_list ap; 65 | va_start(ap, log_fmt); 66 | int m = vsnprintf(_str_ + n, SIZE - n, log_fmt, ap); 67 | va_end(ap); 68 | if (m < 0) { 69 | return; /*error*/ 70 | } 71 | } 72 | BULLSEYE_EXCLUDE_BLOCK_END 73 | _str_[SIZE - 1] = '\0'; 74 | Bridge_invoke_logToJava_callback(severity, _str_); 75 | } 76 | 77 | void logs_from_xio_callback_register() 78 | { 79 | // init log level/severity conversion table 80 | g_xio_log_level_to_jxio_severity[XIO_LOG_LEVEL_FATAL] = lsFATAL; 81 | g_xio_log_level_to_jxio_severity[XIO_LOG_LEVEL_ERROR] = lsERROR; 82 | g_xio_log_level_to_jxio_severity[XIO_LOG_LEVEL_WARN] = lsWARN; 83 | g_xio_log_level_to_jxio_severity[XIO_LOG_LEVEL_INFO] = lsINFO; 84 | g_xio_log_level_to_jxio_severity[XIO_LOG_LEVEL_DEBUG] = lsDEBUG; 85 | g_xio_log_level_to_jxio_severity[XIO_LOG_LEVEL_TRACE] = lsTRACE; 86 | 87 | int optlen = sizeof(xio_log_fn); 88 | const void* optval = (const void *)logs_from_xio_callback; 89 | xio_set_opt(NULL, XIO_OPTLEVEL_ACCELIO, XIO_OPTNAME_LOG_FN, optval, optlen); 90 | } 91 | 92 | #if _BullseyeCoverage 93 | #pragma BullseyeCoverage off 94 | #endif 95 | void logs_from_xio_callback_unregister() 96 | { 97 | xio_set_opt(NULL, XIO_OPTLEVEL_ACCELIO, XIO_OPTNAME_LOG_FN, NULL, 0); 98 | } 99 | #if _BullseyeCoverage 100 | #pragma BullseyeCoverage on 101 | #endif 102 | 103 | void logs_from_xio_set_threshold(log_severity_t threshold) 104 | { 105 | int xio_log_level = XIO_LOG_LEVEL_INFO; 106 | 107 | switch (threshold) { 108 | case lsFATAL: xio_log_level = XIO_LOG_LEVEL_FATAL; break; 109 | case lsERROR: xio_log_level = XIO_LOG_LEVEL_ERROR; break; 110 | case lsWARN: xio_log_level = XIO_LOG_LEVEL_WARN; break; 111 | case lsDEBUG: xio_log_level = XIO_LOG_LEVEL_DEBUG; break; 112 | case lsTRACE: xio_log_level = XIO_LOG_LEVEL_TRACE; break; 113 | 114 | case lsINFO: 115 | default: 116 | xio_log_level = XIO_LOG_LEVEL_INFO; break; 117 | } 118 | xio_set_opt(NULL, XIO_OPTLEVEL_ACCELIO, XIO_OPTNAME_LOG_LEVEL, &xio_log_level, sizeof(enum xio_log_level)); 119 | } 120 | 121 | bool close_xio_connection(ServerSession* jxio_session) 122 | { 123 | struct xio_session *session = jxio_session->get_xio_session(); 124 | struct xio_connection *con = jxio_session->get_xio_connection(); 125 | if (!con) 126 | { 127 | LOG_DBG("ERROR, con is null for jxio_session %p xio_session %p", jxio_session, session); 128 | return false; 129 | } 130 | LOG_DBG("closing connection %p for xio_session=%p, jxio_session=%p", con, session, jxio_session); 131 | BULLSEYE_EXCLUDE_BLOCK_START 132 | if (xio_disconnect(con)) { 133 | LOG_DBG("ERROR, xio_disconnect failed with error '%s' (%d) (xio_session=%p, conn=%p, jxio_session=%p)", 134 | xio_strerror(xio_errno()), xio_errno(), session, con, jxio_session); 135 | return false; 136 | } 137 | BULLSEYE_EXCLUDE_BLOCK_END 138 | LOG_DBG("successfully closed connection=%p, for xio_session=%p, jxio_session=%p", con, session, jxio_session); 139 | return true; 140 | } 141 | 142 | bool forward_session(ServerSession* jxio_session, const char * url) 143 | { 144 | struct xio_session *xio_session = jxio_session->get_xio_session(); 145 | 146 | jxio_session->set_forward(true); 147 | int retVal = xio_accept(xio_session, &url, 1, NULL, 0); 148 | BULLSEYE_EXCLUDE_BLOCK_START 149 | if (retVal) { 150 | LOG_ERR("ERROR forwarding session=%p. error '%s' (%d)", xio_session, xio_strerror(xio_errno()), xio_errno()); 151 | jxio_session->set_forward(false); 152 | return false; 153 | } 154 | BULLSEYE_EXCLUDE_BLOCK_END 155 | return true; 156 | } 157 | 158 | bool accept_session(ServerSession* jxio_session) 159 | { 160 | struct xio_session *xio_session = jxio_session->get_xio_session(); 161 | 162 | int retVal = xio_accept(xio_session, NULL, 0, NULL, 0); 163 | BULLSEYE_EXCLUDE_BLOCK_START 164 | if (retVal) { 165 | LOG_ERR("ERROR accepting session=%p. error '%s' (%d)", xio_session, xio_strerror(xio_errno()), xio_errno()); 166 | return false; 167 | } 168 | BULLSEYE_EXCLUDE_BLOCK_END 169 | return true; 170 | } 171 | 172 | 173 | bool reject_session(ServerSession* jxio_session, int reason, 174 | char *user_context, size_t user_context_len) 175 | { 176 | struct xio_session *xio_session = jxio_session->get_xio_session(); 177 | jxio_session->set_reject(); 178 | LOG_DBG("before reject xio_session=%p. reason is %s (%d)", xio_session, xio_strerror(reason), reason); 179 | 180 | int retVal = xio_reject(xio_session, (enum xio_status)reason, user_context, user_context_len); 181 | BULLSEYE_EXCLUDE_BLOCK_START 182 | if (retVal) { 183 | LOG_DBG("ERROR, rejecting session=%p. error '%s' (%d)",xio_session, xio_strerror(xio_errno()), xio_errno()); 184 | return false; 185 | } 186 | BULLSEYE_EXCLUDE_BLOCK_END 187 | jxio_session->delete_after_teardown = true; 188 | return true; 189 | } 190 | -------------------------------------------------------------------------------- /src/c/src/Utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | #ifndef Utils__H___ 18 | #define Utils__H___ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include //ok 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include // for backtrace 33 | #include 34 | #include "ServerSession.h" 35 | 36 | #define LOG_FATAL(log_fmt, log_args...) LOG_BY_FILE(lsFATAL, log_fmt, ##log_args) 37 | #define LOG_ERR(log_fmt, log_args...) LOG_BY_FILE(lsERROR, log_fmt, ##log_args) 38 | #define LOG_WARN(log_fmt, log_args...) LOG_BY_FILE(lsWARN, log_fmt, ##log_args) 39 | #define LOG_INFO(log_fmt, log_args...) LOG_BY_FILE(lsINFO, log_fmt, ##log_args) 40 | #define LOG_DBG(log_fmt, log_args...) LOG_BY_FILE(lsDEBUG, log_fmt, ##log_args) 41 | #define LOG_TRACE(log_fmt, log_args...) LOG_BY_FILE(lsTRACE, log_fmt, ##log_args) 42 | 43 | 44 | 45 | #define MODULE_INFO this 46 | #define MODULE_HDR_INFO MODULE_NAME "[%p]:%d:%s() " 47 | #define MODULE_FILE_INFO "%s:%d:%s() " 48 | 49 | // THE 'log()' macros that should be used everywhere... 50 | #define LOG_BY_MODULE(severity, log_fmt, log_args...) do { if (severity <= g_log_threshold) log_func(severity, MODULE_HDR_INFO log_fmt "\n", MODULE_INFO, __LINE__, __FUNCTION__, ##log_args);} while(0) 51 | #define LOG_BY_FILE(severity, log_fmt, log_args...) do { if (severity <= g_log_threshold) log_func(severity, MODULE_FILE_INFO log_fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##log_args);} while(0) 52 | 53 | 54 | enum log_severity_t { 55 | lsNONE, 56 | lsFATAL, 57 | lsERROR, 58 | lsWARN, 59 | lsINFO, 60 | lsDEBUG, 61 | lsTRACE, 62 | }; 63 | 64 | 65 | extern log_severity_t g_log_threshold; 66 | const log_severity_t DEFAULT_LOG_THRESHOLD = lsINFO; 67 | 68 | void log_set_threshold(log_severity_t _threshold); 69 | 70 | void log_func(log_severity_t severity, const char *log_fmt, ...); 71 | 72 | // helper functions to setup log collection from AccelIO into JXIO's logging 73 | void logs_from_xio_callback_register(); 74 | void logs_from_xio_callback_unregister(); 75 | void logs_from_xio_set_threshold(log_severity_t threshold); 76 | 77 | bool close_xio_connection(ServerSession* jxio_session); 78 | bool forward_session(ServerSession* jxio_session, const char * url); 79 | bool accept_session(ServerSession* jxio_session); 80 | bool reject_session(ServerSession* jxio_session, int reason, char *user_context, size_t user_context_len); 81 | 82 | #endif // ! Utils__H___ 83 | -------------------------------------------------------------------------------- /src/c/src/bullseye.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | /* 19 | * Bullseye Coverage Definitions 20 | */ 21 | #ifndef BULLSEYE_H_ 22 | #define BULLSEYE_H_ 23 | 24 | #if _BullseyeCoverage 25 | #define BULLSEYE_EXCLUDE_BLOCK_START "BullseyeCoverage save off"; 26 | #define BULLSEYE_EXCLUDE_BLOCK_END "BullseyeCoverage restore"; 27 | #else 28 | #define BULLSEYE_EXCLUDE_BLOCK_START 29 | #define BULLSEYE_EXCLUDE_BLOCK_END 30 | #endif 31 | 32 | 33 | #endif /* BULLSEYE_H_ */ 34 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/EventName.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | package org.accelio.jxio; 19 | 20 | import org.accelio.jxio.EventName; 21 | 22 | /** 23 | * SessionEvents that are received by ClientSession, ServerSession and ServerPortal 24 | * 25 | */ 26 | public enum EventName { 27 | /** 28 | * SESSION_REJECT is received by ClientSession in case the server chose to reject the session 29 | */ 30 | SESSION_REJECT(0), 31 | 32 | /** 33 | * SESSION_CLOSED received by ClientSession or ServerSession. This event is received after session was properly 34 | * closed (close method is asynchronous). This event is received if either of the sides initiated the close 35 | * or if there is internal error on either of the sides 36 | */ 37 | SESSION_CLOSED(1), 38 | 39 | /** 40 | * PORTAL_CLOSED is received by ServerPortal. In case the user initiated close 41 | * of ServerPortal when there are still ServerSessions that are listening on him, all those ServerSessions are 42 | * closed. When all ServerSessions are closed, PORTAL_CLOSED event is received. 43 | */ 44 | PORTAL_CLOSED(2), 45 | 46 | /** 47 | * SESSION_ERROR is received by ClientSession, ServerSession and ServerPortal. 48 | */ 49 | SESSION_ERROR(3); 50 | 51 | private int index; 52 | 53 | private EventName(int i) { 54 | index = i; 55 | } 56 | 57 | private static EventName[] allEvents = values(); 58 | 59 | public static EventName getEventByIndex(int index) { 60 | return allEvents[index]; 61 | } 62 | } -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/WorkerCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio; 18 | 19 | import java.util.HashMap; 20 | import java.util.LinkedList; 21 | 22 | import org.apache.commons.logging.Log; 23 | import org.apache.commons.logging.LogFactory; 24 | import org.apache.lucene.facet.taxonomy.LRUHashMap; 25 | 26 | /** 27 | * For faster connection establish time 28 | * 29 | */ 30 | public class WorkerCache { 31 | public static final String CACHE_TAG = "cacheId"; 32 | private final int MAX_ENTRY_WORKERS = 5; 33 | private final int MAX_HASH = 1000; 34 | private final static Log LOG = LogFactory.getLog(WorkerCache.class.getCanonicalName()); 35 | private HashMap> workersCache = new LRUHashMap>(MAX_HASH); 36 | private WorkerProvider wp; 37 | 38 | 39 | /** 40 | * The worker provider is used by the cache to get a new worker when no free worker is found 41 | */ 42 | public interface WorkerProvider { 43 | /** 44 | * @return free worker that client connection can be forwarded to 45 | */ 46 | public Worker getWorker(); 47 | } 48 | 49 | /** 50 | * Each server portal worker that will be in the cache should implement this interface. 51 | */ 52 | public interface Worker { 53 | /** 54 | * Indicate if the server worker is free and the cache can pass it as an hint. 55 | * @return true if this worker is free, false otherwise. 56 | */ 57 | public boolean isFree(); 58 | } 59 | 60 | /** 61 | * The worker provider is used by the cache to get a new worker when there's no free 62 | * worker from previous connections 63 | * @param wp - provides new workers when no free workers are found. 64 | */ 65 | public WorkerCache(WorkerProvider wp) { 66 | this.wp = wp; 67 | } 68 | 69 | Worker getCachedWorker(String clientId) { 70 | Worker w; 71 | LinkedList clientWorkers = workersCache.get(clientId); 72 | // first time this client connects or wasn't connected for a long time and was removed by LRU 73 | if (clientWorkers == null) { 74 | if (LOG.isDebugEnabled()) 75 | LOG.debug("client id " + clientId + " wasn't found in hash"); 76 | w = wp.getWorker(); 77 | if (w != null) { 78 | LinkedList list = new LinkedList(); 79 | list.add(w); 80 | workersCache.put(clientId, list); 81 | } 82 | return w; 83 | } 84 | // look for free worker in client's previously connected workers 85 | int pos = 0; 86 | while (pos < clientWorkers.size()) { 87 | w = clientWorkers.get(pos); 88 | if (w.isFree()) { 89 | if (LOG.isDebugEnabled()) 90 | LOG.debug("found free worker" + w + " for client id " + clientId); 91 | clientWorkers.remove(pos); 92 | clientWorkers.addFirst(w); 93 | return w; 94 | } 95 | pos++; 96 | } 97 | // no free workers to use from previously connected, get a new one 98 | w = wp.getWorker(); 99 | if (w != null) { 100 | clientWorkers.addFirst(w); 101 | if (clientWorkers.size() > MAX_ENTRY_WORKERS) { 102 | clientWorkers.removeLast(); 103 | } 104 | } 105 | return w; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/exceptions/JxioGeneralException.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.exceptions; 18 | 19 | import java.io.IOException; 20 | 21 | import org.accelio.jxio.EventReason; 22 | 23 | @SuppressWarnings("serial") 24 | public class JxioGeneralException extends IOException { 25 | EventReason reason; 26 | String s; 27 | 28 | public JxioGeneralException(int reason, String methodName) { 29 | this.reason = EventReason.getEventByXioIndex(reason); 30 | formatString(methodName); 31 | } 32 | 33 | public JxioGeneralException(EventReason reason, String methodName) { 34 | this.reason = reason; 35 | formatString(methodName); 36 | } 37 | 38 | public EventReason getReason() { 39 | return reason; 40 | } 41 | 42 | public String toString() { 43 | return this.s; 44 | } 45 | 46 | private void formatString(String methodName) { 47 | this.s = "Got exception '" + this.reason.toString() + "' while calling '" + methodName + "'"; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/exceptions/JxioQueueOverflowException.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.exceptions; 18 | 19 | import java.io.IOException; 20 | 21 | @SuppressWarnings("serial") 22 | public class JxioQueueOverflowException extends IOException { 23 | String s; 24 | 25 | public JxioQueueOverflowException(String methodName) { 26 | this.s = "A queue overflow occurred. " + methodName + " failed"; 27 | } 28 | 29 | public String toString() { 30 | return this.s; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/exceptions/JxioSessionClosedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.exceptions; 18 | 19 | import java.io.IOException; 20 | 21 | @SuppressWarnings("serial") 22 | public class JxioSessionClosedException extends IOException { 23 | String s; 24 | 25 | public JxioSessionClosedException(String methodName) { 26 | this.s = "Session is already closed. " + methodName + " failed"; 27 | } 28 | 29 | public String toString() { 30 | return this.s; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/ElapsedTimeMeasurement.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.impl; 18 | 19 | public class ElapsedTimeMeasurement { 20 | 21 | private long startTimeNano = 0; 22 | 23 | public ElapsedTimeMeasurement() { 24 | resetStartTime(); 25 | } 26 | 27 | public long getNowNano() { 28 | return System.nanoTime(); 29 | } 30 | 31 | public void resetStartTime() { 32 | startTimeNano = getNowNano(); 33 | } 34 | 35 | public boolean isTimeOutNano(long durationTimeNano) { 36 | return (durationTimeNano < getElapsedTimeNano()); 37 | } 38 | 39 | public boolean isTimeOutMicro(long durationTimeMicro) { 40 | return (durationTimeMicro < getElapsedTimeMicro()); 41 | } 42 | 43 | public boolean isTimeOutMilli(long durationTimeMilli) { 44 | return (durationTimeMilli < getElapsedTimeMilli()); 45 | } 46 | 47 | public long getElapsedTimeNano() { 48 | return getNowNano() - startTimeNano; 49 | } 50 | 51 | public long getElapsedTimeMicro() { 52 | return getElapsedTimeNano()/1000L; 53 | } 54 | 55 | public long getElapsedTimeMilli() { 56 | return getElapsedTimeNano()/1000000L; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/Event.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.impl; 18 | 19 | public class Event { 20 | 21 | private int eventType; 22 | private long id; 23 | 24 | Event(int eventType, long id) { 25 | this.eventType = eventType; 26 | this.id = id; 27 | } 28 | 29 | public int getEventType() {return eventType;} 30 | public long getId() {return id;} 31 | } 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/EventMsgError.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.impl; 18 | 19 | import org.accelio.jxio.Msg; 20 | 21 | import org.accelio.jxio.impl.Event; 22 | 23 | public class EventMsgError extends Event { 24 | 25 | private int reason; 26 | private Msg msg; 27 | 28 | public EventMsgError(int eventType, long id, Msg msg, int reason) { 29 | super(eventType, id); 30 | this.reason = reason; 31 | this.msg = msg; 32 | } 33 | 34 | public int getReason() { 35 | return reason; 36 | } 37 | 38 | public Msg getMsg() { 39 | return msg; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/EventNameImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | 18 | package org.accelio.jxio.impl; 19 | 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | 26 | /** 27 | * SessionEvents that are received by ClientSession, ServerSession and ServerPortal 28 | * 29 | */ 30 | public enum EventNameImpl { 31 | /** 32 | * SESSION_REJECT is received by ClientSession in case the server chose to reject the session 33 | */ 34 | SESSION_REJECT(0, 0), 35 | 36 | /** 37 | * SESSION_CLOSED received by ClientSession or ServerSession. 38 | * This event is received after session was properly 39 | * closed (close method is asynchronous). This event is received if either of the sides initiated the close 40 | * or if there is internal error on either of the sides. Matches connection teardown in Accelio 41 | */ 42 | SESSION_CLOSED(4, 1), 43 | 44 | /** 45 | * PORTAL_CLOSED is received by ServerPortal. In case the user initiated close 46 | * of ServerPortal when there are still ServerSessions that are listening on him, all those ServerSessions are 47 | * closed. When all ServerSessions are closed, PORTAL_CLOSED event is received. 48 | */ 49 | PORTAL_CLOSED(2, 2), 50 | 51 | /** 52 | * SESSION_ERROR is received by ClientSession, ServerSession and ServerPortal. 53 | */ 54 | SESSION_ERROR(9, 3), 55 | 56 | /** 57 | * Session TEARDOWN is an internal event 58 | */ 59 | SESSION_TEARDOWN(1, 4), 60 | 61 | /** 62 | * CONNECTION_CLOSED/DISCONNECTED/REFUSED are internal event indicating start of XIO_SESSION_CONNECTION_CLOSED/DISCONNECTED/REFUSED 63 | */ 64 | CONNECTION_CLOSED(5, 5), 65 | CONNECTION_DISCONNECTED(6, 6), 66 | CONNECTION_REFUSED(7, 7), 67 | 68 | /** Internal event indicating that forward was completed for the forwarder 69 | */ 70 | FORWARD_COMPLETED(10, 10), 71 | /** 72 | * Unknown event 73 | */ 74 | UNKNOWN_EVENT(11, -1); 75 | 76 | private int xioIndex; 77 | private int publishedIndex; 78 | 79 | private static final Log LOG = LogFactory.getLog(EventNameImpl.class.getCanonicalName()); 80 | 81 | private static final Map intToTypeMap = new HashMap(); 82 | static { 83 | for (EventNameImpl eventNameImpl : EventNameImpl.values()) { 84 | intToTypeMap.put(eventNameImpl.xioIndex, eventNameImpl); 85 | } 86 | } 87 | 88 | private EventNameImpl(int xioIndex, int publishedIndex) { 89 | this.xioIndex = xioIndex; 90 | this.publishedIndex = publishedIndex; 91 | } 92 | 93 | public int getPublishedIndex() { 94 | return publishedIndex; 95 | } 96 | 97 | public static EventNameImpl getEventByIndex(int xioIndex) { 98 | EventNameImpl eventNameImpl = intToTypeMap.get(Integer.valueOf(xioIndex)); 99 | if (eventNameImpl == null) { 100 | LOG.warn("Unmapped XIO event index = '" + xioIndex + "'. Returning with UNKNOWN_EVENT"); 101 | return EventNameImpl.UNKNOWN_EVENT; 102 | } 103 | return eventNameImpl; 104 | } 105 | } -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/EventNewMsg.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.impl; 18 | 19 | import org.accelio.jxio.Msg; 20 | 21 | import org.accelio.jxio.impl.Event; 22 | 23 | public class EventNewMsg extends Event { 24 | private Msg msg; 25 | 26 | public EventNewMsg(int eventType, long id, Msg msg) { 27 | super(eventType, id); 28 | this.msg = msg; 29 | } 30 | 31 | public Msg getMsg() { 32 | return msg; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/EventNewSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.impl; 18 | 19 | import org.accelio.jxio.impl.Event; 20 | 21 | public class EventNewSession extends Event { 22 | private long ptrSes; 23 | private String uri; 24 | private String srcIP; 25 | 26 | public EventNewSession(int eventType, long id, long ptr, String uri, String ip) { 27 | super(eventType, id); 28 | this.ptrSes = ptr; 29 | this.uri = uri; 30 | this.srcIP = ip; 31 | } 32 | 33 | public long getPtrSes() { 34 | return ptrSes; 35 | } 36 | 37 | public String getUri() { 38 | return uri; 39 | } 40 | 41 | public String getSrcIP() { 42 | return srcIP; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/EventSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.impl; 18 | 19 | import org.accelio.jxio.impl.Event; 20 | 21 | public class EventSession extends Event { 22 | private int errorType; 23 | private int reason; 24 | 25 | public EventSession(int eventType, long id, int error, int r) { 26 | super(eventType, id); 27 | this.errorType = error; 28 | this.reason = r; 29 | } 30 | 31 | public int getErrorType() { 32 | return errorType; 33 | } 34 | 35 | public int getReason() { 36 | return reason; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/EventSessionEstablished.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.impl; 18 | 19 | import org.accelio.jxio.impl.Event; 20 | 21 | public class EventSessionEstablished extends Event { 22 | public EventSessionEstablished(int eventType, long id) { 23 | super(eventType, id); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/impl/LoadLibrary.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.impl; 18 | 19 | import java.io.Closeable; 20 | import java.io.File; 21 | import java.io.FileOutputStream; 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.io.OutputStream; 25 | import java.net.URL; 26 | 27 | public class LoadLibrary { 28 | 29 | /** 30 | * Tries to load the library, by extracting it from the current class jar. If that fails, falls back on 31 | * {@link System#loadLibrary(String)}. 32 | * 33 | * @param String to the library name to be extracted and loaded from the this current jar 34 | * @return true if the the file loaded successfully, or false on error 35 | */ 36 | public static boolean loadLibrary(String resourceName) { 37 | ClassLoader loader = LoadLibrary.class.getClassLoader(); 38 | URL url = loader.getResource(resourceName); 39 | File file = null; 40 | try { 41 | file = extractResource(url); 42 | } catch (IOException e) { 43 | e.printStackTrace(); 44 | System.err.println("JXIO: Native code library failed to extract URL\n" + e); 45 | return false; 46 | } 47 | 48 | if (file != null && file.exists()) { 49 | String filename = file.getAbsolutePath(); 50 | try { 51 | System.load(filename); 52 | } catch (UnsatisfiedLinkError e) { 53 | e.printStackTrace(); 54 | System.err.println("JXIO: Native code library failed to load\n" + e); 55 | return false; 56 | } 57 | if (file.delete() == false) { 58 | System.err.println("JXIO: Error deleting the temp native code library (filename='" + filename + "')\n"); 59 | } 60 | } 61 | return true; 62 | } 63 | 64 | /** 65 | * Extracts a resource into a temp directory. 66 | * 67 | * @param resourceURL the URL of the resource to extract 68 | * @return the File object representing the extracted file 69 | * @throws IOException if fails to extract resource properly 70 | */ 71 | public static File extractResource(URL resourceURL) throws IOException { 72 | InputStream is = resourceURL.openStream(); 73 | if (is == null) { 74 | return null; 75 | } 76 | File file = new File(getTempDir(), new File(resourceURL.getPath()).getName()); 77 | FileOutputStream os = null; 78 | try { 79 | os = new FileOutputStream(file); 80 | copy(is, os); 81 | } finally { 82 | closeQuietly(os); 83 | closeQuietly(is); 84 | } 85 | return file; 86 | } 87 | 88 | /** Temporary directory set and returned by {@link #getTempDir()}. */ 89 | static File tempDir = null; 90 | 91 | /** 92 | * Creates a unique name for {@link #tempDir} out of {@code System.getProperty("java.io.tmpdir")} and 93 | * {@code System.nanoTime()}. 94 | * 95 | * @return {@link #tempDir} 96 | */ 97 | public static File getTempDir() { 98 | if (tempDir == null) { 99 | File tmpdir = new File(System.getProperty("java.io.tmpdir")); 100 | File f = null; 101 | for (int i = 0; i < 1000; i++) { 102 | f = new File(tmpdir, "jxio" + System.nanoTime()); 103 | if (f.mkdir()) { 104 | tempDir = f; 105 | tempDir.deleteOnExit(); 106 | break; 107 | } 108 | } 109 | } 110 | return tempDir; 111 | } 112 | 113 | /** 114 | * Helper function to copy an InputStream into an OutputStream 115 | */ 116 | public static long copy(InputStream is, OutputStream os) throws IOException { 117 | if (is == null || os == null) 118 | return 0; 119 | long length_total = 0; 120 | byte[] buffer = new byte[1024]; 121 | int length = 0; 122 | while ((length = is.read(buffer)) != -1) { 123 | os.write(buffer, 0, length); 124 | length_total += length; 125 | } 126 | return length_total; 127 | } 128 | 129 | /** 130 | * Helper function to close InputStream or OutputStream in a quiet way which hides the exceptions 131 | */ 132 | public static void closeQuietly(Closeable c) { 133 | if (c == null) 134 | return; 135 | try { 136 | c.close(); 137 | } catch (IOException e) { 138 | // No logging in this 'Quite Close' method 139 | // System.err.println("JXIO: Failed to close '" + c + "'\n"); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/jxioConnection/Constants.java: -------------------------------------------------------------------------------- 1 | package org.accelio.jxio.jxioConnection; 2 | 3 | public class Constants { 4 | public static final int MSGPOOL_BUF_SIZE = 64 * 1024; 5 | public static final int CLIENT_INPUT_BUF_COUNT = 100; 6 | public static final int CLIENT_OUTPUT_BUF_COUNT = 100; 7 | public static final int SERVER_INITIAL_BUF_COUNT = 500; 8 | public static final int SERVER_INC_BUF_COUNT = 100; 9 | } 10 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/jxioConnection/JxioConnectionServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.jxioConnection; 18 | 19 | import java.io.InputStream; 20 | import java.io.OutputStream; 21 | import java.net.URI; 22 | import java.net.URISyntaxException; 23 | import java.util.Iterator; 24 | import java.util.concurrent.ConcurrentLinkedQueue; 25 | 26 | import org.apache.commons.logging.Log; 27 | import org.apache.commons.logging.LogFactory; 28 | 29 | import org.accelio.jxio.EventName; 30 | import org.accelio.jxio.EventReason; 31 | import org.accelio.jxio.EventQueueHandler; 32 | import org.accelio.jxio.ServerPortal; 33 | import org.accelio.jxio.ServerSession; 34 | import org.accelio.jxio.ServerSession.SessionKey; 35 | import org.accelio.jxio.WorkerCache.Worker; 36 | import org.accelio.jxio.WorkerCache.WorkerProvider; 37 | import org.accelio.jxio.jxioConnection.JxioConnectionServer; 38 | import org.accelio.jxio.jxioConnection.impl.JxioResourceManager; 39 | import org.accelio.jxio.jxioConnection.impl.ServerWorker; 40 | 41 | public class JxioConnectionServer extends Thread implements WorkerProvider { 42 | private static final Log LOG = LogFactory.getLog(JxioConnectionServer.class 43 | .getCanonicalName()); 44 | private final String name; 45 | private final EventQueueHandler listen_eqh; 46 | private final ServerPortal listener; 47 | private final JxioConnectionServer.Callbacks appCallbacks; 48 | private int numOfWorkers; 49 | private boolean close = false; 50 | private static ConcurrentLinkedQueue SPWorkers = new ConcurrentLinkedQueue(); 51 | 52 | /** 53 | * Ctor that receives from user number of messages to use in the jxio msgpool 54 | * 55 | * @param uri 56 | * @param numWorkers 57 | * - number of worker threads to start with (this number will grow on demand 58 | * @param appCallbacks 59 | * - application callbacks - what to do on new session event 60 | * @param msgPoolCount 61 | * - actual amount of messages that will be used is msgPoolCount - numMsgsToAdd 62 | */ 63 | public JxioConnectionServer(URI uri, int numWorkers, JxioConnectionServer.Callbacks appCallbacks) { 64 | this.appCallbacks = appCallbacks; 65 | numOfWorkers = numWorkers; 66 | listen_eqh = new EventQueueHandler(null); 67 | listener = new ServerPortal(listen_eqh, uri, new PortalServerCallbacks(), this); 68 | name = "[JxioConnectionServer " + listener.toString() + " ]"; 69 | for (int i = 1; i <= numWorkers; i++) { 70 | SPWorkers.add(new ServerWorker(i, listener.getUriForServer(), appCallbacks)); 71 | } 72 | LOG.info(this.toString() + " JxioConnectionServer started, host " + uri.getHost() + " listening on port " 73 | + uri.getPort() + ", numWorkers " + numWorkers); 74 | } 75 | 76 | /** 77 | * Thread entry point when running as a new thread 78 | */ 79 | public void run() { 80 | work(); 81 | listen_eqh.close(); 82 | LOG.info("server done"); 83 | } 84 | 85 | /** 86 | * Entry point when running on the user thread 87 | */ 88 | public void work() { 89 | for (ServerWorker worker : SPWorkers) { 90 | worker.start(); 91 | } 92 | listen_eqh.run(); 93 | } 94 | 95 | /** 96 | * Callbacks for the listener server portal 97 | */ 98 | public class PortalServerCallbacks implements ServerPortal.Callbacks { 99 | 100 | public void onSessionEvent(EventName event, EventReason reason) { 101 | LOG.info(JxioConnectionServer.this.toString() + " GOT EVENT " + event.toString() + "because of " 102 | + reason.toString()); 103 | } 104 | 105 | public void onSessionNew(SessionKey sesKey, String srcIP, Worker workerHint) { 106 | if (close) { 107 | LOG.info(JxioConnectionServer.this.toString() + "Rejecting session"); 108 | listener.reject(sesKey, EventReason.CONNECT_ERROR, "Server is closed"); 109 | return; 110 | } 111 | ServerWorker spw; 112 | if (workerHint == null) { 113 | listener.reject(sesKey, EventReason.CONNECT_ERROR, "No availabe worker was found in cache"); 114 | return; 115 | } else { 116 | spw = (ServerWorker) workerHint; 117 | } 118 | // add last 119 | SPWorkers.remove(spw); 120 | SPWorkers.add(spw); 121 | LOG.info(JxioConnectionServer.this.toString() + " Server worker number " + spw.portalIndex 122 | + " got new session"); 123 | forwardnewSession(sesKey, spw); 124 | } 125 | } 126 | 127 | public String toString() { 128 | return this.name; 129 | } 130 | 131 | /** 132 | * 133 | * The object that implements this interface needs to be a thread 134 | */ 135 | public static interface Callbacks { 136 | public void newSessionOS(URI uri, OutputStream out); 137 | 138 | public void newSessionIS(URI uri, InputStream in); 139 | } 140 | 141 | /** 142 | * Disconnect the server and all worker threads, This can't be undone 143 | */ 144 | public void disconnect() { 145 | if (close) 146 | return; 147 | 148 | close = true; 149 | for (Iterator it = SPWorkers.iterator(); it.hasNext();) { 150 | it.next().disconnect(); 151 | } 152 | listen_eqh.stop(); 153 | } 154 | 155 | @Override 156 | public Worker getWorker() { 157 | for (Worker w : SPWorkers) { 158 | if (w.isFree()) { 159 | return w; 160 | } 161 | } 162 | return createNewWorker(); 163 | } 164 | 165 | private void forwardnewSession(SessionKey ses, ServerWorker s) { 166 | ServerSession session = new ServerSession(ses, s.getSessionCallbacks()); 167 | URI uri; 168 | try { 169 | uri = new URI(ses.getUri()); 170 | s.prepareSession(session, uri); 171 | listener.forward(s.getPortal(), session); 172 | } catch (URISyntaxException e) { 173 | LOG.fatal("URI could not be parsed"); 174 | } 175 | } 176 | 177 | private ServerWorker createNewWorker() { 178 | LOG.info(this.toString() + " Creating new worker"); 179 | numOfWorkers++; 180 | ServerWorker spw = new ServerWorker(numOfWorkers, listener.getUriForServer(), appCallbacks); 181 | spw.start(); 182 | return spw; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/jxioConnection/impl/BufferManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.jxioConnection.impl; 18 | 19 | import java.io.IOException; 20 | import java.nio.ByteBuffer; 21 | 22 | public interface BufferManager { 23 | 24 | void flush(); 25 | 26 | void close(); 27 | 28 | ByteBuffer getNextBuffer() throws IOException; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/jxioConnection/impl/BufferSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.jxioConnection.impl; 18 | 19 | import java.io.IOException; 20 | import java.nio.ByteBuffer; 21 | 22 | public interface BufferSupplier { 23 | 24 | ByteBuffer getNextBuffer() throws IOException; 25 | void flush(); 26 | } 27 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/jxioConnection/impl/JxioResourceManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.jxioConnection.impl; 18 | 19 | import java.util.HashMap; 20 | import java.util.Iterator; 21 | import java.util.LinkedList; 22 | import java.util.Map; 23 | import java.util.concurrent.ConcurrentLinkedQueue; 24 | import java.util.concurrent.ExecutorService; 25 | import java.util.concurrent.Executors; 26 | import java.util.concurrent.ThreadFactory; 27 | 28 | import org.apache.commons.logging.Log; 29 | import org.apache.commons.logging.LogFactory; 30 | import org.accelio.jxio.EventQueueHandler; 31 | import org.accelio.jxio.Msg; 32 | import org.accelio.jxio.MsgPool; 33 | 34 | public class JxioResourceManager { 35 | 36 | private final static Log LOG = LogFactory.getLog(JxioResourceManager.class 37 | .getCanonicalName()); 38 | private static HashMap> msgPools = new HashMap>(); 39 | private static ConcurrentLinkedQueue eqhs = new ConcurrentLinkedQueue(); 40 | private static ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() { 41 | public Thread newThread(Runnable r) { 42 | Thread t = new Thread(r); 43 | t.setDaemon(true); 44 | return t; 45 | } 46 | }); 47 | 48 | static { 49 | Runtime.getRuntime().addShutdownHook(new Thread() { 50 | @Override 51 | public void run() { 52 | cleanCache(); 53 | } 54 | }); 55 | } 56 | 57 | public static MsgPool getMsgPool(int size, int in, int out) { 58 | MsgPool pool = null; 59 | String key = getMsgPoolKey(size, in, out); 60 | 61 | synchronized (msgPools) { 62 | LinkedList list = msgPools.get(key); 63 | 64 | if (list == null) { 65 | list = new LinkedList(); 66 | msgPools.put(key, list); 67 | pool = new MsgPool(size, in, out); 68 | } else if (list.isEmpty()) { 69 | pool = new MsgPool(size, in, out); 70 | } else { 71 | pool = list.poll(); 72 | } 73 | } 74 | if (LOG.isDebugEnabled()) { 75 | LOG.debug("returning " + pool); 76 | } 77 | return pool; 78 | } 79 | 80 | public static void returnMsgPool(MsgPool pool) { 81 | if (pool == null) { 82 | LOG.error("Returning empty pool"); 83 | return; 84 | } 85 | Msg msg = pool.getMsg(); 86 | int in = msg.getIn().capacity(); 87 | int out = msg.getOut().capacity(); 88 | pool.releaseMsg(msg); 89 | 90 | String key = getMsgPoolKey(pool.capacity(), in, out); 91 | synchronized (msgPools) { 92 | LinkedList list = msgPools.get(key); 93 | if (list == null) { 94 | LOG.error("Returning pool that was not created with ResourceManager"); 95 | return; 96 | } 97 | list.add(pool); 98 | msgPools.put(key, list); 99 | } 100 | } 101 | 102 | public static String getMsgPoolKey(int size, int in, int out) { 103 | return size + "|" + in + "|" + out; 104 | } 105 | 106 | public static EventQueueHandler getEqh() { 107 | EventQueueHandler eqh; 108 | DummyContext ctxThread = eqhs.poll(); 109 | if (ctxThread == null) { 110 | eqh = new EventQueueHandler(null); 111 | } else { 112 | eqh = ctxThread.getEqh(); 113 | } 114 | return eqh; 115 | } 116 | 117 | public static void returnEqh(EventQueueHandler eqh) { 118 | DummyContext dummy = new DummyContext(eqh); 119 | executor.execute(dummy); 120 | eqhs.add(dummy); 121 | } 122 | 123 | private static void cleanCache() { 124 | Iterator>> iterator = msgPools.entrySet().iterator(); 125 | while (iterator.hasNext()) { 126 | Map.Entry> entry = iterator.next(); 127 | LinkedList mps = entry.getValue(); 128 | for (MsgPool mp : mps) { 129 | mp.deleteMsgPool(); 130 | } 131 | } 132 | for (DummyContext ctx : eqhs) { 133 | ctx.getEqh().close(); 134 | } 135 | msgPools.clear(); 136 | eqhs.clear(); 137 | } 138 | 139 | /** 140 | * Thread to keep accelio context alive 141 | */ 142 | private static final class DummyContext implements Runnable { 143 | private EventQueueHandler eqh; 144 | 145 | public DummyContext(EventQueueHandler ctx) { 146 | eqh = ctx; 147 | } 148 | 149 | public void run() { 150 | eqh.runEventLoop(EventQueueHandler.INFINITE_EVENTS, EventQueueHandler.INFINITE_DURATION); 151 | synchronized (eqh) { 152 | eqh.notifyAll(); 153 | } 154 | } 155 | 156 | public EventQueueHandler getEqh() { 157 | synchronized (eqh) { 158 | eqh.breakEventLoop(); 159 | try { 160 | eqh.wait(); 161 | } catch (InterruptedException e) { 162 | LOG.error("eqh cache was interrupted while in wait"); 163 | } 164 | } 165 | return eqh; 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/jxioConnection/impl/MultiBufOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.jxioConnection.impl; 18 | 19 | import java.io.IOException; 20 | import java.io.OutputStream; 21 | import java.nio.ByteBuffer; 22 | 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | 26 | import org.accelio.jxio.jxioConnection.impl.BufferSupplier; 27 | 28 | public class MultiBufOutputStream extends OutputStream { 29 | 30 | private static final Log LOG = LogFactory.getLog(MultiBufOutputStream.class); 31 | private final BufferSupplier supplier; 32 | private ByteBuffer outBuf = null; 33 | private boolean connectionOpen = true; 34 | 35 | public MultiBufOutputStream(BufferSupplier sup) { 36 | supplier = sup; 37 | } 38 | 39 | @Override 40 | public synchronized void write(int b) throws IOException { 41 | byte[] temp = new byte[1]; 42 | write(temp, 0, 1); 43 | } 44 | 45 | @Override 46 | public synchronized void write(byte[] b, int off, int len) throws IOException { 47 | int totalWrite = 0; 48 | int bytesWrite; 49 | 50 | if (!connectionOpen) { 51 | throw new IOException("Stream closed."); 52 | } 53 | if (b == null) { 54 | throw new NullPointerException(); 55 | } 56 | // bounds check 57 | if (len < 0 || off < 0 || off + len > b.length) { 58 | throw new ArrayIndexOutOfBoundsException(); 59 | } 60 | if (outBuf == null) { 61 | outBuf = supplier.getNextBuffer(); 62 | } 63 | while (totalWrite < len) { 64 | // bring new buffer if full 65 | if (!outBuf.hasRemaining()) { 66 | outBuf = supplier.getNextBuffer(); 67 | } 68 | bytesWrite = Math.min(len - totalWrite, outBuf.remaining()); 69 | outBuf.put(b, off, bytesWrite); 70 | totalWrite += bytesWrite; 71 | off += bytesWrite; 72 | } 73 | } 74 | 75 | @Override 76 | public synchronized void flush() throws IOException { 77 | supplier.flush(); 78 | outBuf = null; 79 | } 80 | 81 | @Override 82 | public void close() throws IOException { 83 | if (connectionOpen) { 84 | connectionOpen = false; 85 | flush(); 86 | } 87 | } 88 | 89 | /* 90 | * // FOR TESTING! 91 | * public synchronized long skip(long n) throws IOException { 92 | * long numSkipped = 0; 93 | * long skip; 94 | * 95 | * if (outBuf == null) { 96 | * outBuf = bufManager.getNextBuffer(); 97 | * } 98 | * while (numSkipped < n) { 99 | * // bring new buffer if empty 100 | * if (!outBuf.hasRemaining()) { 101 | * outBuf = bufManager.getNextBuffer(); 102 | * } 103 | * skip = Math.min(n - numSkipped, outBuf.remaining()); 104 | * outBuf.position(outBuf.position() + (int) skip); 105 | * numSkipped += skip; 106 | * } 107 | * return numSkipped; 108 | * } 109 | */ 110 | } 111 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/jxioConnection/impl/MultiBuffInputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.jxioConnection.impl; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | import java.nio.ByteBuffer; 22 | 23 | import org.accelio.jxio.jxioConnection.impl.BufferSupplier; 24 | 25 | //inspired from SocketInputStream 26 | public class MultiBuffInputStream extends InputStream { 27 | 28 | private final BufferSupplier supplier; 29 | private ByteBuffer inputBuff = null; 30 | private boolean eof = false; 31 | private boolean connectionOpen = true; 32 | 33 | public MultiBuffInputStream(BufferSupplier sup) { 34 | supplier = sup; 35 | } 36 | 37 | @Override 38 | public synchronized int read() throws IOException { 39 | byte[] temp = new byte[1]; 40 | int n = read(temp, 0, 1); 41 | if (n <= 0) { 42 | ; 43 | return -1; 44 | } 45 | return temp[0] & 0xFF; 46 | } 47 | 48 | @Override 49 | public synchronized int read(byte[] b, int off, int len) throws IOException { 50 | int totalRead = 0; 51 | int bytesRead; 52 | 53 | if (!connectionOpen) { 54 | throw new IOException("Stream closed."); 55 | } 56 | if (eof) { 57 | return -1; 58 | } 59 | if (b == null) { 60 | throw new NullPointerException(); 61 | } 62 | // bounds check 63 | if (len <= 0 || off < 0 || off + len > b.length) { 64 | if (len == 0) { 65 | return 0; 66 | } 67 | throw new ArrayIndexOutOfBoundsException(); 68 | } 69 | try { 70 | if (inputBuff == null) { 71 | inputBuff = supplier.getNextBuffer(); 72 | } 73 | while (totalRead < len) { 74 | // bring new buffer if empty 75 | if (!inputBuff.hasRemaining()) { 76 | inputBuff = supplier.getNextBuffer(); 77 | } 78 | bytesRead = Math.min(len - totalRead, inputBuff.remaining()); 79 | inputBuff.get(b, off, bytesRead); 80 | totalRead += bytesRead; 81 | off += bytesRead; 82 | if (inputBuff.limit() <= inputBuff.position() && inputBuff.position() != inputBuff.capacity()) { 83 | eof = true; 84 | return totalRead; 85 | } 86 | } 87 | } catch (IOException e) { 88 | // no buffer available because the other side closed the connection 89 | eof = true; 90 | } 91 | return totalRead; 92 | } 93 | 94 | @Override 95 | public synchronized int available() throws IOException { 96 | if (!connectionOpen) { 97 | throw new IOException("Stream closed."); 98 | } 99 | return inputBuff.remaining(); 100 | } 101 | 102 | @Override 103 | public void close() throws IOException { 104 | connectionOpen = false; 105 | } 106 | 107 | @Override 108 | public synchronized long skip(long n) throws IOException { 109 | long numSkipped = 0; 110 | long skip; 111 | 112 | if (!connectionOpen) { 113 | throw new IOException("Stream closed."); 114 | } 115 | if (eof || n <= 0) { 116 | return 0; 117 | } 118 | if (inputBuff == null) { 119 | inputBuff = supplier.getNextBuffer(); 120 | } 121 | while (numSkipped < n) { 122 | // bring new buffer if empty 123 | if (!inputBuff.hasRemaining()) { 124 | inputBuff = supplier.getNextBuffer(); 125 | } 126 | skip = Math.min(n - numSkipped, inputBuff.remaining()); 127 | inputBuff.position((int) (inputBuff.position() + skip)); 128 | numSkipped += skip; 129 | } 130 | return numSkipped; 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/java/org/accelio/jxio/jxioConnection/impl/SimpleConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (C) 2013 Mellanox Technologies 3 | ** 4 | ** Licensed under the Apache License, Version 2.0 (the "License"); 5 | ** you may not use this file except in compliance with the License. 6 | ** You may obtain a copy of the License at: 7 | ** 8 | ** http://www.apache.org/licenses/LICENSE-2.0 9 | ** 10 | ** Unless required by applicable law or agreed to in writing, software 11 | ** distributed under the License is distributed on an "AS IS" BASIS, 12 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | ** either express or implied. See the License for the specific language 14 | ** governing permissions and limitations under the License. 15 | ** 16 | */ 17 | package org.accelio.jxio.jxioConnection.impl; 18 | 19 | import java.net.ConnectException; 20 | import java.net.URI; 21 | 22 | import org.apache.commons.logging.Log; 23 | import org.apache.commons.logging.LogFactory; 24 | 25 | import org.accelio.jxio.Msg; 26 | import org.accelio.jxio.MsgPool; 27 | import org.accelio.jxio.EventName; 28 | import org.accelio.jxio.EventReason; 29 | import org.accelio.jxio.ClientSession; 30 | import org.accelio.jxio.EventQueueHandler; 31 | import org.accelio.jxio.exceptions.JxioGeneralException; 32 | import org.accelio.jxio.exceptions.JxioQueueOverflowException; 33 | import org.accelio.jxio.exceptions.JxioSessionClosedException; 34 | import org.accelio.jxio.jxioConnection.impl.JxioResourceManager; 35 | import org.accelio.jxio.jxioConnection.impl.SimpleConnection; 36 | 37 | public abstract class SimpleConnection { 38 | 39 | private static final Log LOG = LogFactory.getLog(SimpleConnection.class.getCanonicalName()); 40 | private boolean established = false; 41 | protected EventQueueHandler eqh; 42 | protected final ClientSession cs; 43 | protected MsgPool msgPool; 44 | protected EventName connectErrorType = null; 45 | protected boolean close = false; 46 | protected Msg msg = null; 47 | 48 | public SimpleConnection(URI uri, int msgIn, int msgOut, int msgCount) throws ConnectException { 49 | eqh = JxioResourceManager.getEqh(); 50 | msgPool = JxioResourceManager.getMsgPool(msgCount, msgIn, msgOut); 51 | long startTime = System.nanoTime(); 52 | cs = new ClientSession(eqh, uri, new ClientCallbacks()); 53 | eqh.runEventLoop(1, EventQueueHandler.INFINITE_DURATION); // session established event 54 | if (!established) { 55 | throw new ConnectException(this.toString() + " could not connect to " + uri.getHost() + " on port " 56 | + uri.getPort() + ", got " + connectErrorType); 57 | } 58 | long endTime = System.nanoTime(); 59 | 60 | LOG.info(cs.toString() + " session established with host " + uri.getHost() + ", time taken to open: " 61 | + (endTime - startTime)); 62 | } 63 | 64 | public class ClientCallbacks implements ClientSession.Callbacks { 65 | 66 | public void onMsgError(Msg msg, EventReason reason) { 67 | if (reason != EventReason.MSG_FLUSHED) { 68 | LOG.info(SimpleConnection.this.toString() + " onMsgErrorCallback, " + reason); 69 | } 70 | msgPool.releaseMsg(msg); 71 | } 72 | 73 | public void onSessionEstablished() { 74 | established = true; 75 | } 76 | 77 | public void onSessionEvent(EventName event, EventReason reason) { 78 | LOG.info(SimpleConnection.this.toString() + " onSessionEvent " + event); 79 | if (event == EventName.SESSION_CLOSED || event == EventName.SESSION_ERROR 80 | || event == EventName.SESSION_REJECT) { // normal exit 81 | connectErrorType = event; 82 | boolean needToClean = !eqh.getInRunEventLoop(); 83 | if (close) { 84 | needToClean = false; 85 | } 86 | close = true; 87 | eqh.breakEventLoop(); 88 | if (needToClean) { 89 | releaseResources(); 90 | } 91 | } 92 | } 93 | 94 | public void onResponse(Msg m) { 95 | msg = m; 96 | if (close) { 97 | msgPool.releaseMsg(m); 98 | msg = null; 99 | } 100 | } 101 | } 102 | 103 | public void disconnect() { 104 | if (close) return; 105 | close = true; 106 | if (LOG.isDebugEnabled()) { 107 | LOG.debug(this.toString() + " jxioConnection disconnect, msgPool.count()" + msgPool.count() 108 | + " msgPool.capacity() " + msgPool.capacity()); 109 | } 110 | handleLastMsg(); 111 | while (msgPool.count() < msgPool.capacity()) { 112 | eqh.runEventLoop(msgPool.capacity() - msgPool.count(), EventQueueHandler.INFINITE_DURATION); 113 | } 114 | if (LOG.isDebugEnabled()) { 115 | LOG.debug(this.toString() + "disconnecting,got all msgs back, closing session"); 116 | } 117 | closeStream(); 118 | cs.close(); 119 | eqh.runEventLoop(EventQueueHandler.INFINITE_EVENTS, EventQueueHandler.INFINITE_DURATION); 120 | releaseResources(); 121 | } 122 | 123 | public void releaseResources() { 124 | if (LOG.isDebugEnabled()) { 125 | LOG.debug(this.toString() + " Releasing resources"); 126 | } 127 | if (eqh != null) 128 | JxioResourceManager.returnEqh(eqh); 129 | if (msgPool != null) 130 | JxioResourceManager.returnMsgPool(msgPool); 131 | eqh = null; 132 | msgPool = null; 133 | } 134 | 135 | public void sendMsg() { 136 | if (msg != null) { 137 | try { 138 | cs.sendRequest(msg); 139 | } catch (JxioSessionClosedException e) { 140 | LOG.debug(this.toString() + " Error sending message: " + e.toString()); 141 | msgPool.releaseMsg(msg); 142 | } catch (JxioQueueOverflowException e) { 143 | LOG.error(this.toString() + " Error sending message: " + e.toString()); 144 | msgPool.releaseMsg(msg); 145 | } catch (JxioGeneralException e) { 146 | LOG.error(this.toString() + " Error sending message: " + e.toString()); 147 | msgPool.releaseMsg(msg); 148 | } 149 | msg = null; 150 | } 151 | } 152 | 153 | public abstract void closeStream(); 154 | 155 | public abstract void handleLastMsg(); 156 | } 157 | -------------------------------------------------------------------------------- /src/java/org/apache/lucene/facet/taxonomy/LRUHashMap.java: -------------------------------------------------------------------------------- 1 | package org.apache.lucene.facet.taxonomy; 2 | 3 | /* 4 | * Licensed to the Apache Software Foundation (ASF) under one or more 5 | * contributor license agreements. See the NOTICE file distributed with 6 | * this work for additional information regarding copyright ownership. 7 | * The ASF licenses this file to You under the Apache License, Version 2.0 8 | * (the "License"); you may not use this file except in compliance with 9 | * the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Taken from lucene-facet-4.9.0 20 | */ 21 | 22 | import java.util.LinkedHashMap; 23 | import java.util.Map; 24 | 25 | /** 26 | * LRUHashMap is an extension of Java's HashMap, which has a bounded size(); 27 | * When it reaches that size, each time a new element is added, the least 28 | * recently used (LRU) entry is removed. 29 | *

30 | * Java makes it very easy to implement LRUHashMap - all its functionality is 31 | * already available from {@link java.util.LinkedHashMap}, and we just need to 32 | * configure that properly. 33 | *

34 | * Note that like HashMap, LRUHashMap is unsynchronized, and the user MUST 35 | * synchronize the access to it if used from several threads. Moreover, while 36 | * with HashMap this is only a concern if one of the threads is modifies the 37 | * map, with LURHashMap every read is a modification (because the LRU order 38 | * needs to be remembered) so proper synchronization is always necessary. 39 | *

40 | * With the usual synchronization mechanisms available to the user, this 41 | * unfortunately means that LRUHashMap will probably perform sub-optimally under 42 | * heavy contention: while one thread uses the hash table (reads or writes), any 43 | * other thread will be blocked from using it - or even just starting to use it 44 | * (e.g., calculating the hash function). A more efficient approach would be not 45 | * to use LinkedHashMap at all, but rather to use a non-locking (as much as 46 | * possible) thread-safe solution, something along the lines of 47 | * java.util.concurrent.ConcurrentHashMap (though that particular class does not 48 | * support the additional LRU semantics, which will need to be added separately 49 | * using a concurrent linked list or additional storage of timestamps (in an 50 | * array or inside the entry objects), or whatever). 51 | * 52 | * @lucene.experimental 53 | */ 54 | public class LRUHashMap extends LinkedHashMap { 55 | 56 | private static final long serialVersionUID = 1L; 57 | private int maxSize; 58 | 59 | /** 60 | * Create a new hash map with a bounded size and with least recently 61 | * used entries removed. 62 | * @param maxSize 63 | * the maximum size (in number of entries) to which the map can grow 64 | * before the least recently used entries start being removed.
65 | * Setting maxSize to a very large value, like 66 | * {@link Integer#MAX_VALUE} is allowed, but is less efficient than 67 | * using {@link java.util.HashMap} because our class needs 68 | * to keep track of the use order (via an additional doubly-linked 69 | * list) which is not used when the map's size is always below the 70 | * maximum size. 71 | */ 72 | public LRUHashMap(int maxSize) { 73 | super(16, 0.75f, true); 74 | this.maxSize = maxSize; 75 | } 76 | 77 | /** 78 | * Return the max size 79 | */ 80 | public int getMaxSize() { 81 | return maxSize; 82 | } 83 | 84 | /** 85 | * setMaxSize() allows changing the map's maximal number of elements 86 | * which was defined at construction time. 87 | *

88 | * Note that if the map is already larger than maxSize, the current 89 | * implementation does not shrink it (by removing the oldest elements); 90 | * Rather, the map remains in its current size as new elements are 91 | * added, and will only start shrinking (until settling again on the 92 | * give maxSize) if existing elements are explicitly deleted. 93 | */ 94 | public void setMaxSize(int maxSize) { 95 | this.maxSize = maxSize; 96 | } 97 | 98 | // We override LinkedHashMap's removeEldestEntry() method. This method 99 | // is called every time a new entry is added, and if we return true 100 | // here, the eldest element will be deleted automatically. In our case, 101 | // we return true if the size of the map grew beyond our limit - ignoring 102 | // what is that eldest element that we'll be deleting. 103 | @Override 104 | protected boolean removeEldestEntry(Map.Entry eldest) { 105 | return size() > maxSize; 106 | } 107 | 108 | @SuppressWarnings("unchecked") 109 | @Override 110 | public LRUHashMap clone() { 111 | return (LRUHashMap) super.clone(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/lib/commons-logging-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accelio/JXIO/a3331e1843a0f384770ca7475a53bff08b96006d/src/lib/commons-logging-1.2.jar -------------------------------------------------------------------------------- /src/lib/commons-logging.jar: -------------------------------------------------------------------------------- 1 | commons-logging-1.2.jar -------------------------------------------------------------------------------- /src/lib/log4j-1.2.15.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accelio/JXIO/a3331e1843a0f384770ca7475a53bff08b96006d/src/lib/log4j-1.2.15.jar --------------------------------------------------------------------------------