From 7573288ab3ede23f97bff2f5caefcb622e7e9842 Mon Sep 17 00:00:00 2001 From: Adam Moss Date: Mon, 9 Mar 2009 23:42:07 +0000 Subject: svn merge -r113780:113785 svn+ssh://svn.lindenlab.com/svn/linden/branches/moss/gst3-t113732 QAR-1333 linux gstreamer compatibility improvements and ADD_BUILD_TEST improvements - combo merge --- indra/cmake/00-Common.cmake | 2 + indra/cmake/CMakeLists.txt | 2 + indra/cmake/LLAddBuildTest.cmake | 116 +++++++++++++++------ indra/linux_crash_logger/llcrashloggerlinux.cpp | 2 +- indra/llcommon/is_approx_equal_fraction.h | 62 +++++++++++ indra/llcommon/llapp.cpp | 6 +- indra/llmath/llmath.h | 46 +-------- indra/llmessage/tests/commtest.h | 60 +++++++++++ indra/llmessage/tests/networkio.h | 93 +++++++++++++++++ indra/llmessage/tests/test_llsdmessage_peer.py | 130 ++++++++++++++++++++++++ indra/llrender/llglheaders.h | 6 +- indra/llwindow/llwindowsdl.cpp | 2 - indra/newview/linux_tools/client-readme.txt | 3 +- indra/newview/linux_tools/wrapper.sh | 13 ++- indra/newview/llappviewerlinux.cpp | 6 ++ indra/test/lltut.h | 2 +- 16 files changed, 467 insertions(+), 84 deletions(-) create mode 100644 indra/llcommon/is_approx_equal_fraction.h create mode 100644 indra/llmessage/tests/commtest.h create mode 100644 indra/llmessage/tests/networkio.h create mode 100644 indra/llmessage/tests/test_llsdmessage_peer.py (limited to 'indra') diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 0edacac7a9..a3c9becf0a 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -156,6 +156,8 @@ if (LINUX) if (VIEWER) add_definitions(-DAPPID=secondlife) add_definitions(-fvisibility=hidden) + # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The viewer doesn't need to catch SIGCHLD anyway. + add_definitions(-DLL_IGNORE_SIGCHLD) if (NOT STANDALONE) # this stops us requiring a really recent glibc at runtime add_definitions(-fno-stack-protector) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 9ddcc62f2c..658441dab1 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -37,6 +37,7 @@ set(cmake_SOURCE_FILES GStreamer.cmake GooglePerfTools.cmake JPEG.cmake + LLAddBuildTest.cmake LLAudio.cmake LLCharacter.cmake LLCommon.cmake @@ -70,6 +71,7 @@ set(cmake_SOURCE_FILES Python.cmake Prebuilt.cmake QuickTime.cmake + RunBuildTest.cmake TemplateCheck.cmake Tut.cmake UI.cmake diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 5d30818642..918a90e982 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -6,12 +6,6 @@ INCLUDE(LLMath) MACRO(ADD_BUILD_TEST_NO_COMMON name parent) # MESSAGE("${CMAKE_CURRENT_SOURCE_DIR}/tests/${name}_test.cpp") IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/${name}_test.cpp") - SET(no_common_libraries - ${APRUTIL_LIBRARIES} - ${APR_LIBRARIES} - ${PTHREAD_LIBRARY} - ${WINDOWS_LIBRARIES} - ) SET(no_common_libraries ${APRUTIL_LIBRARIES} ${APR_LIBRARIES} @@ -23,12 +17,15 @@ MACRO(ADD_BUILD_TEST_NO_COMMON name parent) tests/${name}_test.cpp ${CMAKE_SOURCE_DIR}/test/test.cpp ) - ADD_BUILD_TEST_INTERNAL(${name} ${parent} "${no_common_libraries}" "${no_common_source_files}") + ADD_BUILD_TEST_INTERNAL("${name}" "${parent}" "${no_common_libraries}" "${no_common_source_files}") ENDIF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/${name}_test.cpp") ENDMACRO(ADD_BUILD_TEST_NO_COMMON name parent) MACRO(ADD_BUILD_TEST name parent) + # optional extra parameter: list of additional source files + SET(more_source_files "${ARGN}") + # MESSAGE("${CMAKE_CURRENT_SOURCE_DIR}/tests/${name}_test.cpp") IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/${name}_test.cpp") @@ -44,39 +41,39 @@ MACRO(ADD_BUILD_TEST name parent) tests/${name}_test.cpp ${CMAKE_SOURCE_DIR}/test/test.cpp ${CMAKE_SOURCE_DIR}/test/lltut.cpp + ${more_source_files} ) - ADD_BUILD_TEST_INTERNAL(${name} ${parent} "${basic_libraries}" "${basic_source_files}") + ADD_BUILD_TEST_INTERNAL("${name}" "${parent}" "${basic_libraries}" "${basic_source_files}") + ENDIF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/${name}_test.cpp") ENDMACRO(ADD_BUILD_TEST name parent) +MACRO(ADD_VIEWER_BUILD_TEST name parent) + # This is just like the generic ADD_BUILD_TEST, but we implicitly + # add the necessary precompiled header .cpp file (anyone else find that + # oxymoronic?) because the MSVC build errors will NOT point you there. + ADD_BUILD_TEST("${name}" "${parent}" llviewerprecompiledheaders.cpp) +ENDMACRO(ADD_VIEWER_BUILD_TEST name parent) + + MACRO(ADD_SIMULATOR_BUILD_TEST name parent) - SET(sim_source_files - llsimprecompiledheaders.cpp - ${name}.cpp - tests/${name}_test.cpp - ../test/lltut.cpp - ../test/test.cpp - ) - SET(basic_libraries - ${LLCOMMON_LIBRARIES} - ${APRUTIL_LIBRARIES} - ${APR_LIBRARIES} - ${PTHREAD_LIBRARY} - ${WINDOWS_LIBRARIES} - ) - ADD_BUILD_TEST_INTERNAL(${name} ${parent} "${basic_libraries}" "${sim_source_files}") + ADD_BUILD_TEST("${name}" "${parent}" llsimprecompiledheaders.cpp) if (WINDOWS) SET_SOURCE_FILES_PROPERTIES( "tests/${name}_test.cpp" PROPERTIES COMPILE_FLAGS "/Yullsimprecompiledheaders.h" - ) + ) endif (WINDOWS) ENDMACRO(ADD_SIMULATOR_BUILD_TEST name parent) MACRO(ADD_BUILD_TEST_INTERNAL name parent libraries source_files) + # Optional additional parameter: pathname of Python wrapper script + SET(wrapper "${ARGN}") + #MESSAGE(STATUS "ADD_BUILD_TEST_INTERNAL ${name} wrapper = ${wrapper}") + SET(TEST_SOURCE_FILES ${source_files}) SET(HEADER "${name}.h") set_source_files_properties(${HEADER} @@ -87,17 +84,70 @@ MACRO(ADD_BUILD_TEST_INTERNAL name parent libraries source_files) TARGET_LINK_LIBRARIES(${name}_test ${libraries} ) - + GET_TARGET_PROPERTY(TEST_EXE ${name}_test LOCATION) SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}_test_ok.txt) + + SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}) + IF (wrapper) + SET(TEST_CMD ${PYTHON_EXECUTABLE} ${wrapper} ${TEST_CMD}) + ENDIF (wrapper) + + #MESSAGE(STATUS "ADD_BUILD_TEST_INTERNAL ${name} test_cmd = ${TEST_CMD}") + SET(TEST_SCRIPT_CMD + ${CMAKE_COMMAND} + -DLD_LIBRARY_PATH=${ARCH_PREBUILT_DIRS}:/usr/lib + -DTEST_CMD:STRING="${TEST_CMD}" + -P ${CMAKE_SOURCE_DIR}/cmake/RunBuildTest.cmake + ) + + #MESSAGE(STATUS "ADD_BUILD_TEST_INTERNAL ${name} test_script = ${TEST_SCRIPT_CMD}") ADD_CUSTOM_COMMAND( - OUTPUT ${TEST_OUTPUT} - COMMAND ${TEST_EXE} - ARGS --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS ${name}_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) + OUTPUT ${TEST_OUTPUT} + COMMAND ${TEST_SCRIPT_CMD} + DEPENDS ${name}_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + ADD_CUSTOM_TARGET(${name}_test_ok ALL DEPENDS ${TEST_OUTPUT}) - ADD_DEPENDENCIES(${parent} ${name}_test_ok) + IF (${parent}) + ADD_DEPENDENCIES(${parent} ${name}_test_ok) + ENDIF (${parent}) + +ENDMACRO(ADD_BUILD_TEST_INTERNAL name parent libraries source_files) + + +MACRO(ADD_COMM_BUILD_TEST name parent wrapper) +## MESSAGE(STATUS "ADD_COMM_BUILD_TEST ${name} wrapper = ${wrapper}") + # optional extra parameter: list of additional source files + SET(more_source_files "${ARGN}") +## MESSAGE(STATUS "ADD_COMM_BUILD_TEST ${name} more_source_files = ${more_source_files}") + + SET(libraries + ${LLMESSAGE_LIBRARIES} + ${LLMATH_LIBRARIES} + ${LLVFS_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${APRUTIL_LIBRARIES} + ${APR_LIBRARIES} + ${PTHREAD_LIBRARY} + ${WINDOWS_LIBRARIES} + ) + SET(source_files + ${name}.cpp + tests/${name}_test.cpp + ${CMAKE_SOURCE_DIR}/test/test.cpp + ${CMAKE_SOURCE_DIR}/test/lltut.cpp + ${more_source_files} + ) + + ADD_BUILD_TEST_INTERNAL("${name}" "${parent}" "${libraries}" "${source_files}" "${wrapper}") +ENDMACRO(ADD_COMM_BUILD_TEST name parent wrapper) -ENDMACRO(ADD_BUILD_TEST_INTERNAL name parent libraries) +MACRO(ADD_VIEWER_COMM_BUILD_TEST name parent wrapper) + # This is just like the generic ADD_COMM_BUILD_TEST, but we implicitly + # add the necessary precompiled header .cpp file (anyone else find that + # oxymoronic?) because the MSVC build errors will NOT point you there. +## MESSAGE(STATUS "ADD_VIEWER_COMM_BUILD_TEST ${name} wrapper = ${wrapper}") + ADD_COMM_BUILD_TEST("${name}" "${parent}" "${wrapper}" llviewerprecompiledheaders.cpp) +ENDMACRO(ADD_VIEWER_COMM_BUILD_TEST name parent wrapper) diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp index 2c46a24b65..039b70ec4a 100644 --- a/indra/linux_crash_logger/llcrashloggerlinux.cpp +++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp @@ -91,7 +91,7 @@ static BOOL do_ask_dialog(void) win = gtk_message_dialog_new(NULL, flags, messagetype, buttons, - dialog_text); + "%s", dialog_text); gtk_window_set_type_hint(GTK_WINDOW(win), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_title(GTK_WINDOW(win), dialog_title); diff --git a/indra/llcommon/is_approx_equal_fraction.h b/indra/llcommon/is_approx_equal_fraction.h new file mode 100644 index 0000000000..f95b148590 --- /dev/null +++ b/indra/llcommon/is_approx_equal_fraction.h @@ -0,0 +1,62 @@ +/** + * @file is_approx_equal_fraction.h + * @author Nat Goodspeed + * @date 2009-01-28 + * @brief lltut.h uses is_approx_equal_fraction(). Moved to this header + * file in llcommon so we can use lltut.h for llcommon tests without + * making llcommon depend on llmath. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_IS_APPROX_EQUAL_FRACTION_H) +#define LL_IS_APPROX_EQUAL_FRACTION_H + +#include "lldefs.h" +#include + +/** + * Originally llmath.h contained two complete implementations of + * is_approx_equal_fraction(), with signatures as below, bodies identical save + * where they specifically mentioned F32/F64. Unifying these into a template + * makes sense -- but to preserve the compiler's overload-selection behavior, + * we still wrap the template implementation with the specific overloaded + * signatures. + */ +template +inline BOOL is_approx_equal_fraction_impl(FTYPE x, FTYPE y, U32 frac_bits) +{ + BOOL ret = TRUE; + FTYPE diff = (FTYPE) fabs(x - y); + + S32 diffInt = (S32) diff; + S32 diffFracTolerance = (S32) ((diff - (FTYPE) diffInt) * (1 << frac_bits)); + + // if integer portion is not equal, not enough bits were used for packing + // so error out since either the use case is not correct OR there is + // an issue with pack/unpack. should fail in either case. + // for decimal portion, make sure that the delta is no more than 1 + // based on the number of bits used for packing decimal portion. + if (diffInt != 0 || diffFracTolerance > 1) + { + ret = FALSE; + } + + return ret; +} + +/// F32 flavor +inline BOOL is_approx_equal_fraction(F32 x, F32 y, U32 frac_bits) +{ + return is_approx_equal_fraction_impl(x, y, frac_bits); +} + +/// F64 flavor +inline BOOL is_approx_equal_fraction(F64 x, F64 y, U32 frac_bits) +{ + return is_approx_equal_fraction_impl(x, y, frac_bits); +} + +#endif /* ! defined(LL_IS_APPROX_EQUAL_FRACTION_H) */ diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 998b47450d..199315f34e 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -58,7 +58,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *); /* OSX doesn't support SIGRT* */ S32 LL_SMACKDOWN_SIGNAL = SIGUSR1; S32 LL_HEARTBEAT_SIGNAL = SIGUSR2; -# else +# else // linux or (assumed) other similar unixoid /* We want reliable delivery of our signals - SIGRT* is it. */ /* Old LinuxThreads versions eat SIGRTMIN+0 to SIGRTMIN+2, avoid those. */ /* Note that SIGRTMIN/SIGRTMAX may expand to a glibc function call with a @@ -559,7 +559,9 @@ void setup_signals() sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL); // Asynchronous signals that are normally ignored +#ifndef LL_IGNORE_SIGCHLD sigaction(SIGCHLD, &act, NULL); +#endif // LL_IGNORE_SIGCHLD sigaction(SIGUSR2, &act, NULL); // Asynchronous signals that result in attempted graceful exit @@ -593,7 +595,9 @@ void clear_signals() sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL); // Asynchronous signals that are normally ignored +#ifndef LL_IGNORE_SIGCHLD sigaction(SIGCHLD, &act, NULL); +#endif // LL_IGNORE_SIGCHLD // Asynchronous signals that result in attempted graceful exit sigaction(SIGHUP, &act, NULL); diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 12fc116714..66451b1a27 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -38,6 +38,10 @@ #include "lldefs.h" #include "llstl.h" // *TODO: Remove when LLString is gone #include "llstring.h" // *TODO: Remove when LLString is gone +// lltut.h uses is_approx_equal_fraction(). This was moved to its own header +// file in llcommon so we can use lltut.h for llcommon tests without making +// llcommon depend on llmath. +#include "is_approx_equal_fraction.h" // work around for Windows & older gcc non-standard function names. #if LL_WINDOWS @@ -142,48 +146,6 @@ inline BOOL is_approx_equal(F64 x, F64 y) return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); } -inline BOOL is_approx_equal_fraction(F32 x, F32 y, U32 frac_bits) -{ - BOOL ret = TRUE; - F32 diff = (F32) fabs(x - y); - - S32 diffInt = (S32) diff; - S32 diffFracTolerance = (S32) ((diff - (F32) diffInt) * (1 << frac_bits)); - - // if integer portion is not equal, not enough bits were used for packing - // so error out since either the use case is not correct OR there is - // an issue with pack/unpack. should fail in either case. - // for decimal portion, make sure that the delta is no more than 1 - // based on the number of bits used for packing decimal portion. - if (diffInt != 0 || diffFracTolerance > 1) - { - ret = FALSE; - } - - return ret; -} - -inline BOOL is_approx_equal_fraction(F64 x, F64 y, U32 frac_bits) -{ - BOOL ret = TRUE; - F64 diff = (F64) fabs(x - y); - - S32 diffInt = (S32) diff; - S32 diffFracTolerance = (S32) ((diff - (F64) diffInt) * (1 << frac_bits)); - - // if integer portion is not equal, not enough bits were used for packing - // so error out since either the use case is not correct OR there is - // an issue with pack/unpack. should fail in either case. - // for decimal portion, make sure that the delta is no more than 1 - // based on the number of bits used for packing decimal portion. - if (diffInt != 0 || diffFracTolerance > 1) - { - ret = FALSE; - } - - return ret; -} - inline S32 llabs(const S32 a) { return S32(std::labs(a)); diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h new file mode 100644 index 0000000000..7360230451 --- /dev/null +++ b/indra/llmessage/tests/commtest.h @@ -0,0 +1,60 @@ +/** + * @file commtest.h + * @author Nat Goodspeed + * @date 2009-01-09 + * @brief + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_COMMTEST_H) +#define LL_COMMTEST_H + +#include "networkio.h" +#include "llevents.h" +#include "llsd.h" +#include "llhost.h" +#include "stringize.h" +#include + +/** + * This struct is shared by a couple of standalone comm tests (ADD_COMM_BUILD_TEST). + */ +struct commtest_data +{ + NetworkIO& netio; + LLEventPumps& pumps; + LLEventStream replyPump, errorPump; + LLSD result; + bool success; + LLHost host; + std::string server; + + commtest_data(): + netio(NetworkIO::instance()), + pumps(LLEventPumps::instance()), + replyPump("reply"), + errorPump("error"), + success(false), + host("127.0.0.1", 8000), + server(STRINGIZE("http://" << host.getString() << "/")) + { + replyPump.listen("self", boost::bind(&commtest_data::outcome, this, _1, true)); + errorPump.listen("self", boost::bind(&commtest_data::outcome, this, _1, false)); + } + + bool outcome(const LLSD& _result, bool _success) + { +// std::cout << "commtest_data::outcome(" << _result << ", " << _success << ")\n"; + result = _result; + success = _success; + // Break the wait loop in NetworkIO::pump(), otherwise devs get + // irritated at making the big monolithic test executable take longer + pumps.obtain("done").post(success); + return false; + } +}; + +#endif /* ! defined(LL_COMMTEST_H) */ diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h new file mode 100644 index 0000000000..11c5cc07fc --- /dev/null +++ b/indra/llmessage/tests/networkio.h @@ -0,0 +1,93 @@ +/** + * @file networkio.h + * @author Nat Goodspeed + * @date 2009-01-09 + * @brief + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_NETWORKIO_H) +#define LL_NETWORKIO_H + +#include "llmemory.h" // LLSingleton +#include "llapr.h" +#include "llares.h" +#include "llpumpio.h" +#include "llhttpclient.h" + +/***************************************************************************** +* NetworkIO +*****************************************************************************/ +// Doing this initialization in a class constructor makes sense. But we don't +// want to redo it for each different test. Nor do we want to do it at static- +// init time. Use the lazy, on-demand initialization we get from LLSingleton. +class NetworkIO: public LLSingleton +{ +public: + NetworkIO(): + mServicePump(NULL), + mDone(false) + { + ll_init_apr(); + if (! gAPRPoolp) + { + throw std::runtime_error("Can't initialize APR"); + } + + // Create IO Pump to use for HTTP Requests. + mServicePump = new LLPumpIO(gAPRPoolp); + LLHTTPClient::setPump(*mServicePump); + if (ll_init_ares() == NULL || !gAres->isInitialized()) + { + throw std::runtime_error("Can't start DNS resolver"); + } + + // You can interrupt pump() without waiting the full timeout duration + // by posting an event to the LLEventPump named "done". + LLEventPumps::instance().obtain("done").listen("self", + boost::bind(&NetworkIO::done, this, _1)); + } + + bool pump(F32 timeout=10) + { + // Reset the done flag so we don't pop out prematurely + mDone = false; + // Evidently the IO structures underlying LLHTTPClient need to be + // "pumped". Do some stuff normally performed in the viewer's main + // loop. + LLTimer timer; + while (timer.getElapsedTimeF32() < timeout) + { + if (mDone) + { +// std::cout << "NetworkIO::pump(" << timeout << "): breaking loop after " +// << timer.getElapsedTimeF32() << " seconds\n"; + return true; + } + pumpOnce(); + } + return false; + } + + void pumpOnce() + { + gAres->process(); + mServicePump->pump(); + mServicePump->callback(); + } + + bool done(const LLSD&) + { + mDone = true; + return false; + } + +private: + LLPumpIO* mServicePump; + bool mDone; +}; + +#endif /* ! defined(LL_NETWORKIO_H) */ diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py new file mode 100644 index 0000000000..e62f20912b --- /dev/null +++ b/indra/llmessage/tests/test_llsdmessage_peer.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +"""\ +@file test_llsdmessage_peer.py +@author Nat Goodspeed +@date 2008-10-09 +@brief This script asynchronously runs the executable (with args) specified on + the command line, returning its result code. While that executable is + running, we provide dummy local services for use by C++ tests. + +$LicenseInfo:firstyear=2008&license=viewergpl$ +Copyright (c) 2008, Linden Research, Inc. +$/LicenseInfo$ +""" + +import os +import sys +from threading import Thread +from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tests/ +sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) +from indra.util.fastest_elementtree import parse as xml_parse +from indra.base import llsd + +def debug(*args): + sys.stdout.writelines(args) + sys.stdout.flush() +# comment out the line below to enable debug output +debug = lambda *args: None + +class TestHTTPRequestHandler(BaseHTTPRequestHandler): + """This subclass of BaseHTTPRequestHandler is to receive and echo + LLSD-flavored messages sent by the C++ LLHTTPClient. + """ + def read(self): + # The following logic is adapted from the library module + # SimpleXMLRPCServer.py. + # Get arguments by reading body of request. + # We read this in chunks to avoid straining + # socket.read(); around the 10 or 15Mb mark, some platforms + # begin to have problems (bug #792570). + try: + size_remaining = int(self.headers["content-length"]) + except (KeyError, ValueError): + return "" + max_chunk_size = 10*1024*1024 + L = [] + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + chunk = self.rfile.read(chunk_size) + L.append(chunk) + size_remaining -= len(chunk) + return ''.join(L) + # end of swiped read() logic + + def read_xml(self): + # This approach reads the entire POST data into memory first + return llsd.parse(self.read()) +## # This approach attempts to stream in the LLSD XML from self.rfile, +## # assuming that the underlying XML parser reads its input file +## # incrementally. Unfortunately I haven't been able to make it work. +## tree = xml_parse(self.rfile) +## debug("Finished raw parse\n") +## debug("parsed XML tree %s\n" % tree) +## debug("parsed root node %s\n" % tree.getroot()) +## debug("root node tag %s\n" % tree.getroot().tag) +## return llsd.to_python(tree.getroot()) + + def do_GET(self): + # Of course, don't attempt to read data. + self.answer(dict(reply="success", status=500, + reason="Your GET operation requested failure")) + + def do_POST(self): + # Read the provided POST data. + self.answer(self.read_xml()) + + def answer(self, data): + if "fail" not in self.path: + response = llsd.format_xml(data.get("reply", llsd.LLSD("success"))) + self.send_response(200) + self.send_header("Content-type", "application/llsd+xml") + self.send_header("Content-Length", str(len(response))) + self.end_headers() + self.wfile.write(response) + else: # fail requested + status = data.get("status", 500) + reason = data.get("reason", + self.responses.get(status, + ("fail requested", + "Your request specified failure status %s " + "without providing a reason" % status))[1]) + self.send_error(status, reason) + + def log_request(self, code, size=None): + # For present purposes, we don't want the request splattered onto + # stderr, as it would upset devs watching the test run + pass + + def log_error(self, format, *args): + # Suppress error output as well + pass + +class TestHTTPServer(Thread): + def run(self): + httpd = HTTPServer(('127.0.0.1', 8000), TestHTTPRequestHandler) + debug("Starting HTTP server...\n") + httpd.serve_forever() + +def main(*args): + # Start HTTP server thread. Note that this and all other comm server + # threads should be daemon threads: we'll let them run "forever," + # confident that the whole process will terminate when the main thread + # terminates, which will be when the test executable child process + # terminates. + httpThread = TestHTTPServer(name="httpd") + httpThread.setDaemon(True) + httpThread.start() + # choice of os.spawnv(): + # - [v vs. l] pass a list of args vs. individual arguments, + # - [no p] don't use the PATH because we specifically want to invoke the + # executable passed as our first arg, + # - [no e] child should inherit this process's environment. + debug("Running %s...\n" % (" ".join(args))) + sys.stdout.flush() + rc = os.spawnv(os.P_WAIT, args[0], args) + debug("%s returned %s\n" % (args[0], rc)) + return rc + +if __name__ == "__main__": + sys.exit(main(*sys.argv[1:])) diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 91a01a9266..c7178a5552 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -284,10 +284,12 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; #if LL_LINUX && defined(WINGDIAPI) // WINGDIAPI gets set if we are using the linux nvidia gl.h header which needs // the functions below setting up. -# define LL_LINUX_NV_GL_HEADERS +# define LL_LINUX_NV_GL_HEADERS 1 +#else +# define LL_LINUX_NV_GL_HEADERS 0 #endif // LL_LINUX && defined(WINGDIAPI) -#ifdef LL_LINUX_NV_GL_HEADERS +#if LL_LINUX_NV_GL_HEADERS // Missing functions when using nvidia headers: extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 1a724b5f77..a85cbcf9b9 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -124,9 +124,7 @@ bool LLWindowSDL::ll_try_gtk_init(void) if (!tried_gtk_init) { tried_gtk_init = TRUE; -#if LL_GSTREAMER_ENABLED if (!g_thread_supported ()) g_thread_init (NULL); -#endif // LL_GSTREAMER_ENABLED maybe_lock_display(); gtk_is_good = gtk_init_check(NULL, NULL); maybe_unlock_display(); diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt index 2edc11e305..99c973f7ea 100644 --- a/indra/newview/linux_tools/client-readme.txt +++ b/indra/newview/linux_tools/client-readme.txt @@ -53,7 +53,8 @@ Minimum requirements: * Computer Memory: 512MB (recommended: 768MB or more) * Linux Operating System: A reasonably modern 32-bit Linux environment is required. If you are running a 64-bit Linux distribution then - you will need its 32-bit compatibility environment installed. + you will need its 32-bit compatibility environment installed, but + this configuration is not currently supported. * Video/Graphics Card: o nVidia GeForce 2, GeForce 4mx, or better (recommend one of the following: 6700, 6800, 7600, 7800, 7900, 8400, 8500, 8600, diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index d7b17edbc3..e188abe5d2 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -41,6 +41,17 @@ ## driver bug, try enabling this option and report whether it helps: #export LL_ATI_MOUSE_CURSOR_BUG=x +## - If you experience crashes with streaming video and music, you can +## disable these by enabling this option: +#export LL_DISABLE_GSTREAMER=x + +## - GStreamer is automatically disabled - for now - on 64-bit systems due +## to common fatal incompatibilities; remove/comment these lines if you want +## to try anyway. +if [ "`uname -m`" = "x86_64" ]; then + export LL_DISABLE_GSTREAMER=x + echo '64-bit Linux detected: Disabling GStreamer (streaming video and music) by default; edit ./secondlife to re-enable.' +fi ## Everything below this line is just for advanced troubleshooters. ##------------------------------------------------------------------- @@ -117,7 +128,7 @@ if [ -n "$LL_RUN_ERR" ]; then LL_RUN_ERR_MSG="" if [ "$LL_RUN_ERR" = "runerr" ]; then # generic error running the binary - echo '*** Unclean shutdown. ***' + echo '*** Bad shutdown. ***' if [ "`uname -m`" = "x86_64" ]; then echo cat << EOFMARKER diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 0778503a92..8b81478eaf 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -332,6 +332,12 @@ LLAppViewerLinux::~LLAppViewerLinux() bool LLAppViewerLinux::init() { + // g_thread_init() must be called before *any* use of glib, *and* + // before any mutexes are held, *and* some of our third-party + // libraries likes to use glib functions; in short, do this here + // really early in app startup! + if (!g_thread_supported ()) g_thread_init (NULL); + return LLAppViewer::init(); } diff --git a/indra/test/lltut.h b/indra/test/lltut.h index 6d50ebad33..3a0cc04281 100644 --- a/indra/test/lltut.h +++ b/indra/test/lltut.h @@ -35,7 +35,7 @@ #ifndef LL_LLTUT_H #define LL_LLTUT_H -#include "llmath.h" +#include "is_approx_equal_fraction.h" // instead of llmath.h #include -- cgit v1.2.3