Fix Native EPOLL Build Failure

Motiviation:
If sendmmsg is already defined then the native epoll module failed to build because of conflicting definitions.
The mmsghdr type was also redefined on systems that already supported this structure.

Modifications:
Provide a way so that systems which already define sendmmsg and mmsghdr can build
Provide a way so that systems which don't define sendmmsg and mmsghdr can build

Result:
The native EPOLL module can build in more environments
This commit is contained in:
Scott Mitchell 2014-09-12 15:30:50 -04:00 committed by Norman Maurer
parent e3925be907
commit 94deea409e
2 changed files with 109 additions and 6 deletions

View File

@ -78,6 +78,9 @@
<platform>.</platform> <platform>.</platform>
<forceConfigure>true</forceConfigure> <forceConfigure>true</forceConfigure>
<forceAutogen>true</forceAutogen> <forceAutogen>true</forceAutogen>
<configureArgs>
<arg>${jni.compiler.args}</arg>
</configureArgs>
</configuration> </configuration>
<goals> <goals>
<goal>generate</goal> <goal>generate</goal>
@ -112,6 +115,104 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<!-- Phase must be before regex-glibc-sendmmsg and regex-linux-sendmmsg -->
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<id>ant-get-systeminfo</id>
<configuration>
<exportAntProperties>true</exportAntProperties>
<tasks>
<exec executable="sh" outputproperty="ldd_version">
<arg value="-c"/>
<arg value="ldd --version | head -1"/>
</exec>
<exec executable="uname" outputproperty="uname_os_version">
<arg value="-r"/>
</exec>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<!-- Phase must be before regex-combined-sendmmsg -->
<phase>initialize</phase>
<id>regex-glibc-sendmmsg</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>glibc.sendmmsg.support</name>
<value>${ldd_version}</value>
<!-- Version must be >= 2.14 - set to IO_NETTY_SENDMSSG_NOT_FOUND if this version is not satisfied -->
<regex>^((?!^[^)]+\)\s+(0*2\.1[4-9]|0*2\.[2-9][0-9]+|0*[3-9][0-9]*|0*[1-9]+[0-9]+).*).)*$</regex>
<replacement>IO_NETTY_SENDMSSG_NOT_FOUND</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
<execution>
<!-- Phase must be before regex-combined-sendmmsg -->
<phase>initialize</phase>
<id>regex-linux-sendmmsg</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>linux.sendmmsg.support</name>
<value>${uname_os_version}</value>
<!-- Version must be >= 3 - set to IO_NETTY_SENDMSSG_NOT_FOUND if this version is not satisfied -->
<regex>^((?!^[0-9]*[3-9]\.?.*).)*$</regex>
<replacement>IO_NETTY_SENDMSSG_NOT_FOUND</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
<execution>
<!-- Phase must be before regex-unset-if-needed-sendmmsg -->
<phase>generate-sources</phase>
<id>regex-combined-sendmmsg</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>jni.compiler.args</name>
<value>${linux.sendmmsg.support}${glibc.sendmmsg.support}</value>
<!-- If glibc and linux kernel are both not sufficient...then define the CFLAGS -->
<regex>.*IO_NETTY_SENDMSSG_NOT_FOUND.*</regex>
<replacement>CFLAGS="-DIO_NETTY_SENDMMSG_NOT_FOUND"</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
<execution>
<!-- Phase must be before build-native-lib -->
<phase>generate-sources</phase>
<id>regex-unset-if-needed-sendmmsg</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>jni.compiler.args</name>
<value>${jni.compiler.args}</value>
<!-- If glibc and linux kernel are both not sufficient...then define the CFLAGS -->
<regex>^((?!CFLAGS=).)*$</regex>
<replacement>CFLAGS=""</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -13,6 +13,7 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
#define _GNU_SOURCE
#include <jni.h> #include <jni.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -30,19 +31,20 @@
#include <sys/utsname.h> #include <sys/utsname.h>
#include "io_netty_channel_epoll_Native.h" #include "io_netty_channel_epoll_Native.h"
// optional // optional
extern int accept4(int sockFd, struct sockaddr *addr, socklen_t *addrlen, int flags) __attribute__((weak)); extern int accept4(int sockFd, struct sockaddr *addr, socklen_t *addrlen, int flags) __attribute__((weak));
extern int epoll_create1(int flags) __attribute__((weak)); extern int epoll_create1(int flags) __attribute__((weak));
#ifdef IO_NETTY_SENDMMSG_NOT_FOUND
extern int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags) __attribute__((weak)); extern int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags) __attribute__((weak));
// Just define it here and NOT use #define _GNU_SOURCE as we also want to be able to build on systems that not support #ifndef __USE_GNU
// sendmmsg yet. The problem is if we use _GNU_SOURCE we will not be able to declare sendmmsg as extern
struct mmsghdr { struct mmsghdr {
struct msghdr msg_hdr; /* Message header */ struct msghdr msg_hdr; /* Message header */
unsigned int msg_len; /* Number of bytes transmitted */ unsigned int msg_len; /* Number of bytes transmitted */
}; };
#endif
#endif
// Those are initialized in the init(...) method and cached for performance reasons // Those are initialized in the init(...) method and cached for performance reasons
jmethodID updatePosId = NULL; jmethodID updatePosId = NULL;
@ -123,7 +125,7 @@ jint epollCtl(JNIEnv * env, jint efd, int op, jint fd, jint flags, jint id) {
return epoll_ctl(efd, op, fd, &ev); return epoll_ctl(efd, op, fd, &ev);
} }
jint getOption(JNIEnv *env, jint fd, int level, int optname, const void *optval, socklen_t optlen) { jint getOption(JNIEnv *env, jint fd, int level, int optname, void *optval, socklen_t optlen) {
int code; int code;
code = getsockopt(fd, level, optname, optval, &optlen); code = getsockopt(fd, level, optname, optval, &optlen);
if (code == 0) { if (code == 0) {
@ -987,7 +989,7 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_socketStream(JNIEnv *
JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_bind(JNIEnv * env, jclass clazz, jint fd, jbyteArray address, jint scopeId, jint port) { JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_bind(JNIEnv * env, jclass clazz, jint fd, jbyteArray address, jint scopeId, jint port) {
struct sockaddr_storage addr; struct sockaddr_storage addr;
if (init_sockaddr(env, address, scopeId, port, &addr) == -1) { if (init_sockaddr(env, address, scopeId, port, &addr) == -1) {
return -1; return;
} }
if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1){ if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1){