1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-10-05 19:18:01 +08:00

add mimalloc

This commit is contained in:
stefanocasazza 2020-05-24 01:15:48 +02:00
parent 35fa262ab4
commit 6eaac44aa2
33 changed files with 1076 additions and 1356 deletions

82
configure vendored
View File

@ -1093,6 +1093,7 @@ enable_zip
with_libzopfli
with_libbrotli
with_libquiche
with_libmimalloc
with_magic
enable_ssl_staticlib_deps
with_ssl
@ -1863,6 +1864,7 @@ Optional Packages:
--with-libzopfli use system zopfli library - [will check /usr /usr/local] [default=use if present]
--with-libbrotli use system brotli library - [will check /usr /usr/local] [default=use if present]
--with-libquiche use system quiche library - [will check /usr /usr/local] [default=use if present]
--with-libmimalloc use system mimalloc library - [will check /usr /usr/local] [default=use if present]
--with-magic use system libmagic library - [will check /usr /usr/local] [default=use if present]
--with-ssl use system SSL library - [will check /usr /usr/local] [default=use if present]
--with-pcre use system PCRE library - [will check /usr /usr/local] [default=use if present]
@ -26219,6 +26221,7 @@ $as_echo "${T_MD}C++ stuff:${T_ME}" >&6; }
ulib_libzopfli_msg="no (--with-libzopfli)"
ulib_libbrotli_msg="no (--with-libbrotli)"
ulib_libquiche_msg="no (--with-libquiche)"
ulib_mimalloc_msg="no (--with-libmimalloc)"
ulib_libtdb_msg="no (--with-libtdb)"
ulib_curl_msg="no (--with-curl)"
ulib_expat_msg="no (--with-expat)"
@ -27446,6 +27449,7 @@ libz_version="unknow"
libzopfli_version="unknown"
libbrotli_version="unknown"
libquiche_version="unknown"
mimalloc_version="unknown"
libtdb_version="unknown"
pcre_version="unknown"
ldap_version="unknown"
@ -27748,6 +27752,73 @@ $as_echo "no" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if mimalloc library is wanted" >&5
$as_echo_n "checking if mimalloc library is wanted... " >&6; }
wanted=1;
if test -z "$with_libmimalloc" ; then
wanted=0;
if test -n "$CROSS_ENVIRONMENT" -o "$USP_FLAGS" = "-DAS_cpoll_cppsp_DO" -o "$enable_shared" = "no"; then
with_libmimalloc="no";
else
with_libmimalloc="${CROSS_ENVIRONMENT}/usr";
fi
fi
# Check whether --with-libmimalloc was given.
if test "${with_libmimalloc+set}" = set; then :
withval=$with_libmimalloc;
if test "$withval" = "no"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
for dir in $withval ${CROSS_ENVIRONMENT}/ ${CROSS_ENVIRONMENT}/usr ${CROSS_ENVIRONMENT}/usr/local; do
libmimallocdir="$dir"
if test -f "$dir/include/mimalloc.h"; then
found_libmimalloc="yes";
break;
fi
done
if test x_$found_libmimalloc != x_yes; then
msg="Cannot find libmimalloc library";
if test $wanted = 1; then
as_fn_error $? "$msg" "$LINENO" 5
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $msg" >&5
$as_echo "$msg" >&6; }
fi
else
echo "${T_MD}libmimalloc found in $libmimallocdir${T_ME}"
USE_LIBMIMALLOC=yes
$as_echo "#define USE_LIBMIMALLOC 1" >>confdefs.h
if test -z "$CROSS_ENVIRONMENT" -a x_$PKG_CONFIG != x_no; then
libmimalloc_version=$(pkg-config --modversion mimalloc 2>/dev/null)
fi
if test -z "${libmimalloc}"; then
libmimalloc_version=$(ls $libmimallocdir/lib*/libmimalloc.so.*.* 2>/dev/null | head -n 1 | awk -F'.so.' '{n=2; print $n}' 2>/dev/null)
fi
if test -z "${libmimalloc_version}"; then
libmimalloc_version="unknown"
fi
ULIB_LIBS="$ULIB_LIBS -lmimalloc";
if test $libmimallocdir != "${CROSS_ENVIRONMENT}/" -a $libmimallocdir != "${CROSS_ENVIRONMENT}/usr" -a $libmimallocdir != "${CROSS_ENVIRONMENT}/usr/local"; then
CPPFLAGS="$CPPFLAGS -I$libmimallocdir/include"
LDFLAGS="$LDFLAGS -L$libmimallocdir/lib -Wl,-R$libmimallocdir/lib";
PRG_LDFLAGS="$PRG_LDFLAGS -L$libmimallocdir/lib";
fi
fi
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if MAGIC library is wanted" >&5
$as_echo_n "checking if MAGIC library is wanted... " >&6; }
wanted=1;
@ -29288,6 +29359,10 @@ if test "$USE_LIBQUICHE" = "yes"; then
ulib_libquiche_msg="yes ( $libquiche_version )"
fi
if test "$USE_LIBMIMALLOC" = "yes"; then
ulib_mimalloc_msg="yes ( $libmimalloc_version )"
fi
if test "$USE_LIBTDB" = "yes"; then
ulib_libtdb_msg="yes ( $libtdb_version )"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdb_traverse_read in -ltdb" >&5
@ -30885,6 +30960,11 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
cat >>confdefs.h <<_ACEOF
#define _LIBMIMALLOC_VERSION "$libmimalloc_version"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define _LIBTDB_VERSION "$libtdb_version"
_ACEOF
@ -34294,6 +34374,7 @@ ULIB_SYSCONFDIR="$u_sysconfdir"
LIBZOPFLI support: ${ulib_libzopfli_msg}
LIBBROTLI support: ${ulib_libbrotli_msg}
LIBQUICHE support: ${ulib_libquiche_msg}
MIMALLOC support: ${ulib_mimalloc_msg}
LIBTDB support: ${ulib_libtdb_msg}
PCRE support: ${ulib_pcre_msg}
SSL support: ${ulib_ssl_msg}
@ -34358,6 +34439,7 @@ $as_echo "$as_me: Configured to build src/ulib/lib${ULIB}:
LIBZOPFLI support: ${ulib_libzopfli_msg}
LIBBROTLI support: ${ulib_libbrotli_msg}
LIBQUICHE support: ${ulib_libquiche_msg}
MIMALLOC support: ${ulib_mimalloc_msg}
LIBTDB support: ${ulib_libtdb_msg}
PCRE support: ${ulib_pcre_msg}
SSL support: ${ulib_ssl_msg}

