diff options
-rw-r--r-- | .github/workflows/build.yaml | 15 | ||||
-rw-r--r-- | .github/workflows/which_branch.py | 77 | ||||
-rwxr-xr-x | build.sh | 3 | ||||
-rw-r--r-- | indra/llcommon/classic_callback.h | 10 | ||||
-rw-r--r-- | indra/llcommon/llrand.cpp | 14 | ||||
-rw-r--r-- | indra/llcommon/llthread.cpp | 13 | ||||
-rw-r--r-- | indra/llcommon/llthread.h | 2 | ||||
-rw-r--r-- | indra/llcommon/stdtypes.h | 18 |
8 files changed, 118 insertions, 34 deletions
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d11177965f..d7f0daf8b3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,6 +24,7 @@ jobs: outputs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} viewer_version: ${{ steps.build.outputs.viewer_version }} + viewer_branch: ${{ steps.build.outputs.viewer_branch }} imagename: ${{ steps.build.outputs.imagename }} env: AUTOBUILD_ADDRSIZE: 64 @@ -70,7 +71,7 @@ jobs: uses: actions/checkout@v4 with: repository: secondlife/build-variables - ref: viewer + ref: master path: .build-variables - name: Checkout master-message-template @@ -80,7 +81,7 @@ jobs: path: .master-message-template - name: Install autobuild and python dependencies - run: pip3 install autobuild llsd + run: pip3 install autobuild PyGithub llsd - name: Cache autobuild packages uses: actions/cache@v3 @@ -176,9 +177,15 @@ jobs: if [[ "$GITHUB_REF_TYPE" == "tag" && "${GITHUB_REF_NAME:0:12}" == "Second_Life_" ]] then viewer_channel="${GITHUB_REF_NAME%#*}" export viewer_channel="${viewer_channel//_/ }" + # Since GITHUB_REF_NAME is a tag rather than a branch, we need + # to discover to what branch this tag corresponds. + viewer_branch="$(python3 .github/workflows/which_branch.py \ + --token "${{ github.token }}" ${{ github.workflow_sha }})" else export viewer_channel="Second Life Test" + viewer_branch="${GITHUB_REF_NAME}" fi echo "viewer_channel=$viewer_channel" >> "$GITHUB_OUTPUT" + echo "viewer_branch=$viewer_branch" >> "$GITHUB_OUTPUT" # On windows we need to point the build to the correct python # as neither CMake's FindPython nor our custom Python.cmake module @@ -324,7 +331,7 @@ jobs: version: ${{ needs.build.outputs.viewer_version }} release: - needs: [sign-and-package-windows, sign-and-package-mac] + needs: [build, sign-and-package-windows, sign-and-package-mac] runs-on: ubuntu-latest if: github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life_') steps: @@ -365,8 +372,10 @@ jobs: body: | ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} + ${{ needs.build.outputs.viewer_branch }} prerelease: true generate_release_notes: true + append_body: true # the only reason we generate a GH release is to post build products fail_on_unmatched_files: true files: | diff --git a/.github/workflows/which_branch.py b/.github/workflows/which_branch.py new file mode 100644 index 0000000000..802ea44b5a --- /dev/null +++ b/.github/workflows/which_branch.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +"""\ +@file which_branch.py +@author Nat Goodspeed +@date 2023-11-14 +@brief Discover which git branch(es) correspond to a given commit hash. + +$LicenseInfo:firstyear=2023&license=viewerlgpl$ +Copyright (c) 2023, Linden Research, Inc. +$/LicenseInfo$ +""" + +import github +import re +import sys +import subprocess + +class Error(Exception): + pass + +def branches_for(token, commit, repo=None): + """ + Use the GitHub REST API to discover which branch(es) correspond to the + passed commit hash. The commit string can actually be any of the ways git + permits to identify a commit: + + https://git-scm.com/docs/gitrevisions#_specifying_revisions + + branches_for() generates a (possibly empty) sequence of all the branches + of the specified repo for which the specified commit is the tip. + + If repo is omitted or None, assume the current directory is a local clone + whose 'origin' remote is the GitHub repository of interest. + """ + if not repo: + url = subprocess.check_output(['git', 'remote', 'get-url', 'origin'], + text=True) + parts = re.split(r'[:/]', url.rstrip()) + repo = '/'.join(parts[-2:]).removesuffix('.git') + + gh = github.MainClass.Github(token) + grepo = gh.get_repo(repo) + for branch in grepo.get_branches(): + try: + delta = grepo.compare(base=commit, head=branch.name) + except github.GithubException: + continue + + if delta.ahead_by == 0 and delta.behind_by == 0: + yield branch + +def main(*raw_args): + from argparse import ArgumentParser + parser = ArgumentParser(description= +"%(prog)s reports the branch(es) for which the specified commit hash is the tip.", + epilog="""\ +When GitHub Actions launches a tag build, it checks out the specific changeset +identified by the tag, and so 'git branch' reports detached HEAD. But we use +tag builds to build a GitHub 'release' of the tip of a particular branch, and +it's useful to be able to identify which branch that is. +""") + parser.add_argument('-t', '--token', required=True, + help="""GitHub REST API access token""") + parser.add_argument('-r', '--repo', + help="""GitHub repository name, in the form OWNER/REPOSITORY""") + parser.add_argument('commit', + help="""commit hash at the tip of the sought branch""") + + args = parser.parse_args(raw_args) + for branch in branches_for(token=args.token, commit=args.commit, repo=args.repo): + print(branch.name) + +if __name__ == "__main__": + try: + sys.exit(main(*sys.argv[1:])) + except Error as err: + sys.exit(str(err)) @@ -112,7 +112,8 @@ installer_CYGWIN() fi } -[[ -n "$GITHUB_OUTPUT" ]] || fatal "Need to export GITHUB_OUTPUT" +# if someone wants to run build.sh outside the GitHub environment +[[ -n "$GITHUB_OUTPUT" ]] || export GITHUB_OUTPUT='/dev/null' # The following is based on the Warning for GitHub multiline output strings: # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) diff --git a/indra/llcommon/classic_callback.h b/indra/llcommon/classic_callback.h index 1ad6dbc58f..009c25d67c 100644 --- a/indra/llcommon/classic_callback.h +++ b/indra/llcommon/classic_callback.h @@ -119,11 +119,11 @@ public: * ClassicCallback must not itself be copied or moved! Once you've passed * get_userdata() to some API, this object MUST remain at that address. */ - // However, we can't yet count on C++17 Class Template Argument Deduction, - // which means makeClassicCallback() is still useful, which means we MUST - // be able to return one to construct into caller's instance (move ctor). - // Possible defense: bool 'referenced' data member set by get_userdata(), - // with an llassert_always(! referenced) check in the move constructor. + // However, makeClassicCallback() is useful for deducing the CALLABLE + // type, which means we MUST be able to return one to construct into + // caller's instance (move ctor). Possible defense: bool 'referenced' data + // member set by get_userdata(), with an llassert_always(! referenced) + // check in the move constructor. ClassicCallback(ClassicCallback const&) = delete; ClassicCallback(ClassicCallback&&) = default; // delete; ClassicCallback& operator=(ClassicCallback const&) = delete; diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp index 33afc50cf7..e4065e23bf 100644 --- a/indra/llcommon/llrand.cpp +++ b/indra/llcommon/llrand.cpp @@ -58,7 +58,9 @@ * to restore uniform distribution. */ -static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed()); +// gRandomGenerator is a stateful static object, which is therefore not +// inherently thread-safe. +static thread_local LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed()); // no default implementation, only specific F64 and F32 specializations template <typename REAL> @@ -71,7 +73,7 @@ inline F64 ll_internal_random<F64>() // CPUs (or at least multi-threaded processes) seem to // occasionally give an obviously incorrect random number -- like // 5^15 or something. Sooooo, clamp it as described above. - F64 rv = gRandomGenerator(); + F64 rv{ gRandomGenerator() }; if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0); return rv; } @@ -79,7 +81,13 @@ inline F64 ll_internal_random<F64>() template <> inline F32 ll_internal_random<F32>() { - return F32(ll_internal_random<F64>()); + // *HACK: clamp the result as described above. + // Per Monty, it's important to clamp using the correct fmodf() rather + // than expanding to F64 for fmod() and then truncating back to F32. Prior + // to this change, we were getting sporadic ll_frand() == 1.0 results. + F32 rv{ narrow(gRandomGenerator()) }; + if(!((rv >= 0.0f) && (rv < 1.0f))) return fmodf(rv, 1.0f); + return rv; } /*------------------------------ F64 aliases -------------------------------*/ diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 4eaa05c335..cd4975d9d3 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -113,15 +113,16 @@ LL_COMMON_API bool on_main_thread() return (LLThread::currentID() == main_thread()); } -LL_COMMON_API void assert_main_thread() +LL_COMMON_API bool assert_main_thread() { auto curr = LLThread::currentID(); auto main = main_thread(); - if (curr != main) - { - LL_WARNS() << "Illegal execution from thread id " << curr - << " outside main thread " << main << LL_ENDL; - } + if (curr == main) + return true; + + LL_WARNS() << "Illegal execution from thread id " << curr + << " outside main thread " << main << LL_ENDL; + return false; } // this function has become moot diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 50202631e7..9f1c589fcd 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -152,7 +152,7 @@ public: //============================================================================ -extern LL_COMMON_API void assert_main_thread(); +extern LL_COMMON_API bool assert_main_thread(); extern LL_COMMON_API bool on_main_thread(); #endif // LL_LLTHREAD_H diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h index 0b43d7ad4b..3aba9dda00 100644 --- a/indra/llcommon/stdtypes.h +++ b/indra/llcommon/stdtypes.h @@ -156,18 +156,15 @@ typedef int intptr_t; * type. */ // narrow_holder is a struct that accepts the passed value as its original -// type and provides templated conversion functions to other types. Once we're -// building with compilers that support Class Template Argument Deduction, we -// can rename this class template 'narrow' and eliminate the narrow() factory -// function below. +// type and provides templated conversion functions to other types. template <typename FROM> -class narrow_holder +class narrow { private: FROM mValue; public: - narrow_holder(FROM value): mValue(value) {} + narrow(FROM value): mValue(value) {} /*---------------------- Narrowing unsigned to signed ----------------------*/ template <typename TO, @@ -207,13 +204,4 @@ public: } }; -/// narrow() factory function returns a narrow_holder<FROM>(), which can be -/// implicitly converted to the target type. -template <typename FROM> -inline -narrow_holder<FROM> narrow(FROM value) -{ - return { value }; -} - #endif |