diff --git a/fvtest/porttest/CMakeLists.txt b/fvtest/porttest/CMakeLists.txt index a7bf4b6cc72..1bc675c51c8 100644 --- a/fvtest/porttest/CMakeLists.txt +++ b/fvtest/porttest/CMakeLists.txt @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2017, 2018 IBM Corp. and others +# Copyright (c) 2017, 2020 IBM Corp. and others # # This program and the accompanying materials are made available under # the terms of the Eclipse Public License 2.0 which accompanies this @@ -42,7 +42,8 @@ if(OMR_OPT_CUDA) ) endif() -if(OMR_PORT_SOCKET_SUPPORT) +# TODO: Remove AND (NOT OMR_HOST_OS STREQUAL "win") after OMRSOCK API is implemented on Windows. +if((OMR_PORT_SOCKET_SUPPORT) AND (NOT OMR_HOST_OS STREQUAL "win")) set(socketSources omrsockTest.cpp ) diff --git a/fvtest/porttest/makefile b/fvtest/porttest/makefile index 550e4451c6c..57965fc4208 100644 --- a/fvtest/porttest/makefile +++ b/fvtest/porttest/makefile @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2015, 2016 IBM Corp. and others +# Copyright (c) 2015, 2020 IBM Corp. and others # # This program and the accompanying materials are made available under # the terms of the Eclipse Public License 2.0 which accompanies this @@ -54,7 +54,10 @@ OBJECTS := \ main_function ifeq (1,$(OMR_PORT_SOCKET_SUPPORT)) - OBJECTS += omrsockTest + # TODO: Remove ifneq (win,$(OMR_HOST_OS)) after OMRSOCK API is implemented on Windows. + ifneq (win,$(OMR_HOST_OS)) + OBJECTS += omrsockTest + endif endif vpath main_function.cpp $(top_srcdir)/util/main_function diff --git a/fvtest/porttest/omrsockTest.cpp b/fvtest/porttest/omrsockTest.cpp index 3d7d02ec7d9..10e48afd299 100644 --- a/fvtest/porttest/omrsockTest.cpp +++ b/fvtest/porttest/omrsockTest.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2019 IBM Corp. and others + * Copyright (c) 2019, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -23,6 +23,7 @@ #if defined(OMR_PORT_SOCKET_SUPPORT) #include "omrport.h" #include "omrportsock.h" +#include "omrportsocktypes.h" #include "testHelpers.hpp" /** @@ -41,7 +42,7 @@ int32_t start_server(struct OMRPortLibrary *portLibrary, const char *addrStr, const char *port, int32_t family, omrsock_socket_t *serverSocket, omrsock_sockaddr_t serverAddr) { - return OMRPORT_ERROR_NOTEXIST; + return OMRPORT_ERROR_NOTEXIST; } /** @@ -59,7 +60,7 @@ start_server(struct OMRPortLibrary *portLibrary, const char *addrStr, const char int32_t connect_client_to_server(struct OMRPortLibrary *portLibrary, const char *addrStr, const char *port, int32_t family, omrsock_socket_t *sessionClientSocket, omrsock_sockaddr_t sessionClientAddr) { - return OMRPORT_ERROR_NOTEXIST; + return OMRPORT_ERROR_NOTEXIST; } /** @@ -72,7 +73,24 @@ connect_client_to_server(struct OMRPortLibrary *portLibrary, const char *addrStr */ TEST(PortSockTest, library_function_pointers_not_null) { - /* Unimplemented. */ + OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); + + EXPECT_NE(OMRPORTLIB->sock_getaddrinfo_create_hints, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_getaddrinfo, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_getaddrinfo_length, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_getaddrinfo_family, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_getaddrinfo_socktype, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_getaddrinfo_protocol, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_freeaddrinfo, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_socket, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_bind, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_listen, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_accept, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_send, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_sendto, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_recv, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_recvfrom, (void *)NULL); + EXPECT_NE(OMRPORTLIB->sock_close, (void *)NULL); } /** @@ -83,7 +101,17 @@ TEST(PortSockTest, library_function_pointers_not_null) */ TEST(PortSockTest, per_thread_buffer_functionality) { - /* Unimplemented. */ + OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); + + omrsock_addrinfo_t hints = NULL; + int32_t family = 0; + int32_t sockType = 1; + int32_t protocol = 1; + int32_t flags = 0; + + OMRPORTLIB->sock_getaddrinfo_create_hints(OMRPORTLIB, &hints, family, sockType, protocol, flags); + + ASSERT_NE(hints, (void *)NULL); } /** @@ -104,7 +132,7 @@ TEST(PortSockTest, per_thread_buffer_functionality) */ TEST(PortSockTest, getaddrinfo_creation_and_extraction) { - /* Unimplemented. */ + /* Unimplemented. */ } /** @@ -122,7 +150,7 @@ TEST(PortSockTest, getaddrinfo_creation_and_extraction) */ TEST(PortSockTest, two_socket_communication) { - /* Unimplemented. */ + /* Unimplemented. */ } #endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ diff --git a/include_core/omrport.h b/include_core/omrport.h index 372de5df693..ac671f8cee2 100644 --- a/include_core/omrport.h +++ b/include_core/omrport.h @@ -2006,6 +2006,8 @@ typedef struct OMRPortLibrary { /** see @ref omrheap.c::omrheap_grow "omrheap_grow"*/ BOOLEAN (*heap_grow)(struct OMRPortLibrary *portLibrary, struct J9Heap *heap, uintptr_t growAmount) ; #if defined(OMR_PORT_SOCKET_SUPPORT) + /** see @ref omrsock.c::omrsock_startup "omrsock_startup"*/ + int32_t (*sock_startup)(struct OMRPortLibrary *portLibrary) ; /** see @ref omrsock.c::omrsock_getaddrinfo_create_hints "omrsock_getaddrinfo_create_hints"*/ int32_t (*sock_getaddrinfo_create_hints)(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t *hints, int32_t family, int32_t socktype, int32_t protocol, int32_t flags) ; /** see @ref omrsock.c::omrsock_getaddrinfo "omrsock_getaddrinfo"*/ @@ -2040,6 +2042,8 @@ typedef struct OMRPortLibrary { int32_t (*sock_recvfrom)(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags, omrsock_sockaddr_t addrHandle) ; /** see @ref omrsock.c::omrsock_close "omrsock_close"*/ int32_t (*sock_close)(struct OMRPortLibrary *portLibrary, omrsock_socket_t *sock) ; + /** see @ref omrsock.c::omrsock_shutdown "omrsock_shutdown"*/ + int32_t (*sock_shutdown)(struct OMRPortLibrary *portLibrary) ; #endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ #if defined(OMR_OPT_CUDA) /** CUDA configuration data */ @@ -2484,6 +2488,7 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary); #define omrheap_query_size(param1,param2) privateOmrPortLibrary->heap_query_size(privateOmrPortLibrary, (param1), (param2)) #define omrheap_grow(param1,param2) privateOmrPortLibrary->heap_grow(privateOmrPortLibrary, (param1), (param2)) #if defined(OMR_PORT_SOCKET_SUPPORT) +#define omrsock_startup() privateOmrPortLibrary->sock_startup(privateOmrPortLibrary) #define omrsock_getaddrinfo_create_hints(param1,param2,param3,param4,param5) privateOmrPortLibrary->sock_getaddrinfo_create_hints(privateOmrPortLibrary, (param1), (param2), (param3), (param4), (param5)) #define omrsock_getaddrinfo(param1,param2,param3,param4) privateOmrPortLibrary->sock_getaddrinfo(privateOmrPortLibrary, (param1), (param2), (param3), (param4)) #define omrsock_getaddrinfo_length(param1,param2) privateOmrPortLibrary->sock_getaddrinfo_length(privateOmrPortLibrary, (param1), (param2)) @@ -2501,6 +2506,7 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary); #define omrsock_recv(param1,param2,param3,param4) privateOmrPortLibrary->sock_recv(privateOmrPortLibrary, (param1), (param2), (param3), (param4)) #define omrsock_recvfrom(param1,param2,param3,param4,param5) privateOmrPortLibrary->sock_recvfrom(privateOmrPortLibrary, (param1), (param2), (param3), (param4), (param5)) #define omrsock_close(param1) privateOmrPortLibrary->sock_close(privateOmrPortLibrary, (param1)) +#define omrsock_shutdown() privateOmrPortLibrary->sock_shutdown(privateOmrPortLibrary) #endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ #if defined(OMR_OPT_CUDA) diff --git a/include_core/omrporterror.h b/include_core/omrporterror.h index 6b2438a6cc1..cf7e1a0b587 100644 --- a/include_core/omrporterror.h +++ b/include_core/omrporterror.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 1998, 2016 IBM Corp. and others + * Copyright (c) 1998, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -314,4 +314,18 @@ * @} */ +/** + * @name OMR Socket API Errors + * Error code returned by the socket API + * + * @internal OMRPORT_ERROR_SOCK_* range from -500 to -549 avoid overlap + * @{ + */ +#define OMRPORT_ERROR_SOCK_BASE -500 +#define OMRPORT_ERROR_SOCK_PTB_FAILED (OMRPORT_ERROR_SOCK_BASE - 0) +#define OMRPORT_ERROR_SOCK_SYSTEM_FULL (OMRPORT_ERROR_SOCK_BASE - 1) +/** + * @} + */ + #endif /* omrporterror_h */ diff --git a/include_core/omrportsock.h b/include_core/omrportsock.h index 9b79c2dae52..314064f7869 100644 --- a/include_core/omrportsock.h +++ b/include_core/omrportsock.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2019 IBM Corp. and others + * Copyright (c) 2019, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -26,10 +26,12 @@ /* Pointer to OMRAddInfoNode, a struct that contains addrinfo information. */ typedef struct OMRAddrInfoNode *omrsock_addrinfo_t; -/* Pointer to ip address. It has enough space for Ipv4 or IPv6 addresses. */ +/* Pointer to OMRSockAddrStorage, a struct that contains socket address + * information. It has enough space for Ipv4 or IPv6 addresses. + */ typedef struct OMRSockAddrStorage *omrsock_sockaddr_t; -/* Pointer to a socket descriptor */ +/* Pointer to OMRSocket, a struct that contains socket descriptor. */ typedef struct OMRSocket *omrsock_socket_t; #endif /* !defined(OMRPORTSOCK_H_) */ diff --git a/include_core/omrportsocktypes.h b/include_core/omrportsocktypes.h new file mode 100644 index 00000000000..b19faa48c51 --- /dev/null +++ b/include_core/omrportsocktypes.h @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + +#if !defined(OMRPORTSOCKTYPES_H_) +#define OMRPORTSOCKTYPES_H_ + +/** + * WIN32_LEAN_AND_MEAN determines what is included in Windows.h. If it is + * defined, some unneeded header files in Windows.h will not be included. + */ +#if defined(OMR_OS_WINDOWS) && !defined(WIN32_LEAN_AND_MEAN) +#define WIN32_LEAN_AND_MEAN +#endif /* defined(OMR_OS_WINDOWS) && !defined(WIN32_LEAN_AND_MEAN) */ + +/** + * To avoid WINSOCK redefinition errors. + */ +#if defined(OMR_OS_WINDOWS) && defined(_WINSOCKAPI_) +#undef _WINSOCKAPI_ +#endif /* defined(OMR_OS_WINDOWS) && defined(_WINSOCKAPI_) */ + +#if defined(OMR_OS_WINDOWS) +/** + * windows.h defined UDATA. Ignore its definition to avoid redefinition errors. + */ +#define UDATA UDATA_win32_ +#include +#undef UDATA +#include +#include +#pragma comment(lib, "Ws2_32.lib") +#pragma comment(lib, "Mswsock.lib") +#pragma comment(lib, "AdvApi32.lib") +#else /* defined(OMR_OS_WINDOWS) */ +#include +#include +#endif /* defined(OMR_OS_WINDOWS) */ + +#include +#include + +/** + * Data types required for the socket API. + */ +#if defined(OMR_OS_WINDOWS) +typedef SOCKET omr_os_socket; +typedef struct sockaddr_storage omr_os_sockaddr_storage; /* For IPv4 or IPv6 addresses */ +typedef struct addrinfoW omr_os_addrinfo; /* addrinfo structure – Unicode, for IPv4 or IPv6 */ +#else /* defined(OMR_OS_WINDOWS) */ +typedef int omr_os_socket; +typedef struct sockaddr_storage omr_os_sockaddr_storage; /* For IPv4 or IPv6 addresses */ +typedef struct addrinfo omr_os_addrinfo; /* addrinfo structure for IPv4 or IPv6*/ +#endif /* defined(OMR_OS_WINDOWS) */ + +/** + * A struct for storing socket address information. Big enough to store IPv4 and IPv6 addresses. + */ +typedef struct OMRSockAddrStorage { + omr_os_sockaddr_storage data; +} OMRSockAddrStorage; + +/** + * A struct for storing socket information. + */ +typedef struct OMRSocket { + omr_os_socket data; +} OMRSocket; + +/** + * A node in a linked-list of addrinfo. Filled in using @ref omr_getaddrinfo. + */ +typedef struct OMRAddrInfoNode { + /** + * Pointer to the first addrinfo node in listed list. Defined differently depending on the operating system. + */ + omr_os_addrinfo *addrInfo; + + /** + * Number of addrinfo nodes in linked list. + */ + uint32_t length; +} OMRAddrInfoNode; + +#endif /* !defined(OMRPORTSOCKTYPES_H_) */ diff --git a/port/CMakeLists.txt b/port/CMakeLists.txt index bab6ccf2fc5..1c4169a3854 100644 --- a/port/CMakeLists.txt +++ b/port/CMakeLists.txt @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2017, 2019 IBM Corp. and others +# Copyright (c) 2017, 2020 IBM Corp. and others # # This program and the accompanying materials are made available under # the terms of the Eclipse Public License 2.0 which accompanies this @@ -183,7 +183,7 @@ list(APPEND OBJECTS ) if(OMR_PORT_SOCKET_SUPPORT) - list(APPEND OBJECTS omrsock.c) + list(APPEND OBJECTS omrsock.c omrsockptb.c) endif() if(NOT OMR_HOST_OS STREQUAL "win") diff --git a/port/common/omrport.c b/port/common/omrport.c index 6f1862ab49c..b4277ce015e 100644 --- a/port/common/omrport.c +++ b/port/common/omrport.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2019 IBM Corp. and others + * Copyright (c) 2015, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -302,6 +302,7 @@ static OMRPortLibrary MasterPortLibraryTable = { omrheap_query_size, /* heap_query_size */ omrheap_grow, /* heap_grow*/ #if defined(OMR_PORT_SOCKET_SUPPORT) + omrsock_startup, /* sock_startup */ omrsock_getaddrinfo_create_hints, /* sock_getaddrinfo_create_hints */ omrsock_getaddrinfo, /* sock_getaddrinfo */ omrsock_getaddrinfo_length, /* sock_getaddrinfo_length */ @@ -319,6 +320,7 @@ static OMRPortLibrary MasterPortLibraryTable = { omrsock_recv, /* sock_recv */ omrsock_recvfrom, /* sock_recvfrom */ omrsock_close, /* sock_close */ + omrsock_shutdown, /* sock_shutdown */ #endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ #if defined(OMR_OPT_CUDA) NULL, /* cuda_configData */ @@ -446,6 +448,9 @@ omrport_shutdown_library(struct OMRPortLibrary *portLibrary) #if defined(OMR_OPT_CUDA) portLibrary->cuda_shutdown(portLibrary); #endif /* OMR_OPT_CUDA */ +#if defined(OMR_PORT_SOCKET_SUPPORT) + portLibrary->sock_shutdown(portLibrary); +#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ portLibrary->introspect_shutdown(portLibrary); portLibrary->sig_shutdown(portLibrary); portLibrary->str_shutdown(portLibrary); @@ -647,6 +652,13 @@ omrport_startup_library(struct OMRPortLibrary *portLibrary) goto cleanup; } +#if defined(OMR_PORT_SOCKET_SUPPORT) + rc = portLibrary->sock_startup(portLibrary); + if (0 != rc) { + goto cleanup; + } +#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ + #if defined(OMR_OPT_CUDA) rc = portLibrary->cuda_startup(portLibrary); if (0 != rc) { diff --git a/port/common/omrsock.c b/port/common/omrsock.c index 7abe7480a0d..d3ff75a658f 100644 --- a/port/common/omrsock.c +++ b/port/common/omrsock.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2019 IBM Corp. and others + * Copyright (c) 2019, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -32,6 +32,21 @@ #include "omrporterror.h" #include "omrportsock.h" +/** + * Set up omrsock per thread buffer. + * + * Pass in user preference of IPv6 Support in omrsock_startup: TODO. + * + * @param[in] portLibrary The port library. + * + * @return 0, if no errors occurred, otherwise return an error. + */ +int32_t +omrsock_startup(struct OMRPortLibrary *portLibrary) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + /** * Returns hints as a double pointer to an OMRAddInfoNode structure. * @@ -369,4 +384,17 @@ omrsock_close(struct OMRPortLibrary *portLibrary, omrsock_socket_t *sock) return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; } +/** + * Shut down omrsock per thread buffer. + * + * @param[in] portLibrary The port library. + * + * @return 0, if no errors occurred, otherwise return an error. + */ +int32_t +omrsock_shutdown(struct OMRPortLibrary *portLibrary) +{ + return 0; +} + #endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ diff --git a/port/common/omrsockptb.c b/port/common/omrsockptb.c new file mode 100644 index 00000000000..f3244300b29 --- /dev/null +++ b/port/common/omrsockptb.c @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + +/** + * @file + * @ingroup Port + * @brief Per-thread buffer (PTB) for socket information. + * + * Per thread buffers (PTB) are used to store information that is not shareable among the threads. + * For example when an OS system call fails the error code associated with that error is + * relevant to the thread that called the OS function; it has no meaning to any other thread. + * + * This file contains the functions supported by the port library for creating, accessing and + * destroying per thread buffers. @see omrsock.h for details on the per thread buffer structure. + */ + +#include "omrsockptb.h" + +/** + * @internal + * @brief Omrsock Per Thread Buffer (PTB) Support + * + * Get a per thread buffer. + * + * OMRSocketPTB is the per thread buffer and omrsock_ptb_t is a pointer to OMRSocketPTB. Both are defined + * in @ref omrsockptb.h. + * + * @param[in] portLibrary The port library. + * + * @return a pointer to the per thread buffer on success, otherwise return NULL. + */ +omrsock_ptb_t +omrsock_ptb_get(struct OMRPortLibrary *portLibrary) +{ + omrthread_t self = omrthread_self(); + omrsock_ptb_t ptBuffer = (omrsock_ptb_t)omrthread_tls_get(self, portLibrary->portGlobals->socketTlsKey); + + if (NULL == ptBuffer) { + ptBuffer = (omrsock_ptb_t)portLibrary->mem_allocate_memory(portLibrary, sizeof(OMRSocketPTB), OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY); + if (NULL != ptBuffer) { + if (0 == omrthread_tls_set(self, portLibrary->portGlobals->socketTlsKey, ptBuffer)) { + memset(ptBuffer, 0, sizeof(OMRSocketPTB)); + ptBuffer->portLibrary = portLibrary; + } else { + portLibrary->mem_free_memory(portLibrary, ptBuffer); + ptBuffer = NULL; + } + } + } + return ptBuffer; +} + +/** + * @internal + * @brief Omrsock Per Thread Buffer (PTB) Support + * + * Free the current thread's OMRSocketPTB. This function is the finalizer function referred + * in @ref omrsock_ptb_init. This function is invoked when a thread is detached or terminated + * if the thread's TLS entry for socketTlsKey is non-NULL. + * + * @param[in] socketPTBVoidP The current thread's J9SocketPTB. + * + * @return void return type. + */ +static void J9THREAD_PROC +omrsock_ptb_free(void *socketPTBVoidP) +{ + omrsock_ptb_t ptBuffer = (omrsock_ptb_t)socketPTBVoidP; + struct OMRPortLibrary *portLibrary = ptBuffer->portLibrary; + + /* Free the ptBuffer */ + if (NULL != ptBuffer->addrInfoHints.addrInfo) { + portLibrary->mem_free_memory(portLibrary, ptBuffer->addrInfoHints.addrInfo); + } + + portLibrary->mem_free_memory(portLibrary, ptBuffer); +} + +/** + * @internal + * @brief Omrsock Per Thread Buffer (PTB) Support + * + * Initialize omrsockptb, to use omrsockptb related functions. + * + * This function is called during startup of omrsock. All resources created here should be + * destroyed in @ref omrsock_ptb_shutdown. + * + * @param[in] portLibrary The port library. + * + * @return 0, if no errors occurred, otherwise return an error. + */ +int32_t +omrsock_ptb_init(struct OMRPortLibrary *portLibrary) +{ + if(0 != omrthread_tls_alloc_with_finalizer(&(portLibrary->portGlobals->socketTlsKey), omrsock_ptb_free)){ + return OMRPORT_ERROR_SOCK_PTB_FAILED; + } + return 0; +} + +/** + * @internal + * @brief Omrsock Per Thread Buffer (PTB) Support + * + * Shutdown omrsockptb, shutdown omrsockptb related functions. + * + * This function is called during shutdown of omrsock. Any resources that were created by + * @ref omrsock_ptb_init should be destroyed here. + * + * @param[in] OMRPortLibrary The port library. + * + * @return 0, if no errors occurred, otherwise return an error. + */ +int32_t +omrsock_ptb_shutdown(struct OMRPortLibrary *portLibrary) +{ + if ((NULL != portLibrary->portGlobals) && (0 != portLibrary->portGlobals->socketTlsKey)) { + /* Release the TLS key */ + if (0 != omrthread_tls_free(portLibrary->portGlobals->socketTlsKey)) { + return OMRPORT_ERROR_SOCK_PTB_FAILED; + } + portLibrary->portGlobals->socketTlsKey = 0; + } + return 0; +} diff --git a/port/common/omrsockptb.h b/port/common/omrsockptb.h new file mode 100644 index 00000000000..6b512f9a689 --- /dev/null +++ b/port/common/omrsockptb.h @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + +/* Per-thread buffer functions for socket information */ + +#ifndef OMRSOCKPTB_H_ +#define OMRSOCKPTB_H_ + +#include +#include + +#include "omrport.h" +#include "omrporterror.h" +#include "omrportpriv.h" +#include "omrportsock.h" +#include "omrportsocktypes.h" +#include "thread_api.h" + +/* Per-thread buffer for socket information */ +typedef struct OMRSocketPTB { + OMRAddrInfoNode addrInfoHints; + struct OMRPortLibrary *portLibrary; +} OMRSocketPTB; + +typedef OMRSocketPTB *omrsock_ptb_t; + +omrsock_ptb_t omrsock_ptb_get(struct OMRPortLibrary *portLibrary); +int32_t omrsock_ptb_init(struct OMRPortLibrary *portLibrary); +int32_t omrsock_ptb_shutdown(struct OMRPortLibrary *portLibrary); + +#endif /* OMRSOCKPTB_H_ */ diff --git a/port/omrportpriv.h b/port/omrportpriv.h index 559c6c94fbf..8b744af35dd 100644 --- a/port/omrportpriv.h +++ b/port/omrportpriv.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 1991, 2019 IBM Corp. and others + * Copyright (c) 1991, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -114,6 +114,9 @@ typedef struct OMRPortLibraryGlobalData { struct J9PortControlData control; struct J9NLSDataCache nls_data; omrthread_tls_key_t tls_key; +#if defined(OMR_PORT_SOCKET_SUPPORT) + omrthread_tls_key_t socketTlsKey; +#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ MUTEX tls_mutex; void *buffer_list; void *procSelfMap; @@ -607,6 +610,8 @@ omrsl_shutdown(struct OMRPortLibrary *portLibrary); /* J9SourceJ9Sock*/ #if defined(OMR_PORT_SOCKET_SUPPORT) extern J9_CFUNC int32_t +omrsock_startup(struct OMRPortLibrary *portLibrary); +extern J9_CFUNC int32_t omrsock_getaddrinfo_create_hints(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t *hints, int32_t family, int32_t socktype, int32_t protocol, int32_t flags); extern J9_CFUNC int32_t omrsock_getaddrinfo(struct OMRPortLibrary *portLibrary, char *node, char *service, omrsock_addrinfo_t hints, omrsock_addrinfo_t result); @@ -640,6 +645,8 @@ extern J9_CFUNC int32_t omrsock_recvfrom(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags, omrsock_sockaddr_t addrHandle); extern J9_CFUNC int32_t omrsock_close(struct OMRPortLibrary *portLibrary, omrsock_socket_t *sock); +extern J9_CFUNC int32_t +omrsock_shutdown(struct OMRPortLibrary *portLibrary); #endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ /* J9SourceJ9Str*/ diff --git a/port/port_objects.mk b/port/port_objects.mk index dc326c5c00e..bdb7e40d850 100644 --- a/port/port_objects.mk +++ b/port/port_objects.mk @@ -147,7 +147,8 @@ ifneq (win,$(OMR_HOST_OS)) OBJECTS += omrsignal_context endif ifeq (1, $(OMR_PORT_SOCKET_SUPPORT)) -OBJECTS += omrsock + OBJECTS += omrsock + OBJECTS += omrsockptb endif OBJECTS += omrsl OBJECTS += omrstr diff --git a/port/unix/omrsock.c b/port/unix/omrsock.c new file mode 100644 index 00000000000..1d447022b63 --- /dev/null +++ b/port/unix/omrsock.c @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + +/** + * @file + * @ingroup Port + * @brief Sockets + */ + +#include +#include + +#include "omrcfg.h" +#if defined(OMR_PORT_SOCKET_SUPPORT) +#include "omrport.h" +#include "omrporterror.h" +#include "omrsockptb.h" + +int32_t +omrsock_startup(struct OMRPortLibrary *portLibrary) +{ + return omrsock_ptb_init(portLibrary); +} + +int32_t +omrsock_getaddrinfo_create_hints(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t *hints, int32_t family, int32_t socktype, int32_t protocol, int32_t flags) +{ + *hints = NULL; + omrsock_ptb_t ptBuffer = NULL; + omr_os_addrinfo *ptbHints = NULL; + + /* Initialized the pt buffers if necessary */ + ptBuffer = omrsock_ptb_get(portLibrary); + if (NULL == ptBuffer) { + return OMRPORT_ERROR_SOCK_PTB_FAILED; + } + + ptbHints = (ptBuffer->addrInfoHints).addrInfo; + if (NULL == ptbHints) { + ptbHints = portLibrary->mem_allocate_memory(portLibrary, sizeof(omr_os_addrinfo), OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY); + if (NULL == ptbHints) { + return OMRPORT_ERROR_SOCK_SYSTEM_FULL; + } + } + memset(ptbHints, 0, sizeof(omr_os_addrinfo)); + + ptbHints->ai_flags = flags; + ptbHints->ai_family = family; + ptbHints->ai_socktype = socktype; + ptbHints->ai_protocol = protocol; + + (ptBuffer->addrInfoHints).addrInfo = ptbHints; + *hints = &ptBuffer->addrInfoHints; + return 0; +} + +int32_t +omrsock_getaddrinfo(struct OMRPortLibrary *portLibrary, char *node, char *service, omrsock_addrinfo_t hints, omrsock_addrinfo_t result) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo_length(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t hints, uint32_t *length) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo_family(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t handle, int32_t *family, int32_t index) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo_socktype(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t handle, int32_t *socktype, int32_t index) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo_protocol(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t handle, int32_t *protocol, int32_t index) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_freeaddrinfo(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t handle) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_socket(struct OMRPortLibrary *portLibrary, omrsock_socket_t *sock, int32_t family, int32_t socktype, int32_t protocol) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_bind(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, omrsock_sockaddr_t addr) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_listen(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, int32_t backlog) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_connect(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, omrsock_sockaddr_t addr) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_accept(struct OMRPortLibrary *portLibrary, omrsock_socket_t serverSock, omrsock_sockaddr_t addrHandle, omrsock_socket_t *sockHandle) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_send(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_sendto(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags, omrsock_sockaddr_t addrHandle) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_recv(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_recvfrom(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags, omrsock_sockaddr_t addrHandle) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_close(struct OMRPortLibrary *portLibrary, omrsock_socket_t *sock) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_shutdown(struct OMRPortLibrary *portLibrary) +{ + return omrsock_ptb_shutdown(portLibrary); +} + +#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */ diff --git a/port/win32/omrsock.c b/port/win32/omrsock.c new file mode 100644 index 00000000000..c6d53aaf4d7 --- /dev/null +++ b/port/win32/omrsock.c @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + +/** + * @file + * @ingroup Port + * @brief Sockets + */ + +#include "omrcfg.h" +#if defined(OMR_PORT_SOCKET_SUPPORT) +#include "omrport.h" +#include "omrporterror.h" +#include "omrsockptb.h" + +int32_t +omrsock_startup(struct OMRPortLibrary *portLibrary) +{ + return omrsock_ptb_init(portLibrary); +} + +int32_t +omrsock_getaddrinfo_create_hints(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t *hints, int32_t family, int32_t socktype, int32_t protocol, int32_t flags) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo(struct OMRPortLibrary *portLibrary, char *node, char *service, omrsock_addrinfo_t hints, omrsock_addrinfo_t result) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo_length(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t hints, uint32_t *length) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo_family(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t handle, int32_t *family, int32_t index) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo_socktype(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t handle, int32_t *socktype, int32_t index) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_getaddrinfo_protocol(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t handle, int32_t *protocol, int32_t index) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_freeaddrinfo(struct OMRPortLibrary *portLibrary, omrsock_addrinfo_t handle) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_socket(struct OMRPortLibrary *portLibrary, omrsock_socket_t *sock, int32_t family, int32_t socktype, int32_t protocol) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_bind(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, omrsock_sockaddr_t addr) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_listen(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, int32_t backlog) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_connect(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, omrsock_sockaddr_t addr) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_accept(struct OMRPortLibrary *portLibrary, omrsock_socket_t serverSock, omrsock_sockaddr_t addrHandle, omrsock_socket_t *sockHandle) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_send(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_sendto(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags, omrsock_sockaddr_t addrHandle) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_recv(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_recvfrom(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, uint8_t *buf, int32_t nbyte, int32_t flags, omrsock_sockaddr_t addrHandle) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_close(struct OMRPortLibrary *portLibrary, omrsock_socket_t *sock) +{ + return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; +} + +int32_t +omrsock_shutdown(struct OMRPortLibrary *portLibrary) +{ + return omrsock_ptb_shutdown(portLibrary); +} + +#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */