{"action":"created","comment":{"url":"https://api.github.com/repos/netty/netty/pulls/comments/31320246","id":31320246,"diff_hunk":"@@ -0,0 +1,347 @@\n+/*\n+ * Copyright 2015 The Netty Project\n+ *\n+ * The Netty Project licenses this file to you under the Apache License,\n+ * version 2.0 (the \"License\"); you may not use this file except in compliance\n+ * with the License. You may obtain a copy of the License at:\n+ *\n+ *   http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n+ * License for the specific language governing permissions and limitations\n+ * under the License.\n+ */\n+\n+\n+#ifndef _GNU_SOURCE\n+// libaio, O_DIRECT and other things won't be available without this define\n+#define _GNU_SOURCE\n+#endif\n+\n+//#define DEBUG\n+\n+#include <jni.h>\n+#include <unistd.h>\n+#include <errno.h>\n+#include <libaio.h>\n+#include <sys/types.h>\n+#include <sys/stat.h>\n+#include <fcntl.h>\n+#include <stdlib.h>\n+#include <pthread.h>\n+#include \"io_netty_channel_libaio_DirectFileDescriptorController.h\"\n+#include \"exception_helper.h\"\n+\n+struct io_control {\n+    io_context_t ioContext;\n+    struct io_event * events;\n+\n+    // This is used to make sure we don't return IOCB while something else is using them\n+    // this is to guarantee the submits could be done concurrently with polling\n+    pthread_mutex_t iocbLock;\n+\n+    jclass errorInfoClass;\n+    jmethodID errorInfoConstr;\n+\n+    // a resuable pool of iocb\n+    struct iocb ** iocb;\n+    int queueSize;\n+    int iocbPut;\n+    int iocbGet;\n+    int used;\n+};\n+\n+static inline struct io_control * getIOControl(JNIEnv* env, jobject pointer ) {\n+    struct io_control * ioControl = (struct io_control *) (*env)->GetDirectBufferAddress(env, pointer);\n+    return ioControl;\n+}\n+\n+/**\n+ remove an iocb from the pool of IOCBs. Returns null if full\n+*/\n+static inline struct iocb * getIOCB(struct io_control * control) {\n+    pthread_mutex_lock(&(control->iocbLock));\n+\n+    struct iocb * iocb = 0;\n+\n+    #ifdef DEBUG\n+       fprintf (stderr, \"getIOCB::used=%d, queueSize=%d, get=%d, put=%d\\n\", control->used, control->queueSize, control->iocbGet, control->iocbPut);\n+    #endif\n+\n+    if (control->used < control->queueSize)\n+    {\n+        control->used++;\n+        iocb = control->iocb[control->iocbGet++];\n+\n+        if (control->iocbGet >= control->queueSize)\n+        {\n+           control->iocbGet = 0;\n+        }\n+    }\n+    else\n+    {\n+        #ifdef DEBUG\n+            fprintf (stderr, \"Could not find iocb\\n\");\n+        #endif\n+    }\n+\n+    pthread_mutex_unlock(&(control->iocbLock));\n+    return iocb;\n+}\n+\n+/**\n+  Put an iocb back on the pool of IOCBs\n+*/\n+static inline void putIOCB(struct io_control * control, struct iocb * iocbBack) {\n+    pthread_mutex_lock(&(control->iocbLock));\n+\n+    #ifdef DEBUG\n+       fprintf (stderr, \"putIOCB::used=%d, queueSize=%d, get=%d, put=%d\\n\", control->used, control->queueSize, control->iocbGet, control->iocbPut);\n+    #endif\n+\n+    control->used--;\n+    control->iocb[control->iocbPut++] = iocbBack;\n+    if (control->iocbPut >= control->queueSize)\n+    {\n+       control->iocbPut = 0;\n+    }\n+    pthread_mutex_unlock(&(control->iocbLock));\n+}\n+\n+static inline void * getBuffer(JNIEnv* env, jobject pointer ) {\n+    return (*env)->GetDirectBufferAddress(env, pointer);\n+}\n+\n+JNIEXPORT jobject JNICALL Java_io_netty_channel_libaio_DirectFileDescriptorController_newContext(JNIEnv* env, jclass clazz, jint queueSize) {\n+\n+    io_context_t libaioContext;\n+    int i = 0;\n+\n+    int res = io_queue_init(queueSize, &libaioContext);\n+    if (res) {\n+        // Error, so need to release whatever was done before\n+        free(libaioContext);\n+\n+        throwRuntimeException(env, exceptionMessage(\"Cannot initialize queue:\", -res));\n+        return NULL;\n+    }\n+\n+    struct iocb ** iocb = (struct iocb **)malloc(sizeof(struct iocb *) * queueSize);\n+\n+    for (i = 0; i < queueSize; i++)\n+    {\n+       iocb[i] = (struct iocb *)malloc(sizeof(struct iocb));\n+    }\n+\n+    struct io_event * events = (struct io_event *)malloc(sizeof(struct io_event) * queueSize);\n+\n+    struct io_control * theControl = (struct io_control *) malloc(sizeof(struct io_control));\n+\n+    theControl->errorInfoClass = (*env)->FindClass(env, \"io/netty/channel/libaio/ErrorInfo\");","path":"transport-native-epoll/src/main/c/io_netty_channel_libaio_DirectFileDescriptorController.c","position":142,"original_position":142,"commit_id":"d0e40c771795fbd7b1e1a597b652021002ebed0c","original_commit_id":"d0e40c771795fbd7b1e1a597b652021002ebed0c","user":{"login":"clebertsuconic","id":750514,"avatar_url":"https://avatars.githubusercontent.com/u/750514?v=3","gravatar_id":"","url":"https://api.github.com/users/clebertsuconic","html_url":"https://github.com/clebertsuconic","followers_url":"https://api.github.com/users/clebertsuconic/followers","following_url":"https://api.github.com/users/clebertsuconic/following{/other_user}","gists_url":"https://api.github.com/users/clebertsuconic/gists{/gist_id}","starred_url":"https://api.github.com/users/clebertsuconic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clebertsuconic/subscriptions","organizations_url":"https://api.github.com/users/clebertsuconic/orgs","repos_url":"https://api.github.com/users/clebertsuconic/repos","events_url":"https://api.github.com/users/clebertsuconic/events{/privacy}","received_events_url":"https://api.github.com/users/clebertsuconic/received_events","type":"User","site_admin":false},"body":"I didn't have a loadNative method here since you are already using it at the Native.c\r\n\r\nI can introduce a hook here if you like, but I don't expect having more than one instance per VM (or per application if you are using muliple applications on a single VM)","created_at":"2015-05-29T12:36:19Z","updated_at":"2015-05-29T12:36:19Z","html_url":"https://github.com/netty/netty/pull/3839#discussion_r31320246","pull_request_url":"https://api.github.com/repos/netty/netty/pulls/3839","_links":{"self":{"href":"https://api.github.com/repos/netty/netty/pulls/comments/31320246"},"html":{"href":"https://github.com/netty/netty/pull/3839#discussion_r31320246"},"pull_request":{"href":"https://api.github.com/repos/netty/netty/pulls/3839"}}},"pull_request":{"url":"https://api.github.com/repos/netty/netty/pulls/3839","id":36409120,"html_url":"https://github.com/netty/netty/pull/3839","diff_url":"https://github.com/netty/netty/pull/3839.diff","patch_url":"https://github.com/netty/netty/pull/3839.patch","issue_url":"https://api.github.com/repos/netty/netty/issues/3839","number":3839,"state":"open","locked":false,"title":"https://github.com/netty/netty/issues/3726 - libaio wrapper","user":{"login":"clebertsuconic","id":750514,"avatar_url":"https://avatars.githubusercontent.com/u/750514?v=3","gravatar_id":"","url":"https://api.github.com/users/clebertsuconic","html_url":"https://github.com/clebertsuconic","followers_url":"https://api.github.com/users/clebertsuconic/followers","following_url":"https://api.github.com/users/clebertsuconic/following{/other_user}","gists_url":"https://api.github.com/users/clebertsuconic/gists{/gist_id}","starred_url":"https://api.github.com/users/clebertsuconic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clebertsuconic/subscriptions","organizations_url":"https://api.github.com/users/clebertsuconic/orgs","repos_url":"https://api.github.com/users/clebertsuconic/repos","events_url":"https://api.github.com/users/clebertsuconic/events{/privacy}","received_events_url":"https://api.github.com/users/clebertsuconic/received_events","type":"User","site_admin":false},"body":"text from the main commit:\r\n\r\n    [#3726] Implementation of a JNI wrapper for libaio\r\n    \r\n    https://github.com/netty/netty/issues/3726\r\n    \r\n    Motivation:\r\n    \r\n    libaio is a fast library for accessing files, implementing a JNI wrapper\r\n    would give a boost on accessing files\r\n    \r\n    Modification:\r\n    \r\n    * Add DirectFileDescriptorController Which will handle the libaio queue among multiple files\r\n    * Add DirectFileDescriptor representing the files\r\n    * ErrorInfo A class to contain error information on callbacks in case of submission failures\r\n    * Added a native module as part of transport-native-epoll\r\n    \r\n    Result:\r\n    \r\n    There is now a library that could handle files through asynchronous queues and direct memory access\r\n","created_at":"2015-05-28T13:58:42Z","updated_at":"2015-05-29T12:36:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c162824d0c320f4b75697f090b4e8cd4e017e01b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/netty/netty/pulls/3839/commits","review_comments_url":"https://api.github.com/repos/netty/netty/pulls/3839/comments","review_comment_url":"https://api.github.com/repos/netty/netty/pulls/comments{/number}","comments_url":"https://api.github.com/repos/netty/netty/issues/3839/comments","statuses_url":"https://api.github.com/repos/netty/netty/statuses/d0e40c771795fbd7b1e1a597b652021002ebed0c","head":{"label":"clebertsuconic:master","ref":"master","sha":"d0e40c771795fbd7b1e1a597b652021002ebed0c","user":{"login":"clebertsuconic","id":750514,"avatar_url":"https://avatars.githubusercontent.com/u/750514?v=3","gravatar_id":"","url":"https://api.github.com/users/clebertsuconic","html_url":"https://github.com/clebertsuconic","followers_url":"https://api.github.com/users/clebertsuconic/followers","following_url":"https://api.github.com/users/clebertsuconic/following{/other_user}","gists_url":"https://api.github.com/users/clebertsuconic/gists{/gist_id}","starred_url":"https://api.github.com/users/clebertsuconic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clebertsuconic/subscriptions","organizations_url":"https://api.github.com/users/clebertsuconic/orgs","repos_url":"https://api.github.com/users/clebertsuconic/repos","events_url":"https://api.github.com/users/clebertsuconic/events{/privacy}","received_events_url":"https://api.github.com/users/clebertsuconic/received_events","type":"User","site_admin":false},"repo":{"id":6553410,"name":"netty","full_name":"clebertsuconic/netty","owner":{"login":"clebertsuconic","id":750514,"avatar_url":"https://avatars.githubusercontent.com/u/750514?v=3","gravatar_id":"","url":"https://api.github.com/users/clebertsuconic","html_url":"https://github.com/clebertsuconic","followers_url":"https://api.github.com/users/clebertsuconic/followers","following_url":"https://api.github.com/users/clebertsuconic/following{/other_user}","gists_url":"https://api.github.com/users/clebertsuconic/gists{/gist_id}","starred_url":"https://api.github.com/users/clebertsuconic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clebertsuconic/subscriptions","organizations_url":"https://api.github.com/users/clebertsuconic/orgs","repos_url":"https://api.github.com/users/clebertsuconic/repos","events_url":"https://api.github.com/users/clebertsuconic/events{/privacy}","received_events_url":"https://api.github.com/users/clebertsuconic/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/clebertsuconic/netty","description":"Netty project - an event-driven asynchronous network application framework","fork":true,"url":"https://api.github.com/repos/clebertsuconic/netty","forks_url":"https://api.github.com/repos/clebertsuconic/netty/forks","keys_url":"https://api.github.com/repos/clebertsuconic/netty/keys{/key_id}","collaborators_url":"https://api.github.com/repos/clebertsuconic/netty/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/clebertsuconic/netty/teams","hooks_url":"https://api.github.com/repos/clebertsuconic/netty/hooks","issue_events_url":"https://api.github.com/repos/clebertsuconic/netty/issues/events{/number}","events_url":"https://api.github.com/repos/clebertsuconic/netty/events","assignees_url":"https://api.github.com/repos/clebertsuconic/netty/assignees{/user}","branches_url":"https://api.github.com/repos/clebertsuconic/netty/branches{/branch}","tags_url":"https://api.github.com/repos/clebertsuconic/netty/tags","blobs_url":"https://api.github.com/repos/clebertsuconic/netty/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/clebertsuconic/netty/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/clebertsuconic/netty/git/refs{/sha}","trees_url":"https://api.github.com/repos/clebertsuconic/netty/git/trees{/sha}","statuses_url":"https://api.github.com/repos/clebertsuconic/netty/statuses/{sha}","languages_url":"https://api.github.com/repos/clebertsuconic/netty/languages","stargazers_url":"https://api.github.com/repos/clebertsuconic/netty/stargazers","contributors_url":"https://api.github.com/repos/clebertsuconic/netty/contributors","subscribers_url":"https://api.github.com/repos/clebertsuconic/netty/subscribers","subscription_url":"https://api.github.com/repos/clebertsuconic/netty/subscription","commits_url":"https://api.github.com/repos/clebertsuconic/netty/commits{/sha}","git_commits_url":"https://api.github.com/repos/clebertsuconic/netty/git/commits{/sha}","comments_url":"https://api.github.com/repos/clebertsuconic/netty/comments{/number}","issue_comment_url":"https://api.github.com/repos/clebertsuconic/netty/issues/comments{/number}","contents_url":"https://api.github.com/repos/clebertsuconic/netty/contents/{+path}","compare_url":"https://api.github.com/repos/clebertsuconic/netty/compare/{base}...{head}","merges_url":"https://api.github.com/repos/clebertsuconic/netty/merges","archive_url":"https://api.github.com/repos/clebertsuconic/netty/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/clebertsuconic/netty/downloads","issues_url":"https://api.github.com/repos/clebertsuconic/netty/issues{/number}","pulls_url":"https://api.github.com/repos/clebertsuconic/netty/pulls{/number}","milestones_url":"https://api.github.com/repos/clebertsuconic/netty/milestones{/number}","notifications_url":"https://api.github.com/repos/clebertsuconic/netty/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/clebertsuconic/netty/labels{/name}","releases_url":"https://api.github.com/repos/clebertsuconic/netty/releases{/id}","created_at":"2012-11-05T23:16:10Z","updated_at":"2015-05-06T02:40:07Z","pushed_at":"2015-05-28T21:17:29Z","git_url":"git://github.com/clebertsuconic/netty.git","ssh_url":"git@github.com:clebertsuconic/netty.git","clone_url":"https://github.com/clebertsuconic/netty.git","svn_url":"https://github.com/clebertsuconic/netty","homepage":"http://netty.io/","size":34607,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"netty:master","ref":"master","sha":"ed4a89082bb29b9e7d869c5d25d6b9ea8fc9d25b","user":{"login":"netty","id":473791,"avatar_url":"https://avatars.githubusercontent.com/u/473791?v=3","gravatar_id":"","url":"https://api.github.com/users/netty","html_url":"https://github.com/netty","followers_url":"https://api.github.com/users/netty/followers","following_url":"https://api.github.com/users/netty/following{/other_user}","gists_url":"https://api.github.com/users/netty/gists{/gist_id}","starred_url":"https://api.github.com/users/netty/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/netty/subscriptions","organizations_url":"https://api.github.com/users/netty/orgs","repos_url":"https://api.github.com/users/netty/repos","events_url":"https://api.github.com/users/netty/events{/privacy}","received_events_url":"https://api.github.com/users/netty/received_events","type":"Organization","site_admin":false},"repo":{"id":1064563,"name":"netty","full_name":"netty/netty","owner":{"login":"netty","id":473791,"avatar_url":"https://avatars.githubusercontent.com/u/473791?v=3","gravatar_id":"","url":"https://api.github.com/users/netty","html_url":"https://github.com/netty","followers_url":"https://api.github.com/users/netty/followers","following_url":"https://api.github.com/users/netty/following{/other_user}","gists_url":"https://api.github.com/users/netty/gists{/gist_id}","starred_url":"https://api.github.com/users/netty/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/netty/subscriptions","organizations_url":"https://api.github.com/users/netty/orgs","repos_url":"https://api.github.com/users/netty/repos","events_url":"https://api.github.com/users/netty/events{/privacy}","received_events_url":"https://api.github.com/users/netty/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/netty/netty","description":"Netty project - an event-driven asynchronous network application framework","fork":false,"url":"https://api.github.com/repos/netty/netty","forks_url":"https://api.github.com/repos/netty/netty/forks","keys_url":"https://api.github.com/repos/netty/netty/keys{/key_id}","collaborators_url":"https://api.github.com/repos/netty/netty/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/netty/netty/teams","hooks_url":"https://api.github.com/repos/netty/netty/hooks","issue_events_url":"https://api.github.com/repos/netty/netty/issues/events{/number}","events_url":"https://api.github.com/repos/netty/netty/events","assignees_url":"https://api.github.com/repos/netty/netty/assignees{/user}","branches_url":"https://api.github.com/repos/netty/netty/branches{/branch}","tags_url":"https://api.github.com/repos/netty/netty/tags","blobs_url":"https://api.github.com/repos/netty/netty/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/netty/netty/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/netty/netty/git/refs{/sha}","trees_url":"https://api.github.com/repos/netty/netty/git/trees{/sha}","statuses_url":"https://api.github.com/repos/netty/netty/statuses/{sha}","languages_url":"https://api.github.com/repos/netty/netty/languages","stargazers_url":"https://api.github.com/repos/netty/netty/stargazers","contributors_url":"https://api.github.com/repos/netty/netty/contributors","subscribers_url":"https://api.github.com/repos/netty/netty/subscribers","subscription_url":"https://api.github.com/repos/netty/netty/subscription","commits_url":"https://api.github.com/repos/netty/netty/commits{/sha}","git_commits_url":"https://api.github.com/repos/netty/netty/git/commits{/sha}","comments_url":"https://api.github.com/repos/netty/netty/comments{/number}","issue_comment_url":"https://api.github.com/repos/netty/netty/issues/comments{/number}","contents_url":"https://api.github.com/repos/netty/netty/contents/{+path}","compare_url":"https://api.github.com/repos/netty/netty/compare/{base}...{head}","merges_url":"https://api.github.com/repos/netty/netty/merges","archive_url":"https://api.github.com/repos/netty/netty/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/netty/netty/downloads","issues_url":"https://api.github.com/repos/netty/netty/issues{/number}","pulls_url":"https://api.github.com/repos/netty/netty/pulls{/number}","milestones_url":"https://api.github.com/repos/netty/netty/milestones{/number}","notifications_url":"https://api.github.com/repos/netty/netty/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/netty/netty/labels{/name}","releases_url":"https://api.github.com/repos/netty/netty/releases{/id}","created_at":"2010-11-09T09:22:21Z","updated_at":"2015-05-29T07:46:35Z","pushed_at":"2015-05-29T01:47:58Z","git_url":"git://github.com/netty/netty.git","ssh_url":"git@github.com:netty/netty.git","clone_url":"https://github.com/netty/netty.git","svn_url":"https://github.com/netty/netty","homepage":"http://netty.io/","size":130388,"stargazers_count":4692,"watchers_count":4692,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2311,"mirror_url":null,"open_issues_count":278,"forks":2311,"open_issues":278,"watchers":4692,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/netty/netty/pulls/3839"},"html":{"href":"https://github.com/netty/netty/pull/3839"},"issue":{"href":"https://api.github.com/repos/netty/netty/issues/3839"},"comments":{"href":"https://api.github.com/repos/netty/netty/issues/3839/comments"},"review_comments":{"href":"https://api.github.com/repos/netty/netty/pulls/3839/comments"},"review_comment":{"href":"https://api.github.com/repos/netty/netty/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/netty/netty/pulls/3839/commits"},"statuses":{"href":"https://api.github.com/repos/netty/netty/statuses/d0e40c771795fbd7b1e1a597b652021002ebed0c"}}}}