View File

@ -1309,6 +1309,7 @@ dnl initialize all the info variables to 'no'
ulib_libzopfli_msg="no (--with-libzopfli)"
ulib_libbrotli_msg="no (--with-libbrotli)"
ulib_libquiche_msg="no (--with-libquiche)"
ulib_mimalloc_msg="no (--with-libmimalloc)"
ulib_libtdb_msg="no (--with-libtdb)"
ulib_curl_msg="no (--with-curl)"
ulib_expat_msg="no (--with-expat)"
@ -1447,6 +1448,7 @@ libz_version="unknow"
libzopfli_version="unknown"
libbrotli_version="unknown"
libquiche_version="unknown"
mimalloc_version="unknown"
libtdb_version="unknown"
pcre_version="unknown"
ldap_version="unknown"
@ -1538,6 +1540,10 @@ if test "$USE_LIBQUICHE" = "yes"; then
ulib_libquiche_msg="yes ( $libquiche_version )"
fi
if test "$USE_LIBMIMALLOC" = "yes"; then
ulib_mimalloc_msg="yes ( $libmimalloc_version )"
fi
if test "$USE_LIBTDB" = "yes"; then
ulib_libtdb_msg="yes ( $libtdb_version )"
AC_CHECK_LIB(tdb,tdb_traverse_read)
@ -2034,6 +2040,7 @@ AC_DEFINE_UNQUOTED(_LIBZ_VERSION, "$libz_version", [libz - general purpose c
AC_DEFINE_UNQUOTED(_LIBZOPFLI_VERSION, "$libzopfli_version", [libzopfli - google compression library version])
AC_DEFINE_UNQUOTED(_LIBBROTLI_VERSION, "$libbrotli_version", [libbrotli - google compression library version])
AC_DEFINE_UNQUOTED(_LIBQUICHE_VERSION, "$libquiche_version", [libquiche - library version of implementation of the QUIC transport protocol and HTTP/3])
AC_DEFINE_UNQUOTED(_LIBMIMALLOC_VERSION,"$libmimalloc_version",[libmimalloc - library version of implementation of the QUIC transport protocol and HTTP/3])
AC_DEFINE_UNQUOTED(_LIBTDB_VERSION, "$libtdb_version", [libtdb - samba Trivial DB library version])
AC_DEFINE_UNQUOTED(_LIBSSH_VERSION, "$libssh_version", [libSSH version])
AC_DEFINE_UNQUOTED(_SSL_VERSION, "$ssl_version", [SSL version])
@ -3126,6 +3133,7 @@ AC_MSG_NOTICE([Configured to build src/ulib/lib${ULIB}:
LIBZOPFLI support: ${ulib_libzopfli_msg}
LIBBROTLI support: ${ulib_libbrotli_msg}
LIBQUICHE support: ${ulib_libquiche_msg}
MIMALLOC support: ${ulib_mimalloc_msg}
LIBTDB support: ${ulib_libtdb_msg}
PCRE support: ${ulib_pcre_msg}
SSL support: ${ulib_ssl_msg}

View File

@ -285,6 +285,17 @@ public:
void insert(const UString& k, const void* e) { return insert(k.rep, e); }
void replace(const char* k, uint32_t klen, const void* e)
{
U_TRACE(0, "UHashMap<void*>::replace(%#.*S,%u,%p)", klen, k, klen, e)
setKey(k, klen);
lookup();
replaceAfterFind(e);
}
void* erase(const char* k, uint32_t klen)
{
U_TRACE(0, "UHashMap<void*>::erase(%#.*S,%u)", klen, k, klen)
@ -987,6 +998,17 @@ public:
void insert(const UString& k, const T* e) { return insert(k.rep, e); }
void replace(const char* k, uint32_t klen, const T* e)
{
U_TRACE(0, "UHashMap<T*>::replace(%#.*S,%u,%p)", klen, k, klen, e)
setKey(k, klen);
lookup();
replaceAfterFind(e);
}
// find a elem in the array with key
T* at(const UString& k) { return (T*) UHashMap<void*>::at(k.rep); }

View File

@ -87,7 +87,8 @@ public:
}
// method VIRTUAL to define
virtual int handlerConnect() { return U_NOTIFIER_DELETE; }
virtual int handlerRead() { return U_NOTIFIER_DELETE; }
virtual int handlerWrite() { return U_NOTIFIER_DELETE; }
virtual int handlerTimeout() { return U_NOTIFIER_DELETE; }

View File

@ -747,6 +747,9 @@
/* Define if enable libmagic support */
#undef USE_LIBMAGIC
/* Define if enable libmimalloc support */
#undef USE_LIBMIMALLOC
/* Define if enable libpcre support */
#undef USE_LIBPCRE
@ -1010,6 +1013,10 @@
/* libevent - event notification library version */
#undef _LIBEVENT_VERSION
/* libmimalloc - library version of implementation of the QUIC transport
protocol and HTTP/3 */
#undef _LIBMIMALLOC_VERSION
/* libquiche - library version of implementation of the QUIC transport
protocol and HTTP/3 */
#undef _LIBQUICHE_VERSION

View File

@ -16,6 +16,12 @@
#include <ulib/internal/common.h>
#ifdef USE_LIBMIMALLOC
# include <mimalloc.h> // mimalloc-new-delete.h
# define malloc(x) mi_malloc(x)
# define free(x) mi_free(x)
#endif
// ---------------------------------------------------------------------------------------------------------------
// U_STACK_TYPE_[0-9] 'type' stack for which the request is serviced with preallocation
@ -524,7 +530,7 @@ public:
#endif
static void* malloc(uint32_t num, uint32_t type_size = sizeof(char), bool bzero = false);
static void* u_malloc(uint32_t num, uint32_t type_size = sizeof(char), bool bzero = false);
#ifdef DEBUG
static const char* obj_class;
@ -602,7 +608,7 @@ template <class T> bool u_check_memory_vector(T* _vec, uint32_t n)
# define U_MEMORY_ALLOCATOR \
void* operator new( size_t sz) { U_INTERNAL_ASSERT(sz <= U_MAX_SIZE_PREALLOCATE); return UMemoryPool::pop(U_SIZE_TO_STACK_INDEX(sz)); } \
void* operator new[](size_t sz) { return UMemoryPool::malloc(sz); }
void* operator new[](size_t sz) { return UMemoryPool::u_malloc(sz); }
# define U_MEMORY_DEALLOCATOR \
void operator delete( void* _ptr, size_t sz) { U_INTERNAL_ASSERT(sz <= U_MAX_SIZE_PREALLOCATE); UMemoryPool::push( _ptr, U_SIZE_TO_STACK_INDEX(sz)); } \
void operator delete[](void* _ptr, size_t sz) { UMemoryPool::_free(_ptr, sz); }

View File

@ -865,7 +865,7 @@ protected:
bool processRequest(char recvtype);
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__)
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
bool sendRequest(UStringType&& pipeline)
#else
bool sendRequest(const UString& pipeline)
@ -1037,7 +1037,7 @@ private:
// by Victor Stewart
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__)
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
class UCompileTimeRESPEncoder : public UCompileTimeStringFormatter {
private:

View File

@ -673,7 +673,13 @@ public:
*/
virtual bool connectServer(const UString& server, unsigned int iServPort, int timeoutMS = 0);
#ifdef HAVE_EPOLL_WAIT
// this method initiates an asynchronous connection that you must later wait on with UNotifier::waitOnAsynchronousConnects
virtual bool beginAsynchronousConnect(const UString& server, unsigned int iServPort);
virtual bool finishAsynchronousConnect();
#endif
/**
* This method is called to receive a block of data on the connected socket.
* The parameters signify the payload receiving buffer and its size.

View File

@ -185,7 +185,12 @@ public:
# endif
}
#endif
#ifdef HAVE_EPOLL_WAIT
// this timeout does not include time spent in event handlers, only time waiting on epoll
static bool waitOnAsynchronousBatch(const UVector<UEventFd *>& waiting, int op, int timeoutMS = -1);
#endif
// READ - WRITE
// param timeoutMS specified the timeout value, in milliseconds.

View File

@ -3172,6 +3172,7 @@ public:
}
};
# if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
template<typename T>
concept bool UCompileTimeStringType = requires(T string) {
is_ctv_v<T>;
@ -3188,7 +3189,7 @@ inline bool operator==(const UCompileTimeStringType& lhs, const UString& rhs){ r
inline bool operator!=(const UString& lhs, const UCompileTimeStringType& rhs){ return !lhs.equal(rhs.string); }
inline bool operator!=(const UCompileTimeStringType& lhs, const UString& rhs){ return !rhs.equal(lhs.string); }
# endif
# endif
#endif
#endif

View File

@ -49,14 +49,18 @@ public:
Short = 0x006
};
typedef struct conn_io {
quiche_conn* conn;
quiche_h3_conn* http3;
} conn_io;
static bool handlerRead();
static bool handlerAccept();
static int loadConfigParam();
protected:
static quiche_conn* conn;
static conn_io conn;
static size_t conn_id_len;
static quiche_h3_conn* http3;
static quiche_config* qconfig;
static quiche_h3_config* http3_config;
static struct sockaddr_storage peer_addr;

View File

@ -214,6 +214,59 @@ AC_DEFUN([AC_CHECK_PACKAGE],[
fi
], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(if mimalloc library is wanted)
wanted=1;
if test -z "$with_libmimalloc" ; then
wanted=0;
if test -n "$CROSS_ENVIRONMENT" -o "$USP_FLAGS" = "-DAS_cpoll_cppsp_DO" -o "$enable_shared" = "no"; then
with_libmimalloc="no";
else
with_libmimalloc="${CROSS_ENVIRONMENT}/usr";
fi
fi
AC_ARG_WITH(libmimalloc, [ --with-libmimalloc use system mimalloc library - [[will check /usr /usr/local]] [[default=use if present]]], [
if test "$withval" = "no"; then
AC_MSG_RESULT(no)
else
AC_MSG_RESULT(yes)
for dir in $withval ${CROSS_ENVIRONMENT}/ ${CROSS_ENVIRONMENT}/usr ${CROSS_ENVIRONMENT}/usr/local; do
libmimallocdir="$dir"
if test -f "$dir/include/mimalloc.h"; then
found_libmimalloc="yes";
break;
fi
done
if test x_$found_libmimalloc != x_yes; then
msg="Cannot find libmimalloc library";
if test $wanted = 1; then
AC_MSG_ERROR($msg)
else
AC_MSG_RESULT($msg)
fi
else
echo "${T_MD}libmimalloc found in $libmimallocdir${T_ME}"
USE_LIBMIMALLOC=yes
AC_DEFINE(USE_LIBMIMALLOC, 1, [Define if enable libmimalloc support])
if test -z "$CROSS_ENVIRONMENT" -a x_$PKG_CONFIG != x_no; then
libmimalloc_version=$(pkg-config --modversion mimalloc 2>/dev/null)
fi
if test -z "${libmimalloc}"; then
libmimalloc_version=$(ls $libmimallocdir/lib*/libmimalloc.so.*.* 2>/dev/null | head -n 1 | awk -F'.so.' '{n=2; print $n}' 2>/dev/null)
fi
if test -z "${libmimalloc_version}"; then
libmimalloc_version="unknown"
fi
ULIB_LIBS="$ULIB_LIBS -lmimalloc";
if test $libmimallocdir != "${CROSS_ENVIRONMENT}/" -a $libmimallocdir != "${CROSS_ENVIRONMENT}/usr" -a $libmimallocdir != "${CROSS_ENVIRONMENT}/usr/local"; then
CPPFLAGS="$CPPFLAGS -I$libmimallocdir/include"
LDFLAGS="$LDFLAGS -L$libmimallocdir/lib -Wl,-R$libmimallocdir/lib";
PRG_LDFLAGS="$PRG_LDFLAGS -L$libmimallocdir/lib";
fi
fi
fi
], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(if MAGIC library is wanted)
wanted=1;
if test -z "$with_magic" ; then

View File

@ -111,7 +111,7 @@ bool UCache::open(const UString& path, const UString& dir, const UString* enviro
if (( _x.size() == 0 ||
(_x.fstat(), _x.st_mtime < _y.st_mtime)) &&
(UDirWalk::setFollowLinks(true), n = dirwalk.walk(vec1)))
(UDirWalk::setFollowLinks(true), (n = dirwalk.walk(vec1))))
{
exist = false;

View File

@ -121,7 +121,7 @@ void UCommand::setCommand()
uint32_t n = 1+ncmd+1;
argv_exec = (char**) UMemoryPool::malloc(n + U_ADD_ARGS, sizeof(char*)); // U_ADD_ARGS => space for addArgument()...
argv_exec = (char**) UMemoryPool::u_malloc(n + U_ADD_ARGS, sizeof(char*)); // U_ADD_ARGS => space for addArgument()...
U_MEMCPY(argv_exec, argv, n * sizeof(char*)); // NB: copy also null terminator...
}
@ -145,7 +145,7 @@ uint32_t UCommand::setEnvironment(const UString& env, char**& _envp)
uint32_t n = _nenv + 1; // NB: consider also null terminator...
_envp = (char**) UMemoryPool::malloc(n, sizeof(char*)); // NB: consider also null terminator...
_envp = (char**) UMemoryPool::u_malloc(n, sizeof(char*)); // NB: consider also null terminator...
U_MEMCPY(_envp, argp, n * sizeof(char*)); // NB: copy also null terminator...

View File

@ -61,7 +61,7 @@ void UHashMap<void*>::_allocate(uint32_t n)
U_INTERNAL_ASSERT_EQUALS(n & (n-1), 0)
info = (uint8_t*) U_SYSCALL(malloc, "%u", n*(1+UHashMapNode::size())); // UMemoryPool::malloc(n, 1+UHashMapNode::size(), false);
info = (uint8_t*) U_SYSCALL(malloc, "%u", n*(1+UHashMapNode::size())); // UMemoryPool::u_malloc(n, 1+UHashMapNode::size(), false);
table = (char*) (info + n);
U_INTERNAL_ASSERT_POINTER_MSG(info, "cannot allocate memory, exiting...")

View File

@ -301,7 +301,7 @@ uint32_t UCDB::makeFinish(bool _reset)
uint32_t index;
};
cdb_tmp* tmp = (cdb_tmp*) UMemoryPool::malloc(nrecord, sizeof(cdb_tmp));
cdb_tmp* tmp = (cdb_tmp*) UMemoryPool::u_malloc(nrecord, sizeof(cdb_tmp));
cdb_tmp* ptmp = tmp;
cdb_hash_table_slot* pslot;

