summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yaml15
-rw-r--r--.github/workflows/which_branch.py77
-rwxr-xr-xbuild.sh3
-rw-r--r--indra/llcommon/classic_callback.h10
-rw-r--r--indra/llcommon/llrand.cpp14
-rw-r--r--indra/llcommon/llthread.cpp13
-rw-r--r--indra/llcommon/llthread.h2
-rw-r--r--indra/llcommon/stdtypes.h18
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))
diff --git a/build.sh b/build.sh
index 22f9e0c78a..32e6fd8ca4 100755
--- a/build.sh
+++ b/build.sh
@@ -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