summaryrefslogtreecommitdiff
path: root/indra/llcorehttp
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2026-08-11 21:39:19 -0400
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2026-08-11 21:39:19 -0400
commit8cabc33e960ca93fdc1a32c77cf611269d95d51b (patch)
tree931fcecac10bf73214efa07cc3d704ba2bd01272 /indra/llcorehttp
parent9b7ab49575b54523128952af6686d17eb6696725 (diff)
parentd045f9aa32789a35628aced166145c182751acbf (diff)
Merge remote-tracking branch 'origin/develop-linux' into geenz/linux-to-develop
Diffstat (limited to 'indra/llcorehttp')
-rw-r--r--indra/llcorehttp/CMakeLists.txt15
-rw-r--r--indra/llcorehttp/_httpservice.cpp50
-rw-r--r--indra/llcorehttp/_httpservice.h2
-rw-r--r--indra/llcorehttp/_mutex.h11
-rw-r--r--indra/llcorehttp/_refcounted.h10
-rw-r--r--indra/llcorehttp/_thread.h103
-rw-r--r--indra/llcorehttp/httpcommon.cpp4
-rw-r--r--indra/llcorehttp/httpcommon.h6
-rw-r--r--[-rwxr-xr-x]indra/llcorehttp/llhttpconstants.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcorehttp/llhttpconstants.h2
-rw-r--r--[-rwxr-xr-x]indra/llcorehttp/tests/llcorehttp_test.cpp0
-rw-r--r--indra/llcorehttp/tests/test_httprequest.hpp15
12 files changed, 96 insertions, 122 deletions
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 05b788a433..58bbdb2d9a 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -81,6 +81,7 @@ list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES})
add_library (llcorehttp ${llcorehttp_SOURCE_FILES})
target_link_libraries(
llcorehttp
+ llmath
llcommon
ll::libcurl
ll::openssl
@@ -92,6 +93,10 @@ target_include_directories( llcorehttp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
# lead to circular dependencies (or in case of cmake, the first project declaring it's dependencies wins)
target_include_directories( llcorehttp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../llmessage)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llcorehttp REUSE_FROM llprecompiled)
+endif ()
+
# tests
set(LLCOREHTTP_TESTS ON CACHE BOOL
"Build and run llcorehttp integration tests specifically")
@@ -131,7 +136,7 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
${PYTHON_EXECUTABLE}
"${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py"
)
-
+
#
# Example Programs
#
@@ -151,6 +156,7 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
set_target_properties(http_texture_load
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
+ FOLDER "Tests"
)
if (WINDOWS)
@@ -163,6 +169,13 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
)
endif (WINDOWS)
+ if(DARWIN)
+ set_target_properties(http_texture_load
+ PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
+ )
+ endif()
+
target_link_libraries(http_texture_load ${example_libs})
endif (LL_TESTS AND LLCOREHTTP_TESTS)
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index a8660decc3..e14a533479 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -70,7 +70,6 @@ volatile HttpService::EState HttpService::sState(NOT_INITIALIZED);
HttpService::HttpService()
: mRequestQueue(NULL),
mExitRequested(0U),
- mThread(NULL),
mPolicy(NULL),
mTransport(NULL),
mLastPolicy(0)
@@ -89,23 +88,30 @@ HttpService::~HttpService()
{
if (mRequestQueue->stopQueue())
{
- // Give mRequestQueue a chance to finish
- ms_sleep(10);
+ // Now wait a bit for the thread to exit
+ S32 counter = 0;
+ const S32 MAX_WAIT = 600;
+ while (counter < MAX_WAIT)
+ {
+ if (STOPPED == sState)
+ {
+ break;
+ }
+ // Sleep for a tenth of a second
+ ms_sleep(100);
+ std::this_thread::yield();
+ counter++;
+ }
}
}
- if (mThread)
+ if (mThread && RUNNING == sState)
{
- if (! mThread->timedJoin(250))
- {
- // Failed to join, expect problems ahead so do a hard termination.
- LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE
- << "State: " << S32(sState)
- << " Last policy: " << U32(mLastPolicy)
- << LL_ENDL;
+ // Failed to shutdown, expect problems ahead so do a hard termination.
+ LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE << "State: " << S32(sState)
+ << " Last policy: " << U32(mLastPolicy) << LL_ENDL;
- mThread->cancel();
- }
+ mThread->cancel();
}
}
@@ -121,11 +127,7 @@ HttpService::~HttpService()
delete mPolicy;
mPolicy = NULL;
- if (mThread)
- {
- mThread->release();
- mThread = NULL;
- }
+ mThread.reset();
}
@@ -204,14 +206,15 @@ void HttpService::startThread()
if (mThread)
{
- mThread->release();
+ mThread.reset();
}
// Push current policy definitions, enable policy & transport components
mPolicy->start();
mTransport->start(mLastPolicy + 1);
- mThread = new LLCoreInt::HttpThread(boost::bind(&HttpService::threadRun, this, _1));
+ mThread = std::make_unique<LLCoreInt::HttpThread>(boost::bind(&HttpService::threadRun, this, _1));
+ mThread->detach(); // Detach thread to let it clean its self up
sState = RUNNING;
}
@@ -282,12 +285,9 @@ void HttpService::shutdown()
// requested to stop.
void HttpService::threadRun(LLCoreInt::HttpThread * thread)
{
+ set_thread_name("HttpService");
LL_PROFILER_SET_THREAD_NAME("HttpService");
- boost::this_thread::disable_interruption di;
-
- LLThread::registerThreadID();
-
ELoopSpeed loop(REQUEST_SLEEP);
while (! mExitRequested)
{
@@ -314,7 +314,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
{
LOG_UNHANDLED_EXCEPTION("");
}
- catch (std::bad_alloc&)
+ catch (const std::bad_alloc&)
{
LLMemory::logMemoryInfo(true);
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index 7202b496fc..4540fb9383 100644
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -218,7 +218,7 @@ protected:
static volatile EState sState;
HttpRequestQueue * mRequestQueue; // Refcounted
LLAtomicU32 mExitRequested;
- LLCoreInt::HttpThread * mThread;
+ std::unique_ptr<LLCoreInt::HttpThread> mThread;
// === working-thread-only data ===
HttpPolicy * mPolicy; // Simple pointer, has ownership
diff --git a/indra/llcorehttp/_mutex.h b/indra/llcorehttp/_mutex.h
index 5e0164eb51..43782d3a37 100644
--- a/indra/llcorehttp/_mutex.h
+++ b/indra/llcorehttp/_mutex.h
@@ -27,9 +27,8 @@
#ifndef LLCOREINT_MUTEX_H_
#define LLCOREINT_MUTEX_H_
-
-#include <boost/thread.hpp>
-
+#include <condition_variable>
+#include <mutex>
namespace LLCoreInt
{
@@ -37,17 +36,17 @@ namespace LLCoreInt
// MUTEX TYPES
// unique mutex type
-typedef boost::mutex HttpMutex;
+typedef std::mutex HttpMutex;
// CONDITION VARIABLES
// standard condition variable
-typedef boost::condition_variable HttpConditionVariable;
+typedef std::condition_variable HttpConditionVariable;
// LOCKS AND FENCES
// scoped unique lock
-typedef boost::unique_lock<HttpMutex> HttpScopedLock;
+typedef std::unique_lock<HttpMutex> HttpScopedLock;
}
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index 63684b5e2c..bc90f8274d 100644
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -30,7 +30,6 @@
#include "linden_common.h"
-#include "fix_macros.h"
#include <boost/intrusive_ptr.hpp>
#include "llatomic.h"
@@ -40,12 +39,11 @@ namespace LLCoreInt
class RefCounted
{
-private:
- RefCounted() = delete; // may not be default constructed
- RefCounted(const RefCounted&) = delete;
- RefCounted& operator=(const RefCounted&) = delete;
-
public:
+ RefCounted() = delete; // Not defined - may not be default constructed
+ RefCounted(const RefCounted&) = delete; // Not defined - may not be copy constructed
+ void operator=(const RefCounted&) = delete; // Not defined
+
explicit RefCounted(bool const implicit)
: mRefCount(implicit)
{}
diff --git a/indra/llcorehttp/_thread.h b/indra/llcorehttp/_thread.h
index 93efbbedbc..66b9689c5a 100644
--- a/indra/llcorehttp/_thread.h
+++ b/indra/llcorehttp/_thread.h
@@ -29,94 +29,75 @@
#include "linden_common.h"
-#include <boost/thread.hpp>
-#include <boost/function.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <functional>
+#include <thread>
-#include "apr.h" // thread-related functions
#include "_refcounted.h"
namespace LLCoreInt
{
-class HttpThread : public RefCounted
+class HttpThread
{
-private:
- // May not be default constructed or copied
- HttpThread() = delete;
- HttpThread(const HttpThread&) = delete;
- void operator=(const HttpThread &) = delete;
-
- void at_exit()
- {
- // the thread function has exited so we need to release our reference
- // to ourself so that we will be automagically cleaned up.
- release();
- }
+public:
+ HttpThread() = delete; // Not defined
+ HttpThread(const HttpThread&) = delete; // Not defined
+ void operator=(const HttpThread &) = delete; // Not defined
+private:
void run()
- { // THREAD CONTEXT
-
- // Take out additional reference for the at_exit handler
- addRef();
- boost::this_thread::at_thread_exit(boost::bind(&HttpThread::at_exit, this));
-
- // run the thread function
- mThreadFunc(this);
-
- } // THREAD CONTEXT
-
-protected:
- virtual ~HttpThread()
- {
- delete mThread;
- }
+ { // THREAD CONTEXT
+ // run the thread function
+ mThreadFunc(this);
+ } // THREAD CONTEXT
public:
/// Constructs a thread object for concurrent execution but does
/// not start running. Caller receives on refcount on the thread
/// instance. If the thread is started, another will be taken
/// out for the exit handler.
- explicit HttpThread(boost::function<void (HttpThread *)> threadFunc)
- : RefCounted(true), // implicit reference
- mThreadFunc(threadFunc)
- {
- // this creates a boost thread that will call HttpThread::run on this instance
- // and pass it the threadfunc callable...
- boost::function<void()> f = boost::bind(&HttpThread::run, this);
+ explicit HttpThread(std::function<void (HttpThread *)> threadFunc)
+ : mThreadFunc(threadFunc)
+ {
+ // this creates a std thread that will call HttpThread::run on this instance
+ // and pass it the threadfunc callable...
+ std::function<void()> f = std::bind(&HttpThread::run, this);
- mThread = new boost::thread(f);
- }
+ mThread = std::make_unique<std::thread>(f);
+ mNativeHandle = mThread->native_handle();
+ }
- inline void join()
- {
- mThread->join();
- }
+ ~HttpThread() = default;
- inline bool timedJoin(S32 millis)
- {
- return mThread->timed_join(boost::posix_time::milliseconds(millis));
- }
+ inline void join()
+ {
+ mThread->join();
+ }
inline bool joinable() const
- {
- return mThread->joinable();
- }
+ {
+ return mThread->joinable();
+ }
+
+ inline void detach()
+ {
+ mThread->detach();
+ }
// A very hostile method to force a thread to quit
inline void cancel()
- {
- boost::thread::native_handle_type thread(mThread->native_handle());
-#if LL_WINDOWS
- TerminateThread(thread, 0);
+ {
+#if LL_WINDOWS
+ TerminateThread(mNativeHandle, 0);
#else
- pthread_cancel(thread);
+ pthread_cancel(mNativeHandle);
#endif
- }
+ }
private:
- boost::function<void(HttpThread *)> mThreadFunc;
- boost::thread * mThread;
+ std::function<void(HttpThread *)> mThreadFunc;
+ std::unique_ptr<std::thread> mThread;
+ std::thread::native_handle_type mNativeHandle;
}; // end class HttpThread
} // end namespace LLCoreInt
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index a1b5f55e8d..dabc61975d 100644
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -36,10 +36,6 @@
namespace LLCore
{
-const HttpStatus::type_enum_t HttpStatus::EXT_CURL_EASY;
-const HttpStatus::type_enum_t HttpStatus::EXT_CURL_MULTI;
-const HttpStatus::type_enum_t HttpStatus::LLCORE;
-
HttpStatus::operator U32() const
{
// Effectively, concatenate mType (high) with mStatus (low).
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 1c003a0966..001fd08f93 100644
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -340,9 +340,9 @@ struct HttpStatus
return *this;
}
- static const type_enum_t EXT_CURL_EASY = 0; ///< mStatus is an error from a curl_easy_*() call
- static const type_enum_t EXT_CURL_MULTI = 1; ///< mStatus is an error from a curl_multi_*() call
- static const type_enum_t LLCORE = 2; ///< mStatus is an HE_* error code
+ static constexpr type_enum_t EXT_CURL_EASY = 0; ///< mStatus is an error from a curl_easy_*() call
+ static constexpr type_enum_t EXT_CURL_MULTI = 1; ///< mStatus is an error from a curl_multi_*() call
+ static constexpr type_enum_t LLCORE = 2; ///< mStatus is an HE_* error code
///< 100-999 directly represent HTTP status codes
/// Test for successful status in the code regardless
/// of error source (internal, libcurl).
diff --git a/indra/llcorehttp/llhttpconstants.cpp b/indra/llcorehttp/llhttpconstants.cpp
index 7a671543d9..7a671543d9 100755..100644
--- a/indra/llcorehttp/llhttpconstants.cpp
+++ b/indra/llcorehttp/llhttpconstants.cpp
diff --git a/indra/llcorehttp/llhttpconstants.h b/indra/llcorehttp/llhttpconstants.h
index 71c1dfa173..d05d0f1af1 100755..100644
--- a/indra/llcorehttp/llhttpconstants.h
+++ b/indra/llcorehttp/llhttpconstants.h
@@ -100,6 +100,8 @@ extern const std::string HTTP_VERB_POST;
extern const std::string HTTP_VERB_DELETE;
extern const std::string HTTP_VERB_MOVE;
extern const std::string HTTP_VERB_OPTIONS;
+extern const std::string HTTP_VERB_PATCH;
+extern const std::string HTTP_VERB_COPY;
enum EHTTPMethod
{
diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp
index c7c50e6166..c7c50e6166 100755..100644
--- a/indra/llcorehttp/tests/llcorehttp_test.cpp
+++ b/indra/llcorehttp/tests/llcorehttp_test.cpp
diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp
index 77ed8df066..68f8c4f71f 100644
--- a/indra/llcorehttp/tests/test_httprequest.hpp
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -2744,13 +2744,6 @@ void HttpRequestTestObjectType::test<22>()
set_test_name("BUG-2295");
-#if LL_WINDOWS && ADDRESS_SIZE == 64
- // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
- if (getenv("TEAMCITY_PROJECT_NAME"))
- {
- skip("BUG-2295 - partial load on W64 causes freeze");
- }
-#endif
// Handler can be stack-allocated *if* there are no dangling
// references to it after completion of this method.
// Create before memory record as the string copy will bump numbers.
@@ -2924,14 +2917,6 @@ void HttpRequestTestObjectType::test<23>()
set_test_name("HttpRequest GET 503s with 'Retry-After'");
-#if LL_WINDOWS && ADDRESS_SIZE == 64
- // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
- if (getenv("TEAMCITY_PROJECT_NAME"))
- {
- skip("llcorehttp 503-with-retry test hangs on Windows 64");
- }
-#endif
-
// This tests mainly that the code doesn't fall over if
// various well- and mis-formed Retry-After headers are
// sent along with the response. Direct inspection of