View File

@ -1843,7 +1843,7 @@ URDBObjectHandler<UDataStorage*>::URDBObjectHandler(const UString& pathdb, int _
{
uint32_t sz = pDataStorage->size();
if (sz) pDataStorage->recdata = (char*) UMemoryPool::malloc(sz);
if (sz) pDataStorage->recdata = (char*) UMemoryPool::u_malloc(sz);
U_INTERNAL_DUMP("pDataStorage->recdata(%u) = %p", sz, pDataStorage->recdata)
}

View File

@ -451,9 +451,9 @@ bool UMemoryPool::check(void* ptr)
# endif
#endif
void* UMemoryPool::malloc(uint32_t num, uint32_t type_size, bool bzero)
void* UMemoryPool::u_malloc(uint32_t num, uint32_t type_size, bool bzero)
{
U_TRACE(0, "UMemoryPool::malloc(%u,%u,%b)", num, type_size, bzero)
U_TRACE(0, "UMemoryPool::u_malloc(%u,%u,%b)", num, type_size, bzero)
U_INTERNAL_ASSERT_MAJOR(num, 0)
U_INTERNAL_ASSERT_MAJOR(type_size, 0)

View File

@ -28,8 +28,8 @@ ULDAPEntry::ULDAPEntry(int num_names, const char** names, int num_entry)
n_entry = num_entry;
attr_name = names;
dn = (char**) UMemoryPool::malloc(num_entry, sizeof(char*), true);
attr_val = (UString**) UMemoryPool::malloc(num_entry * num_names, sizeof(UString*), true);
dn = (char**) UMemoryPool::u_malloc(num_entry, sizeof(char*), true);
attr_val = (UString**) UMemoryPool::u_malloc(num_entry * num_names, sizeof(UString*), true);
}
ULDAPEntry::~ULDAPEntry()

View File

@ -352,7 +352,7 @@ bool UREDISClient_Base::deleteKeys(const char* pattern, uint32_t len) // Delete
// by Victor Stewart
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__)
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
int UREDISClusterMaster::handlerRead()
{

View File

@ -87,8 +87,8 @@ UIptAccount::UIptAccount(bool bSocketIsIPv6) : USocket(bSocketIsIPv6)
// 4096 bytes default buffer should save us from reallocations as it fits 200 concurrent active clients
data = UMemoryPool::malloc(IPT_ACCOUNT_MIN_BUFSIZE);
data_size = IPT_ACCOUNT_MIN_BUFSIZE;
data = UMemoryPool::u_malloc(IPT_ACCOUNT_MIN_BUFSIZE);
data_size = IPT_ACCOUNT_MIN_BUFSIZE;
#endif
}
@ -162,7 +162,7 @@ bool UIptAccount::readEntries(const char* table, bool bflush)
UMemoryPool::_free(data, data_size);
data = UMemoryPool::malloc(new_size);
data = UMemoryPool::u_malloc(new_size);
data_size = new_size;
}

