summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--[-rwxr-xr-x]indra/llcommon/CMakeLists.txt19
-rw-r--r--[-rwxr-xr-x]indra/llcommon/ctype_workaround.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/fix_macros.h4
-rw-r--r--[-rwxr-xr-x]indra/llcommon/indra_constants.cpp2
-rw-r--r--[-rwxr-xr-x]indra/llcommon/indra_constants.h2
-rw-r--r--[-rwxr-xr-x]indra/llcommon/is_approx_equal_fraction.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/linden_common.h1
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llallocator.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llallocator.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llallocator_heap_profile.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llallocator_heap_profile.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llapp.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llapp.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llapr.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llapr.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llassettype.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llassettype.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llbase32.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llbase32.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llbase64.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llbase64.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llbitpack.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llbitpack.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llboost.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcommon.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcommon.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcommonutils.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcommonutils.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcoros.cpp159
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcoros.h191
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcrc.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcrc.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcriticaldamp.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcriticaldamp.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldate.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldate.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldefs.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldependencies.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldependencies.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldepthstack.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldictionary.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldictionary.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldoubledispatch.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llendianswizzle.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llerror.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llerror.h10
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llerrorcontrol.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llerrorlegacy.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llerrorthread.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llerrorthread.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llevent.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llevent.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventapi.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventapi.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventcoro.cpp239
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventcoro.h333
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventdispatcher.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventdispatcher.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventemitter.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventfilter.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventfilter.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llevents.cpp48
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llevents.h61
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventtimer.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lleventtimer.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llfasttimer.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llfasttimer.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llfile.cpp537
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llfile.h213
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llfindlocale.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llfindlocale.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llfixedbuffer.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llfixedbuffer.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llformat.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llformat.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llframetimer.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llframetimer.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llhandle.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llhash.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llheartbeat.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llheartbeat.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llindexedvector.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llinitparam.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llinitparam.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llinstancetracker.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llinstancetracker.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llkeythrottle.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llkeyusetracker.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llleap.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llleap.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llleaplistener.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llleaplistener.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lllistenerwrapper.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llliveappconfig.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llliveappconfig.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lllivefile.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lllivefile.h0
-rw-r--r--indra/llcommon/llmake.h63
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmd5.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmd5.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmemory.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmemory.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmemorystream.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmemorystream.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmetricperformancetester.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmetricperformancetester.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmetrics.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmetrics.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmortician.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llmortician.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llpointer.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llpreprocessor.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llpriqueuemap.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llprocess.cpp6
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llprocess.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llprocessor.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llprocessor.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llptrto.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llptrto.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llqueuedthread.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llqueuedthread.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llrand.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llrand.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llrefcount.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llrefcount.h9
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llregistry.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llrun.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llrun.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsafehandle.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsd.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsd.h0
-rw-r--r--indra/llcommon/llsdjson.cpp126
-rw-r--r--indra/llcommon/llsdjson.h77
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsdparam.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsdparam.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsdserialize.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsdserialize.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsdserialize_xml.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsdserialize_xml.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsdutil.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsdutil.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsimplehash.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsingleton.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsingleton.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsmoothstep.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstacktrace.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstacktrace.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstl.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstreamqueue.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstreamqueue.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstreamtools.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstreamtools.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstrider.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstring.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstring.h2
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstringtable.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llstringtable.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsys.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llsys.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llthread.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llthread.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llthreadsafequeue.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llthreadsafequeue.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lltimer.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lltimer.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lltreeiterators.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lluri.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lluri.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lluuid.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lluuid.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llworkerthread.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llworkerthread.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/stdtypes.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/stringize.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/StringVec.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/bitpack_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/commonmisc_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/listener.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llallocator_heap_profile_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llallocator_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llbase64_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/lldate_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/lldependencies_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llerror_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/lleventcoro_test.cpp752
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/lleventdispatcher_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/lleventfilter_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llframetimer_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llinstancetracker_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/lllazy_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llleap_test.cpp10
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llmemtype_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llprocess_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llprocessor_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llrand_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llsdserialize_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llsingleton_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llstreamqueue_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/llstring_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/lltreeiterators_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/lluri_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/stringize_test.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/tests/wrapllerrs.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/timer.h0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/timing.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/u64.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcommon/u64.h0
207 files changed, 1400 insertions, 1464 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 5863310162..907dbab8f8 100755..100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -8,6 +8,7 @@ include(LLCommon)
include(Linking)
include(Boost)
include(LLSharedLibs)
+include(JsonCpp)
include(GoogleBreakpad)
include(GooglePerfTools)
include(Copy3rdPartyLibs)
@@ -17,6 +18,7 @@ include(URIPARSER)
include_directories(
${EXPAT_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
+ ${JSONCPP_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS}
${BREAKPAD_INCLUDE_DIRECTORIES}
${URIPARSER_INCLUDE_DIRS}
@@ -86,6 +88,7 @@ set(llcommon_SOURCE_FILES
llrefcount.cpp
llrun.cpp
llsd.cpp
+ llsdjson.cpp
llsdparam.cpp
llsdserialize.cpp
llsdserialize_xml.cpp
@@ -195,6 +198,7 @@ set(llcommon_HEADER_FILES
llrefcount.h
llsafehandle.h
llsd.h
+ llsdjson.h
llsdparam.h
llsdserialize.h
llsdserialize_xml.h
@@ -262,10 +266,14 @@ target_link_libraries(
${APRUTIL_LIBRARIES}
${APR_LIBRARIES}
${EXPAT_LIBRARIES}
+ ${JSONCPP_LIBRARIES}
${ZLIB_LIBRARIES}
${WINDOWS_LIBRARIES}
+ ${BOOST_COROUTINE_LIBRARY}
+ ${BOOST_CONTEXT_LIBRARY}
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
+ ${BOOST_SYSTEM_LIBRARY}
${GOOGLE_PERFTOOLS_LIBRARIES}
${URIPARSER_LIBRARIES}
)
@@ -286,7 +294,14 @@ if (LL_TESTS)
LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}")
#set(TEST_DEBUG on)
- set(test_libs llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES} ${GOOGLEMOCK_LIBRARIES})
+ set(test_libs llcommon
+ ${LLCOMMON_LIBRARIES}
+ ${WINDOWS_LIBRARIES}
+ ${GOOGLEMOCK_LIBRARIES}
+ ${BOOST_COROUTINE_LIBRARY}
+ ${BOOST_CONTEXT_LIBRARY}
+ ${BOOST_THREAD_LIBRARY}
+ ${BOOST_SYSTEM_LIBRARY})
LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llbase64 "" "${test_libs}")
@@ -308,7 +323,7 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs};${BOOST_CONTEXT_LIBRARY};${BOOST_THREAD_LIBRARY};${BOOST_COROUTINE_LIBRARY};${BOOST_SYSTEM_LIBRARY}")
+ LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}")
diff --git a/indra/llcommon/ctype_workaround.h b/indra/llcommon/ctype_workaround.h
index 552be9fb90..552be9fb90 100755..100644
--- a/indra/llcommon/ctype_workaround.h
+++ b/indra/llcommon/ctype_workaround.h
diff --git a/indra/llcommon/fix_macros.h b/indra/llcommon/fix_macros.h
index ef959decff..43c09c54bc 100755..100644
--- a/indra/llcommon/fix_macros.h
+++ b/indra/llcommon/fix_macros.h
@@ -16,10 +16,6 @@
// these macros all over again.
// who injects MACROS with such generic names?! Grr.
-#ifdef equivalent
-#undef equivalent
-#endif
-
#ifdef check
#undef check
#endif
diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp
index f3989ee1d0..1d094cd4f4 100755..100644
--- a/indra/llcommon/indra_constants.cpp
+++ b/indra/llcommon/indra_constants.cpp
@@ -67,3 +67,5 @@ const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); /
const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER
const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER
+
+const LLUUID IMG_BLACK_SQUARE ("3b39cc01-c2d1-e194-1181-e4404978b20c"); // On dataserver
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index 02f063f5e8..6d39aef32e 100755..100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -205,6 +205,8 @@ LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL;
LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL;
+LL_COMMON_API extern const LLUUID IMG_BLACK_SQUARE;
+
// radius within which a chat message is fully audible
const F32 CHAT_NORMAL_RADIUS = 20.f;
diff --git a/indra/llcommon/is_approx_equal_fraction.h b/indra/llcommon/is_approx_equal_fraction.h
index 4a9b2e2725..4a9b2e2725 100755..100644
--- a/indra/llcommon/is_approx_equal_fraction.h
+++ b/indra/llcommon/is_approx_equal_fraction.h
diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h
index 5cfcdab41c..e5a913a6a9 100755..100644
--- a/indra/llcommon/linden_common.h
+++ b/indra/llcommon/linden_common.h
@@ -51,6 +51,7 @@
#include <cstdlib>
#include <ctime>
#include <iosfwd>
+#include <memory>
// Linden only libs in alpha-order other than stdtypes.h
// *NOTE: Please keep includes here to a minimum, see above.
diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp
index 34fc28d8cc..34fc28d8cc 100755..100644
--- a/indra/llcommon/llallocator.cpp
+++ b/indra/llcommon/llallocator.cpp
diff --git a/indra/llcommon/llallocator.h b/indra/llcommon/llallocator.h
index d26ad73c5b..d26ad73c5b 100755..100644
--- a/indra/llcommon/llallocator.h
+++ b/indra/llcommon/llallocator.h
diff --git a/indra/llcommon/llallocator_heap_profile.cpp b/indra/llcommon/llallocator_heap_profile.cpp
index b2eafde1aa..b2eafde1aa 100755..100644
--- a/indra/llcommon/llallocator_heap_profile.cpp
+++ b/indra/llcommon/llallocator_heap_profile.cpp
diff --git a/indra/llcommon/llallocator_heap_profile.h b/indra/llcommon/llallocator_heap_profile.h
index 69300b829b..69300b829b 100755..100644
--- a/indra/llcommon/llallocator_heap_profile.h
+++ b/indra/llcommon/llallocator_heap_profile.h
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 5a40845e7d..5a40845e7d 100755..100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index d9933b3d36..d9933b3d36 100755..100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index a548c96002..a548c96002 100755..100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index b1b0fc4718..b1b0fc4718 100755..100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 5ae2df3994..5ae2df3994 100755..100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 3a4b5dad18..3a4b5dad18 100755..100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
diff --git a/indra/llcommon/llbase32.cpp b/indra/llcommon/llbase32.cpp
index 349567c90b..349567c90b 100755..100644
--- a/indra/llcommon/llbase32.cpp
+++ b/indra/llcommon/llbase32.cpp
diff --git a/indra/llcommon/llbase32.h b/indra/llcommon/llbase32.h
index eeb96d789d..eeb96d789d 100755..100644
--- a/indra/llcommon/llbase32.h
+++ b/indra/llcommon/llbase32.h
diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp
index 4e82cf7f20..4e82cf7f20 100755..100644
--- a/indra/llcommon/llbase64.cpp
+++ b/indra/llcommon/llbase64.cpp
diff --git a/indra/llcommon/llbase64.h b/indra/llcommon/llbase64.h
index 16d2c217d0..16d2c217d0 100755..100644
--- a/indra/llcommon/llbase64.h
+++ b/indra/llcommon/llbase64.h
diff --git a/indra/llcommon/llbitpack.cpp b/indra/llcommon/llbitpack.cpp
index 622a099945..622a099945 100755..100644
--- a/indra/llcommon/llbitpack.cpp
+++ b/indra/llcommon/llbitpack.cpp
diff --git a/indra/llcommon/llbitpack.h b/indra/llcommon/llbitpack.h
index f99a354cd4..f99a354cd4 100755..100644
--- a/indra/llcommon/llbitpack.h
+++ b/indra/llcommon/llbitpack.h
diff --git a/indra/llcommon/llboost.h b/indra/llcommon/llboost.h
index 57d958a51a..57d958a51a 100755..100644
--- a/indra/llcommon/llboost.h
+++ b/indra/llcommon/llboost.h
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 19642b0982..19642b0982 100755..100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
diff --git a/indra/llcommon/llcommon.h b/indra/llcommon/llcommon.h
index ca9cad5d05..ca9cad5d05 100755..100644
--- a/indra/llcommon/llcommon.h
+++ b/indra/llcommon/llcommon.h
diff --git a/indra/llcommon/llcommonutils.cpp b/indra/llcommon/llcommonutils.cpp
index d82554c202..d82554c202 100755..100644
--- a/indra/llcommon/llcommonutils.cpp
+++ b/indra/llcommon/llcommonutils.cpp
diff --git a/indra/llcommon/llcommonutils.h b/indra/llcommon/llcommonutils.h
index 20ada27830..20ada27830 100755..100644
--- a/indra/llcommon/llcommonutils.h
+++ b/indra/llcommon/llcommonutils.h
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index baaddcaed1..d16bf0160b 100755..100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -39,6 +39,62 @@
#include "llerror.h"
#include "stringize.h"
+// do nothing, when we need nothing done
+void LLCoros::no_cleanup(CoroData*) {}
+
+// CoroData for the currently-running coroutine. Use a thread_specific_ptr
+// because each thread potentially has its own distinct pool of coroutines.
+// This thread_specific_ptr does NOT own the CoroData object! That's owned by
+// LLCoros::mCoros. It merely identifies it. For this reason we instantiate
+// it with a no-op cleanup function.
+boost::thread_specific_ptr<LLCoros::CoroData>
+LLCoros::sCurrentCoro(LLCoros::no_cleanup);
+
+//static
+LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)
+{
+ CoroData* current = sCurrentCoro.get();
+ if (! current)
+ {
+ LL_ERRS("LLCoros") << "Calling " << caller << " from non-coroutine context!" << LL_ENDL;
+ }
+ return *current;
+}
+
+//static
+LLCoros::coro::self& LLCoros::get_self()
+{
+ return *get_CoroData("get_self()").mSelf;
+}
+
+//static
+void LLCoros::set_consuming(bool consuming)
+{
+ get_CoroData("set_consuming()").mConsuming = consuming;
+}
+
+//static
+bool LLCoros::get_consuming()
+{
+ return get_CoroData("get_consuming()").mConsuming;
+}
+
+llcoro::Suspending::Suspending():
+ mSuspended(LLCoros::sCurrentCoro.get())
+{
+ // Revert mCurrentCoro to the value it had at the moment we last switched
+ // into this coroutine.
+ LLCoros::sCurrentCoro.reset(mSuspended->mPrev);
+}
+
+llcoro::Suspending::~Suspending()
+{
+ // Okay, we're back, update our mPrev
+ mSuspended->mPrev = LLCoros::sCurrentCoro.get();
+ // and reinstate our sCurrentCoro.
+ LLCoros::sCurrentCoro.reset(mSuspended);
+}
+
LLCoros::LLCoros():
// MAINT-2724: default coroutine stack size too small on Windows.
// Previously we used
@@ -53,14 +109,33 @@ LLCoros::LLCoros():
bool LLCoros::cleanup(const LLSD&)
{
+ static std::string previousName;
+ static int previousCount = 0;
// Walk the mCoros map, checking and removing completed coroutines.
for (CoroMap::iterator mi(mCoros.begin()), mend(mCoros.end()); mi != mend; )
{
// Has this coroutine exited (normal return, exception, exit() call)
// since last tick?
- if (mi->second->exited())
+ if (mi->second->mCoro.exited())
{
- LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
+ if (previousName != mi->first)
+ {
+ previousName = mi->first;
+ previousCount = 1;
+ }
+ else
+ {
+ ++previousCount;
+ }
+
+ if ((previousCount < 5) || !(previousCount % 50))
+ {
+ if (previousCount < 5)
+ LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
+ else
+ LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << "("<< previousCount << ")" << LL_ENDL;
+
+ }
// The erase() call will invalidate its passed iterator value --
// so increment mi FIRST -- but pass its original value to
// erase(). This is what postincrement is all about.
@@ -78,6 +153,9 @@ bool LLCoros::cleanup(const LLSD&)
std::string LLCoros::generateDistinctName(const std::string& prefix) const
{
+ static std::string previousName;
+ static int previousCount = 0;
+
// Allowing empty name would make getName()'s not-found return ambiguous.
if (prefix.empty())
{
@@ -94,7 +172,25 @@ std::string LLCoros::generateDistinctName(const std::string& prefix) const
{
if (mCoros.find(name) == mCoros.end())
{
- LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
+ if (previousName != name)
+ {
+ previousName = name;
+ previousCount = 1;
+ }
+ else
+ {
+ ++previousCount;
+ }
+
+ if ((previousCount < 5) || !(previousCount % 50))
+ {
+ if (previousCount < 5)
+ LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
+ else
+ LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << "(" << previousCount << ")" << LL_ENDL;
+
+ }
+
return name;
}
}
@@ -114,20 +210,15 @@ bool LLCoros::kill(const std::string& name)
return true;
}
-std::string LLCoros::getNameByID(const void* self_id) const
+std::string LLCoros::getName() const
{
- // Walk the existing coroutines, looking for one from which the 'self_id'
- // passed to us comes.
- for (CoroMap::const_iterator mi(mCoros.begin()), mend(mCoros.end()); mi != mend; ++mi)
+ CoroData* current = sCurrentCoro.get();
+ if (! current)
{
- namespace coro_private = boost::dcoroutines::detail;
- if (static_cast<void*>(coro_private::coroutine_accessor::get_impl(const_cast<coro&>(*mi->second)).get())
- == self_id)
- {
- return mi->first;
- }
+ // not in a coroutine
+ return "";
}
- return "";
+ return current->mName;
}
void LLCoros::setStackSize(S32 stacksize)
@@ -136,10 +227,24 @@ void LLCoros::setStackSize(S32 stacksize)
mStackSize = stacksize;
}
+// Top-level wrapper around caller's coroutine callable. This function accepts
+// the coroutine library's implicit coro::self& parameter and sets sCurrentSelf
+// but does not pass it down to the caller's callable.
+void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& callable)
+{
+ // capture the 'self' param in CoroData
+ data->mSelf = &self;
+ // run the code the caller actually wants in the coroutine
+ callable();
+ // This cleanup isn't perfectly symmetrical with the way we initially set
+ // data->mPrev, but this is our last chance to reset mCurrentCoro.
+ sCurrentCoro.reset(data->mPrev);
+}
+
/*****************************************************************************
* MUST BE LAST
*****************************************************************************/
-// Turn off MSVC optimizations for just LLCoros::launchImpl() -- see
+// Turn off MSVC optimizations for just LLCoros::launch() -- see
// DEV-32777. But MSVC doesn't support push/pop for optimization flags as it
// does for warning suppression, and we really don't want to force
// optimization ON for other code even in Debug or RelWithDebInfo builds.
@@ -147,15 +252,35 @@ void LLCoros::setStackSize(S32 stacksize)
#if LL_MSVC
// work around broken optimizations
#pragma warning(disable: 4748)
+#pragma warning(disable: 4355) // 'this' used in initializer list: yes, intentionally
#pragma optimize("", off)
#endif // LL_MSVC
-std::string LLCoros::launchImpl(const std::string& prefix, coro* newCoro)
+LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name,
+ const callable_t& callable, S32 stacksize):
+ mPrev(prev),
+ mName(name),
+ // Wrap the caller's callable in our toplevel() function so we can manage
+ // sCurrentCoro appropriately at startup and shutdown of each coroutine.
+ mCoro(boost::bind(toplevel, _1, this, callable), stacksize),
+ // don't consume events unless specifically directed
+ mConsuming(false),
+ mSelf(0)
+{
+}
+
+std::string LLCoros::launch(const std::string& prefix, const callable_t& callable)
{
std::string name(generateDistinctName(prefix));
+ // pass the current value of sCurrentCoro as previous context
+ CoroData* newCoro = new CoroData(sCurrentCoro.get(), name,
+ callable, mStackSize);
+ // Store it in our pointer map
mCoros.insert(name, newCoro);
+ // also set it as current
+ sCurrentCoro.reset(newCoro);
/* Run the coroutine until its first wait, then return here */
- (*newCoro)(std::nothrow);
+ (newCoro->mCoro)(std::nothrow);
return name;
}
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 01ee11da1a..39316ed0e6 100755..100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -30,14 +30,20 @@
#define LL_LLCOROS_H
#include <boost/dcoroutine/coroutine.hpp>
+#include <boost/dcoroutine/future.hpp>
#include "llsingleton.h"
#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/function.hpp>
+#include <boost/thread/tss.hpp>
#include <string>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/iteration/local.hpp>
#include <stdexcept>
+// forward-declare helper class
+namespace llcoro
+{
+class Suspending;
+}
+
/**
* Registry of named Boost.Coroutine instances
*
@@ -80,8 +86,8 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
public:
/// Canonical boost::dcoroutines::coroutine signature we use
typedef boost::dcoroutines::coroutine<void()> coro;
- /// Canonical 'self' type
- typedef coro::self self;
+ /// Canonical callable type
+ typedef boost::function<void()> callable_t;
/**
* Create and start running a new coroutine with specified name. The name
@@ -94,39 +100,33 @@ public:
* {
* public:
* ...
- * // Do NOT NOT NOT accept reference params other than 'self'!
+ * // Do NOT NOT NOT accept reference params!
* // Pass by value only!
- * void myCoroutineMethod(LLCoros::self& self, std::string, LLSD);
+ * void myCoroutineMethod(std::string, LLSD);
* ...
* };
* ...
* std::string name = LLCoros::instance().launch(
- * "mycoro", boost::bind(&MyClass::myCoroutineMethod, this, _1,
+ * "mycoro", boost::bind(&MyClass::myCoroutineMethod, this,
* "somestring", LLSD(17));
* @endcode
*
- * Your function/method must accept LLCoros::self& as its first parameter.
- * It can accept any other parameters you want -- but ONLY BY VALUE!
- * Other reference parameters are a BAD IDEA! You Have Been Warned. See
+ * Your function/method can accept any parameters you want -- but ONLY BY
+ * VALUE! Reference parameters are a BAD IDEA! You Have Been Warned. See
* DEV-32777 comments for an explanation.
*
- * Pass a callable that accepts the single LLCoros::self& parameter. It
- * may work to pass a free function whose only parameter is 'self'; for
- * all other cases use boost::bind(). Of course, for a non-static class
- * method, the first parameter must be the class instance. Use the
- * placeholder _1 for the 'self' parameter. Any other parameters should be
- * passed via the bind() expression.
+ * Pass a nullary callable. It works to directly pass a nullary free
+ * function (or static method); for all other cases use boost::bind(). Of
+ * course, for a non-static class method, the first parameter must be the
+ * class instance. Any other parameters should be passed via the bind()
+ * expression.
*
* launch() tweaks the suggested name so it won't collide with any
* existing coroutine instance, creates the coroutine instance, registers
* it with the tweaked name and runs it until its first wait. At that
* point it returns the tweaked name.
*/
- template <typename CALLABLE>
- std::string launch(const std::string& prefix, const CALLABLE& callable)
- {
- return launchImpl(prefix, new coro(callable, mStackSize));
- }
+ std::string launch(const std::string& prefix, const callable_t& callable);
/**
* Abort a running coroutine by name. Normally, when a coroutine either
@@ -138,33 +138,150 @@ public:
bool kill(const std::string& name);
/**
- * From within a coroutine, pass its @c self object to look up the
- * (tweaked) name string by which this coroutine is registered. Returns
- * the empty string if not found (e.g. if the coroutine was launched by
- * hand rather than using LLCoros::launch()).
+ * From within a coroutine, look up the (tweaked) name string by which
+ * this coroutine is registered. Returns the empty string if not found
+ * (e.g. if the coroutine was launched by hand rather than using
+ * LLCoros::launch()).
*/
- template <typename COROUTINE_SELF>
- std::string getName(const COROUTINE_SELF& self) const
- {
- return getNameByID(self.get_id());
- }
-
- /// getName() by self.get_id()
- std::string getNameByID(const void* self_id) const;
+ std::string getName() const;
/// for delayed initialization
void setStackSize(S32 stacksize);
+ /// get the current coro::self& for those who really really care
+ static coro::self& get_self();
+
+ /**
+ * Most coroutines, most of the time, don't "consume" the events for which
+ * they're suspending. This way, an arbitrary number of listeners (whether
+ * coroutines or simple callbacks) can be registered on a particular
+ * LLEventPump, every listener responding to each of the events on that
+ * LLEventPump. But a particular coroutine can assert that it will consume
+ * each event for which it suspends. (See also llcoro::postAndSuspend(),
+ * llcoro::VoidListener)
+ */
+ static void set_consuming(bool consuming);
+ static bool get_consuming();
+
+ /**
+ * Please do NOT directly use boost::dcoroutines::future! It is essential
+ * to maintain the "current" coroutine at every context switch. This
+ * Future wraps the essential boost::dcoroutines::future functionality
+ * with that maintenance.
+ */
+ template <typename T>
+ class Future;
+
private:
- friend class LLSingleton<LLCoros>;
LLCoros();
- std::string launchImpl(const std::string& prefix, coro* newCoro);
+ friend class LLSingleton<LLCoros>;
+ friend class llcoro::Suspending;
std::string generateDistinctName(const std::string& prefix) const;
bool cleanup(const LLSD&);
+ struct CoroData;
+ static void no_cleanup(CoroData*);
+ static void toplevel(coro::self& self, CoroData* data, const callable_t& callable);
+ static CoroData& get_CoroData(const std::string& caller);
S32 mStackSize;
- typedef boost::ptr_map<std::string, coro> CoroMap;
+
+ // coroutine-local storage, as it were: one per coro we track
+ struct CoroData
+ {
+ CoroData(CoroData* prev, const std::string& name,
+ const callable_t& callable, S32 stacksize);
+
+ // The boost::dcoroutines library supports asymmetric coroutines. Every
+ // time we context switch out of a coroutine, we pass control to the
+ // previously-active one (or to the non-coroutine stack owned by the
+ // thread). So our management of the "current" coroutine must be able to
+ // restore the previous value when we're about to switch away.
+ CoroData* mPrev;
+ // tweaked name of the current coroutine
+ const std::string mName;
+ // the actual coroutine instance
+ LLCoros::coro mCoro;
+ // set_consuming() state
+ bool mConsuming;
+ // When the dcoroutine library calls a top-level callable, it implicitly
+ // passes coro::self& as the first parameter. All our consumer code used
+ // to explicitly pass coro::self& down through all levels of call stack,
+ // because at the leaf level we need it for context-switching. But since
+ // coroutines are based on cooperative switching, we can cause the
+ // top-level entry point to stash a pointer to the currently-running
+ // coroutine, and manage it appropriately as we switch out and back in.
+ // That eliminates the need to pass it as an explicit parameter down
+ // through every level, which is unfortunately viral in nature. Finding it
+ // implicitly rather than explicitly allows minor maintenance in which a
+ // leaf-level function adds a new async I/O call that suspends the calling
+ // coroutine, WITHOUT having to propagate coro::self& through every
+ // function signature down to that point -- and of course through every
+ // other caller of every such function.
+ LLCoros::coro::self* mSelf;
+ };
+ typedef boost::ptr_map<std::string, CoroData> CoroMap;
CoroMap mCoros;
+
+ // identify the current coroutine's CoroData
+ static boost::thread_specific_ptr<LLCoros::CoroData> sCurrentCoro;
+};
+
+namespace llcoro
+{
+
+/// Instantiate one of these in a block surrounding any leaf point when
+/// control literally switches away from this coroutine.
+class Suspending
+{
+public:
+ Suspending();
+ ~Suspending();
+
+private:
+ LLCoros::CoroData* mSuspended;
+};
+
+} // namespace llcoro
+
+template <typename T>
+class LLCoros::Future
+{
+ typedef boost::dcoroutines::future<T> dfuture;
+
+public:
+ Future():
+ mFuture(get_self())
+ {}
+
+ typedef typename boost::dcoroutines::make_callback_result<dfuture>::type callback_t;
+
+ callback_t make_callback()
+ {
+ return boost::dcoroutines::make_callback(mFuture);
+ }
+
+#ifndef LL_LINUX
+ explicit
+#endif
+ operator bool() const
+ {
+ return bool(mFuture);
+ }
+
+ bool operator!() const
+ {
+ return ! mFuture;
+ }
+
+ T get()
+ {
+ // instantiate Suspending to manage the "current" coroutine
+ llcoro::Suspending suspended;
+ return *mFuture;
+ }
+
+private:
+ dfuture mFuture;
};
#endif /* ! defined(LL_LLCOROS_H) */
diff --git a/indra/llcommon/llcrc.cpp b/indra/llcommon/llcrc.cpp
index 626bb1e564..626bb1e564 100755..100644
--- a/indra/llcommon/llcrc.cpp
+++ b/indra/llcommon/llcrc.cpp
diff --git a/indra/llcommon/llcrc.h b/indra/llcommon/llcrc.h
index 3f41b28ffa..3f41b28ffa 100755..100644
--- a/indra/llcommon/llcrc.h
+++ b/indra/llcommon/llcrc.h
diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp
index 54be855f67..54be855f67 100755..100644
--- a/indra/llcommon/llcriticaldamp.cpp
+++ b/indra/llcommon/llcriticaldamp.cpp
diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h
index 1fb6a1af29..1fb6a1af29 100755..100644
--- a/indra/llcommon/llcriticaldamp.h
+++ b/indra/llcommon/llcriticaldamp.h
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 7a2a0869f4..7a2a0869f4 100755..100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index be2cd2d051..be2cd2d051 100755..100644
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h
index 5a4b8325f4..5a4b8325f4 100755..100644
--- a/indra/llcommon/lldefs.h
+++ b/indra/llcommon/lldefs.h
diff --git a/indra/llcommon/lldependencies.cpp b/indra/llcommon/lldependencies.cpp
index 0e72c175cb..0e72c175cb 100755..100644
--- a/indra/llcommon/lldependencies.cpp
+++ b/indra/llcommon/lldependencies.cpp
diff --git a/indra/llcommon/lldependencies.h b/indra/llcommon/lldependencies.h
index e0294e271b..e0294e271b 100755..100644
--- a/indra/llcommon/lldependencies.h
+++ b/indra/llcommon/lldependencies.h
diff --git a/indra/llcommon/lldepthstack.h b/indra/llcommon/lldepthstack.h
index b65840d342..b65840d342 100755..100644
--- a/indra/llcommon/lldepthstack.h
+++ b/indra/llcommon/lldepthstack.h
diff --git a/indra/llcommon/lldictionary.cpp b/indra/llcommon/lldictionary.cpp
index e16c35ed6a..e16c35ed6a 100755..100644
--- a/indra/llcommon/lldictionary.cpp
+++ b/indra/llcommon/lldictionary.cpp
diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h
index 5800ec5e5d..5800ec5e5d 100755..100644
--- a/indra/llcommon/lldictionary.h
+++ b/indra/llcommon/lldictionary.h
diff --git a/indra/llcommon/lldoubledispatch.h b/indra/llcommon/lldoubledispatch.h
index 8ed295b6f1..8ed295b6f1 100755..100644
--- a/indra/llcommon/lldoubledispatch.h
+++ b/indra/llcommon/lldoubledispatch.h
diff --git a/indra/llcommon/llendianswizzle.h b/indra/llcommon/llendianswizzle.h
index 4c08074a9c..4c08074a9c 100755..100644
--- a/indra/llcommon/llendianswizzle.h
+++ b/indra/llcommon/llendianswizzle.h
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 5ed348e13c..5ed348e13c 100755..100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 63040e1772..3beef65723 100755..100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -354,6 +354,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
#define LL_WARNS(...) lllog(LLError::LEVEL_WARN, false, ##__VA_ARGS__)
#define LL_ERRS(...) lllog(LLError::LEVEL_ERROR, false, ##__VA_ARGS__)
// alternative to llassert_always that prints explanatory message
+#define LL_WARNS_IF(exp, ...) if (exp) LL_WARNS(##__VA_ARGS__) << "(" #exp ")"
#define LL_ERRS_IF(exp, ...) if (exp) LL_ERRS(##__VA_ARGS__) << "(" #exp ")"
// Only print the log message once (good for warnings or infos that would otherwise
@@ -362,13 +363,4 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
#define LL_INFOS_ONCE(...) lllog(LLError::LEVEL_INFO, true, ##__VA_ARGS__)
#define LL_WARNS_ONCE(...) lllog(LLError::LEVEL_WARN, true, ##__VA_ARGS__)
-// DEPRECATED: Use the new macros that allow tags and *look* like macros.
-#define lldebugs LL_COMPILE_TIME_MESSAGE("Warning: lldebugs deprecated, use LL_DEBUGS() instead") LL_DEBUGS()
-#define llinfos LL_COMPILE_TIME_MESSAGE("Warning: llinfos deprecated, use LL_INFOS() instead") LL_INFOS()
-#define llwarns LL_COMPILE_TIME_MESSAGE("Warning: llwarns deprecated, use LL_WARNS() instead") LL_WARNS()
-#define llerrs LL_COMPILE_TIME_MESSAGE("Warning: llerrs deprecated, use LL_ERRS() instead") LL_ERRS()
-#define llcont LL_COMPILE_TIME_MESSAGE("Warning: llcont deprecated, use LL_CONT instead") LL_CONT
-#define llendl LL_COMPILE_TIME_MESSAGE("Warning: llendl deprecated, use LL_ENDL instead") LL_ENDL
-
-
#endif // LL_LLERROR_H
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index 56ac52e5de..56ac52e5de 100755..100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h
index 31dd207008..31dd207008 100755..100644
--- a/indra/llcommon/llerrorlegacy.h
+++ b/indra/llcommon/llerrorlegacy.h
diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp
index f6bc68b5c1..f6bc68b5c1 100755..100644
--- a/indra/llcommon/llerrorthread.cpp
+++ b/indra/llcommon/llerrorthread.cpp
diff --git a/indra/llcommon/llerrorthread.h b/indra/llcommon/llerrorthread.h
index 474cef3a50..474cef3a50 100755..100644
--- a/indra/llcommon/llerrorthread.h
+++ b/indra/llcommon/llerrorthread.h
diff --git a/indra/llcommon/llevent.cpp b/indra/llcommon/llevent.cpp
index 633df01588..633df01588 100755..100644
--- a/indra/llcommon/llevent.cpp
+++ b/indra/llcommon/llevent.cpp
diff --git a/indra/llcommon/llevent.h b/indra/llcommon/llevent.h
index 28ce7de102..28ce7de102 100755..100644
--- a/indra/llcommon/llevent.h
+++ b/indra/llcommon/llevent.h
diff --git a/indra/llcommon/lleventapi.cpp b/indra/llcommon/lleventapi.cpp
index ff5459c1eb..ff5459c1eb 100755..100644
--- a/indra/llcommon/lleventapi.cpp
+++ b/indra/llcommon/lleventapi.cpp
diff --git a/indra/llcommon/lleventapi.h b/indra/llcommon/lleventapi.h
index 5991fe8fd5..5991fe8fd5 100755..100644
--- a/indra/llcommon/lleventapi.h
+++ b/indra/llcommon/lleventapi.h
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 81cc33fbba..578a2b62c8 100755..100644
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
@@ -38,34 +38,60 @@
#include "llsdserialize.h"
#include "llerror.h"
#include "llcoros.h"
+#include "llmake.h"
-std::string LLEventDetail::listenerNameForCoroImpl(const void* self_id)
+#include "lleventfilter.h"
+
+namespace
{
- // First, if this coroutine was launched by LLCoros::launch(), find that name.
- std::string name(LLCoros::instance().getNameByID(self_id));
+
+/**
+ * suspendUntilEventOn() permits a coroutine to temporarily listen on an
+ * LLEventPump any number of times. We don't really want to have to ask
+ * the caller to label each such call with a distinct string; the whole
+ * point of suspendUntilEventOn() is to present a nice sequential interface to
+ * the underlying LLEventPump-with-named-listeners machinery. So we'll use
+ * LLEventPump::inventName() to generate a distinct name for each
+ * temporary listener. On the other hand, because a given coroutine might
+ * call suspendUntilEventOn() any number of times, we don't really want to
+ * consume an arbitrary number of generated inventName()s: that namespace,
+ * though large, is nonetheless finite. So we memoize an invented name for
+ * each distinct coroutine instance.
+ */
+std::string listenerNameForCoro()
+{
+ // If this coroutine was launched by LLCoros::launch(), find that name.
+ std::string name(LLCoros::instance().getName());
if (! name.empty())
{
return name;
}
- // Apparently this coroutine wasn't launched by LLCoros::launch(). Check
- // whether we have a memo for this self_id.
- typedef std::map<const void*, std::string> MapType;
- static MapType memo;
- MapType::const_iterator found = memo.find(self_id);
- if (found != memo.end())
- {
- // this coroutine instance has called us before, reuse same name
- return found->second;
- }
// this is the first time we've been called for this coroutine instance
name = LLEventPump::inventName("coro");
- memo[self_id] = name;
- LL_INFOS("LLEventCoro") << "listenerNameForCoroImpl(" << self_id << "): inventing coro name '"
+ LL_INFOS("LLEventCoro") << "listenerNameForCoro(): inventing coro name '"
<< name << "'" << LL_ENDL;
return name;
}
-void LLEventDetail::storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)
+/**
+ * Implement behavior described for postAndSuspend()'s @a replyPumpNamePath
+ * parameter:
+ *
+ * * If <tt>path.isUndefined()</tt>, do nothing.
+ * * If <tt>path.isString()</tt>, @a dest is an LLSD map: store @a value
+ * into <tt>dest[path.asString()]</tt>.
+ * * If <tt>path.isInteger()</tt>, @a dest is an LLSD array: store @a
+ * value into <tt>dest[path.asInteger()]</tt>.
+ * * If <tt>path.isArray()</tt>, iteratively apply the rules above to step
+ * down through the structure of @a dest. The last array entry in @a
+ * path specifies the entry in the lowest-level structure in @a dest
+ * into which to store @a value.
+ *
+ * @note
+ * In the degenerate case in which @a path is an empty array, @a dest will
+ * @em become @a value rather than @em containing it.
+ */
+void storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)
{
if (rawPath.isUndefined())
{
@@ -118,6 +144,185 @@ void LLEventDetail::storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD&
*pdest = value;
}
+/// For LLCoros::Future<LLSD>::make_callback(), the callback has a signature
+/// like void callback(LLSD), which isn't a valid LLEventPump listener: such
+/// listeners must return bool.
+template <typename LISTENER>
+class FutureListener
+{
+public:
+ // FutureListener is instantiated on the coroutine stack: the stack, in
+ // other words, that wants to suspend.
+ FutureListener(const LISTENER& listener):
+ mListener(listener),
+ // Capture the suspending coroutine's flag as a consuming or
+ // non-consuming listener.
+ mConsume(LLCoros::get_consuming())
+ {}
+
+ // operator()() is called on the main stack: the stack on which the
+ // expected event is fired.
+ bool operator()(const LLSD& event)
+ {
+ mListener(event);
+ // tell upstream LLEventPump whether listener consumed
+ return mConsume;
+ }
+
+protected:
+ LISTENER mListener;
+ bool mConsume;
+};
+
+} // anonymous
+
+void llcoro::suspend()
+{
+ // By viewer convention, we post an event on the "mainloop" LLEventPump
+ // each iteration of the main event-handling loop. So waiting for a single
+ // event on "mainloop" gives us a one-frame suspend.
+ suspendUntilEventOn("mainloop");
+}
+
+void llcoro::suspendUntilTimeout(float seconds)
+{
+ LLEventTimeout timeout;
+
+ timeout.eventAfter(seconds, LLSD());
+ llcoro::suspendUntilEventOn(timeout);
+}
+
+LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+ const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath)
+{
+ // declare the future
+ LLCoros::Future<LLSD> future;
+ // make a callback that will assign a value to the future, and listen on
+ // the specified LLEventPump with that callback
+ std::string listenerName(listenerNameForCoro());
+ LLTempBoundListener connection(
+ replyPump.getPump().listen(listenerName,
+ llmake<FutureListener>(future.make_callback())));
+ // skip the "post" part if requestPump is default-constructed
+ if (requestPump)
+ {
+ // If replyPumpNamePath is non-empty, store the replyPump name in the
+ // request event.
+ LLSD modevent(event);
+ storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());
+ LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << listenerName
+ << " posting to " << requestPump.getPump().getName()
+ << LL_ENDL;
+
+ // *NOTE:Mani - Removed because modevent could contain user's hashed passwd.
+ // << ": " << modevent << LL_ENDL;
+ requestPump.getPump().post(modevent);
+ }
+ LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << listenerName
+ << " about to wait on LLEventPump " << replyPump.getPump().getName()
+ << LL_ENDL;
+ // calling get() on the future makes us wait for it
+ LLSD value(future.get());
+ LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << listenerName
+ << " resuming with " << value << LL_ENDL;
+ // returning should disconnect the connection
+ return value;
+}
+
+namespace
+{
+
+/**
+ * This helper is specifically for postAndSuspend2(). We use a single future
+ * object, but we want to listen on two pumps with it. Since we must still
+ * adapt from the callable constructed by boost::dcoroutines::make_callback()
+ * (void return) to provide an event listener (bool return), we've adapted
+ * FutureListener for the purpose. The basic idea is that we construct a
+ * distinct instance of FutureListener2 -- binding different instance data --
+ * for each of the pumps. Then, when a pump delivers an LLSD value to either
+ * FutureListener2, it can combine that LLSD with its discriminator to feed
+ * the future object.
+ *
+ * DISCRIM is a template argument so we can use llmake() rather than
+ * having to write our own argument-deducing helper function.
+ */
+template <typename LISTENER, typename DISCRIM>
+class FutureListener2: public FutureListener<LISTENER>
+{
+ typedef FutureListener<LISTENER> super;
+
+public:
+ // instantiated on coroutine stack: the stack about to suspend
+ FutureListener2(const LISTENER& listener, DISCRIM discriminator):
+ super(listener),
+ mDiscrim(discriminator)
+ {}
+
+ // called on main stack: the stack on which event is fired
+ bool operator()(const LLSD& event)
+ {
+ // our future object is defined to accept LLEventWithID
+ super::mListener(LLEventWithID(event, mDiscrim));
+ // tell LLEventPump whether or not event was consumed
+ return super::mConsume;
+ }
+
+private:
+ const DISCRIM mDiscrim;
+};
+
+} // anonymous
+
+namespace llcoro
+{
+
+LLEventWithID postAndSuspend2(const LLSD& event,
+ const LLEventPumpOrPumpName& requestPump,
+ const LLEventPumpOrPumpName& replyPump0,
+ const LLEventPumpOrPumpName& replyPump1,
+ const LLSD& replyPump0NamePath,
+ const LLSD& replyPump1NamePath)
+{
+ // declare the future
+ LLCoros::Future<LLEventWithID> future;
+ // either callback will assign a value to this future; listen on
+ // each specified LLEventPump with a callback
+ std::string name(listenerNameForCoro());
+ LLTempBoundListener connection0(
+ replyPump0.getPump().listen(
+ name + "a",
+ llmake<FutureListener2>(future.make_callback(), 0)));
+ LLTempBoundListener connection1(
+ replyPump1.getPump().listen(
+ name + "b",
+ llmake<FutureListener2>(future.make_callback(), 1)));
+ // skip the "post" part if requestPump is default-constructed
+ if (requestPump)
+ {
+ // If either replyPumpNamePath is non-empty, store the corresponding
+ // replyPump name in the request event.
+ LLSD modevent(event);
+ storeToLLSDPath(modevent, replyPump0NamePath,
+ replyPump0.getPump().getName());
+ storeToLLSDPath(modevent, replyPump1NamePath,
+ replyPump1.getPump().getName());
+ LL_DEBUGS("lleventcoro") << "postAndSuspend2(): coroutine " << name
+ << " posting to " << requestPump.getPump().getName()
+ << ": " << modevent << LL_ENDL;
+ requestPump.getPump().post(modevent);
+ }
+ LL_DEBUGS("lleventcoro") << "postAndSuspend2(): coroutine " << name
+ << " about to wait on LLEventPumps " << replyPump0.getPump().getName()
+ << ", " << replyPump1.getPump().getName() << LL_ENDL;
+ // calling get() on the future makes us wait for it
+ LLEventWithID value(future.get());
+ LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << name
+ << " resuming with (" << value.first << ", " << value.second << ")"
+ << LL_ENDL;
+ // returning should disconnect both connections
+ return value;
+}
+
LLSD errorException(const LLEventWithID& result, const std::string& desc)
{
// If the result arrived on the error pump (pump 1), instead of
@@ -144,3 +349,5 @@ LLSD errorLog(const LLEventWithID& result, const std::string& desc)
// A simple return must therefore be from the reply pump (pump 0).
return result.first;
}
+
+} // namespace llcoro
diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h
index abbeeaa373..2105faf861 100755..100644
--- a/indra/llcommon/lleventcoro.h
+++ b/indra/llcommon/lleventcoro.h
@@ -29,11 +29,10 @@
#if ! defined(LL_LLEVENTCORO_H)
#define LL_LLEVENTCORO_H
-#include <boost/dcoroutine/coroutine.hpp>
-#include <boost/dcoroutine/future.hpp>
#include <boost/optional.hpp>
#include <string>
#include <stdexcept>
+#include <utility> // std::pair
#include "llevents.h"
#include "llerror.h"
@@ -74,111 +73,46 @@ private:
boost::optional<LLEventPump&> mPump;
};
-/// This is an adapter for a signature like void LISTENER(const LLSD&), which
-/// isn't a valid LLEventPump listener: such listeners should return bool.
-template <typename LISTENER>
-class LLVoidListener
+namespace llcoro
{
-public:
- LLVoidListener(const LISTENER& listener):
- mListener(listener)
- {}
- bool operator()(const LLSD& event)
- {
- mListener(event);
- // don't swallow the event, let other listeners see it
- return false;
- }
-private:
- LISTENER mListener;
-};
-
-/// LLVoidListener helper function to infer the type of the LISTENER
-template <typename LISTENER>
-LLVoidListener<LISTENER> voidlistener(const LISTENER& listener)
-{
- return LLVoidListener<LISTENER>(listener);
-}
-
-namespace LLEventDetail
-{
- /// Implementation for listenerNameForCoro(), see below
- LL_COMMON_API std::string listenerNameForCoroImpl(const void* self_id);
- /**
- * waitForEventOn() permits a coroutine to temporarily listen on an
- * LLEventPump any number of times. We don't really want to have to ask
- * the caller to label each such call with a distinct string; the whole
- * point of waitForEventOn() is to present a nice sequential interface to
- * the underlying LLEventPump-with-named-listeners machinery. So we'll use
- * LLEventPump::inventName() to generate a distinct name for each
- * temporary listener. On the other hand, because a given coroutine might
- * call waitForEventOn() any number of times, we don't really want to
- * consume an arbitrary number of generated inventName()s: that namespace,
- * though large, is nonetheless finite. So we memoize an invented name for
- * each distinct coroutine instance (each different 'self' object). We
- * can't know the type of 'self', because it depends on the coroutine
- * body's signature. So we cast its address to void*, looking for distinct
- * pointer values. Yes, that means that an early coroutine could cache a
- * value here, then be destroyed, only to be supplanted by a later
- * coroutine (of the same or different type), and we'll end up
- * "recognizing" the second one and reusing the listener name -- but
- * that's okay, since it won't collide with any listener name used by the
- * earlier coroutine since that earlier coroutine no longer exists.
- */
- template <typename COROUTINE_SELF>
- std::string listenerNameForCoro(COROUTINE_SELF& self)
- {
- return listenerNameForCoroImpl(self.get_id());
- }
+/**
+ * Yield control from a coroutine for one "mainloop" tick. If your coroutine
+ * runs without suspending for nontrivial time, sprinkle in calls to this
+ * function to avoid stalling the rest of the viewer processing.
+ */
+void suspend();
- /**
- * Implement behavior described for postAndWait()'s @a replyPumpNamePath
- * parameter:
- *
- * * If <tt>path.isUndefined()</tt>, do nothing.
- * * If <tt>path.isString()</tt>, @a dest is an LLSD map: store @a value
- * into <tt>dest[path.asString()]</tt>.
- * * If <tt>path.isInteger()</tt>, @a dest is an LLSD array: store @a
- * value into <tt>dest[path.asInteger()]</tt>.
- * * If <tt>path.isArray()</tt>, iteratively apply the rules above to step
- * down through the structure of @a dest. The last array entry in @a
- * path specifies the entry in the lowest-level structure in @a dest
- * into which to store @a value.
- *
- * @note
- * In the degenerate case in which @a path is an empty array, @a dest will
- * @em become @a value rather than @em containing it.
- */
- LL_COMMON_API void storeToLLSDPath(LLSD& dest, const LLSD& path, const LLSD& value);
-} // namespace LLEventDetail
+/**
+ * Yield control from a coroutine for at least the specified number of seconds
+ */
+void suspendUntilTimeout(float seconds);
/**
- * Post specified LLSD event on the specified LLEventPump, then wait for a
+ * Post specified LLSD event on the specified LLEventPump, then suspend for a
* response on specified other LLEventPump. This is more than mere
* convenience: the difference between this function and the sequence
* @code
* requestPump.post(myEvent);
- * LLSD reply = waitForEventOn(self, replyPump);
+ * LLSD reply = suspendUntilEventOn(replyPump);
* @endcode
* is that the sequence above fails if the reply is posted immediately on
* @a replyPump, that is, before <tt>requestPump.post()</tt> returns. In the
* sequence above, the running coroutine isn't even listening on @a replyPump
- * until <tt>requestPump.post()</tt> returns and @c waitForEventOn() is
+ * until <tt>requestPump.post()</tt> returns and @c suspendUntilEventOn() is
* entered. Therefore, the coroutine completely misses an immediate reply
- * event, making it wait indefinitely.
+ * event, making it suspend indefinitely.
*
- * By contrast, postAndWait() listens on the @a replyPump @em before posting
+ * By contrast, postAndSuspend() listens on the @a replyPump @em before posting
* the specified LLSD event on the specified @a requestPump.
*
- * @param self The @c self object passed into a coroutine
* @param event LLSD data to be posted on @a requestPump
* @param requestPump an LLEventPump on which to post @a event. Pass either
* the LLEventPump& or its string name. However, if you pass a
* default-constructed @c LLEventPumpOrPumpName, we skip the post() call.
- * @param replyPump an LLEventPump on which postAndWait() will listen for a
+ * @param replyPump an LLEventPump on which postAndSuspend() will listen for a
* reply. Pass either the LLEventPump& or its string name. The calling
- * coroutine will wait until that reply arrives. (If you're concerned about a
+ * coroutine will suspend until that reply arrives. (If you're concerned about a
* reply that might not arrive, please see also LLEventTimeout.)
* @param replyPumpNamePath specifies the location within @a event in which to
* store <tt>replyPump.getName()</tt>. This is a strictly optional convenience
@@ -201,101 +135,29 @@ namespace LLEventDetail
* @a replyPumpNamePath specifies the entry in the lowest-level structure in
* @a event into which to store <tt>replyPump.getName()</tt>.
*/
-template <typename SELF>
-LLSD postAndWait(SELF& self, const LLSD& event, const LLEventPumpOrPumpName& requestPump,
- const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD())
-{
- // declare the future
- boost::dcoroutines::future<LLSD> future(self);
- // make a callback that will assign a value to the future, and listen on
- // the specified LLEventPump with that callback
- std::string listenerName(LLEventDetail::listenerNameForCoro(self));
- LLTempBoundListener connection(
- replyPump.getPump().listen(listenerName,
- voidlistener(boost::dcoroutines::make_callback(future))));
- // skip the "post" part if requestPump is default-constructed
- if (requestPump)
- {
- // If replyPumpNamePath is non-empty, store the replyPump name in the
- // request event.
- LLSD modevent(event);
- LLEventDetail::storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());
- LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
- << " posting to " << requestPump.getPump().getName()
- << LL_ENDL;
-
- // *NOTE:Mani - Removed because modevent could contain user's hashed passwd.
- // << ": " << modevent << LL_ENDL;
- requestPump.getPump().post(modevent);
- }
- LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
- << " about to wait on LLEventPump " << replyPump.getPump().getName()
- << LL_ENDL;
- // trying to dereference ("resolve") the future makes us wait for it
- LLSD value(*future);
- LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
- << " resuming with " << value << LL_ENDL;
- // returning should disconnect the connection
- return value;
-}
+LLSD postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+ const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD());
/// Wait for the next event on the specified LLEventPump. Pass either the
/// LLEventPump& or its string name.
-template <typename SELF>
-LLSD waitForEventOn(SELF& self, const LLEventPumpOrPumpName& pump)
+inline
+LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump)
{
- // This is now a convenience wrapper for postAndWait().
- return postAndWait(self, LLSD(), LLEventPumpOrPumpName(), pump);
+ // This is now a convenience wrapper for postAndSuspend().
+ return postAndSuspend(LLSD(), LLEventPumpOrPumpName(), pump);
}
-/// return type for two-pump variant of waitForEventOn()
+} // namespace llcoro
+
+/// return type for two-pump variant of suspendUntilEventOn()
typedef std::pair<LLSD, int> LLEventWithID;
-namespace LLEventDetail
+namespace llcoro
{
- /**
- * This helper is specifically for the two-pump version of waitForEventOn().
- * We use a single future object, but we want to listen on two pumps with it.
- * Since we must still adapt from (the callable constructed by)
- * boost::dcoroutines::make_callback() (void return) to provide an event
- * listener (bool return), we've adapted LLVoidListener for the purpose. The
- * basic idea is that we construct a distinct instance of WaitForEventOnHelper
- * -- binding different instance data -- for each of the pumps. Then, when a
- * pump delivers an LLSD value to either WaitForEventOnHelper, it can combine
- * that LLSD with its discriminator to feed the future object.
- */
- template <typename LISTENER>
- class WaitForEventOnHelper
- {
- public:
- WaitForEventOnHelper(const LISTENER& listener, int discriminator):
- mListener(listener),
- mDiscrim(discriminator)
- {}
- // this signature is required for an LLEventPump listener
- bool operator()(const LLSD& event)
- {
- // our future object is defined to accept LLEventWithID
- mListener(LLEventWithID(event, mDiscrim));
- // don't swallow the event, let other listeners see it
- return false;
- }
- private:
- LISTENER mListener;
- const int mDiscrim;
- };
-
- /// WaitForEventOnHelper type-inference helper
- template <typename LISTENER>
- WaitForEventOnHelper<LISTENER> wfeoh(const LISTENER& listener, int discriminator)
- {
- return WaitForEventOnHelper<LISTENER>(listener, discriminator);
- }
-} // namespace LLEventDetail
/**
* This function waits for a reply on either of two specified LLEventPumps.
- * Otherwise, it closely resembles postAndWait(); please see the documentation
+ * Otherwise, it closely resembles postAndSuspend(); please see the documentation
* for that function for detailed parameter info.
*
* While we could have implemented the single-pump variant in terms of this
@@ -310,81 +172,41 @@ namespace LLEventDetail
* the index of the pump on which it arrived (0 or 1).
*
* @note
- * I'd have preferred to overload the name postAndWait() for both signatures.
+ * I'd have preferred to overload the name postAndSuspend() for both signatures.
* But consider the following ambiguous call:
* @code
- * postAndWait(self, LLSD(), requestPump, replyPump, "someString");
+ * postAndSuspend(LLSD(), requestPump, replyPump, "someString");
* @endcode
* "someString" could be converted to either LLSD (@a replyPumpNamePath for
* the single-pump function) or LLEventOrPumpName (@a replyPump1 for two-pump
* function).
*
- * It seems less burdensome to write postAndWait2() than to write either
+ * It seems less burdensome to write postAndSuspend2() than to write either
* LLSD("someString") or LLEventOrPumpName("someString").
*/
-template <typename SELF>
-LLEventWithID postAndWait2(SELF& self, const LLSD& event,
+LLEventWithID postAndSuspend2(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
const LLEventPumpOrPumpName& replyPump0,
const LLEventPumpOrPumpName& replyPump1,
const LLSD& replyPump0NamePath=LLSD(),
- const LLSD& replyPump1NamePath=LLSD())
-{
- // declare the future
- boost::dcoroutines::future<LLEventWithID> future(self);
- // either callback will assign a value to this future; listen on
- // each specified LLEventPump with a callback
- std::string name(LLEventDetail::listenerNameForCoro(self));
- LLTempBoundListener connection0(
- replyPump0.getPump().listen(name + "a",
- LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 0)));
- LLTempBoundListener connection1(
- replyPump1.getPump().listen(name + "b",
- LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 1)));
- // skip the "post" part if requestPump is default-constructed
- if (requestPump)
- {
- // If either replyPumpNamePath is non-empty, store the corresponding
- // replyPump name in the request event.
- LLSD modevent(event);
- LLEventDetail::storeToLLSDPath(modevent, replyPump0NamePath,
- replyPump0.getPump().getName());
- LLEventDetail::storeToLLSDPath(modevent, replyPump1NamePath,
- replyPump1.getPump().getName());
- LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
- << " posting to " << requestPump.getPump().getName()
- << ": " << modevent << LL_ENDL;
- requestPump.getPump().post(modevent);
- }
- LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
- << " about to wait on LLEventPumps " << replyPump0.getPump().getName()
- << ", " << replyPump1.getPump().getName() << LL_ENDL;
- // trying to dereference ("resolve") the future makes us wait for it
- LLEventWithID value(*future);
- LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << name
- << " resuming with (" << value.first << ", " << value.second << ")"
- << LL_ENDL;
- // returning should disconnect both connections
- return value;
-}
+ const LLSD& replyPump1NamePath=LLSD());
/**
* Wait for the next event on either of two specified LLEventPumps.
*/
-template <typename SELF>
+inline
LLEventWithID
-waitForEventOn(SELF& self,
- const LLEventPumpOrPumpName& pump0, const LLEventPumpOrPumpName& pump1)
+suspendUntilEventOn(const LLEventPumpOrPumpName& pump0, const LLEventPumpOrPumpName& pump1)
{
- // This is now a convenience wrapper for postAndWait2().
- return postAndWait2(self, LLSD(), LLEventPumpOrPumpName(), pump0, pump1);
+ // This is now a convenience wrapper for postAndSuspend2().
+ return postAndSuspend2(LLSD(), LLEventPumpOrPumpName(), pump0, pump1);
}
/**
- * Helper for the two-pump variant of waitForEventOn(), e.g.:
+ * Helper for the two-pump variant of suspendUntilEventOn(), e.g.:
*
* @code
- * LLSD reply = errorException(waitForEventOn(self, replyPump, errorPump),
+ * LLSD reply = errorException(suspendUntilEventOn(replyPump, errorPump),
* "error response from login.cgi");
* @endcode
*
@@ -400,6 +222,8 @@ waitForEventOn(SELF& self,
*/
LLSD errorException(const LLEventWithID& result, const std::string& desc);
+} // namespace llcoro
+
/**
* Exception thrown by errorException(). We don't call this LLEventError
* because it's not an error in event processing: rather, this exception
@@ -420,12 +244,17 @@ private:
LLSD mData;
};
+namespace llcoro
+{
+
/**
* Like errorException(), save that this trips a fatal error using LL_ERRS
* rather than throwing an exception.
*/
LL_COMMON_API LLSD errorLog(const LLEventWithID& result, const std::string& desc);
+} // namespace llcoro
+
/**
* Certain event APIs require the name of an LLEventPump on which they should
* post results. While it works to invent a distinct name and let
@@ -437,7 +266,7 @@ LL_COMMON_API LLSD errorLog(const LLEventWithID& result, const std::string& desc
* 2. Provide its actual name to the event API in question as the name of the
* reply LLEventPump.
* 3. Initiate the request to the event API.
- * 4. Call your LLEventTempStream's wait() method to wait for the reply.
+ * 4. Call your LLEventTempStream's suspend() method to suspend for the reply.
* 5. Let the LLCoroEventPump go out of scope.
*/
class LL_COMMON_API LLCoroEventPump
@@ -454,26 +283,16 @@ public:
/**
* Wait for an event on this LLEventPump.
- *
- * @note
- * The other major usage pattern we considered was to bind @c self at
- * LLCoroEventPump construction time, which would avoid passing the
- * parameter to each wait() call. But if we were going to bind @c self as
- * a class member, we'd need to specify a class template parameter
- * indicating its type. The big advantage of passing it to the wait() call
- * is that the type can be implicit.
*/
- template <typename SELF>
- LLSD wait(SELF& self)
+ LLSD suspend()
{
- return waitForEventOn(self, mPump);
+ return llcoro::suspendUntilEventOn(mPump);
}
- template <typename SELF>
- LLSD postAndWait(SELF& self, const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+ LLSD postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
const LLSD& replyPumpNamePath=LLSD())
{
- return ::postAndWait(self, event, requestPump, mPump, replyPumpNamePath);
+ return llcoro::postAndSuspend(event, requestPump, mPump, replyPumpNamePath);
}
private:
@@ -509,57 +328,51 @@ public:
/// request pump 1
LLEventPump& getPump1() { return mPump1; }
- /// waitForEventOn(self, either of our two LLEventPumps)
- template <typename SELF>
- LLEventWithID wait(SELF& self)
+ /// suspendUntilEventOn(either of our two LLEventPumps)
+ LLEventWithID suspend()
{
- return waitForEventOn(self, mPump0, mPump1);
+ return llcoro::suspendUntilEventOn(mPump0, mPump1);
}
- /// errorException(wait(self))
- template <typename SELF>
- LLSD waitWithException(SELF& self)
+ /// errorException(suspend())
+ LLSD suspendWithException()
{
- return errorException(wait(self), std::string("Error event on ") + getName1());
+ return llcoro::errorException(suspend(), std::string("Error event on ") + getName1());
}
- /// errorLog(wait(self))
- template <typename SELF>
- LLSD waitWithLog(SELF& self)
+ /// errorLog(suspend())
+ LLSD suspendWithLog()
{
- return errorLog(wait(self), std::string("Error event on ") + getName1());
+ return llcoro::errorLog(suspend(), std::string("Error event on ") + getName1());
}
- template <typename SELF>
- LLEventWithID postAndWait(SELF& self, const LLSD& event,
+ LLEventWithID postAndSuspend(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
const LLSD& replyPump0NamePath=LLSD(),
const LLSD& replyPump1NamePath=LLSD())
{
- return postAndWait2(self, event, requestPump, mPump0, mPump1,
- replyPump0NamePath, replyPump1NamePath);
+ return llcoro::postAndSuspend2(event, requestPump, mPump0, mPump1,
+ replyPump0NamePath, replyPump1NamePath);
}
- template <typename SELF>
- LLSD postAndWaitWithException(SELF& self, const LLSD& event,
+ LLSD postAndSuspendWithException(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
const LLSD& replyPump0NamePath=LLSD(),
const LLSD& replyPump1NamePath=LLSD())
{
- return errorException(postAndWait(self, event, requestPump,
- replyPump0NamePath, replyPump1NamePath),
- std::string("Error event on ") + getName1());
+ return llcoro::errorException(postAndSuspend(event, requestPump,
+ replyPump0NamePath, replyPump1NamePath),
+ std::string("Error event on ") + getName1());
}
- template <typename SELF>
- LLSD postAndWaitWithLog(SELF& self, const LLSD& event,
+ LLSD postAndSuspendWithLog(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
const LLSD& replyPump0NamePath=LLSD(),
const LLSD& replyPump1NamePath=LLSD())
{
- return errorLog(postAndWait(self, event, requestPump,
- replyPump0NamePath, replyPump1NamePath),
- std::string("Error event on ") + getName1());
+ return llcoro::errorLog(postAndSuspend(event, requestPump,
+ replyPump0NamePath, replyPump1NamePath),
+ std::string("Error event on ") + getName1());
}
private:
diff --git a/indra/llcommon/lleventdispatcher.cpp b/indra/llcommon/lleventdispatcher.cpp
index 5b6d4efbe9..5b6d4efbe9 100755..100644
--- a/indra/llcommon/lleventdispatcher.cpp
+++ b/indra/llcommon/lleventdispatcher.cpp
diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h
index 7acc61de4e..7acc61de4e 100755..100644
--- a/indra/llcommon/lleventdispatcher.h
+++ b/indra/llcommon/lleventdispatcher.h
diff --git a/indra/llcommon/lleventemitter.h b/indra/llcommon/lleventemitter.h
index cd82fc56f9..cd82fc56f9 100755..100644
--- a/indra/llcommon/lleventemitter.h
+++ b/indra/llcommon/lleventemitter.h
diff --git a/indra/llcommon/lleventfilter.cpp b/indra/llcommon/lleventfilter.cpp
index d36a107254..d36a107254 100755..100644
--- a/indra/llcommon/lleventfilter.cpp
+++ b/indra/llcommon/lleventfilter.cpp
diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h
index e822a664f5..e822a664f5 100755..100644
--- a/indra/llcommon/lleventfilter.h
+++ b/indra/llcommon/lleventfilter.h
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index 1c928b3db8..645c29d770 100755..100644
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
@@ -132,6 +132,17 @@ LLEventPump& LLEventPumps::obtain(const std::string& name)
return *newInstance;
}
+bool LLEventPumps::post(const std::string&name, const LLSD&message)
+{
+ PumpMap::iterator found = mPumpMap.find(name);
+
+ if (found == mPumpMap.end())
+ return false;
+
+ return (*found).second->post(message);
+}
+
+
void LLEventPumps::flush()
{
// Flush every known LLEventPump instance. Leave it up to each instance to
@@ -497,6 +508,43 @@ bool LLEventStream::post(const LLSD& event)
}
/*****************************************************************************
+ * LLEventMailDrop
+ *****************************************************************************/
+bool LLEventMailDrop::post(const LLSD& event)
+{
+ bool posted = false;
+
+ if (!mSignal->empty())
+ posted = LLEventStream::post(event);
+
+ if (!posted)
+ { // if the event was not handled we will save it for later so that it can
+ // be posted to any future listeners when they attach.
+ mEventHistory.push_back(event);
+ }
+
+ return posted;
+}
+
+LLBoundListener LLEventMailDrop::listen_impl(const std::string& name,
+ const LLEventListener& listener,
+ const NameList& after,
+ const NameList& before)
+{
+ if (!mEventHistory.empty())
+ {
+ if (listener(mEventHistory.front()))
+ {
+ mEventHistory.pop_front();
+ }
+ }
+
+ return LLEventStream::listen_impl(name, listener, after, before);
+
+}
+
+
+/*****************************************************************************
* LLEventQueue
*****************************************************************************/
bool LLEventQueue::post(const LLSD& event)
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 0cbd1da32d..6175329a9d 100755..100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -217,6 +217,18 @@ public:
* an instance without conferring @em ownership.
*/
LLEventPump& obtain(const std::string& name);
+
+ /**
+ * Find the named LLEventPump instance. If it exists post the message to it.
+ * If the pump does not exist, do nothing.
+ *
+ * returns the result of the LLEventPump::post. If no pump exists returns false.
+ *
+ * This is syntactically similar to LLEventPumps::instance().post(name, message),
+ * however if the pump does not already exist it will not be created.
+ */
+ bool post(const std::string&, const LLSD&);
+
/**
* Flush all known LLEventPump instances
*/
@@ -496,7 +508,7 @@ public:
// at the boost::bind object itself before that happens.
return LLEventDetail::visit_and_connect(name,
listener,
- boost::bind(&LLEventPump::listen_impl,
+ boost::bind(&LLEventPump::listen_invoke,
this,
name,
_1,
@@ -541,13 +553,23 @@ private:
virtual void reset();
+
+
private:
- virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&,
- const NameList& after,
- const NameList& before);
+ LLBoundListener listen_invoke(const std::string& name, const LLEventListener& listener,
+ const NameList& after,
+ const NameList& before)
+ {
+ return this->listen_impl(name, listener, after, before);
+ }
+
std::string mName;
protected:
+ virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&,
+ const NameList& after,
+ const NameList& before);
+
/// implement the dispatching
boost::shared_ptr<LLStandardSignal> mSignal;
@@ -586,10 +608,39 @@ public:
};
/*****************************************************************************
+ * LLEventMailDrop
+ *****************************************************************************/
+/**
+ * LLEventMailDrop is a specialization of LLEventStream. Events are posted normally,
+ * however if no listeners return that they have handled the event it is placed in
+ * a queue. Subsequent attaching listeners will receive stored events from the queue
+ * until a listener indicates that the event has been handled. In order to receive
+ * multiple events from a mail drop the listener must disconnect and reconnect.
+ */
+class LL_COMMON_API LLEventMailDrop : public LLEventStream
+{
+public:
+ LLEventMailDrop(const std::string& name, bool tweak = false) : LLEventStream(name, tweak) {}
+ virtual ~LLEventMailDrop() {}
+
+ /// Post an event to all listeners
+ virtual bool post(const LLSD& event);
+
+protected:
+ virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&,
+ const NameList& after,
+ const NameList& before);
+
+private:
+ typedef std::list<LLSD> EventList;
+ EventList mEventHistory;
+};
+
+/*****************************************************************************
* LLEventQueue
*****************************************************************************/
/**
- * LLEventQueue isa LLEventPump whose post() method defers calling registered
+ * LLEventQueue is a LLEventPump whose post() method defers calling registered
* listeners until flush() is called.
*/
class LL_COMMON_API LLEventQueue: public LLEventPump
diff --git a/indra/llcommon/lleventtimer.cpp b/indra/llcommon/lleventtimer.cpp
index 0d96e03da4..0d96e03da4 100755..100644
--- a/indra/llcommon/lleventtimer.cpp
+++ b/indra/llcommon/lleventtimer.cpp
diff --git a/indra/llcommon/lleventtimer.h b/indra/llcommon/lleventtimer.h
index dc918121e1..dc918121e1 100755..100644
--- a/indra/llcommon/lleventtimer.h
+++ b/indra/llcommon/lleventtimer.h
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 3d28cd15b0..3d28cd15b0 100755..100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 2370253078..2370253078 100755..100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 295c97eac8..873a7bce25 100755..100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -421,551 +421,42 @@ LLFILE * LLFile::_Fiopen(const std::string& filename,
#endif /* LL_WINDOWS */
-/************** llstdio file buffer ********************************/
-
-
-#if !LL_WINDOWS
-llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c)
-{
- int_type __ret = traits_type::eof();
- const bool __testeof = traits_type::eq_int_type(__c, __ret);
- const bool __testout = _M_mode & ios_base::out;
- if (__testout && !_M_reading)
- {
- if (this->pbase() < this->pptr())
- {
- // If appropriate, append the overflow char.
- if (!__testeof)
- {
- *this->pptr() = traits_type::to_char_type(__c);
- this->pbump(1);
- }
-
- // Convert pending sequence to external representation,
- // and output.
- if (_convert_to_external(this->pbase(),
- this->pptr() - this->pbase()))
- {
- _M_set_buffer(0);
- __ret = traits_type::not_eof(__c);
- }
- }
- else if (_M_buf_size > 1)
- {
- // Overflow in 'uncommitted' mode: set _M_writing, set
- // the buffer to the initial 'write' mode, and put __c
- // into the buffer.
- _M_set_buffer(0);
- _M_writing = true;
- if (!__testeof)
- {
- *this->pptr() = traits_type::to_char_type(__c);
- this->pbump(1);
- }
- __ret = traits_type::not_eof(__c);
- }
- else
- {
- // Unbuffered.
- char_type __conv = traits_type::to_char_type(__c);
- if (__testeof || _convert_to_external(&__conv, 1))
- {
- _M_writing = true;
- __ret = traits_type::not_eof(__c);
- }
- }
- }
- return __ret;
-}
-
-bool llstdio_filebuf::_convert_to_external(char_type* __ibuf,
- std::streamsize __ilen)
-{
- // Sizes of external and pending output.
- streamsize __elen;
- streamsize __plen;
- if (__check_facet(_M_codecvt).always_noconv())
- {
- //__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
- __elen = fwrite(reinterpret_cast<void*>(__ibuf), 1,
- __ilen, _M_file.file());
- __plen = __ilen;
- }
- else
- {
- // Worst-case number of external bytes needed.
- // XXX Not done encoding() == -1.
- streamsize __blen = __ilen * _M_codecvt->max_length();
- char* __buf = static_cast<char*>(__builtin_alloca(__blen));
-
- char* __bend;
- const char_type* __iend;
- codecvt_base::result __r;
- __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
- __iend, __buf, __buf + __blen, __bend);
-
- if (__r == codecvt_base::ok || __r == codecvt_base::partial)
- __blen = __bend - __buf;
- else if (__r == codecvt_base::noconv)
- {
- // Same as the always_noconv case above.
- __buf = reinterpret_cast<char*>(__ibuf);
- __blen = __ilen;
- }
- else
- __throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
- "conversion error"));
-
- //__elen = _M_file.xsputn(__buf, __blen);
- __elen = fwrite(__buf, 1, __blen, _M_file.file());
- __plen = __blen;
-
- // Try once more for partial conversions.
- if (__r == codecvt_base::partial && __elen == __plen)
- {
- const char_type* __iresume = __iend;
- streamsize __rlen = this->pptr() - __iend;
- __r = _M_codecvt->out(_M_state_cur, __iresume,
- __iresume + __rlen, __iend, __buf,
- __buf + __blen, __bend);
- if (__r != codecvt_base::error)
- {
- __rlen = __bend - __buf;
- //__elen = _M_file.xsputn(__buf, __rlen);
- __elen = fwrite(__buf, 1, __rlen, _M_file.file());
- __plen = __rlen;
- }
- else
- {
- __throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
- "conversion error"));
- }
- }
- }
- return __elen == __plen;
-}
-
-llstdio_filebuf::int_type llstdio_filebuf::underflow()
-{
- int_type __ret = traits_type::eof();
- const bool __testin = _M_mode & ios_base::in;
- if (__testin)
- {
- if (_M_writing)
- {
- if (overflow() == traits_type::eof())
- return __ret;
- //_M_set_buffer(-1);
- //_M_writing = false;
- }
- // Check for pback madness, and if so switch back to the
- // normal buffers and jet outta here before expensive
- // fileops happen...
- _M_destroy_pback();
-
- if (this->gptr() < this->egptr())
- return traits_type::to_int_type(*this->gptr());
-
- // Get and convert input sequence.
- const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
-
- // Will be set to true if ::fread() returns 0 indicating EOF.
- bool __got_eof = false;
- // Number of internal characters produced.
- streamsize __ilen = 0;
- codecvt_base::result __r = codecvt_base::ok;
- if (__check_facet(_M_codecvt).always_noconv())
- {
- //__ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
- // __buflen);
- __ilen = fread(reinterpret_cast<void*>(this->eback()), 1,
- __buflen, _M_file.file());
- if (__ilen == 0)
- __got_eof = true;
- }
- else
- {
- // Worst-case number of external bytes.
- // XXX Not done encoding() == -1.
- const int __enc = _M_codecvt->encoding();
- streamsize __blen; // Minimum buffer size.
- streamsize __rlen; // Number of chars to read.
- if (__enc > 0)
- __blen = __rlen = __buflen * __enc;
- else
- {
- __blen = __buflen + _M_codecvt->max_length() - 1;
- __rlen = __buflen;
- }
- const streamsize __remainder = _M_ext_end - _M_ext_next;
- __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
-
- // An imbue in 'read' mode implies first converting the external
- // chars already present.
- if (_M_reading && this->egptr() == this->eback() && __remainder)
- __rlen = 0;
-
- // Allocate buffer if necessary and move unconverted
- // bytes to front.
- if (_M_ext_buf_size < __blen)
- {
- char* __buf = new char[__blen];
- if (__remainder)
- __builtin_memcpy(__buf, _M_ext_next, __remainder);
-
- delete [] _M_ext_buf;
- _M_ext_buf = __buf;
- _M_ext_buf_size = __blen;
- }
- else if (__remainder)
- __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
-
- _M_ext_next = _M_ext_buf;
- _M_ext_end = _M_ext_buf + __remainder;
- _M_state_last = _M_state_cur;
-
- do
- {
- if (__rlen > 0)
- {
- // Sanity check!
- // This may fail if the return value of
- // codecvt::max_length() is bogus.
- if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
- {
- __throw_ios_failure(__N("llstdio_filebuf::underflow "
- "codecvt::max_length() "
- "is not valid"));
- }
- //streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
- streamsize __elen = fread(_M_ext_end, 1,
- __rlen, _M_file.file());
- if (__elen == 0)
- __got_eof = true;
- else if (__elen == -1)
- break;
- //_M_ext_end += __elen;
- }
-
- char_type* __iend = this->eback();
- if (_M_ext_next < _M_ext_end)
- {
- __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
- _M_ext_end, _M_ext_next,
- this->eback(),
- this->eback() + __buflen, __iend);
- }
- if (__r == codecvt_base::noconv)
- {
- size_t __avail = _M_ext_end - _M_ext_buf;
- __ilen = std::min(__avail, __buflen);
- traits_type::copy(this->eback(),
- reinterpret_cast<char_type*>
- (_M_ext_buf), __ilen);
- _M_ext_next = _M_ext_buf + __ilen;
- }
- else
- __ilen = __iend - this->eback();
-
- // _M_codecvt->in may return error while __ilen > 0: this is
- // ok, and actually occurs in case of mixed encodings (e.g.,
- // XML files).
- if (__r == codecvt_base::error)
- break;
-
- __rlen = 1;
- } while (__ilen == 0 && !__got_eof);
- }
-
- if (__ilen > 0)
- {
- _M_set_buffer(__ilen);
- _M_reading = true;
- __ret = traits_type::to_int_type(*this->gptr());
- }
- else if (__got_eof)
- {
- // If the actual end of file is reached, set 'uncommitted'
- // mode, thus allowing an immediate write without an
- // intervening seek.
- _M_set_buffer(-1);
- _M_reading = false;
- // However, reaching it while looping on partial means that
- // the file has got an incomplete character.
- if (__r == codecvt_base::partial)
- __throw_ios_failure(__N("llstdio_filebuf::underflow "
- "incomplete character in file"));
- }
- else if (__r == codecvt_base::error)
- __throw_ios_failure(__N("llstdio_filebuf::underflow "
- "invalid byte sequence in file"));
- else
- __throw_ios_failure(__N("llstdio_filebuf::underflow "
- "error reading the file"));
- }
- return __ret;
-}
-
-std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n)
-{
- // Clear out pback buffer before going on to the real deal...
- streamsize __ret = 0;
- if (_M_pback_init)
- {
- if (__n > 0 && this->gptr() == this->eback())
- {
- *__s++ = *this->gptr();
- this->gbump(1);
- __ret = 1;
- --__n;
- }
- _M_destroy_pback();
- }
-
- // Optimization in the always_noconv() case, to be generalized in the
- // future: when __n > __buflen we read directly instead of using the
- // buffer repeatedly.
- const bool __testin = _M_mode & ios_base::in;
- const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
-
- if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
- && __testin && !_M_writing)
- {
- // First, copy the chars already present in the buffer.
- const streamsize __avail = this->egptr() - this->gptr();
- if (__avail != 0)
- {
- if (__avail == 1)
- *__s = *this->gptr();
- else
- traits_type::copy(__s, this->gptr(), __avail);
- __s += __avail;
- this->gbump(__avail);
- __ret += __avail;
- __n -= __avail;
- }
-
- // Need to loop in case of short reads (relatively common
- // with pipes).
- streamsize __len;
- for (;;)
- {
- //__len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n);
- __len = fread(reinterpret_cast<void*>(__s), 1,
- __n, _M_file.file());
- if (__len == -1)
- __throw_ios_failure(__N("llstdio_filebuf::xsgetn "
- "error reading the file"));
- if (__len == 0)
- break;
-
- __n -= __len;
- __ret += __len;
- if (__n == 0)
- break;
-
- __s += __len;
- }
-
- if (__n == 0)
- {
- _M_set_buffer(0);
- _M_reading = true;
- }
- else if (__len == 0)
- {
- // If end of file is reached, set 'uncommitted'
- // mode, thus allowing an immediate write without
- // an intervening seek.
- _M_set_buffer(-1);
- _M_reading = false;
- }
- }
- else
- __ret += __streambuf_type::xsgetn(__s, __n);
-
- return __ret;
-}
-
-std::streamsize llstdio_filebuf::xsputn(const char_type* __s, std::streamsize __n)
-{
- // Optimization in the always_noconv() case, to be generalized in the
- // future: when __n is sufficiently large we write directly instead of
- // using the buffer.
- streamsize __ret = 0;
- const bool __testout = _M_mode & ios_base::out;
- if (__check_facet(_M_codecvt).always_noconv()
- && __testout && !_M_reading)
- {
- // Measurement would reveal the best choice.
- const streamsize __chunk = 1ul << 10;
- streamsize __bufavail = this->epptr() - this->pptr();
-
- // Don't mistake 'uncommitted' mode buffered with unbuffered.
- if (!_M_writing && _M_buf_size > 1)
- __bufavail = _M_buf_size - 1;
-
- const streamsize __limit = std::min(__chunk, __bufavail);
- if (__n >= __limit)
- {
- const streamsize __buffill = this->pptr() - this->pbase();
- const char* __buf = reinterpret_cast<const char*>(this->pbase());
- //__ret = _M_file.xsputn_2(__buf, __buffill,
- // reinterpret_cast<const char*>(__s), __n);
- if (__buffill)
- {
- __ret = fwrite(__buf, 1, __buffill, _M_file.file());
- }
- if (__ret == __buffill)
- {
- __ret += fwrite(reinterpret_cast<const char*>(__s), 1,
- __n, _M_file.file());
- }
- if (__ret == __buffill + __n)
- {
- _M_set_buffer(0);
- _M_writing = true;
- }
- if (__ret > __buffill)
- __ret -= __buffill;
- else
- __ret = 0;
- }
- else
- __ret = __streambuf_type::xsputn(__s, __n);
- }
- else
- __ret = __streambuf_type::xsputn(__s, __n);
- return __ret;
-}
-
-int llstdio_filebuf::sync()
-{
- return (_M_file.sync() == 0 ? 0 : -1);
-}
-#endif
#if LL_WINDOWS
/************** input file stream ********************************/
-llifstream::llifstream() :
- _M_filebuf(),
- std::istream(&_M_filebuf)
-{
-}
+llifstream::llifstream() {}
// explicit
-llifstream::llifstream(const std::string& _Filename,
- ios_base::openmode _Mode) :
- _M_filebuf(),
- std::istream(&_M_filebuf)
+llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode):
+ std::ifstream(utf8str_to_utf16str( _Filename ).c_str(),
+ _Mode | ios_base::in)
{
- llutf16string wideName = utf8str_to_utf16str( _Filename );
- if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
- {
- _Myios::setstate(ios_base::failbit);
- }
}
-// explicit
-llifstream::llifstream(const char* _Filename,
- ios_base::openmode _Mode) :
- _M_filebuf(),
- std::istream(&_M_filebuf)
+void llifstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
- llutf16string wideName = utf8str_to_utf16str( _Filename );
- if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
- {
- _Myios::setstate(ios_base::failbit);
- }
-}
-
-bool llifstream::is_open() const
-{ // test if C stream has been opened
- return _M_filebuf.is_open();
-}
-
-void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
-{ // open a C stream with specified mode
- llutf16string wideName = utf8str_to_utf16str( _Filename );
- if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0)
- {
- _Myios::setstate(ios_base::failbit);
- }
- else
- {
- _Myios::clear();
- }
-}
-
-void llifstream::close()
-{ // close the C stream
- if (_M_filebuf.close() == 0)
- {
- _Myios::setstate(ios_base::failbit);
- }
+ std::ifstream::open(utf8str_to_utf16str(_Filename).c_str(),
+ _Mode | ios_base::in);
}
/************** output file stream ********************************/
-llofstream::llofstream() :
- _M_filebuf(),
- std::ostream(&_M_filebuf)
-{
-}
+llofstream::llofstream() {}
// explicit
-llofstream::llofstream(const std::string& _Filename,
- ios_base::openmode _Mode) :
- _M_filebuf(),
- std::ostream(&_M_filebuf)
+llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode):
+ std::ofstream(utf8str_to_utf16str( _Filename ).c_str(),
+ _Mode | ios_base::out)
{
- llutf16string wideName = utf8str_to_utf16str( _Filename );
- if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
- {
- _Myios::setstate(ios_base::failbit);
- }
}
-// explicit
-llofstream::llofstream(const char* _Filename,
- ios_base::openmode _Mode) :
- _M_filebuf(),
- std::ostream(&_M_filebuf)
+void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
- llutf16string wideName = utf8str_to_utf16str( _Filename );
- if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
- {
- _Myios::setstate(ios_base::failbit);
- }
-}
-
-bool llofstream::is_open() const
-{ // test if C stream has been opened
- return _M_filebuf.is_open();
-}
-
-void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
-{ // open a C stream with specified mode
- llutf16string wideName = utf8str_to_utf16str( _Filename );
- if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
- {
- _Myios::setstate(ios_base::failbit);
- }
- else
- {
- _Myios::clear();
- }
-}
-
-void llofstream::close()
-{ // close the C stream
- if (_M_filebuf.close() == 0)
- {
- _Myios::setstate(ios_base::failbit);
- }
+ std::ofstream::open(utf8str_to_utf16str( _Filename ).c_str(),
+ _Mode | ios_base::out);
}
/************** helper functions ********************************/
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index 347c9867aa..3e25228aeb 100755..100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -45,7 +45,6 @@ typedef FILE LLFILE;
typedef struct _stat llstat;
#else
typedef struct stat llstat;
-#include <ext/stdio_filebuf.h>
#include <bits/postypes.h>
#endif
@@ -86,123 +85,16 @@ public:
static const char * tmpdir();
};
-/**
- * @brief Provides a layer of compatibility for C/POSIX.
- *
- * This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and
- * VC's basic_filebuf implementation.
- * This file buffer provides extensions for working with standard C FILE*'s
- * and POSIX file descriptors for platforms that support this.
-*/
-namespace
-{
-#if LL_WINDOWS
-typedef std::filebuf _Myfb;
-#else
-typedef __gnu_cxx::stdio_filebuf< char > _Myfb;
-typedef std::__c_file _Filet;
-#endif /* LL_WINDOWS */
-}
-
-class LL_COMMON_API llstdio_filebuf : public _Myfb
-{
-public:
- /**
- * deferred initialization / destruction
- */
- llstdio_filebuf() : _Myfb() {}
- virtual ~llstdio_filebuf() {}
-
- /**
- * @param f An open @c FILE*.
- * @param mode Same meaning as in a standard filebuf.
- * @param size Optimal or preferred size of internal buffer, in chars.
- * Defaults to system's @c BUFSIZ.
- *
- * This constructor associates a file stream buffer with an open
- * C @c FILE*. The @c FILE* will not be automatically closed when the
- * stdio_filebuf is closed/destroyed.
- */
- llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode,
- //size_t __size = static_cast<size_t>(BUFSIZ)) :
- size_t __size = static_cast<size_t>(1)) :
-#if LL_WINDOWS
- _Myfb(__f) {}
-#else
- _Myfb(__f, __mode, __size) {}
-#endif
-
- /**
- * @brief Opens an external file.
- * @param s The name of the file.
- * @param mode The open mode flags.
- * @return @c this on success, NULL on failure
- *
- * If a file is already open, this function immediately fails.
- * Otherwise it tries to open the file named @a s using the flags
- * given in @a mode.
- */
- //llstdio_filebuf* open(const char *_Filename,
- // std::ios_base::openmode _Mode);
-
- /**
- * @param fd An open file descriptor.
- * @param mode Same meaning as in a standard filebuf.
- * @param size Optimal or preferred size of internal buffer, in chars.
- *
- * This constructor associates a file stream buffer with an open
- * POSIX file descriptor. The file descriptor will be automatically
- * closed when the stdio_filebuf is closed/destroyed.
- */
-#if !LL_WINDOWS
- llstdio_filebuf(int __fd, std::ios_base::openmode __mode,
- //size_t __size = static_cast<size_t>(BUFSIZ)) :
- size_t __size = static_cast<size_t>(1)) :
- _Myfb(__fd, __mode, __size) {}
-#endif
-
-// *TODO: Seek the underlying c stream for better cross-platform compatibility?
-#if !LL_WINDOWS
-protected:
- /** underflow() and uflow() functions are called to get the next
- * character from the real input source when the buffer is empty.
- * Buffered input uses underflow()
- */
- /*virtual*/ int_type underflow();
-
- /* Convert internal byte sequence to external, char-based
- * sequence via codecvt.
- */
- bool _convert_to_external(char_type*, std::streamsize);
-
- /** The overflow() function is called to transfer characters to the
- * real output destination when the buffer is full. A call to
- * overflow(c) outputs the contents of the buffer plus the
- * character c.
- * Consume some sequence of the characters in the pending sequence.
- */
- /*virtual*/ int_type overflow(int_type __c = traits_type::eof());
-
- /** sync() flushes the underlying @c FILE* stream.
- */
- /*virtual*/ int sync();
-
- std::streamsize xsgetn(char_type*, std::streamsize);
- std::streamsize xsputn(const char_type*, std::streamsize);
-#endif
-};
-
#if LL_WINDOWS
/**
* @brief Controlling input for files.
*
* This class supports reading from named files, using the inherited
- * functions from std::basic_istream. To control the associated
- * sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
- * which allows construction using a pre-exisintg file stream buffer.
- * We refer to this std::basic_filebuf (or derivative) as @c sb.
+ * functions from std::ifstream. The only added value is that our constructor
+ * Does The Right Thing when passed a non-ASCII pathname. Sadly, that isn't
+ * true of Microsoft's std::ifstream.
*/
-class LL_COMMON_API llifstream : public std::istream
+class LL_COMMON_API llifstream : public std::ifstream
{
// input stream associated with a C stream
public:
@@ -225,32 +117,6 @@ class LL_COMMON_API llifstream : public std::istream
*/
explicit llifstream(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::in);
- explicit llifstream(const char* _Filename,
- ios_base::openmode _Mode = ios_base::in);
-
- /**
- * @brief The destructor does nothing.
- *
- * The file is closed by the filebuf object, not the formatting
- * stream.
- */
- virtual ~llifstream() {}
-
- // Members:
- /**
- * @brief Accessing the underlying buffer.
- * @return The current basic_filebuf buffer.
- *
- * This hides both signatures of std::basic_ios::rdbuf().
- */
- llstdio_filebuf* rdbuf() const
- { return const_cast<llstdio_filebuf*>(&_M_filebuf); }
-
- /**
- * @brief Wrapper to test for an open file.
- * @return @c rdbuf()->is_open()
- */
- bool is_open() const;
/**
* @brief Opens an external file.
@@ -261,34 +127,19 @@ class LL_COMMON_API llifstream : public std::istream
* fails, @c failbit is set in the stream's error state.
*/
void open(const std::string& _Filename,
- ios_base::openmode _Mode = ios_base::in)
- { open(_Filename.c_str(), _Mode); }
- void open(const char* _Filename,
ios_base::openmode _Mode = ios_base::in);
-
- /**
- * @brief Close the file.
- *
- * Calls @c llstdio_filebuf::close(). If that function
- * fails, @c failbit is set in the stream's error state.
- */
- void close();
-
- private:
- llstdio_filebuf _M_filebuf;
};
/**
* @brief Controlling output for files.
*
- * This class supports writing to named files, using the inherited
- * functions from std::basic_ostream. To control the associated
- * sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
- * which allows construction using a pre-exisintg file stream buffer.
- * We refer to this std::basic_filebuf (or derivative) as @c sb.
+ * This class supports writing to named files, using the inherited functions
+ * from std::ofstream. The only added value is that our constructor Does The
+ * Right Thing when passed a non-ASCII pathname. Sadly, that isn't true of
+ * Microsoft's std::ofstream.
*/
-class LL_COMMON_API llofstream : public std::ostream
+class LL_COMMON_API llofstream : public std::ofstream
{
public:
// Constructors:
@@ -306,62 +157,20 @@ class LL_COMMON_API llofstream : public std::ostream
* @param Filename String specifying the filename.
* @param Mode Open file in specified mode (see std::ios_base).
*
- * @c ios_base::out|ios_base::trunc is automatically included in
- * @a mode.
+ * @c ios_base::out is automatically included in @a mode.
*/
explicit llofstream(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
- explicit llofstream(const char* _Filename,
- ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
-
- /**
- * @brief The destructor does nothing.
- *
- * The file is closed by the filebuf object, not the formatting
- * stream.
- */
- virtual ~llofstream() {}
-
- // Members:
- /**
- * @brief Accessing the underlying buffer.
- * @return The current basic_filebuf buffer.
- *
- * This hides both signatures of std::basic_ios::rdbuf().
- */
- llstdio_filebuf* rdbuf() const
- { return const_cast<llstdio_filebuf*>(&_M_filebuf); }
-
- /**
- * @brief Wrapper to test for an open file.
- * @return @c rdbuf()->is_open()
- */
- bool is_open() const;
/**
* @brief Opens an external file.
* @param Filename The name of the file.
* @param Node The open mode flags.
*
- * Calls @c llstdio_filebuf::open(s,mode|out). If that function
- * fails, @c failbit is set in the stream's error state.
+ * @c ios_base::out is automatically included in @a mode.
*/
void open(const std::string& _Filename,
- ios_base::openmode _Mode = ios_base::out|ios_base::trunc)
- { open(_Filename.c_str(), _Mode); }
- void open(const char* _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
-
- /**
- * @brief Close the file.
- *
- * Calls @c llstdio_filebuf::close(). If that function
- * fails, @c failbit is set in the stream's error state.
- */
- void close();
-
- private:
- llstdio_filebuf _M_filebuf;
};
diff --git a/indra/llcommon/llfindlocale.cpp b/indra/llcommon/llfindlocale.cpp
index f019bd0c64..f019bd0c64 100755..100644
--- a/indra/llcommon/llfindlocale.cpp
+++ b/indra/llcommon/llfindlocale.cpp
diff --git a/indra/llcommon/llfindlocale.h b/indra/llcommon/llfindlocale.h
index 6770db5774..6770db5774 100755..100644
--- a/indra/llcommon/llfindlocale.h
+++ b/indra/llcommon/llfindlocale.h
diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp
index d394f179fb..d394f179fb 100755..100644
--- a/indra/llcommon/llfixedbuffer.cpp
+++ b/indra/llcommon/llfixedbuffer.cpp
diff --git a/indra/llcommon/llfixedbuffer.h b/indra/llcommon/llfixedbuffer.h
index 554cf48a4c..554cf48a4c 100755..100644
--- a/indra/llcommon/llfixedbuffer.h
+++ b/indra/llcommon/llfixedbuffer.h
diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp
index 3b2b3038ea..3b2b3038ea 100755..100644
--- a/indra/llcommon/llformat.cpp
+++ b/indra/llcommon/llformat.cpp
diff --git a/indra/llcommon/llformat.h b/indra/llcommon/llformat.h
index fb8e7cd045..fb8e7cd045 100755..100644
--- a/indra/llcommon/llformat.h
+++ b/indra/llcommon/llformat.h
diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp
index 1e9920746b..1e9920746b 100755..100644
--- a/indra/llcommon/llframetimer.cpp
+++ b/indra/llcommon/llframetimer.cpp
diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h
index 81bd5da8a3..81bd5da8a3 100755..100644
--- a/indra/llcommon/llframetimer.h
+++ b/indra/llcommon/llframetimer.h
diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h
index 401e4d759a..401e4d759a 100755..100644
--- a/indra/llcommon/llhandle.h
+++ b/indra/llcommon/llhandle.h
diff --git a/indra/llcommon/llhash.h b/indra/llcommon/llhash.h
index 4b58e81565..4b58e81565 100755..100644
--- a/indra/llcommon/llhash.h
+++ b/indra/llcommon/llhash.h
diff --git a/indra/llcommon/llheartbeat.cpp b/indra/llcommon/llheartbeat.cpp
index 19b7452748..19b7452748 100755..100644
--- a/indra/llcommon/llheartbeat.cpp
+++ b/indra/llcommon/llheartbeat.cpp
diff --git a/indra/llcommon/llheartbeat.h b/indra/llcommon/llheartbeat.h
index 4a75fcc103..4a75fcc103 100755..100644
--- a/indra/llcommon/llheartbeat.h
+++ b/indra/llcommon/llheartbeat.h
diff --git a/indra/llcommon/llindexedvector.h b/indra/llcommon/llindexedvector.h
index 68c3821802..68c3821802 100755..100644
--- a/indra/llcommon/llindexedvector.h
+++ b/indra/llcommon/llindexedvector.h
diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index aa2f4eb289..aa2f4eb289 100755..100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index c65b05f610..c65b05f610 100755..100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 11fc53f8c8..11fc53f8c8 100755..100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 9783644e66..9783644e66 100755..100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
diff --git a/indra/llcommon/llkeythrottle.h b/indra/llcommon/llkeythrottle.h
index 1f576cc19e..1f576cc19e 100755..100644
--- a/indra/llcommon/llkeythrottle.h
+++ b/indra/llcommon/llkeythrottle.h
diff --git a/indra/llcommon/llkeyusetracker.h b/indra/llcommon/llkeyusetracker.h
index 1fb222dd40..1fb222dd40 100755..100644
--- a/indra/llcommon/llkeyusetracker.h
+++ b/indra/llcommon/llkeyusetracker.h
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index 84d2a12f65..84d2a12f65 100755..100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h
index e33f25e530..e33f25e530 100755..100644
--- a/indra/llcommon/llleap.h
+++ b/indra/llcommon/llleap.h
diff --git a/indra/llcommon/llleaplistener.cpp b/indra/llcommon/llleaplistener.cpp
index fa5730f112..fa5730f112 100755..100644
--- a/indra/llcommon/llleaplistener.cpp
+++ b/indra/llcommon/llleaplistener.cpp
diff --git a/indra/llcommon/llleaplistener.h b/indra/llcommon/llleaplistener.h
index 2193d81b9e..2193d81b9e 100755..100644
--- a/indra/llcommon/llleaplistener.h
+++ b/indra/llcommon/llleaplistener.h
diff --git a/indra/llcommon/lllistenerwrapper.h b/indra/llcommon/lllistenerwrapper.h
index 09d074abca..09d074abca 100755..100644
--- a/indra/llcommon/lllistenerwrapper.h
+++ b/indra/llcommon/lllistenerwrapper.h
diff --git a/indra/llcommon/llliveappconfig.cpp b/indra/llcommon/llliveappconfig.cpp
index a9b1cdf4f6..a9b1cdf4f6 100755..100644
--- a/indra/llcommon/llliveappconfig.cpp
+++ b/indra/llcommon/llliveappconfig.cpp
diff --git a/indra/llcommon/llliveappconfig.h b/indra/llcommon/llliveappconfig.h
index 4fd7c26a07..4fd7c26a07 100755..100644
--- a/indra/llcommon/llliveappconfig.h
+++ b/indra/llcommon/llliveappconfig.h
diff --git a/indra/llcommon/lllivefile.cpp b/indra/llcommon/lllivefile.cpp
index ea485c2d86..ea485c2d86 100755..100644
--- a/indra/llcommon/lllivefile.cpp
+++ b/indra/llcommon/lllivefile.cpp
diff --git a/indra/llcommon/lllivefile.h b/indra/llcommon/lllivefile.h
index 320aa4bc3e..320aa4bc3e 100755..100644
--- a/indra/llcommon/lllivefile.h
+++ b/indra/llcommon/lllivefile.h
diff --git a/indra/llcommon/llmake.h b/indra/llcommon/llmake.h
new file mode 100644
index 0000000000..9a662a0640
--- /dev/null
+++ b/indra/llcommon/llmake.h
@@ -0,0 +1,63 @@
+/**
+ * @file llmake.h
+ * @author Nat Goodspeed
+ * @date 2015-12-18
+ * @brief Generic llmake<Template>(arg) function to instantiate
+ * Template<decltype(arg)>(arg).
+ *
+ * Many of our class templates have an accompanying helper function to
+ * make an instance with arguments of arbitrary type. llmake()
+ * eliminates the need to declare a new helper function for every such
+ * class template.
+ *
+ * also relevant:
+ *
+ * Template parameter deduction for constructors
+ * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0091r0.html
+ *
+ * https://github.com/viboes/std-make
+ *
+ * but obviously we're not there yet.
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Copyright (c) 2015, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLMAKE_H)
+#define LL_LLMAKE_H
+
+/*==========================================================================*|
+// When we allow ourselves to compile with C++11 features enabled, this form
+// should generically handle an arbitrary number of arguments.
+
+template <template<typename...> class CLASS_TEMPLATE, typename... ARGS>
+CLASS_TEMPLATE<ARGS...> llmake(ARGS && ... args)
+{
+ return CLASS_TEMPLATE<ARGS...>(std::forward<ARGS>(args)...);
+}
+|*==========================================================================*/
+
+// As of 2015-12-18, this is what we'll use instead. Add explicit overloads
+// for different numbers of template parameters as use cases arise.
+
+/**
+ * Usage: llmake<SomeTemplate>(arg)
+ *
+ * Deduces the type T of 'arg' and returns an instance of SomeTemplate<T>
+ * initialized with 'arg'. Assumes a constructor accepting T (by value,
+ * reference or whatever).
+ */
+template <template<typename> class CLASS_TEMPLATE, typename ARG1>
+CLASS_TEMPLATE<ARG1> llmake(const ARG1& arg1)
+{
+ return CLASS_TEMPLATE<ARG1>(arg1);
+}
+
+template <template<typename, typename> class CLASS_TEMPLATE, typename ARG1, typename ARG2>
+CLASS_TEMPLATE<ARG1, ARG2> llmake(const ARG1& arg1, const ARG2& arg2)
+{
+ return CLASS_TEMPLATE<ARG1, ARG2>(arg1, arg2);
+}
+
+#endif /* ! defined(LL_LLMAKE_H) */
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp
index f942a976b7..f942a976b7 100755..100644
--- a/indra/llcommon/llmd5.cpp
+++ b/indra/llcommon/llmd5.cpp
diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h
index 1526e6ac3c..1526e6ac3c 100755..100644
--- a/indra/llcommon/llmd5.h
+++ b/indra/llcommon/llmd5.h
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 3a8eabac09..3a8eabac09 100755..100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 0fb257aab1..0fb257aab1 100755..100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
diff --git a/indra/llcommon/llmemorystream.cpp b/indra/llcommon/llmemorystream.cpp
index 707ac8fd0f..707ac8fd0f 100755..100644
--- a/indra/llcommon/llmemorystream.cpp
+++ b/indra/llcommon/llmemorystream.cpp
diff --git a/indra/llcommon/llmemorystream.h b/indra/llcommon/llmemorystream.h
index e28f012192..e28f012192 100755..100644
--- a/indra/llcommon/llmemorystream.h
+++ b/indra/llcommon/llmemorystream.h
diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp
index 1fc821d9a9..1fc821d9a9 100755..100644
--- a/indra/llcommon/llmetricperformancetester.cpp
+++ b/indra/llcommon/llmetricperformancetester.cpp
diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h
index 1a18cdf36f..1a18cdf36f 100755..100644
--- a/indra/llcommon/llmetricperformancetester.h
+++ b/indra/llcommon/llmetricperformancetester.h
diff --git a/indra/llcommon/llmetrics.cpp b/indra/llcommon/llmetrics.cpp
index d40afe5160..d40afe5160 100755..100644
--- a/indra/llcommon/llmetrics.cpp
+++ b/indra/llcommon/llmetrics.cpp
diff --git a/indra/llcommon/llmetrics.h b/indra/llcommon/llmetrics.h
index 85a6986049..85a6986049 100755..100644
--- a/indra/llcommon/llmetrics.h
+++ b/indra/llcommon/llmetrics.h
diff --git a/indra/llcommon/llmortician.cpp b/indra/llcommon/llmortician.cpp
index 287f096eae..287f096eae 100755..100644
--- a/indra/llcommon/llmortician.cpp
+++ b/indra/llcommon/llmortician.cpp
diff --git a/indra/llcommon/llmortician.h b/indra/llcommon/llmortician.h
index 9517e2db5e..9517e2db5e 100755..100644
--- a/indra/llcommon/llmortician.h
+++ b/indra/llcommon/llmortician.h
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index 9a6453ea48..9a6453ea48 100755..100644
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 2c4bcc91f6..2c4bcc91f6 100755..100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
diff --git a/indra/llcommon/llpriqueuemap.h b/indra/llcommon/llpriqueuemap.h
index d8d3edd48a..d8d3edd48a 100755..100644
--- a/indra/llcommon/llpriqueuemap.h
+++ b/indra/llcommon/llpriqueuemap.h
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
index e0aa30cc1a..44f56daf2d 100755..100644
--- a/indra/llcommon/llprocess.cpp
+++ b/indra/llcommon/llprocess.cpp
@@ -710,7 +710,7 @@ LLProcess::LLProcess(const LLSDOrParams& params):
// Tie the lifespan of this child process to the lifespan of our APR
// pool: on destruction of the pool, forcibly kill the process. Tell
- // APR to try SIGTERM and wait 3 seconds. If that didn't work, use
+ // APR to try SIGTERM and suspend 3 seconds. If that didn't work, use
// SIGKILL.
apr_pool_note_subprocess(gAPRPoolp, &mProcess, APR_KILL_AFTER_TIMEOUT);
|*==========================================================================*/
@@ -989,9 +989,9 @@ void LLProcess::handle_status(int reason, int status)
// wi->rv = apr_proc_wait(wi->child, &wi->rc, &wi->why, APR_NOWAIT);
// It's just wrong to call apr_proc_wait() here. The only way APR knows to
// call us with APR_OC_REASON_DEATH is that it's already reaped this child
- // process, so calling wait() will only produce "huh?" from the OS. We
+ // process, so calling suspend() will only produce "huh?" from the OS. We
// must rely on the status param passed in, which unfortunately comes
- // straight from the OS wait() call, which means we have to decode it by
+ // straight from the OS suspend() call, which means we have to decode it by
// hand.
mStatus = interpret_status(status);
LL_INFOS("LLProcess") << getStatusString() << LL_ENDL;
diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h
index 43ccadc412..43ccadc412 100755..100644
--- a/indra/llcommon/llprocess.h
+++ b/indra/llcommon/llprocess.h
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index e3e1d0c391..e3e1d0c391 100755..100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index 90e5bc59ee..90e5bc59ee 100755..100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
diff --git a/indra/llcommon/llptrto.cpp b/indra/llcommon/llptrto.cpp
index b270291bd6..b270291bd6 100755..100644
--- a/indra/llcommon/llptrto.cpp
+++ b/indra/llcommon/llptrto.cpp
diff --git a/indra/llcommon/llptrto.h b/indra/llcommon/llptrto.h
index 4082e30de6..4082e30de6 100755..100644
--- a/indra/llcommon/llptrto.h
+++ b/indra/llcommon/llptrto.h
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 8cef4293cd..8cef4293cd 100755..100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h
index d3704b0fe2..d3704b0fe2 100755..100644
--- a/indra/llcommon/llqueuedthread.h
+++ b/indra/llcommon/llqueuedthread.h
diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp
index cb28a8f5c3..cb28a8f5c3 100755..100644
--- a/indra/llcommon/llrand.cpp
+++ b/indra/llcommon/llrand.cpp
diff --git a/indra/llcommon/llrand.h b/indra/llcommon/llrand.h
index ad317d5bf7..ad317d5bf7 100755..100644
--- a/indra/llcommon/llrand.h
+++ b/indra/llcommon/llrand.h
diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp
index a638df2c7c..a638df2c7c 100755..100644
--- a/indra/llcommon/llrefcount.cpp
+++ b/indra/llcommon/llrefcount.cpp
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 3836a9b5fb..1107973569 100755..100644
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -144,14 +144,9 @@ private:
};
/**
- * intrusive pointer support
- * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
- */
-/**
* intrusive pointer support for LLThreadSafeRefCount
* this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
*/
-
inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
{
p->ref();
@@ -162,6 +157,10 @@ inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
p->unref();
}
+/**
+ * intrusive pointer support
+ * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
+ */
inline void intrusive_ptr_add_ref(LLRefCount* p)
{
p->ref();
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
index 29950c108d..29950c108d 100755..100644
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
diff --git a/indra/llcommon/llrun.cpp b/indra/llcommon/llrun.cpp
index f5d3f302fa..f5d3f302fa 100755..100644
--- a/indra/llcommon/llrun.cpp
+++ b/indra/llcommon/llrun.cpp
diff --git a/indra/llcommon/llrun.h b/indra/llcommon/llrun.h
index a117405366..a117405366 100755..100644
--- a/indra/llcommon/llrun.h
+++ b/indra/llcommon/llrun.h
diff --git a/indra/llcommon/llsafehandle.h b/indra/llcommon/llsafehandle.h
index 4226bf04f0..4226bf04f0 100755..100644
--- a/indra/llcommon/llsafehandle.h
+++ b/indra/llcommon/llsafehandle.h
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 57aa7d9c07..57aa7d9c07 100755..100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 7b9b1285f5..7b9b1285f5 100755..100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp
new file mode 100644
index 0000000000..8caaaee534
--- /dev/null
+++ b/indra/llcommon/llsdjson.cpp
@@ -0,0 +1,126 @@
+/**
+ * @file llsdjson.cpp
+ * @brief LLSD flexible data system
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// Must turn on conditional declarations in header file so definitions end up
+// with proper linkage.
+#define LLSD_DEBUG_INFO
+#include "linden_common.h"
+
+#include "llsdjson.h"
+
+#include "llerror.h"
+#include "../llmath/llmath.h"
+
+//=========================================================================
+LLSD LlsdFromJson(const Json::Value &val)
+{
+ LLSD result;
+
+ switch (val.type())
+ {
+ default:
+ case Json::nullValue:
+ break;
+ case Json::intValue:
+ result = LLSD(static_cast<LLSD::Integer>(val.asInt()));
+ break;
+ case Json::uintValue:
+ result = LLSD(static_cast<LLSD::Integer>(val.asUInt()));
+ break;
+ case Json::realValue:
+ result = LLSD(static_cast<LLSD::Real>(val.asDouble()));
+ break;
+ case Json::stringValue:
+ result = LLSD(static_cast<LLSD::String>(val.asString()));
+ break;
+ case Json::booleanValue:
+ result = LLSD(static_cast<LLSD::Boolean>(val.asBool()));
+ break;
+ case Json::arrayValue:
+ result = LLSD::emptyArray();
+ for (Json::ValueConstIterator it = val.begin(); it != val.end(); ++it)
+ {
+ result.append(LlsdFromJson((*it)));
+ }
+ break;
+ case Json::objectValue:
+ result = LLSD::emptyMap();
+ for (Json::ValueConstIterator it = val.begin(); it != val.end(); ++it)
+ {
+ result[it.memberName()] = LlsdFromJson((*it));
+ }
+ break;
+ }
+ return result;
+}
+
+//=========================================================================
+Json::Value LlsdToJson(const LLSD &val)
+{
+ Json::Value result;
+
+ switch (val.type())
+ {
+ case LLSD::TypeUndefined:
+ result = Json::Value::null;
+ break;
+ case LLSD::TypeBoolean:
+ result = Json::Value(static_cast<bool>(val.asBoolean()));
+ break;
+ case LLSD::TypeInteger:
+ result = Json::Value(static_cast<int>(val.asInteger()));
+ break;
+ case LLSD::TypeReal:
+ result = Json::Value(static_cast<double>(val.asReal()));
+ break;
+ case LLSD::TypeURI:
+ case LLSD::TypeDate:
+ case LLSD::TypeUUID:
+ case LLSD::TypeString:
+ result = Json::Value(val.asString());
+ break;
+ case LLSD::TypeMap:
+ result = Json::Value(Json::objectValue);
+ for (LLSD::map_const_iterator it = val.beginMap(); it != val.endMap(); ++it)
+ {
+ result[it->first] = LlsdToJson(it->second);
+ }
+ break;
+ case LLSD::TypeArray:
+ result = Json::Value(Json::arrayValue);
+ for (LLSD::array_const_iterator it = val.beginArray(); it != val.endArray(); ++it)
+ {
+ result.append(LlsdToJson(*it));
+ }
+ break;
+ case LLSD::TypeBinary:
+ default:
+ LL_ERRS("LlsdToJson") << "Unsupported conversion to JSON from LLSD type (" << val.type() << ")." << LL_ENDL;
+ break;
+ }
+
+ return result;
+}
diff --git a/indra/llcommon/llsdjson.h b/indra/llcommon/llsdjson.h
new file mode 100644
index 0000000000..2be7112404
--- /dev/null
+++ b/indra/llcommon/llsdjson.h
@@ -0,0 +1,77 @@
+/**
+ * @file llsdjson.cpp
+ * @brief LLSD flexible data system
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSDJSON_H
+#define LL_LLSDJSON_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "stdtypes.h"
+
+#include "llsd.h"
+#include "value.h"
+
+/// Convert a parsed JSON structure into LLSD maintaining member names and
+/// array indexes.
+/// JSON/JavaScript types are converted as follows:
+///
+/// JSON Type | LLSD Type
+/// --------------+--------------
+/// null | undefined
+/// integer | LLSD::Integer
+/// unsigned | LLSD::Integer
+/// real/numeric | LLSD::Real
+/// string | LLSD::String
+/// boolean | LLSD::Boolean
+/// array | LLSD::Array
+/// object | LLSD::Map
+///
+/// For maps and arrays child entries will be converted and added to the structure.
+/// Order is preserved for an array but not for objects.
+LLSD LlsdFromJson(const Json::Value &val);
+
+/// Convert an LLSD object into Parsed JSON object maintaining member names and
+/// array indexs.
+///
+/// Types are converted as follows:
+/// LLSD Type | JSON Type
+/// --------------+----------------
+/// TypeUndefined | null
+/// TypeBoolean | boolean
+/// TypeInteger | integer
+/// TypeReal | real/numeric
+/// TypeString | string
+/// TypeURI | string
+/// TypeDate | string
+/// TypeUUID | string
+/// TypeMap | object
+/// TypeArray | array
+/// TypeBinary | unsupported
+Json::Value LlsdToJson(const LLSD &val);
+
+#endif // LL_LLSDJSON_H
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index 2e7b46f885..2e7b46f885 100755..100644
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h
index 09f1bdf1e3..09f1bdf1e3 100755..100644
--- a/indra/llcommon/llsdparam.h
+++ b/indra/llcommon/llsdparam.h
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index d49ff0feb5..d49ff0feb5 100755..100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 23a0c8cfb1..23a0c8cfb1 100755..100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 8d72a1c329..8d72a1c329 100755..100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
diff --git a/indra/llcommon/llsdserialize_xml.h b/indra/llcommon/llsdserialize_xml.h
index dcc5f3d3c7..dcc5f3d3c7 100755..100644
--- a/indra/llcommon/llsdserialize_xml.h
+++ b/indra/llcommon/llsdserialize_xml.h
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index 6ad4a97149..6ad4a97149 100755..100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h
index 99cb79aa54..99cb79aa54 100755..100644
--- a/indra/llcommon/llsdutil.h
+++ b/indra/llcommon/llsdutil.h
diff --git a/indra/llcommon/llsimplehash.h b/indra/llcommon/llsimplehash.h
index 727b4568d8..727b4568d8 100755..100644
--- a/indra/llcommon/llsimplehash.h
+++ b/indra/llcommon/llsimplehash.h
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index 9b49e52377..9b49e52377 100755..100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 6e6291a165..6e6291a165 100755..100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
diff --git a/indra/llcommon/llsmoothstep.h b/indra/llcommon/llsmoothstep.h
index 1f97a3ec89..1f97a3ec89 100755..100644
--- a/indra/llcommon/llsmoothstep.h
+++ b/indra/llcommon/llsmoothstep.h
diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp
index bbf0e1e141..bbf0e1e141 100755..100644
--- a/indra/llcommon/llstacktrace.cpp
+++ b/indra/llcommon/llstacktrace.cpp
diff --git a/indra/llcommon/llstacktrace.h b/indra/llcommon/llstacktrace.h
index 335765386a..335765386a 100755..100644
--- a/indra/llcommon/llstacktrace.h
+++ b/indra/llcommon/llstacktrace.h
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 0435cb8a08..0435cb8a08 100755..100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
diff --git a/indra/llcommon/llstreamqueue.cpp b/indra/llcommon/llstreamqueue.cpp
index 1116a2b6a2..1116a2b6a2 100755..100644
--- a/indra/llcommon/llstreamqueue.cpp
+++ b/indra/llcommon/llstreamqueue.cpp
diff --git a/indra/llcommon/llstreamqueue.h b/indra/llcommon/llstreamqueue.h
index 0726bad175..0726bad175 100755..100644
--- a/indra/llcommon/llstreamqueue.h
+++ b/indra/llcommon/llstreamqueue.h
diff --git a/indra/llcommon/llstreamtools.cpp b/indra/llcommon/llstreamtools.cpp
index d7a6f47932..d7a6f47932 100755..100644
--- a/indra/llcommon/llstreamtools.cpp
+++ b/indra/llcommon/llstreamtools.cpp
diff --git a/indra/llcommon/llstreamtools.h b/indra/llcommon/llstreamtools.h
index 1b04bf91d7..1b04bf91d7 100755..100644
--- a/indra/llcommon/llstreamtools.h
+++ b/indra/llcommon/llstreamtools.h
diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h
index ed9284d2c5..ed9284d2c5 100755..100644
--- a/indra/llcommon/llstrider.h
+++ b/indra/llcommon/llstrider.h
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f3b8999883..f3b8999883 100755..100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 0177f48bf5..393f6d7a8c 100755..100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -1394,6 +1394,7 @@ BOOL LLStringUtilBase<T>::containsNonprintable(const string_type& string)
return rv;
}
+// *TODO: reimplement in terms of algorithm
//static
template<class T>
void LLStringUtilBase<T>::stripNonprintable(string_type& string)
@@ -1427,6 +1428,7 @@ void LLStringUtilBase<T>::stripNonprintable(string_type& string)
delete []c_string;
}
+// *TODO: reimplement in terms of algorithm
template<class T>
std::basic_string<T> LLStringUtilBase<T>::quote(const string_type& str,
const string_type& triggers,
diff --git a/indra/llcommon/llstringtable.cpp b/indra/llcommon/llstringtable.cpp
index f288999964..f288999964 100755..100644
--- a/indra/llcommon/llstringtable.cpp
+++ b/indra/llcommon/llstringtable.cpp
diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h
index ff09e71677..ff09e71677 100755..100644
--- a/indra/llcommon/llstringtable.h
+++ b/indra/llcommon/llstringtable.h
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 1a66612e87..1a66612e87 100755..100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 962367f69f..962367f69f 100755..100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index c3f235c6ee..c3f235c6ee 100755..100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 6f9ec10fd3..6f9ec10fd3 100755..100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
index 185f0d63fb..185f0d63fb 100755..100644
--- a/indra/llcommon/llthreadsafequeue.cpp
+++ b/indra/llcommon/llthreadsafequeue.cpp
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 58cac38769..58cac38769 100755..100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 76e892212a..76e892212a 100755..100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index ec70213447..ec70213447 100755..100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
diff --git a/indra/llcommon/lltreeiterators.h b/indra/llcommon/lltreeiterators.h
index ba861ae70b..ba861ae70b 100755..100644
--- a/indra/llcommon/lltreeiterators.h
+++ b/indra/llcommon/lltreeiterators.h
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 9f12d49244..9f12d49244 100755..100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index c82a666e48..c82a666e48 100755..100644
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index e3671047b4..e3671047b4 100755..100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index dd8660a3c8..dd8660a3c8 100755..100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 4c197dc1d6..4c197dc1d6 100755..100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index 09776816a8..09776816a8 100755..100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h
index bf3f3f9ee8..bf3f3f9ee8 100755..100644
--- a/indra/llcommon/stdtypes.h
+++ b/indra/llcommon/stdtypes.h
diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index a5a90d7297..a5a90d7297 100755..100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
diff --git a/indra/llcommon/tests/StringVec.h b/indra/llcommon/tests/StringVec.h
index a380b00a05..a380b00a05 100755..100644
--- a/indra/llcommon/tests/StringVec.h
+++ b/indra/llcommon/tests/StringVec.h
diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp
index 9bfd567068..9bfd567068 100755..100644
--- a/indra/llcommon/tests/bitpack_test.cpp
+++ b/indra/llcommon/tests/bitpack_test.cpp
diff --git a/indra/llcommon/tests/commonmisc_test.cpp b/indra/llcommon/tests/commonmisc_test.cpp
index 4b3e07fa75..4b3e07fa75 100755..100644
--- a/indra/llcommon/tests/commonmisc_test.cpp
+++ b/indra/llcommon/tests/commonmisc_test.cpp
diff --git a/indra/llcommon/tests/listener.h b/indra/llcommon/tests/listener.h
index 9c5c18a150..9c5c18a150 100755..100644
--- a/indra/llcommon/tests/listener.h
+++ b/indra/llcommon/tests/listener.h
diff --git a/indra/llcommon/tests/llallocator_heap_profile_test.cpp b/indra/llcommon/tests/llallocator_heap_profile_test.cpp
index 44a9705803..44a9705803 100755..100644
--- a/indra/llcommon/tests/llallocator_heap_profile_test.cpp
+++ b/indra/llcommon/tests/llallocator_heap_profile_test.cpp
diff --git a/indra/llcommon/tests/llallocator_test.cpp b/indra/llcommon/tests/llallocator_test.cpp
index 4e62eaee67..4e62eaee67 100755..100644
--- a/indra/llcommon/tests/llallocator_test.cpp
+++ b/indra/llcommon/tests/llallocator_test.cpp
diff --git a/indra/llcommon/tests/llbase64_test.cpp b/indra/llcommon/tests/llbase64_test.cpp
index d0394150fa..d0394150fa 100755..100644
--- a/indra/llcommon/tests/llbase64_test.cpp
+++ b/indra/llcommon/tests/llbase64_test.cpp
diff --git a/indra/llcommon/tests/lldate_test.cpp b/indra/llcommon/tests/lldate_test.cpp
index 7c95ccb91f..7c95ccb91f 100755..100644
--- a/indra/llcommon/tests/lldate_test.cpp
+++ b/indra/llcommon/tests/lldate_test.cpp
diff --git a/indra/llcommon/tests/lldependencies_test.cpp b/indra/llcommon/tests/lldependencies_test.cpp
index b5e189a465..b5e189a465 100755..100644
--- a/indra/llcommon/tests/lldependencies_test.cpp
+++ b/indra/llcommon/tests/lldependencies_test.cpp
diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index f51279e817..f51279e817 100755..100644
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp
index 2096807e53..a459d17fb8 100755..100644
--- a/indra/llcommon/tests/lleventcoro_test.cpp
+++ b/indra/llcommon/tests/lleventcoro_test.cpp
@@ -59,17 +59,17 @@
// http://www.boost.org/LICENSE_1_0.txt)
/*****************************************************************************/
+#define BOOST_RESULT_OF_USE_TR1 1
// On some platforms, Boost.Coroutine must #define magic symbols before
// #including platform-API headers. Naturally, that's ineffective unless the
// Boost.Coroutine #include is the *first* #include of the platform header.
// That means that client code must generally #include Boost.Coroutine headers
// before anything else.
#include <boost/dcoroutine/coroutine.hpp>
-// Normally, lleventcoro.h obviates future.hpp. We only include this because
-// we implement a "by hand" test of future functionality.
-#include <boost/dcoroutine/future.hpp>
#include <boost/bind.hpp>
#include <boost/range.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
#include "linden_common.h"
@@ -82,9 +82,12 @@
#include "llevents.h"
#include "tests/wrapllerrs.h"
#include "stringize.h"
+#include "llcoros.h"
#include "lleventcoro.h"
#include "../test/debug.h"
+using namespace llcoro;
+
/*****************************************************************************
* from the banana.cpp example program borrowed for test<1>()
*****************************************************************************/
@@ -121,13 +124,10 @@ typedef coroutine<std::string::iterator(void)> match_coroutine_type;
/*****************************************************************************
* Test helpers
*****************************************************************************/
-// I suspect this will be typical of coroutines used in Linden software
-typedef boost::dcoroutines::coroutine<void()> coroutine_type;
-
/// Simulate an event API whose response is immediate: sent on receipt of the
/// initial request, rather than after some delay. This is the case that
-/// distinguishes postAndWait() from calling post(), then calling
-/// waitForEventOn().
+/// distinguishes postAndSuspend() from calling post(), then calling
+/// suspendUntilEventOn().
class ImmediateAPI
{
public:
@@ -162,306 +162,7 @@ private:
*****************************************************************************/
namespace tut
{
- struct coroutine_data
- {
- // Define coroutine bodies as methods here so they can use ensure*()
-
- void explicit_wait(coroutine_type::self& self)
- {
- BEGIN
- {
- // ... do whatever preliminary stuff must happen ...
-
- // declare the future
- boost::dcoroutines::future<LLSD> future(self);
- // tell the future what to wait for
- LLTempBoundListener connection(
- LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future))));
- ensure("Not yet", ! future);
- // attempting to dereference ("resolve") the future causes the calling
- // coroutine to wait for it
- debug("about to wait");
- result = *future;
- ensure("Got it", future);
- }
- END
- }
-
- void waitForEventOn1(coroutine_type::self& self)
- {
- BEGIN
- {
- result = waitForEventOn(self, "source");
- }
- END
- }
-
- void waitForEventOn2(coroutine_type::self& self)
- {
- BEGIN
- {
- LLEventWithID pair = waitForEventOn(self, "reply", "error");
- result = pair.first;
- which = pair.second;
- debug(STRINGIZE("result = " << result << ", which = " << which));
- }
- END
- }
-
- void postAndWait1(coroutine_type::self& self)
- {
- BEGIN
- {
- result = postAndWait(self,
- LLSDMap("value", 17), // request event
- immediateAPI.getPump(), // requestPump
- "reply1", // replyPump
- "reply"); // request["reply"] = name
- }
- END
- }
-
- void postAndWait2(coroutine_type::self& self)
- {
- BEGIN
- {
- LLEventWithID pair = ::postAndWait2(self,
- LLSDMap("value", 18),
- immediateAPI.getPump(),
- "reply2",
- "error2",
- "reply",
- "error");
- result = pair.first;
- which = pair.second;
- debug(STRINGIZE("result = " << result << ", which = " << which));
- }
- END
- }
-
- void postAndWait2_1(coroutine_type::self& self)
- {
- BEGIN
- {
- LLEventWithID pair = ::postAndWait2(self,
- LLSDMap("value", 18)("fail", LLSD()),
- immediateAPI.getPump(),
- "reply2",
- "error2",
- "reply",
- "error");
- result = pair.first;
- which = pair.second;
- debug(STRINGIZE("result = " << result << ", which = " << which));
- }
- END
- }
-
- void coroPump(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPump waiter;
- replyName = waiter.getName();
- result = waiter.wait(self);
- }
- END
- }
-
- void coroPumpPost(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPump waiter;
- result = waiter.postAndWait(self, LLSDMap("value", 17),
- immediateAPI.getPump(), "reply");
- }
- END
- }
-
- void coroPumps(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- LLEventWithID pair(waiter.wait(self));
- result = pair.first;
- which = pair.second;
- }
- END
- }
-
- void coroPumpsNoEx(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- result = waiter.waitWithException(self);
- }
- END
- }
-
- void coroPumpsEx(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- try
- {
- result = waiter.waitWithException(self);
- debug("no exception");
- }
- catch (const LLErrorEvent& e)
- {
- debug(STRINGIZE("exception " << e.what()));
- errordata = e.getData();
- }
- }
- END
- }
-
- void coroPumpsNoLog(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- result = waiter.waitWithLog(self);
- }
- END
- }
-
- void coroPumpsLog(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- WrapLLErrs capture;
- try
- {
- result = waiter.waitWithLog(self);
- debug("no exception");
- }
- catch (const WrapLLErrs::FatalException& e)
- {
- debug(STRINGIZE("exception " << e.what()));
- threw = e.what();
- }
- }
- END
- }
-
- void coroPumpsPost(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- LLEventWithID pair(waiter.postAndWait(self, LLSDMap("value", 23),
- immediateAPI.getPump(), "reply", "error"));
- result = pair.first;
- which = pair.second;
- }
- END
- }
-
- void coroPumpsPost_1(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- LLEventWithID pair(
- waiter.postAndWait(self, LLSDMap("value", 23)("fail", LLSD()),
- immediateAPI.getPump(), "reply", "error"));
- result = pair.first;
- which = pair.second;
- }
- END
- }
-
- void coroPumpsPostNoEx(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- result = waiter.postAndWaitWithException(self, LLSDMap("value", 8),
- immediateAPI.getPump(), "reply", "error");
- }
- END
- }
-
- void coroPumpsPostEx(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- try
- {
- result = waiter.postAndWaitWithException(self,
- LLSDMap("value", 9)("fail", LLSD()),
- immediateAPI.getPump(), "reply", "error");
- debug("no exception");
- }
- catch (const LLErrorEvent& e)
- {
- debug(STRINGIZE("exception " << e.what()));
- errordata = e.getData();
- }
- }
- END
- }
-
- void coroPumpsPostNoLog(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- result = waiter.postAndWaitWithLog(self, LLSDMap("value", 30),
- immediateAPI.getPump(), "reply", "error");
- }
- END
- }
-
- void coroPumpsPostLog(coroutine_type::self& self)
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- WrapLLErrs capture;
- try
- {
- result = waiter.postAndWaitWithLog(self,
- LLSDMap("value", 31)("fail", LLSD()),
- immediateAPI.getPump(), "reply", "error");
- debug("no exception");
- }
- catch (const WrapLLErrs::FatalException& e)
- {
- debug(STRINGIZE("exception " << e.what()));
- threw = e.what();
- }
- }
- END
- }
-
- void ensure_done(coroutine_type& coro)
- {
- ensure("coroutine complete", ! coro);
- }
-
- ImmediateAPI immediateAPI;
- std::string replyName, errorName, threw;
- LLSD result, errordata;
- int which;
- };
+ struct coroutine_data {};
typedef test_group<coroutine_data> coroutine_group;
typedef coroutine_group::object object;
coroutine_group coroutinegrp("coroutine");
@@ -511,54 +212,122 @@ namespace tut
ensure("done", ! matcher);
}
+ // use static data so we can intersperse coroutine functions with the
+ // tests that engage them
+ ImmediateAPI immediateAPI;
+ std::string replyName, errorName, threw, stringdata;
+ LLSD result, errordata;
+ int which;
+
+ // reinit vars at the start of each test
+ void clear()
+ {
+ replyName.clear();
+ errorName.clear();
+ threw.clear();
+ stringdata.clear();
+ result = LLSD();
+ errordata = LLSD();
+ which = 0;
+ }
+
+ void explicit_wait(boost::shared_ptr<LLCoros::Future<std::string>::callback_t>& cbp)
+ {
+ BEGIN
+ {
+ // The point of this test is to verify / illustrate suspending a
+ // coroutine for something other than an LLEventPump. In other
+ // words, this shows how to adapt to any async operation that
+ // provides a callback-style notification (and prove that it
+ // works).
+
+ LLCoros::Future<std::string> future;
+ // get the callback from that future
+ LLCoros::Future<std::string>::callback_t callback(future.make_callback());
+
+ // Perhaps we would send a request to a remote server and arrange
+ // for 'callback' to be called on response. Of course that might
+ // involve an adapter object from the actual callback signature to
+ // the signature of 'callback' -- in this case, void(std::string).
+ // For test purposes, instead of handing 'callback' (or the
+ // adapter) off to some I/O subsystem, we'll just pass it back to
+ // our caller.
+ cbp.reset(new LLCoros::Future<std::string>::callback_t(callback));
+
+ ensure("Not yet", ! future);
+ // calling get() on the future causes us to suspend
+ debug("about to suspend");
+ stringdata = future.get();
+ ensure("Got it", bool(future));
+ }
+ END
+ }
+
template<> template<>
void object::test<2>()
{
+ clear();
set_test_name("explicit_wait");
DEBUG;
// Construct the coroutine instance that will run explicit_wait.
- // Pass the ctor a callable that accepts the coroutine_type::self
- // param passed by the library.
- coroutine_type coro(boost::bind(&coroutine_data::explicit_wait, this, _1));
- // Start the coroutine
- coro(std::nothrow);
- // When the coroutine waits for the event pump, it returns here.
- debug("about to send");
- // Satisfy the wait.
- LLEventPumps::instance().obtain("source").post("received");
- // Now wait for the coroutine to complete.
- ensure_done(coro);
+ boost::shared_ptr<LLCoros::Future<std::string>::callback_t> respond;
+ LLCoros::instance().launch("test<2>",
+ boost::bind(explicit_wait, boost::ref(respond)));
+ // When the coroutine waits for the future, it returns here.
+ debug("about to respond");
+ // Now we're the I/O subsystem delivering a result. This immediately
+ // transfers control back to the coroutine.
+ (*respond)("received");
// ensure the coroutine ran and woke up again with the intended result
- ensure_equals(result.asString(), "received");
+ ensure_equals(stringdata, "received");
+ }
+
+ void waitForEventOn1()
+ {
+ BEGIN
+ {
+ result = suspendUntilEventOn("source");
+ }
+ END
}
template<> template<>
void object::test<3>()
{
+ clear();
set_test_name("waitForEventOn1");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn1, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<3>", waitForEventOn1);
debug("about to send");
LLEventPumps::instance().obtain("source").post("received");
debug("back from send");
- ensure_done(coro);
ensure_equals(result.asString(), "received");
}
+ void waitForEventOn2()
+ {
+ BEGIN
+ {
+ LLEventWithID pair = suspendUntilEventOn("reply", "error");
+ result = pair.first;
+ which = pair.second;
+ debug(STRINGIZE("result = " << result << ", which = " << which));
+ }
+ END
+ }
+
template<> template<>
void object::test<4>()
{
+ clear();
set_test_name("waitForEventOn2 reply");
{
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<4>", waitForEventOn2);
debug("about to send");
LLEventPumps::instance().obtain("reply").post("received");
debug("back from send");
- ensure_done(coro);
}
ensure_equals(result.asString(), "received");
ensure_equals("which pump", which, 0);
@@ -567,43 +336,65 @@ namespace tut
template<> template<>
void object::test<5>()
{
+ clear();
set_test_name("waitForEventOn2 error");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<5>", waitForEventOn2);
debug("about to send");
LLEventPumps::instance().obtain("error").post("badness");
debug("back from send");
- ensure_done(coro);
ensure_equals(result.asString(), "badness");
ensure_equals("which pump", which, 1);
}
+ void coroPump()
+ {
+ BEGIN
+ {
+ LLCoroEventPump waiter;
+ replyName = waiter.getName();
+ result = waiter.suspend();
+ }
+ END
+ }
+
template<> template<>
void object::test<6>()
{
+ clear();
set_test_name("coroPump");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPump, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<6>", coroPump);
debug("about to send");
LLEventPumps::instance().obtain(replyName).post("received");
debug("back from send");
- ensure_done(coro);
ensure_equals(result.asString(), "received");
}
+ void coroPumps()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ replyName = waiter.getName0();
+ errorName = waiter.getName1();
+ LLEventWithID pair(waiter.suspend());
+ result = pair.first;
+ which = pair.second;
+ }
+ END
+ }
+
template<> template<>
void object::test<7>()
{
+ clear();
set_test_name("coroPumps reply");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<7>", coroPumps);
debug("about to send");
LLEventPumps::instance().obtain(replyName).post("received");
debug("back from send");
- ensure_done(coro);
ensure_equals(result.asString(), "received");
ensure_equals("which pump", which, 0);
}
@@ -611,188 +402,389 @@ namespace tut
template<> template<>
void object::test<8>()
{
+ clear();
set_test_name("coroPumps error");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<8>", coroPumps);
debug("about to send");
LLEventPumps::instance().obtain(errorName).post("badness");
debug("back from send");
- ensure_done(coro);
ensure_equals(result.asString(), "badness");
ensure_equals("which pump", which, 1);
}
+ void coroPumpsNoEx()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ replyName = waiter.getName0();
+ errorName = waiter.getName1();
+ result = waiter.suspendWithException();
+ }
+ END
+ }
+
template<> template<>
void object::test<9>()
{
+ clear();
set_test_name("coroPumpsNoEx");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoEx, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<9>", coroPumpsNoEx);
debug("about to send");
LLEventPumps::instance().obtain(replyName).post("received");
debug("back from send");
- ensure_done(coro);
ensure_equals(result.asString(), "received");
}
+ void coroPumpsEx()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ replyName = waiter.getName0();
+ errorName = waiter.getName1();
+ try
+ {
+ result = waiter.suspendWithException();
+ debug("no exception");
+ }
+ catch (const LLErrorEvent& e)
+ {
+ debug(STRINGIZE("exception " << e.what()));
+ errordata = e.getData();
+ }
+ }
+ END
+ }
+
template<> template<>
void object::test<10>()
{
+ clear();
set_test_name("coroPumpsEx");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsEx, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<10>", coroPumpsEx);
debug("about to send");
LLEventPumps::instance().obtain(errorName).post("badness");
debug("back from send");
- ensure_done(coro);
ensure("no result", result.isUndefined());
ensure_equals("got error", errordata.asString(), "badness");
}
+ void coroPumpsNoLog()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ replyName = waiter.getName0();
+ errorName = waiter.getName1();
+ result = waiter.suspendWithLog();
+ }
+ END
+ }
+
template<> template<>
void object::test<11>()
{
+ clear();
set_test_name("coroPumpsNoLog");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoLog, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<11>", coroPumpsNoLog);
debug("about to send");
LLEventPumps::instance().obtain(replyName).post("received");
debug("back from send");
- ensure_done(coro);
ensure_equals(result.asString(), "received");
}
+ void coroPumpsLog()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ replyName = waiter.getName0();
+ errorName = waiter.getName1();
+ WrapLLErrs capture;
+ try
+ {
+ result = waiter.suspendWithLog();
+ debug("no exception");
+ }
+ catch (const WrapLLErrs::FatalException& e)
+ {
+ debug(STRINGIZE("exception " << e.what()));
+ threw = e.what();
+ }
+ }
+ END
+ }
+
template<> template<>
void object::test<12>()
{
+ clear();
set_test_name("coroPumpsLog");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsLog, this, _1));
- coro(std::nothrow);
+ LLCoros::instance().launch("test<12>", coroPumpsLog);
debug("about to send");
LLEventPumps::instance().obtain(errorName).post("badness");
debug("back from send");
- ensure_done(coro);
ensure("no result", result.isUndefined());
ensure_contains("got error", threw, "badness");
}
+ void postAndWait1()
+ {
+ BEGIN
+ {
+ result = postAndSuspend(LLSDMap("value", 17), // request event
+ immediateAPI.getPump(), // requestPump
+ "reply1", // replyPump
+ "reply"); // request["reply"] = name
+ }
+ END
+ }
+
template<> template<>
void object::test<13>()
{
+ clear();
set_test_name("postAndWait1");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::postAndWait1, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<13>", postAndWait1);
ensure_equals(result.asInteger(), 18);
}
+ void postAndWait2()
+ {
+ BEGIN
+ {
+ LLEventWithID pair = ::postAndSuspend2(LLSDMap("value", 18),
+ immediateAPI.getPump(),
+ "reply2",
+ "error2",
+ "reply",
+ "error");
+ result = pair.first;
+ which = pair.second;
+ debug(STRINGIZE("result = " << result << ", which = " << which));
+ }
+ END
+ }
+
template<> template<>
void object::test<14>()
{
+ clear();
set_test_name("postAndWait2");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::postAndWait2, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<14>", postAndWait2);
ensure_equals(result.asInteger(), 19);
ensure_equals(which, 0);
}
+ void postAndWait2_1()
+ {
+ BEGIN
+ {
+ LLEventWithID pair = ::postAndSuspend2(LLSDMap("value", 18)("fail", LLSD()),
+ immediateAPI.getPump(),
+ "reply2",
+ "error2",
+ "reply",
+ "error");
+ result = pair.first;
+ which = pair.second;
+ debug(STRINGIZE("result = " << result << ", which = " << which));
+ }
+ END
+ }
+
template<> template<>
void object::test<15>()
{
+ clear();
set_test_name("postAndWait2_1");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::postAndWait2_1, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<15>", postAndWait2_1);
ensure_equals(result.asInteger(), 19);
ensure_equals(which, 1);
}
+ void coroPumpPost()
+ {
+ BEGIN
+ {
+ LLCoroEventPump waiter;
+ result = waiter.postAndSuspend(LLSDMap("value", 17),
+ immediateAPI.getPump(), "reply");
+ }
+ END
+ }
+
template<> template<>
void object::test<16>()
{
+ clear();
set_test_name("coroPumpPost");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpPost, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<16>", coroPumpPost);
ensure_equals(result.asInteger(), 18);
}
+ void coroPumpsPost()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ LLEventWithID pair(waiter.postAndSuspend(LLSDMap("value", 23),
+ immediateAPI.getPump(), "reply", "error"));
+ result = pair.first;
+ which = pair.second;
+ }
+ END
+ }
+
template<> template<>
void object::test<17>()
{
+ clear();
set_test_name("coroPumpsPost reply");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<17>", coroPumpsPost);
ensure_equals(result.asInteger(), 24);
ensure_equals("which pump", which, 0);
}
+ void coroPumpsPost_1()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ LLEventWithID pair(
+ waiter.postAndSuspend(LLSDMap("value", 23)("fail", LLSD()),
+ immediateAPI.getPump(), "reply", "error"));
+ result = pair.first;
+ which = pair.second;
+ }
+ END
+ }
+
template<> template<>
void object::test<18>()
{
+ clear();
set_test_name("coroPumpsPost error");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost_1, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<18>", coroPumpsPost_1);
ensure_equals(result.asInteger(), 24);
ensure_equals("which pump", which, 1);
}
+ void coroPumpsPostNoEx()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ result = waiter.postAndSuspendWithException(LLSDMap("value", 8),
+ immediateAPI.getPump(), "reply", "error");
+ }
+ END
+ }
+
template<> template<>
void object::test<19>()
{
+ clear();
set_test_name("coroPumpsPostNoEx");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoEx, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<19>", coroPumpsPostNoEx);
ensure_equals(result.asInteger(), 9);
}
+ void coroPumpsPostEx()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ try
+ {
+ result = waiter.postAndSuspendWithException(
+ LLSDMap("value", 9)("fail", LLSD()),
+ immediateAPI.getPump(), "reply", "error");
+ debug("no exception");
+ }
+ catch (const LLErrorEvent& e)
+ {
+ debug(STRINGIZE("exception " << e.what()));
+ errordata = e.getData();
+ }
+ }
+ END
+ }
+
template<> template<>
void object::test<20>()
{
+ clear();
set_test_name("coroPumpsPostEx");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostEx, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<20>", coroPumpsPostEx);
ensure("no result", result.isUndefined());
ensure_equals("got error", errordata.asInteger(), 10);
}
+ void coroPumpsPostNoLog()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ result = waiter.postAndSuspendWithLog(LLSDMap("value", 30),
+ immediateAPI.getPump(), "reply", "error");
+ }
+ END
+ }
+
template<> template<>
void object::test<21>()
{
+ clear();
set_test_name("coroPumpsPostNoLog");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoLog, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<21>", coroPumpsPostNoLog);
ensure_equals(result.asInteger(), 31);
}
+ void coroPumpsPostLog()
+ {
+ BEGIN
+ {
+ LLCoroEventPumps waiter;
+ WrapLLErrs capture;
+ try
+ {
+ result = waiter.postAndSuspendWithLog(
+ LLSDMap("value", 31)("fail", LLSD()),
+ immediateAPI.getPump(), "reply", "error");
+ debug("no exception");
+ }
+ catch (const WrapLLErrs::FatalException& e)
+ {
+ debug(STRINGIZE("exception " << e.what()));
+ threw = e.what();
+ }
+ }
+ END
+ }
+
template<> template<>
void object::test<22>()
{
+ clear();
set_test_name("coroPumpsPostLog");
DEBUG;
- coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostLog, this, _1));
- coro(std::nothrow);
- ensure_done(coro);
+ LLCoros::instance().launch("test<22>", coroPumpsPostLog);
ensure("no result", result.isUndefined());
ensure_contains("got error", threw, "32");
}
diff --git a/indra/llcommon/tests/lleventdispatcher_test.cpp b/indra/llcommon/tests/lleventdispatcher_test.cpp
index 5a4df81bf1..5a4df81bf1 100755..100644
--- a/indra/llcommon/tests/lleventdispatcher_test.cpp
+++ b/indra/llcommon/tests/lleventdispatcher_test.cpp
diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp
index 2cdfb52f2f..2cdfb52f2f 100755..100644
--- a/indra/llcommon/tests/lleventfilter_test.cpp
+++ b/indra/llcommon/tests/lleventfilter_test.cpp
diff --git a/indra/llcommon/tests/llframetimer_test.cpp b/indra/llcommon/tests/llframetimer_test.cpp
index be372bb855..be372bb855 100755..100644
--- a/indra/llcommon/tests/llframetimer_test.cpp
+++ b/indra/llcommon/tests/llframetimer_test.cpp
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index c7d4b8a06b..c7d4b8a06b 100755..100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
diff --git a/indra/llcommon/tests/lllazy_test.cpp b/indra/llcommon/tests/lllazy_test.cpp
index 32a717f4fc..32a717f4fc 100755..100644
--- a/indra/llcommon/tests/lllazy_test.cpp
+++ b/indra/llcommon/tests/lllazy_test.cpp
diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
index 2d88e2c676..d342dece84 100755..100644
--- a/indra/llcommon/tests/llleap_test.cpp
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -36,10 +36,18 @@ StringVec sv(const StringVec& listof) { return listof; }
#if defined(LL_WINDOWS)
#define sleep(secs) _sleep((secs) * 1000)
-#endif
+// WOLF-300: It appears that driving a megabyte of data through an LLLeap pipe
+// causes Windows abdominal pain such that it later fails code-signing in some
+// mysterious way. Entirely suppressing these LLLeap tests pushes the failure
+// rate MUCH lower. Can we re-enable them with a smaller data size on Windows?
+const size_t BUFFERED_LENGTH = 100*1024;
+
+#else // not Windows
const size_t BUFFERED_LENGTH = 1023*1024; // try wrangling just under a megabyte of data
+#endif
+
void waitfor(const std::vector<LLLeap*>& instances, int timeout=60)
{
int i;
diff --git a/indra/llcommon/tests/llmemtype_test.cpp b/indra/llcommon/tests/llmemtype_test.cpp
index 1f050d6dc7..1f050d6dc7 100755..100644
--- a/indra/llcommon/tests/llmemtype_test.cpp
+++ b/indra/llcommon/tests/llmemtype_test.cpp
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index 5ba343b183..5ba343b183 100755..100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
diff --git a/indra/llcommon/tests/llprocessor_test.cpp b/indra/llcommon/tests/llprocessor_test.cpp
index 884e1b5e5b..884e1b5e5b 100755..100644
--- a/indra/llcommon/tests/llprocessor_test.cpp
+++ b/indra/llcommon/tests/llprocessor_test.cpp
diff --git a/indra/llcommon/tests/llrand_test.cpp b/indra/llcommon/tests/llrand_test.cpp
index 383e6f9e0a..383e6f9e0a 100755..100644
--- a/indra/llcommon/tests/llrand_test.cpp
+++ b/indra/llcommon/tests/llrand_test.cpp
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index 6fbb9abfc0..6fbb9abfc0 100755..100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp
index 385289aefe..385289aefe 100755..100644
--- a/indra/llcommon/tests/llsingleton_test.cpp
+++ b/indra/llcommon/tests/llsingleton_test.cpp
diff --git a/indra/llcommon/tests/llstreamqueue_test.cpp b/indra/llcommon/tests/llstreamqueue_test.cpp
index 050ad5c5bf..050ad5c5bf 100755..100644
--- a/indra/llcommon/tests/llstreamqueue_test.cpp
+++ b/indra/llcommon/tests/llstreamqueue_test.cpp
diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp
index a7aa347222..a7aa347222 100755..100644
--- a/indra/llcommon/tests/llstring_test.cpp
+++ b/indra/llcommon/tests/llstring_test.cpp
diff --git a/indra/llcommon/tests/lltreeiterators_test.cpp b/indra/llcommon/tests/lltreeiterators_test.cpp
index 1d619867d4..1d619867d4 100755..100644
--- a/indra/llcommon/tests/lltreeiterators_test.cpp
+++ b/indra/llcommon/tests/lltreeiterators_test.cpp
diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp
index 4c64f15ca7..4c64f15ca7 100755..100644
--- a/indra/llcommon/tests/lluri_test.cpp
+++ b/indra/llcommon/tests/lluri_test.cpp
diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp
index 2a4ed44a67..2a4ed44a67 100755..100644
--- a/indra/llcommon/tests/stringize_test.cpp
+++ b/indra/llcommon/tests/stringize_test.cpp
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index 785197ba11..785197ba11 100755..100644
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
diff --git a/indra/llcommon/timer.h b/indra/llcommon/timer.h
index 82d19c2d32..82d19c2d32 100755..100644
--- a/indra/llcommon/timer.h
+++ b/indra/llcommon/timer.h
diff --git a/indra/llcommon/timing.cpp b/indra/llcommon/timing.cpp
index c2dc695ef3..c2dc695ef3 100755..100644
--- a/indra/llcommon/timing.cpp
+++ b/indra/llcommon/timing.cpp
diff --git a/indra/llcommon/u64.cpp b/indra/llcommon/u64.cpp
index 02c2c15d26..02c2c15d26 100755..100644
--- a/indra/llcommon/u64.cpp
+++ b/indra/llcommon/u64.cpp
diff --git a/indra/llcommon/u64.h b/indra/llcommon/u64.h
index 75c8a59136..75c8a59136 100755..100644
--- a/indra/llcommon/u64.h
+++ b/indra/llcommon/u64.h