View File

@ -2175,7 +2175,7 @@ int UNoCatPlugIn::handlerInit()
U_INTERNAL_ASSERT_EQUALS(UPing::addrmask, U_NULLPTR)
// UPing::addrmask = (fd_set*) UServer_Base::getOffsetToDataShare(sizeof(fd_set) + sizeof(uint32_t));
UPing::addrmask = (fd_set*) UMemoryPool::malloc(1, sizeof(fd_set) + sizeof(uint32_t));
UPing::addrmask = (fd_set*) UMemoryPool::u_malloc(1, sizeof(fd_set) + sizeof(uint32_t));
// crypto cmd
@ -2280,8 +2280,8 @@ int UNoCatPlugIn::handlerFork()
U_INTERNAL_DUMP("num_radio = %u", num_radio)
// sockp = (UPing**) UMemoryPool::malloc(num_radio, sizeof(UPing*));
vaddr = (UVector<UIPAddress*>**) UMemoryPool::malloc(num_radio, sizeof(UVector<UIPAddress*>*));
// sockp = (UPing**) UMemoryPool::u_malloc(num_radio, sizeof(UPing*));
vaddr = (UVector<UIPAddress*>**) UMemoryPool::u_malloc(num_radio, sizeof(UVector<UIPAddress*>*));
// UPing::addrmask = (fd_set*) UServer_Base::getPointerToDataShare(UPing::addrmask);

View File

@ -1173,6 +1173,66 @@ ok: setLocal();
U_RETURN(false);
}
#ifdef HAVE_EPOLL_WAIT
bool USocket::beginAsynchronousConnect(const UString& server, unsigned int iServPort)
{
U_TRACE(1, "USocket::beginAsynchronousConnect(%V,%u)", server.rep, iServPort)
U_CHECK_MEMORY
U_INTERNAL_ASSERT(server.isNullTerminated())
if (isOpen() == false) _socket();
if (cRemoteAddress.setHostName(server, U_socket_IPv6(this)))
{
setNonBlocking(); // we assume all sockets are blocking, so we will set nonBlocking for connect then unset back to blocking
SocketAddress cServer(iRemotePort = iServPort, cRemoteAddress);
/*
Yes, a non-blocking connect() can return 0 (which means success), although this is not likely to happen with TCP. "Immediately" means that the kernel does not have to wait to determine the status. Situations where you could see this include
1) UDP sockets, where connect() is basically advisory, allowing send() to be used later, rather than sendto().
2) Streaming UNIX domain sockets, where the peer is in the same kernel and thus could be scrutinized immediately.
3) A TCP connection to 127.0.0.1 (localhost).
*/
int result = U_FF_SYSCALL(connect, "%d,%p,%d", getFd(), (sockaddr*)cServer, cServer.sizeOf());
if ( (result == -1 && errno == EINPROGRESS) || (result == 0 && finishAsynchronousConnect()) ) U_RETURN(true);
_close_socket();
}
U_RETURN(false);
}
bool USocket::finishAsynchronousConnect()
{
U_TRACE_NO_PARAM(0, "USocket::finishAsynchronousConnect()")
setBlocking();
uint32_t error = U_NOT_FOUND, tmp = sizeof(uint32_t);
(void) getSockOpt(SOL_SOCKET, SO_ERROR, (void*)&error, tmp);
if (error == 0)
{
iState = CONNECT;
U_RETURN(true);
}
iState = -(errno = error);
U_RETURN(false);
}
#endif
int USocket::send(const char* pData, uint32_t iDataLen)
{
U_TRACE(1, "USocket::send(%p,%u)", pData, iDataLen)

View File

@ -279,8 +279,8 @@ next:
U_INTERNAL_ASSERT_EQUALS(kqevents, 0)
U_INTERNAL_ASSERT_EQUALS(kqrevents, 0)
kqevents = (struct kevent*) UMemoryPool::malloc(max_connection, sizeof(struct kevent), true);
kqrevents = (struct kevent*) UMemoryPool::malloc(max_connection, sizeof(struct kevent), true);
kqevents = (struct kevent*) UMemoryPool::u_malloc(max_connection, sizeof(struct kevent), true);
kqrevents = (struct kevent*) UMemoryPool::u_malloc(max_connection, sizeof(struct kevent), true);
// Check for Mac OS X kqueue bug. If kqueue works, then kevent will succeed, and it will stick an error in events[0].
// If kqueue is broken, then kevent will fail (This detects an old bug in Mac OS X 10.4, fixed in 10.5)
@ -303,7 +303,7 @@ next:
U_INTERNAL_ASSERT_EQUALS(events, U_NULLPTR)
events =
pevents = (struct epoll_event*) UMemoryPool::malloc(max_connection+1, sizeof(struct epoll_event), true);
pevents = (struct epoll_event*) UMemoryPool::u_malloc(max_connection+1, sizeof(struct epoll_event), true);
# ifdef HAVE_EPOLL_CTL_BATCH
for (int i = 0; i < U_EPOLL_CTL_CMD_SIZE; ++i)
@ -1362,6 +1362,79 @@ int UNotifier::waitForRead(int fd, int timeoutMS)
U_RETURN(ret);
}
#ifdef HAVE_EPOLL_WAIT
bool UNotifier::waitOnAsynchronousBatch(const UVector<UEventFd*>& waiting, int op, int timeoutMS)
{
U_TRACE_NO_PARAM(0, "UNotifier::waitOnAsynchronousBatch()");
uint32_t waitingOnN = waiting.size();
int epollfd = U_SYSCALL(epoll_create1, "%d", 0);
struct epoll_event* events;
struct epoll_event* pevents;
events =
pevents = (struct epoll_event*) UMemoryPool::u_malloc(waitingOnN + 1, sizeof(struct epoll_event), true);
for (uint32_t i = 0; i < waitingOnN; ++i)
{
UEventFd* waiter = waiting.at(i);
struct epoll_event _events = { (uint32_t)op, { waiter } };
(void) U_FF_SYSCALL(epoll_ctl, "%d,%d,%d,%p", epollfd, EPOLL_CTL_ADD, waiter->UEventFd::fd, &_events);
}
bool result = true;
UTimeVal* timer = U_NULLPTR;
if (timeoutMS > 0) U_NEW(UTimeVal, timer, UTimeVal);
do {
if (timer) timer->start();
int nfd_ready = U_FF_SYSCALL(epoll_wait, "%d,%p,%u,%d", epollfd, events, waitingOnN, timeoutMS);
if (nfd_ready <= 0) // either timed out or failed
{
result = false;
break;
}
// if it had timed out it would have returned 0, so we still have some time left
if (timer) timeoutMS -= timer->stop();
waitingOnN -= nfd_ready;
pevents = events;
do {
UEventFd* waiter = (UEventFd*)events->data.ptr;
switch (op)
{
case POLLIN: waiter->handlerRead(); break;
case POLLOUT: waiter->handlerConnect(); break; // it's the responsibility of the wrapper to check if the connect completed succesfully or not
default: break;
}
pevents++;
}
while (--nfd_ready > 0);
}
while (waitingOnN > 0);
if (timer) U_DELETE(timer);
UMemoryPool::_free(events, waiting.size() + 1, sizeof(struct epoll_event));
(void) U_FF_SYSCALL(close, "%d", epollfd);
U_RETURN(result);
}
#endif
int UNotifier::waitForWrite(int fd, int timeoutMS)
{
U_TRACE(0, "UNotifier::waitForWrite(%d,%d)", fd, timeoutMS)

View File

@ -67,6 +67,11 @@
#else
# define LIBQUICHE_ENABLE "no"
#endif
#ifdef USE_LIBMIMALLOC
# define LIBMIMALLOC_ENABLE "yes ( " _LIBMIMALLOC_VERSION " )"
#else
# define LIBMIMALLOC_ENABLE "no"
#endif
#ifdef USE_LIBTDB
# define LIBTDB_ENABLE "yes ( " _LIBTDB_VERSION " )"
#else
@ -727,6 +732,7 @@ PYTHON language support: yes ( 2.7 )
"LIBZOPFLI support......:%W " LIBZOPFLI_ENABLE "%W\n" \
"LIBBROTLI support......:%W " LIBBROTLI_ENABLE "%W\n" \
"LIBQUICHE support......:%W " LIBQUICHE_ENABLE "%W\n" \
"MIMALLOC support.......:%W " LIBMIMALLOC_ENABLE "%W\n" \
"LIBTDB support.........:%W " LIBTDB_ENABLE "%W\n" \
"PCRE support...........:%W " LIBPCRE_ENABLE "%W\n" \
"SSL support............:%W " LIBSSL_ENABLE "%W\n" \
@ -806,6 +812,7 @@ PYTHON language support: yes ( 2.7 )
BRIGHTYELLOW, RESET,
BRIGHTYELLOW, RESET,
BRIGHTYELLOW, RESET,
BRIGHTYELLOW, RESET,
// parser
BRIGHTYELLOW, RESET,
BRIGHTYELLOW, RESET);

View File

@ -363,7 +363,7 @@ bool UMySqlStatement::setBindParam(UOrmDriver* pdrv)
{
USqlStatementBindParam* param;
mysql_vparam = (MYSQL_BIND*) UMemoryPool::malloc(num_bind_param, sizeof(MYSQL_BIND), true);
mysql_vparam = (MYSQL_BIND*) UMemoryPool::u_malloc(num_bind_param, sizeof(MYSQL_BIND), true);
for (uint32_t i = 0; i < num_bind_param; ++i)
{
@ -494,7 +494,7 @@ bool UMySqlStatement::setBindResult(UOrmDriver* pdrv)
{
USqlStatementBindResult* result;
mysql_vresult = (MYSQL_BIND*) UMemoryPool::malloc(num_bind_result, sizeof(MYSQL_BIND), true);
mysql_vresult = (MYSQL_BIND*) UMemoryPool::u_malloc(num_bind_result, sizeof(MYSQL_BIND), true);
for (uint32_t i = 0; i < num_bind_result; ++i)
{

View File

@ -192,7 +192,7 @@ UPgSqlStatement::UPgSqlStatement(const char* s, uint32_t n) : USqlStatement(U_NU
{
vparam.reserve(num_bind_param);
paramTypes = (Oid*) UMemoryPool::malloc(num_bind_param * 3, sizeof(int), false);
paramTypes = (Oid*) UMemoryPool::u_malloc(num_bind_param * 3, sizeof(int), false);
}
}
@ -417,7 +417,7 @@ bool UPgSqlStatement::setBindParam(UOrmDriver* pdrv)
{
if (paramValues == U_NULLPTR)
{
paramValues = (const char**) UMemoryPool::malloc(num_bind_param, sizeof(const char*), false);
paramValues = (const char**) UMemoryPool::u_malloc(num_bind_param, sizeof(const char*), false);
U_INTERNAL_ASSERT_EQUALS(paramLengths, U_NULLPTR)

View File

@ -911,8 +911,8 @@ void UQueryParser::startEvaluate(bPFpr func)
uint32_t sz = termRoots->size();
negatives = (UVector<UString>**) UMemoryPool::malloc(sz, sizeof(void*));
positives = (UVector<UString>**) UMemoryPool::malloc(sz, sizeof(void*));
negatives = (UVector<UString>**) UMemoryPool::u_malloc(sz, sizeof(void*));
positives = (UVector<UString>**) UMemoryPool::u_malloc(sz, sizeof(void*));
for (uint32_t i = 0; i < sz; ++i)
{

View File

@ -25,9 +25,8 @@ size_t UHTTP3::conn_id_len;
uint8_t UHTTP3::conn_id[QUICHE_MAX_CONN_ID_LEN];
uint32_t UHTTP3::peer_addr_len;
uint32_t UHTTP3::quiche_max_packet_size = U_MAX_DATAGRAM_SIZE;
quiche_conn* UHTTP3::conn;
quiche_config* UHTTP3::qconfig;
quiche_h3_conn* UHTTP3::http3;
UHTTP3::conn_io UHTTP3::conn;
quiche_h3_config* UHTTP3::http3_config;
struct sockaddr_storage UHTTP3::peer_addr;
@ -186,6 +185,7 @@ bool UHTTP3::handlerRead()
U_INTERNAL_ASSERT(UServer_Base::budp)
int rc;
void* pconn;
uint8_t pkt_type;
uint32_t pkt_version;
size_t scid_len, token_len;
@ -240,123 +240,132 @@ bool UHTTP3::handlerRead()
"pkt_version = %d pkt_type = %d",
scid_len, scid_len, scid, token_len, token_len, token, conn_id_len, conn_id_len, conn_id, pkt_version, pkt_type)
U_INTERNAL_DUMP("conn = %p", conn)
// Lookup a connection based on the packet's connection ID. If there is no connection matching, create a new one
pconn = (peers->empty() ? U_NULLPTR : peers->at((const char*)conn_id, conn_id_len));
if (conn == U_NULLPTR)
U_INTERNAL_DUMP("pconn = %p", pconn)
if (pconn == U_NULLPTR)
{
// Lookup a connection based on the packet's connection ID. If there is no connection matching, create a new one
UServer_Base::pClientImage = (peers->empty() ? U_NULLPTR : peers->at((const char*)conn_id, conn_id_len));
const char* pkt = "vneg";
if (UServer_Base::pClientImage == U_NULLPTR)
if (pkt_type != Initial)
{
const char* pkt = "vneg";
U_DEBUG("UHTTP3::handlerRead(): packet is NOT initial: %d", pkt_type);
if (pkt_type != Initial)
{
U_DEBUG("UHTTP3::handlerRead(): packet is NOT initial: %d", pkt_type);
continue;
}
// Returns true if the given protocol version is supported
if (U_SYSCALL(quiche_version_is_supported, "%u", pkt_version) == false)
{
U_DEBUG("UHTTP3::handlerRead(): version negotiation");
// Writes a version negotiation packet
written = U_SYSCALL(quiche_negotiate_version, "%p,%u,%p,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, out, sizeof(out));
pkt: if (written < 0)
{
U_DEBUG("UHTTP3::handlerRead(): failed to create %s packet: %d", pkt, written);
U_RETURN(false);
}
sent = U_SYSCALL(sendto, "%d,%p,%u,%u,%p,%d", fd, out, written, 0, (struct sockaddr*)&peer_addr, peer_addr_len);
if (sent == written)
{
U_DEBUG("UHTTP3::handlerRead(): sent %u bytes", sent);
}
else
{
U_DEBUG("UHTTP3::handlerRead(): failed to send");
}
U_RETURN(false);
}
if (token_len == 0)
{
uint8_t odcid[QUICHE_MAX_CONN_ID_LEN];
// Generate a stateless retry token. The token includes the static string `"quiche"` followed
// by the IP address of the client and by the original destination connection ID generated by the client
U_DEBUG("UHTTP3::handlerRead(): stateless retry");
(void) memcpy(token, U_CONSTANT_TO_PARAM("quiche"));
(void) memcpy(token + U_CONSTANT_SIZE("quiche"), &peer_addr, peer_addr_len);
(void) memcpy(token + U_CONSTANT_SIZE("quiche") + peer_addr_len, conn_id, conn_id_len);
token_len = U_CONSTANT_SIZE("quiche") + peer_addr_len + conn_id_len;
u__memcpy(odcid, conn_id, conn_id_len, __PRETTY_FUNCTION__);
// Writes a retry packet
written = U_SYSCALL(quiche_retry, "%p,%u,%p,%u,%p,%u,%p,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, odcid, conn_id_len, token, token_len, out, sizeof(out));
pkt = "retry";
goto pkt;
}
// Validates a stateless retry token. This checks that the ticket includes the `"quiche"` static string, and that the client IP address matches the address stored in the ticket
if (token_len < U_CONSTANT_SIZE("quiche") ||
memcmp(token, U_CONSTANT_TO_PARAM("quiche")))
{
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
U_RETURN(false);
}
token_len -= U_CONSTANT_SIZE("quiche");
const char* ptr = (const char*)&token[0] + U_CONSTANT_SIZE("quiche");
if (token_len < peer_addr_len ||
memcmp(ptr, &peer_addr, peer_addr_len))
{
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
U_RETURN(false);
}
ptr += peer_addr_len;
token_len -= peer_addr_len;
if (conn_id_len != token_len) // The token was not valid, meaning the retry failed, so drop the packet
{
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
U_RETURN(false);
}
// Reuse the source connection ID we sent in the Retry packet, instead of changing it again. Creates a new server-side connection
conn = (quiche_conn*) U_SYSCALL(quiche_accept, "%p,%u,%p,%u,%p", conn_id, conn_id_len, (const uint8_t*)ptr, token_len, qconfig);
if (conn == U_NULLPTR)
{
U_DEBUG("UHTTP3::handlerRead(): failed to create connection");
U_RETURN(false);
}
continue;
}
// Client Initial packets must be at least 1200 bytes
if (iBytesRead < QUICHE_MIN_CLIENT_INITIAL_LEN)
{
U_DEBUG("UHTTP3::handlerRead(): quic initial packet is too short: %d", iBytesRead);
continue;
}
// Returns true if the given protocol version is supported
if (U_SYSCALL(quiche_version_is_supported, "%u", pkt_version) == false)
{
U_DEBUG("UHTTP3::handlerRead(): version negotiation");
// Writes a version negotiation packet
written = U_SYSCALL(quiche_negotiate_version, "%p,%u,%p,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, out, sizeof(out));
pkt: if (written < 0)
{
U_DEBUG("UHTTP3::handlerRead(): failed to create %s packet: %d", pkt, written);
U_RETURN(false);
}
sent = U_SYSCALL(sendto, "%d,%p,%u,%u,%p,%d", fd, out, written, 0, (struct sockaddr*)&peer_addr, peer_addr_len);
if (sent == written)
{
U_DEBUG("UHTTP3::handlerRead(): sent %u bytes", sent);
}
else
{
U_DEBUG("UHTTP3::handlerRead(): failed to send");
}
U_RETURN(false);
}
if (token_len == 0)
{
uint8_t odcid[QUICHE_MAX_CONN_ID_LEN];
// Generate a stateless retry token. The token includes the static string `"quiche"` followed
// by the IP address of the client and by the original destination connection ID generated by the client
U_DEBUG("UHTTP3::handlerRead(): stateless retry");
(void) memcpy(token, U_CONSTANT_TO_PARAM("quiche"));
(void) memcpy(token + U_CONSTANT_SIZE("quiche"), &peer_addr, peer_addr_len);
(void) memcpy(token + U_CONSTANT_SIZE("quiche") + peer_addr_len, conn_id, conn_id_len);
token_len = U_CONSTANT_SIZE("quiche") + peer_addr_len + conn_id_len;
u__memcpy(odcid, conn_id, conn_id_len, __PRETTY_FUNCTION__);
// Writes a retry packet
written = U_SYSCALL(quiche_retry, "%p,%u,%p,%u,%p,%u,%p,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, odcid, conn_id_len, token, token_len, out, sizeof(out));
pkt = "retry";
goto pkt;
}
// Validates a stateless retry token. This checks that the ticket includes the `"quiche"` static string, and that the client IP address matches the address stored in the ticket
if (token_len < U_CONSTANT_SIZE("quiche") ||
memcmp(token, U_CONSTANT_TO_PARAM("quiche")))
{
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
U_RETURN(false);
}
token_len -= U_CONSTANT_SIZE("quiche");
const char* ptr = (const char*)&token[0] + U_CONSTANT_SIZE("quiche");
if (token_len < peer_addr_len ||
memcmp(ptr, &peer_addr, peer_addr_len))
{
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
U_RETURN(false);
}
ptr += peer_addr_len;
token_len -= peer_addr_len;
if (conn_id_len != token_len) // The token was not valid, meaning the retry failed, so drop the packet
{
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
U_RETURN(false);
}
U_INTERNAL_ASSERT_EQUALS(conn.conn, U_NULLPTR)
// Reuse the source connection ID we sent in the Retry packet, instead of changing it again. Creates a new server-side connection
conn.conn = (quiche_conn*) U_SYSCALL(quiche_accept, "%p,%u,%p,%u,%p", conn_id, conn_id_len, (const uint8_t*)ptr, token_len, qconfig);
if (conn.conn == U_NULLPTR)
{
U_DEBUG("UHTTP3::handlerRead(): failed to create connection");
U_RETURN(false);
}
peers->insert((const char*)conn_id, conn_id_len, (const UClientImage_Base*)&conn);
}
// Processes QUIC packets received from the peer
done = U_SYSCALL(quiche_conn_recv, "%p,%p,%u", conn, (uint8_t*)data, iBytesRead);
done = U_SYSCALL(quiche_conn_recv, "%p,%p,%u", conn.conn, (uint8_t*)data, iBytesRead);
if (done == QUICHE_ERR_DONE)
{
@ -374,17 +383,17 @@ pkt: if (written < 0)
U_DEBUG("UHTTP3::handlerRead(): recv %d bytes", done);
if (U_SYSCALL(quiche_conn_is_in_early_data, "%p", conn) || // the connection has a pending handshake that has progressed
U_SYSCALL(quiche_conn_is_established, "%p", conn)) // the connection handshake is complete
if (U_SYSCALL(quiche_conn_is_in_early_data, "%p", conn.conn) || // the connection has a pending handshake that has progressed
U_SYSCALL(quiche_conn_is_established, "%p", conn.conn)) // the connection handshake is complete
{
U_DEBUG("UHTTP3::handlerRead(): connection handshake is complete");
U_INTERNAL_ASSERT_EQUALS(http3, U_NULLPTR)
U_INTERNAL_ASSERT_EQUALS(conn.http3, U_NULLPTR)
// Creates a new HTTP/3 connection using the provided QUIC connection
http3 = (quiche_h3_conn*) U_SYSCALL(quiche_h3_conn_new_with_transport, "%p,%p", conn, http3_config);
conn.http3 = (quiche_h3_conn*) U_SYSCALL(quiche_h3_conn_new_with_transport, "%p,%p", conn.conn, http3_config);
if (http3 == U_NULLPTR)
if (conn.http3 == U_NULLPTR)
{
U_DEBUG("UHTTP3::handlerAccept(): failed to create HTTP/3 connection");
@ -396,7 +405,7 @@ pkt: if (written < 0)
while (true)
{
// Processes HTTP/3 data received from the peer
done = U_SYSCALL(quiche_h3_conn_poll, "%p,%p,%p", http3, conn, &ev);
done = U_SYSCALL(quiche_h3_conn_poll, "%p,%p,%p", conn.http3, conn.conn, &ev);
if (done < 0) break;
@ -465,7 +474,7 @@ pkt: if (written < 0)
while (true)
{
written = U_SYSCALL(quiche_conn_send, "%p,%p,%u", conn, out, sizeof(out));
written = U_SYSCALL(quiche_conn_send, "%p,%p,%u", conn.conn, out, sizeof(out));
if (written == QUICHE_ERR_DONE)
{
@ -502,20 +511,20 @@ bool UHTTP3::handlerAccept()
{
U_TRACE_NO_PARAM(0, "UHTTP3::handlerAccept()")
U_INTERNAL_ASSERT_POINTER(conn)
U_INTERNAL_ASSERT_POINTER(http3)
U_INTERNAL_ASSERT_POINTER(conn.conn)
U_INTERNAL_ASSERT_POINTER(conn.http3)
U_INTERNAL_ASSERT(UServer_Base::budp)
U_INTERNAL_ASSERT_POINTER(UServer_Base::pClientImage)
UServer_Base::pClientImage->conn = conn;
UServer_Base::pClientImage->http3 = http3;
UServer_Base::pClientImage->conn = conn.conn;
UServer_Base::pClientImage->http3 = conn.http3;
conn = U_NULLPTR;
http3 = U_NULLPTR;
conn.conn = U_NULLPTR;
conn.http3 = U_NULLPTR;
UServer_Base::pClientImage->socket->setRemoteAddressAndPort();
peers->insert((const char*)conn_id, conn_id_len, UServer_Base::pClientImage);
peers->replace((const char*)conn_id, conn_id_len, UServer_Base::pClientImage);
U_RETURN(true);
}

View File

@ -1 +1 @@
07F4
0800

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1504,7 +1504,7 @@ U_EXPORT main(int argc, char* argv[])
U_ASSERT( byte_count == U_STRING_FROM_CONSTANT("4.0 GiB") )
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX)
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
UString token = U_STRING_FROM_CONSTANT("a"),
firstname = U_STRING_FROM_CONSTANT("Victor"),
lastname = U_STRING_FROM_CONSTANT("Stewart"),