mirror of
https://github.com/matrix-construct/construct
synced 2024-06-11 14:38:57 +02:00
Compare commits
372 commits
Author | SHA1 | Date | |
---|---|---|---|
0624b69246 | |||
e5ae70c521 | |||
759871ce8e | |||
3c9a4f8c57 | |||
f6b3b8b758 | |||
4fe85805bf | |||
b6cb1180f7 | |||
741304271e | |||
cd2b92b8fe | |||
feb4ac1fd3 | |||
d4ba215a3b | |||
8a705f77a9 | |||
f86fddc3a3 | |||
8eb10c5d1a | |||
a7a3275817 | |||
82feeb5274 | |||
8af781c5d7 | |||
29f3ddfc3e | |||
0b888b662a | |||
bbed809975 | |||
f9aeae5516 | |||
9301980f9d | |||
ca80d66e85 | |||
e7ad503f8c | |||
f70d837258 | |||
6f5121dc6a | |||
91a8fcbe43 | |||
b4b26484ec | |||
faf796a56b | |||
48e0755a79 | |||
5f5be52fa9 | |||
5f0b98e5d1 | |||
62a1c850cc | |||
e874e28473 | |||
55f332c821 | |||
44a4f33e45 | |||
04025af961 | |||
d1b0722169 | |||
0943cfd69c | |||
8b0cf48578 | |||
8eb4de920c | |||
5a06c0066e | |||
4ebc9fefaf | |||
5f3398bf52 | |||
dabc8b4304 | |||
d80f29b65a | |||
6c3420afbc | |||
6072229dcc | |||
956aa7682f | |||
238cc10489 | |||
1a032b28b7 | |||
f08b9e85cd | |||
9ce44aadd5 | |||
78d6e4ce03 | |||
882629ab53 | |||
8ade7c814e | |||
4d5d99ab2c | |||
502a03a8cf | |||
1e42fa16a7 | |||
0a151a3a90 | |||
fa46231e3a | |||
336026dde6 | |||
d5df04a183 | |||
080748f0af | |||
321ea3d641 | |||
d41926bc6f | |||
58476f59c3 | |||
8dc50db2dc | |||
2122412c6d | |||
15cb6bfdca | |||
fa0365fa31 | |||
02e09728a5 | |||
dc13381822 | |||
22b9cf515c | |||
a10992b813 | |||
c77df219b5 | |||
55a73624d2 | |||
cab2b4c822 | |||
79f5e4fd8d | |||
4c06793980 | |||
ef27ae50dc | |||
6e7d63ce6d | |||
73a3a4cb35 | |||
b40c21545a | |||
b4e75dfdf0 | |||
ba6030f4ce | |||
dd6d17433e | |||
7904fa0563 | |||
1f35421cec | |||
af783c8dfe | |||
e30c77283c | |||
8c629f20a6 | |||
b2d3ae4d0d | |||
c8ff5bbc37 | |||
715f21564e | |||
50481585b0 | |||
5d40121d53 | |||
b906650946 | |||
11d0ab9eaf | |||
24cb1b804f | |||
13d21ca83c | |||
7501f983a6 | |||
193d87ef76 | |||
922db35dd5 | |||
02dd645748 | |||
a67227f28f | |||
b21558fada | |||
97692b7330 | |||
fc91ace4f2 | |||
219571e69c | |||
d2c47b0d9e | |||
8cbeb98b59 | |||
25ed05429b | |||
4518cf104a | |||
c02b3d845f | |||
32d4d44662 | |||
b260bd85a7 | |||
d4d8063dee | |||
7be2582714 | |||
6264071248 | |||
602833d0ef | |||
1b933f8b8f | |||
2db42a7e70 | |||
7929733978 | |||
1b67a12a5f | |||
38c9a77a8f | |||
8f4fe45034 | |||
c7a89fcd89 | |||
5303e170d3 | |||
ffecc8bd22 | |||
d4b3a0db66 | |||
38e77c64c6 | |||
b1c2576c20 | |||
ef930635de | |||
02c862e4bc | |||
674b6489a4 | |||
999ef88b7f | |||
7046010ff9 | |||
92da7381ce | |||
4ecf1ef037 | |||
3ec562ce0b | |||
a8c16e0fd0 | |||
66629046e1 | |||
4339639732 | |||
95d5361c20 | |||
95274dd0cd | |||
bffa445d37 | |||
1b8ad3e160 | |||
04acaabf91 | |||
575211d37e | |||
6d73a65867 | |||
b3832541ff | |||
14f55f6110 | |||
82482278fb | |||
fc495f06ef | |||
1973e2c086 | |||
63c70ecdfc | |||
13f3d1ebc6 | |||
b07fa8c110 | |||
4d2478f814 | |||
f2626d39a7 | |||
c3c73fcbe7 | |||
19462b5fae | |||
96b1d68933 | |||
c807550ca7 | |||
3709cda233 | |||
eca02723b3 | |||
ee31b5a59f | |||
4e16f1849b | |||
3fcfaddc3e | |||
abf1ed47c6 | |||
cc36c17c03 | |||
1e4f44f41d | |||
5994475542 | |||
eff25f45f1 | |||
c6ce4d3229 | |||
76def3378f | |||
767f6cbae5 | |||
dcfae310ab | |||
2331de3f3e | |||
0b6669ca20 | |||
43838608fd | |||
f85781b65a | |||
d01e937f3e | |||
9558637c20 | |||
e3edcefe17 | |||
ac3b85114b | |||
684dd18497 | |||
fb9b68b4e3 | |||
00094e272f | |||
98e366e012 | |||
b5932ba33c | |||
70b49b96d2 | |||
ac8889b74c | |||
e7089e8e7f | |||
7e28a27549 | |||
fb9f2b0bcc | |||
8ebd2089f2 | |||
96119166fa | |||
527af013f7 | |||
cefcc75943 | |||
2147d00dd4 | |||
9836f65c05 | |||
da8948a740 | |||
2ccc8b8be3 | |||
087d13d37e | |||
f4747d96ff | |||
a7211b6a02 | |||
58c96bf758 | |||
3e9c225c24 | |||
0c20fa69d9 | |||
ae10f735ec | |||
48950bf1c9 | |||
1d58cd2266 | |||
9aaae46ead | |||
d5c2ff0e99 | |||
198049615b | |||
bc381359c7 | |||
a4c3a6be82 | |||
f2d94b5cc0 | |||
e57fc466cd | |||
12641056d2 | |||
9a74602523 | |||
95ed5ad905 | |||
f3a1416f65 | |||
0e5b1907d2 | |||
20b9b392af | |||
2d10ac2c78 | |||
4371380fe9 | |||
44acc6a287 | |||
ce7760b213 | |||
59072bd622 | |||
08ea4b0e72 | |||
679ed39ccc | |||
eb59239d32 | |||
017af932ed | |||
2d78dbdbb9 | |||
a549fd0b80 | |||
a1d4e448ea | |||
694b208829 | |||
eb0a564d0b | |||
cd78f802b2 | |||
4abe844c72 | |||
fe1dfbce9b | |||
35e1ba3321 | |||
ba70036789 | |||
0f4d048fab | |||
bb0e226760 | |||
3dafa47ac3 | |||
605245953a | |||
371c50cfcc | |||
0907fa08e3 | |||
121f9febc7 | |||
74f2093d9c | |||
19c740a182 | |||
91ac6a9269 | |||
560bd5edad | |||
3c1d633efd | |||
b96c552e46 | |||
d264a5019d | |||
53ff7e229b | |||
91fafda7bb | |||
ab7dd15618 | |||
fc06ea8ded | |||
7f45a7eb63 | |||
2c3dab1abc | |||
e83bc5d930 | |||
096a67ff8d | |||
ab77a32dce | |||
56984d59e9 | |||
5d7a4e4b36 | |||
ce6b4496b3 | |||
8fae18d8ea | |||
4519ecf6e3 | |||
99f6289922 | |||
7ffb8476c2 | |||
44bdc2f94b | |||
6cb41fced9 | |||
73c5a4f36b | |||
137824eb77 | |||
9154233db5 | |||
2948bf7cd1 | |||
a104e44e3e | |||
9eec649b4d | |||
7472177a78 | |||
b0ad960bae | |||
cc7bc15d89 | |||
21bc6c4e97 | |||
73f4a68b8f | |||
314dacdce0 | |||
cd6eb8ed0a | |||
bb84740517 | |||
9c856c4f34 | |||
5141982828 | |||
5856c2fd0e | |||
2060fb2993 | |||
e7cf7ab0fc | |||
9cb3bf2c28 | |||
6b62fb1fe6 | |||
364f7d9c3e | |||
647babdcbe | |||
61f12bb751 | |||
ff666cc75a | |||
b1bb516bba | |||
34bd1e0709 | |||
ea92976369 | |||
e961b23d1e | |||
96d5b6fe57 | |||
1627986fed | |||
cfaf6a90f1 | |||
93bed7bc63 | |||
72dce4364c | |||
884c2e68b7 | |||
e479a17f51 | |||
c30776fc59 | |||
5a35d63b64 | |||
17f0923eff | |||
6e33d52bda | |||
06583f7bfb | |||
5bd594d165 | |||
c521a20fb3 | |||
262bde6fdf | |||
de1a566909 | |||
0f3fea3b72 | |||
1e0919de71 | |||
e177accad8 | |||
9bf8e08753 | |||
62d175b17c | |||
0fd5514d49 | |||
1a8889503f | |||
c78a7e96b9 | |||
61248a4c5b | |||
f301d6641c | |||
23c8a6c5cb | |||
6e6afb9d30 | |||
716134186e | |||
f1676fdb80 | |||
04c81a41ed | |||
5fb1a6633d | |||
b93348f6e1 | |||
d28d3d8084 | |||
4e209855de | |||
b4938361c6 | |||
77cd8832c1 | |||
92ca127f54 | |||
c7033a4df1 | |||
be1d6ed454 | |||
47f670b7a2 | |||
edab741e9f | |||
b3ba3eb443 | |||
36b85a5c78 | |||
d48e6ccb8d | |||
4edf7f0052 | |||
1607ce0a1f | |||
416066d01b | |||
affd1f2913 | |||
499bec0a1a | |||
df85c1c642 | |||
60bff84004 | |||
62001d9e7e | |||
032b815276 | |||
bc3aa62d59 | |||
fbd5b3f571 | |||
84539e3d95 | |||
028c456aca | |||
7320ea0fcb | |||
fb162605a6 | |||
990482308e | |||
f39e25f972 | |||
b0217fd371 | |||
45a3b8765f | |||
e1ca32e89a |
|
@ -1,15 +1,20 @@
|
|||
version: master_{build}
|
||||
clone_depth: 1
|
||||
skip_tags: true
|
||||
|
||||
services:
|
||||
- docker
|
||||
- docker
|
||||
|
||||
branches:
|
||||
only:
|
||||
- appveyor
|
||||
|
||||
environment:
|
||||
COMMAND: if [[ "${APPVEYOR_REPO_COMMIT_MESSAGE@Q}" == *"[ci debug]"* ]]; then export DEBUG_FLAGS="--enable-debug"; fi; if [[ "${APPVEYOR_REPO_COMMIT_MESSAGE@Q}" == *"[ci gdb]"* ]]; then apt-get update && apt-get -y install gdb && export CONSTRUCT="gdb --batch -ex r -ex bt --return-child-result --args construct"; else export CONSTRUCT="construct"; fi && rmdir -v deps/rocksdb && ln -sv /usr/src/rocksdb deps && ./autogen.sh && ./configure --enable-assert ${DEBUG_FLAGS} && make install && ${CONSTRUCT} -smoketest -debug localhost
|
||||
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu1804
|
||||
DOCKER_IMAGE: jevolk/construct:ubuntu-22.04-base-build-gcc-9-amd64
|
||||
DOCKER_IMAGE: jevolk/construct:ubuntu-22.04-base-build-gcc-10-amd64
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu1804
|
||||
DOCKER_IMAGE: jevolk/construct:ubuntu-22.04-base-build-gcc-12-amd64
|
||||
|
@ -18,8 +23,8 @@ environment:
|
|||
DOCKER_IMAGE: jevolk/construct:ubuntu-22.04-full-build-clang-15-amd64
|
||||
|
||||
for:
|
||||
-
|
||||
build_script:
|
||||
-
|
||||
build_script:
|
||||
- docker run -v `pwd`:/build "${DOCKER_IMAGE}" /bin/bash -c "${COMMAND}"
|
||||
|
||||
matrix:
|
||||
|
|
98
.github/workflows/docker.yml
vendored
Normal file
98
.github/workflows/docker.yml
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
#
|
||||
# Build docker images
|
||||
#
|
||||
name: Docker Images
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
features:
|
||||
type: string
|
||||
description: JSON array of feature-set names to build images for.
|
||||
distros:
|
||||
type: string
|
||||
description: JSON array of operating system distros to build for.
|
||||
machines:
|
||||
type: string
|
||||
description: JSON array of machines to build for.
|
||||
toolchains:
|
||||
type: string
|
||||
description: JSON array of compiler toolchains to build for.
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
ctor_id: ${{vars.DOCKER_ID}}
|
||||
ctor_url: https://github.com/${{github.repository}}
|
||||
|
||||
jobs:
|
||||
# Build the base-feature intermediate images (cached and not shipped).
|
||||
base:
|
||||
uses: ./.github/workflows/docker_prime.yml
|
||||
with:
|
||||
id: ${{github.env.ctor_id}}
|
||||
url: ${{github.env.ctor_url}}
|
||||
features: '["base"]'
|
||||
distros: ${{github.event.inputs.distros || vars.DOCKER_DISTROS}}
|
||||
machines: ${{github.event.inputs.machines || vars.DOCKER_MACHINES}}
|
||||
test: ${{contains(github.events.push.commits[0].message, '[ci test]')}}
|
||||
|
||||
# Build the full-feature intermediate images (cached and not shipped).
|
||||
full:
|
||||
uses: ./.github/workflows/docker_prime.yml
|
||||
needs: [base]
|
||||
with:
|
||||
id: ${{github.env.ctor_id}}
|
||||
url: ${{github.env.ctor_url}}
|
||||
features: '["full"]'
|
||||
distros: ${{github.event.inputs.distros || vars.DOCKER_DISTROS}}
|
||||
machines: ${{github.event.inputs.machines || vars.DOCKER_MACHINES}}
|
||||
test: ${{contains(github.events.push.commits[0].message, '[ci test]')}}
|
||||
|
||||
# Build the leaf images (shipped and not cached)
|
||||
built:
|
||||
needs: [base, full]
|
||||
runs-on: ${{matrix.machine}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
feature: ${{fromJSON(github.event.inputs.features || vars.DOCKER_FEATURES)}}
|
||||
distro: ${{fromJSON(github.event.inputs.distros || vars.DOCKER_DISTROS)}}
|
||||
machine: ${{fromJSON(github.event.inputs.machines || vars.DOCKER_MACHINES)}}
|
||||
toolchain: ${{fromJSON(github.event.inputs.toolchains || vars.DOCKER_TOOLCHAINS)}}
|
||||
exclude:
|
||||
- distro: alpine-3.17
|
||||
toolchain: gcc-10 # n/a on distro version
|
||||
- distro: alpine-3.17
|
||||
toolchain: gcc-11 # n/a on distro version
|
||||
- distro: alpine-3.17
|
||||
toolchain: clang-14 # n/a on distro version
|
||||
- distro: ubuntu-22.04
|
||||
toolchain: clang-15 # n/a on distro version
|
||||
- machine: arm64
|
||||
toolchain: gcc-12 # build hangs
|
||||
- machine: arm64
|
||||
toolchain: gcc-11 # build hangs
|
||||
- machine: arm64
|
||||
toolchain: gcc-10 # build hangs
|
||||
- machine: arm64
|
||||
distro: alpine-3.17
|
||||
toolchain: clang-14 # smoketest crash
|
||||
- machine: arm64
|
||||
distro: alpine-3.17
|
||||
toolchain: clang-15 # smoketest crash
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: build
|
||||
env:
|
||||
ctor_features: ${{matrix.feature}}
|
||||
ctor_distros: ${{matrix.distro}}
|
||||
ctor_machines: ${{matrix.machine}}
|
||||
ctor_toolchains: ${{matrix.toolchain}}
|
||||
ctor_test: ${{contains(github.events.push.commits[0].message, '[ci test]')}}
|
||||
|
||||
run: |
|
||||
docker/build-and-push-images.sh
|
62
.github/workflows/docker_prime.yml
vendored
Normal file
62
.github/workflows/docker_prime.yml
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
#
|
||||
# Build intermediate images
|
||||
#
|
||||
# Called to build lower-layer images which other images depend on. These are
|
||||
# cached for use by the next layer but not shipped to users.
|
||||
#
|
||||
name: Docker Images Prime
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
id:
|
||||
type: string
|
||||
description: Dockerhub acct/repo identity.
|
||||
url:
|
||||
type: string
|
||||
description: Git repository for checkout.
|
||||
features:
|
||||
type: string
|
||||
description: JSON array of feature-set names to build images for.
|
||||
distros:
|
||||
type: string
|
||||
description: JSON array of operating system distros to build for.
|
||||
machines:
|
||||
type: string
|
||||
description: JSON array of machines to build for.
|
||||
test:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
description: Echo all docker commands rather than invoking them.
|
||||
|
||||
concurrency:
|
||||
group: ${{github.workflow}}-${{inputs.features}}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
ctor_id: ${{inputs.id}}
|
||||
ctor_url: ${{inputs.url}}
|
||||
|
||||
jobs:
|
||||
prime:
|
||||
runs-on: ${{matrix.machine}}
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
feature: ${{fromJSON(inputs.features)}}
|
||||
distro: ${{fromJSON(inputs.distros)}}
|
||||
machine: ${{fromJSON(inputs.machines)}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: build
|
||||
env:
|
||||
ctor_features: ${{matrix.feature}}
|
||||
ctor_distros: ${{matrix.distro}}
|
||||
ctor_machines: ${{matrix.machine}}
|
||||
ctor_toolchains: false
|
||||
ctor_test: ${{inputs.test}}
|
||||
|
||||
run: |
|
||||
docker/build-and-push-images.sh ${{matrix.feature}}
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -19,6 +19,7 @@ Makefile
|
|||
*.gch
|
||||
*.cache
|
||||
*.tmp
|
||||
*.save
|
||||
*.profdata
|
||||
.deps
|
||||
.dirstamp
|
||||
|
|
18
README.md
18
README.md
|
@ -1,10 +1,10 @@
|
|||
# This — is The **Construct**
|
||||
|
||||
#### Federated Messaging Server
|
||||
#### FEDERATED MESSAGING SERVER
|
||||
|
||||
[![Chat in #construct:zemos.net](https://img.shields.io/matrix/construct:zemos.net.svg?label=Chat%20in%20%23construct%3Azemos.net&logo=matrix&server_fqdn=matrix.org&style=for-the-badge&color=5965AF)](https://matrix.to/#/#construct:zemos.net) [![](https://img.shields.io/badge/License-BSD-5965AF.svg?label=%20license&style=for-the-badge)]()
|
||||
|
||||
### 📦 RUN YOUR OWN
|
||||
### 🚚 GET CONSTRUCT
|
||||
|
||||
- `git clone https://github.com/matrix-construct/construct`
|
||||
|
||||
|
@ -13,19 +13,17 @@
|
|||
[![](https://img.shields.io/github/directory-file-count/matrix-construct/construct.svg?type=dir&label=directories&logo=GitHub&style=flat-square&color=5965AF)](https://github.com/matrix-construct/construct)
|
||||
[![](https://img.shields.io/github/directory-file-count/matrix-construct/construct.svg?type=file&label=files&logo=GitHub&style=flat-square&color=5965AF)](https://github.com/matrix-construct/construct)
|
||||
|
||||
| Fully Featured Builds | Minimal Dependencies |
|
||||
|:---|:---|
|
||||
| [![](https://img.shields.io/docker/image-size/jevolk/construct/ubuntu-22.04-full-built-clang-15-amd64.svg?logoWidth=25&label=ubuntu%2022.04%20amd64&logo=Docker&style=flat-square&color=5965AF)](https://registry.hub.docker.com/r/jevolk/construct/tags) | [![](https://img.shields.io/docker/image-size/jevolk/construct/ubuntu-22.04-base-built-gcc-12-amd64.svg?logoWidth=25&label=ubuntu%2022.04%20amd64&logo=Docker&style=flat-square&color=5965AF)](https://registry.hub.docker.com/r/jevolk/construct/tags)
|
||||
| [![](https://img.shields.io/docker/image-size/jevolk/construct/alpine-3.16-full-built-clang-amd64.svg?logoWidth=25&label=alpine%203.16%20clang%20amd64&logo=Docker&style=flat-square&color=5965AF)](https://registry.hub.docker.com/r/jevolk/construct/tags) | [![](https://img.shields.io/docker/image-size/jevolk/construct/alpine-3.16-base-built-clang-amd64.svg?logoWidth=25&label=alpine%203.16%20clang%20amd64&logo=Docker&style=flat-square&color=5965AF)](https://registry.hub.docker.com/r/jevolk/construct/tags)
|
||||
| [![](https://img.shields.io/docker/image-size/jevolk/construct/alpine-3.16-full-built-gcc-amd64.svg?logoWidth=25&label=alpine%203.16%20gcc%20amd64&logo=Docker&style=flat-square&color=5965AF)](https://registry.hub.docker.com/r/jevolk/construct/tags) | [![](https://img.shields.io/docker/image-size/jevolk/construct/alpine-3.16-base-built-gcc-amd64.svg?logoWidth=25&label=alpine%203.16%20gcc%20amd64&logo=Docker&style=flat-square&color=5965AF)](https://registry.hub.docker.com/r/jevolk/construct/tags)
|
||||
- 📦 [**DISTRIBUTION PACKAGES**](https://github.com/matrix-construct/construct/wiki/PACKAGE)
|
||||
|
||||
- 🐋 [**DOCKER IMAGES**](https://github.com/matrix-construct/construct/wiki/DOCKER)
|
||||
|
||||
### 🗒️ INSTRUCTIONS
|
||||
|
||||
1. 🏗️ [BUILD](https://github.com/matrix-construct/construct/wiki/BUILD) instructions to compile Construct from source.
|
||||
1. 🏗️ [**BUILD**](https://github.com/matrix-construct/construct/wiki/BUILD) to compile Construct from source.
|
||||
|
||||
2. 🪛 [SETUP](https://github.com/matrix-construct/construct/wiki/SETUP) instructions to run Construct for the first time.
|
||||
2. 🪛 [**SETUP**](https://github.com/matrix-construct/construct/wiki/SETUP) to run Construct for the first time.
|
||||
|
||||
3. ⚡ [TUNING](https://github.com/matrix-construct/construct/wiki/TUNING) guide to optimize Construct for your deployment.
|
||||
3. ⚡ [**TUNING**](https://github.com/matrix-construct/construct/wiki/TUNING) to optimize Construct for your deployment.
|
||||
|
||||
- 🙋 [TROUBLESHOOTING](https://github.com/matrix-construct/construct/wiki/Troubleshooting-problems) guide for solutions to possible problems.
|
||||
|
||||
|
|
403
configure.ac
403
configure.ac
|
@ -83,6 +83,16 @@ dnl
|
|||
dnl Platform
|
||||
dnl
|
||||
|
||||
dnl
|
||||
dnl Hardwares
|
||||
dnl
|
||||
|
||||
AM_CONDITIONAL([AMD64], [[[[ $host_cpu = *x86_64* ]]]])
|
||||
AM_CONDITIONAL([X86_64], [[[[ $host_cpu = *x86_64* ]]]])
|
||||
|
||||
AM_CONDITIONAL([ARM64], [[[[ $host_cpu = *aarch64* ]]]])
|
||||
AM_CONDITIONAL([AARCH64], [[[[ $host_cpu = *aarch64* ]]]])
|
||||
|
||||
dnl
|
||||
dnl Compiler brand
|
||||
dnl
|
||||
|
@ -151,21 +161,25 @@ dnl Debugging mode
|
|||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to enable debugging)
|
||||
AC_ARG_ENABLE(debug, RB_HELP_STRING([--enable-debug], [Enable debugging suite for development]),
|
||||
AC_ARG_ENABLE(debug, RB_HELP_STRING([--enable-debug=[[no]]], [Enable debugging suite for development]),
|
||||
[
|
||||
debug=$enableval
|
||||
], [
|
||||
debug="no"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$debug])
|
||||
AM_CONDITIONAL([DEBUG], [[[[ "$debug" = "yes" ]]]])
|
||||
|
||||
AM_COND_IF([DEBUG],
|
||||
[
|
||||
debug="yes"
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SUBST(DEBUG, 1)
|
||||
RB_DEFINE_UNQUOTED([DEBUG], [1], [Not configured for release when lit.])
|
||||
RB_DEFINE_UNQUOTED([DEBUG_LEVEL], [1], [Defined to 0 for release; or > 0 otherwise])
|
||||
], [
|
||||
debug="no"
|
||||
AC_MSG_RESULT([no])
|
||||
RB_DEFINE_UNQUOTED([DEBUG_LEVEL], [0], [Defined to 0 for release])
|
||||
RB_DEFINE_UNQUOTED([DEBUG_LEVEL], [0], [Defined to 0 for release; or > 0 otherwise])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([DEBUG], [[[[ "$DEBUG" = "1" ]]]])
|
||||
|
||||
dnl
|
||||
dnl Compactness
|
||||
dnl
|
||||
|
@ -173,14 +187,19 @@ dnl
|
|||
AC_MSG_CHECKING(Optimize for size; strip symbols; force no debugging)
|
||||
AC_ARG_ENABLE(compact, RB_HELP_STRING([--enable-compact], [Optimize for size and compactness]),
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SUBST(COMPACT, 1)
|
||||
RB_DEFINE_UNQUOTED([COMPACT], [1], [Not configured for compactness when lit.])
|
||||
compact=$enableval
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
compact="no"
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([COMPACT], [[[[ "$COMPACT" = "1" ]]]])
|
||||
AC_MSG_RESULT([$compact])
|
||||
AM_CONDITIONAL([COMPACT], [[[[ "$compact" = "yes" ]]]])
|
||||
|
||||
AM_COND_IF([COMPACT],
|
||||
[
|
||||
AC_SUBST(COMPACT, 1)
|
||||
RB_DEFINE_UNQUOTED([COMPACT], [1], [Not configured for compactness when lit.])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Explicit assert switch for still using assert() without --enable-debug
|
||||
|
@ -189,26 +208,26 @@ dnl
|
|||
AC_MSG_CHECKING(whether to explicitly enable assertions)
|
||||
AC_ARG_ENABLE(assert, RB_HELP_STRING([--enable-assert], [Enable assertions without --enable-debug]),
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SUBST(ASSERT, 1)
|
||||
assert=$enableval
|
||||
AC_MSG_RESULT([$assert])
|
||||
], [
|
||||
AM_COND_IF(DEBUG,
|
||||
[
|
||||
AC_MSG_RESULT([no, but assertions are enabled anyway])
|
||||
AC_SUBST(ASSERT, 1)
|
||||
assert="yes"
|
||||
AC_MSG_RESULT([$assert, enabled by default with --enable-debug])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
assert="no"
|
||||
AC_MSG_RESULT([$assert])
|
||||
])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([ASSERT], [[[[ "$ASSERT" = "1" ]]]])
|
||||
AM_CONDITIONAL([ASSERT], [[[[ "$assert" = "yes" ]]]])
|
||||
|
||||
AM_COND_IF(ASSERT,
|
||||
[
|
||||
assert="yes"
|
||||
assert_type="abort"
|
||||
AC_SUBST(ASSERT, 1)
|
||||
], [
|
||||
assert="no"
|
||||
CPPDEFINE([NDEBUG])
|
||||
])
|
||||
|
||||
|
@ -216,18 +235,17 @@ dnl
|
|||
dnl Switch to control the action of assert()
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to change the behavior of assertions)
|
||||
AC_ARG_WITH(assert, RB_HELP_STRING([--with-assert[[[=abort]]]], [Soften assertion behavior]),
|
||||
AC_MSG_CHECKING(what the result of a failed assertion implies)
|
||||
AC_ARG_WITH(assert, RB_HELP_STRING([--with-assert[[[=abort]]]], [Change assertion behavior]),
|
||||
[
|
||||
assert_type=$withval
|
||||
AC_MSG_RESULT([yes, "$assert_type"])
|
||||
AC_SUBST(ASSERT_TYPE, $assert_type)
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
AM_COND_IF(ASSERT,
|
||||
[
|
||||
AC_MSG_RESULT([$assert_type])
|
||||
AC_SUBST(ASSERT_TYPE, $assert_type)
|
||||
|
||||
if [[ ! -z "$assert_type" ]]; then
|
||||
|
||||
if [[ "$assert_type" != "abort" ]]; then
|
||||
|
@ -243,6 +261,9 @@ AM_COND_IF(ASSERT,
|
|||
fi
|
||||
|
||||
fi
|
||||
], [
|
||||
AC_MSG_RESULT([nothing without assertions enabled])
|
||||
assert_type=""
|
||||
])
|
||||
|
||||
dnl
|
||||
|
@ -252,19 +273,46 @@ dnl
|
|||
AC_MSG_CHECKING(whether to explicitly enable optimized build)
|
||||
AC_ARG_ENABLE(optimize, RB_HELP_STRING([--enable-optimize], [Enable optimization even with --enable-debug]),
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SUBST(OPTIMIZE, 1)
|
||||
optimize=$enableval
|
||||
AC_MSG_RESULT([$optimize])
|
||||
], [
|
||||
AM_COND_IF(DEBUG,
|
||||
[
|
||||
AC_MSG_RESULT([no])
|
||||
optimize="no"
|
||||
AC_MSG_RESULT([$optimize, disabled by default with --enable-debug])
|
||||
], [
|
||||
AC_MSG_RESULT([no, but optimized build is enabled anyway])
|
||||
AC_SUBST(OPTIMIZE, 1)
|
||||
optimize="yes"
|
||||
AC_MSG_RESULT([$optimize])
|
||||
])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([OPTIMIZE], [[[[ "$OPTIMIZE" = "1" ]]]])
|
||||
AM_CONDITIONAL([OPTIMIZE], [[[[ "$optimize" = "yes" ]]]])
|
||||
|
||||
AM_COND_IF([OPTIMIZE],
|
||||
[
|
||||
AC_SUBST(OPTIMIZE, 1)
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Enable target clones code generation
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to generate code for target clones)
|
||||
AC_ARG_ENABLE(clones, RB_HELP_STRING([--enable-clones], [Enable target clones generation]),
|
||||
[
|
||||
clones="yes"
|
||||
], [
|
||||
clones="no"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$clones])
|
||||
AM_CONDITIONAL([CLONES], [[[[ "$clones" = "yes" ]]]])
|
||||
|
||||
AM_COND_IF([CLONES],
|
||||
[
|
||||
AC_SUBST(CLONES, 1)
|
||||
RB_DEFINE([CLONES], [1], [Function multi-versioning for different architectures])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Explicit link-time-optimization switch
|
||||
|
@ -291,7 +339,6 @@ if test "$lto" = "yes"; then
|
|||
], [
|
||||
lto="yes"
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SUBST(LTO, 1)
|
||||
])
|
||||
], [
|
||||
lto="no"
|
||||
|
@ -305,7 +352,12 @@ else
|
|||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([LTO], [[[[ "$LTO" = "1" ]]]])
|
||||
AM_CONDITIONAL([LTO], [[[[ "$lto" = "yes" ]]]])
|
||||
|
||||
AM_COND_IF([LTO],
|
||||
[
|
||||
AC_SUBST(LTO, 1)
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Explicit optimization level switch
|
||||
|
@ -401,67 +453,74 @@ dnl Precompiled headers
|
|||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to enable precompiled headers)
|
||||
AC_ARG_ENABLE(pch, RB_HELP_STRING([--disable-pch], [Disable precompiled header generation]),
|
||||
AC_ARG_ENABLE(pch, RB_HELP_STRING([--enable-pch], [Enable precompiled header generation]),
|
||||
[
|
||||
build_pch=$enableval
|
||||
AC_MSG_RESULT([$enableval])
|
||||
], [
|
||||
build_pch="yes"
|
||||
CPPDEFINE([PCH])
|
||||
AC_MSG_RESULT([yes])
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$build_pch])
|
||||
AM_CONDITIONAL([BUILD_PCH], [[[[ "$build_pch" = "yes" ]]]])
|
||||
AM_CONDITIONAL([CLANG_PCH], [[[[ "$build_pch" = "yes" ]] && [[ $CXX = clang* ]]]])
|
||||
|
||||
AM_COND_IF([BUILD_PCH],
|
||||
[
|
||||
CPPDEFINE([PCH])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Generic Mode compilation
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to enable generic mode or tune for this host)
|
||||
AC_MSG_CHECKING(whether to enable generic mode or emit for this host)
|
||||
AC_ARG_ENABLE(generic, RB_HELP_STRING([--enable-generic], [Emit more generic code for pkg binaries]),
|
||||
[
|
||||
enable_generic="yes"
|
||||
AC_MSG_RESULT([yes])
|
||||
RB_DEFINE([GENERIC], [1], [Building binary tuned for generic architectures])
|
||||
], [
|
||||
enable_generic="no"
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$enable_generic])
|
||||
AM_CONDITIONAL([GENERIC], [[[[ "$enable_generic" = "yes" ]]]])
|
||||
|
||||
dnl
|
||||
dnl Untuned Mode compilation
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to enable fully untuned mode)
|
||||
AC_ARG_ENABLE(untuned, RB_HELP_STRING([--enable-untuned], [Emit no special feature instructions]),
|
||||
AM_COND_IF([GENERIC],
|
||||
[
|
||||
enable_untuned="yes"
|
||||
AC_MSG_RESULT([yes])
|
||||
RB_DEFINE([UNTUNED], [1], [Building binary without extended-feature cpu instructions.])
|
||||
], [
|
||||
enable_untuned="no"
|
||||
AC_MSG_RESULT([no])
|
||||
RB_DEFINE([GENERIC], [1], [Building binary tuned for generic architectures])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([UNTUNED], [[[[ "$enable_untuned" = "yes" ]]]])
|
||||
dnl
|
||||
dnl Tuned compilation
|
||||
dnl
|
||||
|
||||
machine=""
|
||||
AC_MSG_CHECKING(whether to emit specific architecture features)
|
||||
AC_ARG_WITH(machine, RB_HELP_STRING([--with-machine], [Emit special feature instructions]),
|
||||
[
|
||||
if [[ "$withval" != "yes" ]]; then
|
||||
machine=$withval
|
||||
fi
|
||||
])
|
||||
|
||||
if [[ ! -z "$machine" ]]; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Disable third-party allocators
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to allow available third-party allocator libraries from being used)
|
||||
AC_ARG_ENABLE(malloc-libs, RB_HELP_STRING([--disable-malloc-libs], [Disable third-party dynamic memory libraries (jemalloc/tcmalloc/etc)]),
|
||||
AC_ARG_ENABLE(malloc-libs, RB_HELP_STRING([--enable-malloc-libs], [Enable third-party dynamic memory libraries (jemalloc/tcmalloc/etc)]),
|
||||
[
|
||||
use_malloc_libs=$enableval
|
||||
AC_MSG_RESULT([$enableval])
|
||||
], [
|
||||
use_malloc_libs="yes"
|
||||
AC_MSG_RESULT([yes])
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$use_malloc_libs])
|
||||
AM_CONDITIONAL([MALLOC_LIBS], [[[[ "$use_malloc_libs" = "yes" ]]]])
|
||||
|
||||
dnl
|
||||
|
@ -475,6 +534,7 @@ AC_ARG_ENABLE(lowmem-compile, RB_HELP_STRING([--enable-lowmem-compile], [Enable
|
|||
lowmem_compile="no"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$lowmem_compile])
|
||||
AM_CONDITIONAL([LOWMEM_COMPILE], [[[[ $lowmem_compile = "yes" ]]]])
|
||||
|
||||
dnl
|
||||
|
@ -719,16 +779,20 @@ AM_COND_IF([GCC],
|
|||
[
|
||||
RB_VAR_PREPEND([CXXFLAGS], ["-fstack-protector-explicit"])
|
||||
|
||||
dnl These flags should not be used on Intel-CET capable platforms
|
||||
dnl TODO: XXX
|
||||
AS_IF([test "$CXX_EPOCH" -ge "9"],
|
||||
AS_CASE([$host_cpu],
|
||||
[x86_64],
|
||||
[
|
||||
AM_COND_IF([GENERIC],
|
||||
dnl These flags should not be used on Intel-CET capable platforms
|
||||
dnl TODO: XXX
|
||||
AS_IF([test "$CXX_EPOCH" -ge "9"],
|
||||
[
|
||||
RB_VAR_PREPEND([CXXFLAGS], ["-fcf-protection=full"])
|
||||
], [
|
||||
RB_VAR_PREPEND([CXXFLAGS], ["-fcf-protection=none"])
|
||||
RB_VAR_PREPEND([CXXFLAGS], ["-mmanual-endbr"])
|
||||
AM_COND_IF([GENERIC],
|
||||
[
|
||||
RB_VAR_PREPEND([CXXFLAGS], ["-fcf-protection=return"])
|
||||
], [
|
||||
RB_VAR_PREPEND([CXXFLAGS], ["-fcf-protection=none"])
|
||||
RB_VAR_PREPEND([CXXFLAGS], ["-mmanual-endbr"])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
@ -742,40 +806,83 @@ dnl
|
|||
dnl Machine Tuning
|
||||
dnl
|
||||
|
||||
TUNE_FLAGS=""
|
||||
AM_COND_IF([UNTUNED],
|
||||
MACHINE_FLAGS=""
|
||||
|
||||
dnl Initial machine
|
||||
machine_arch="native"
|
||||
machine_tune="native"
|
||||
|
||||
AM_COND_IF([CLANG],
|
||||
[
|
||||
machine_tuning="generic ${host_cpu} and untuned"
|
||||
RB_VAR_PREPEND([TUNE_FLAGS], ["-mno-default"])
|
||||
], [
|
||||
AM_COND_IF([GENERIC],
|
||||
AS_IF([test "$CXX_EPOCH" -lt "15"],
|
||||
[
|
||||
machine_tuning="generic ${host_cpu}"
|
||||
RB_VAR_PREPEND([TUNE_FLAGS], ["-mtune=generic"])
|
||||
], [
|
||||
machine_tuning="${host_cpu} native"
|
||||
|
||||
AS_CASE([$host_cpu],
|
||||
[x86_64],
|
||||
AS_IF([test "$host_cpu" = "aarch64"],
|
||||
[
|
||||
dnl AMD K10's SSE4a doesn't work with valgrind
|
||||
RB_VAR_PREPEND([TUNE_FLAGS], ["-mno-sse4a"])
|
||||
|
||||
dnl Not accepted by clang on aarch64
|
||||
RB_VAR_PREPEND([TUNE_FLAGS], ["-march=native"])
|
||||
machine_arch=""
|
||||
])
|
||||
|
||||
RB_VAR_PREPEND([TUNE_FLAGS], ["-mtune=native"])
|
||||
])
|
||||
])
|
||||
|
||||
RB_VAR_PREPEND([CXXFLAGS], ["$TUNE_FLAGS"])
|
||||
AM_COND_IF([GENERIC],
|
||||
[
|
||||
machine_tune="generic"
|
||||
AS_CASE([$host_cpu],
|
||||
[x86_64],
|
||||
[
|
||||
machine_arch="x86-64"
|
||||
])
|
||||
])
|
||||
|
||||
dnl Specific extension specification
|
||||
machine_feat=""
|
||||
for feature in $machine; do
|
||||
if [[ $(echo $feature | cut -d"=" -f1) == "arch" ]]; then
|
||||
machine_arch=$(echo $feature | cut -d"=" -f2)
|
||||
elif [[ $(echo $feature | cut -d"=" -f1) == "tune" ]]; then
|
||||
machine_tune=$(echo $feature | cut -d"=" -f2)
|
||||
else
|
||||
machine_feat="$feature $machine_feat"
|
||||
RB_VAR_PREPEND([MACHINE_FLAGS], [-m${feature}])
|
||||
fi
|
||||
done
|
||||
|
||||
dnl Ensures mtune=generic accompanies one of the generic march= options
|
||||
dnl even if --enable-generic wasn't given, otherwise gcc will reject.
|
||||
AM_COND_IF_NOT([GENERIC],
|
||||
[
|
||||
AS_CASE([$machine_arch],
|
||||
[x86-64*],
|
||||
[
|
||||
machine_tune="generic"
|
||||
], [
|
||||
machine_tune=$machine_arch
|
||||
])
|
||||
])
|
||||
|
||||
dnl Specific extension underrides
|
||||
AS_CASE([$host_cpu],
|
||||
[x86_64],
|
||||
[
|
||||
dnl AMD K10's SSE4a doesn't work with valgrind
|
||||
RB_VAR_PREPEND([MACHINE_FLAGS], [-mno-sse4a])
|
||||
])
|
||||
|
||||
if [[ ! -z "$machine_tune" ]]; then
|
||||
RB_VAR_PREPEND([MACHINE_FLAGS], [-mtune=$machine_tune])
|
||||
fi
|
||||
|
||||
if [[ ! -z "$machine_arch" ]]; then
|
||||
RB_VAR_PREPEND([MACHINE_FLAGS], [-march=$machine_arch])
|
||||
fi
|
||||
|
||||
machine_tuning="${host_cpu} arch=$machine_arch tune=$machine_tune :$machine_feat"
|
||||
RB_VAR_PREPEND([CXXFLAGS], [$MACHINE_FLAGS])
|
||||
|
||||
dnl Get the target features for this build from gcc into a readable string
|
||||
AM_COND_IF([GCC],
|
||||
[
|
||||
_cxx=$(echo "${CXX}" | cut -d' ' -f1)
|
||||
_cmd="${_cxx} -Q --help=target ${TUNE_FLAGS}"
|
||||
_cmd="${_cxx} -Q --help=target ${MACHINE_FLAGS}"
|
||||
machine_features=$(${_cmd} | grep enabled | grep -v 'mno-')
|
||||
machine_features=$(printf "\n${machine_features}")
|
||||
])
|
||||
|
@ -785,7 +892,7 @@ AM_COND_IF([CLANG],
|
|||
[
|
||||
_flag=0
|
||||
_cxx=$(echo "${CXX}" | cut -d' ' -f1)
|
||||
_str=$(${_cxx} -E ${TUNE_FLAGS} - -### 2>&1)
|
||||
_str=$(${_cxx} -E ${MACHINE_FLAGS} - -### 2>&1)
|
||||
machine_features=""
|
||||
for i in $_str; do
|
||||
if [[ $i == '"-target-feature"' ]]; then
|
||||
|
@ -804,22 +911,24 @@ dnl
|
|||
dnl Compiler warnings
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING(whether to disable warnings)
|
||||
AC_MSG_CHECKING(whether to enable warnings)
|
||||
AC_ARG_ENABLE(warnings,
|
||||
RB_HELP_STRING([--disable-warnings], [Disable all sorts of warnings like a rockstar]),
|
||||
RB_HELP_STRING([--enable-warnings], [Disable all sorts of warnings like a rockstar]),
|
||||
[
|
||||
AC_MSG_RESULT([$enableval])
|
||||
warnings="$enableval"
|
||||
warnings=$enableval
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
warnings="yes"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$warnings])
|
||||
AM_CONDITIONAL([WARNINGS], [[[[ "$warnings" = "yes" ]]]])
|
||||
|
||||
AC_DEFUN([RB_MAYBE_CWARN],
|
||||
[
|
||||
if test x"$warnings" == x"yes"; then
|
||||
AM_COND_IF([WARNINGS],
|
||||
[
|
||||
RB_MAYBE_CXXFLAG([$1], [$2])
|
||||
fi
|
||||
])
|
||||
])
|
||||
|
||||
STACK_USAGE_WARNING=16384
|
||||
|
@ -842,11 +951,9 @@ RB_MAYBE_CWARN([-Wstrict-aliasing=2 -Wstrict-overflow=5], charybdis_cv_c_gcc_w_s
|
|||
RB_MAYBE_CWARN([-Wdisabled-optimization], charybdis_cv_c_gcc_w_disabled_optimization)
|
||||
RB_MAYBE_CWARN([-Winvalid-pch], charybdis_cv_c_gcc_w_invalid_pch)
|
||||
RB_MAYBE_CWARN([-Winit-self], charybdis_cv_c_gcc_w_init_self)
|
||||
RB_MAYBE_CWARN([-Wuninitialized], charybdis_cv_c_gcc_w_uninitialized)
|
||||
RB_MAYBE_CWARN([-Wunreachable-code], charybdis_cv_c_gcc_w_unreachable_code)
|
||||
RB_MAYBE_CWARN([-Wno-overloaded-virtual], charybdis_cv_c_gcc_w_overloaded_virtual)
|
||||
RB_MAYBE_CWARN([-Wnon-virtual-dtor], charybdis_cv_c_gcc_w_non_virtual_dtor)
|
||||
RB_MAYBE_CWARN([-Wnoexcept], charybdis_cv_c_gcc_w_noexcept)
|
||||
RB_MAYBE_CWARN([-Wsized-deallocation], charybdis_cv_c_gcc_w_sized_deallocation)
|
||||
RB_MAYBE_CWARN([-Wctor-dtor-privacy], charybdis_cv_c_gcc_w_ctor_dtor_privacy)
|
||||
RB_MAYBE_CWARN([-Wsign-promo], charybdis_cv_c_gcc_w_sign_promo)
|
||||
|
@ -861,6 +968,7 @@ RB_MAYBE_CWARN([-Wodr], charybdis_cv_c_gcc_w_odr)
|
|||
RB_MAYBE_CWARN([-Wimplicit-fallthrough], charybdis_cv_c_gcc_w_implicit_fallthrough)
|
||||
|
||||
RB_MAYBE_CWARN([-Werror=return-type], charybdis_cv_c_gcc_w_error_return_type)
|
||||
RB_MAYBE_CWARN([-Werror=reorder], charybdis_cv_c_gcc_w_error_reorder)
|
||||
|
||||
dnl Compiler specific
|
||||
AM_COND_IF([GCC],
|
||||
|
@ -874,22 +982,13 @@ AM_COND_IF([GCC],
|
|||
RB_MAYBE_CWARN([-Walloca], charybdis_cv_c_gcc_w_alloca)
|
||||
RB_MAYBE_CWARN([-Wvector-operation-performance], charybdis_cv_c_gcc_w_vector_operation_performance)
|
||||
RB_MAYBE_CWARN([-Wstringop-overflow=4], charybdis_cv_c_gcc_w_stringop_overflow)
|
||||
|
||||
AM_COND_IF([DEBUG],
|
||||
[
|
||||
RB_MAYBE_CWARN([-Wsuggest-attribute=format], charybdis_cv_c_gcc_w_suggest_attribute_format)
|
||||
RB_MAYBE_CWARN([-Wsuggest-attribute=noreturn], charybdis_cv_c_gcc_w_suggest_attribute_noreturn)
|
||||
RB_MAYBE_CWARN([-Wsuggest-attribute=malloc], charybdis_cv_c_gcc_w_suggest_attribute_malloc)
|
||||
RB_MAYBE_CWARN([-Wsuggest-attribute=cold], charybdis_cv_c_gcc_w_suggest_attribute_cold)
|
||||
dnl RB_MAYBE_CWARN([-Wsuggest-attribute=pure], charybdis_cv_c_gcc_w_suggest_attribute_pure)
|
||||
dnl RB_MAYBE_CWARN([-Wsuggest-attribute=const], charybdis_cv_c_gcc_w_suggest_attribute_const)
|
||||
])
|
||||
])
|
||||
|
||||
dnl Compiler specific
|
||||
AM_COND_IF([CLANG],
|
||||
[
|
||||
RB_MAYBE_CWARN([-Werror=return-stack-address], charybdis_cv_c_gcc_w_error_return_stack_address)
|
||||
RB_MAYBE_CWARN([-Werror=abstract-final-class], charybdis_cv_c_gcc_w_error_abstract_final_class)
|
||||
|
||||
RB_MAYBE_CWARN([-Wundefined-reinterpret-cast], charybdis_cv_c_gcc_w_undefined_reinterpret_cast)
|
||||
RB_MAYBE_CWARN([-Wconditional-uninitialized], charybdis_cv_c_gcc_w_conditional_uninitialized)
|
||||
|
@ -916,6 +1015,8 @@ RB_MAYBE_CWARN([-Wno-unused-label], charybdis_cv_c_gcc_w_unused_label)
|
|||
RB_MAYBE_CWARN([-Wno-unused-value], charybdis_cv_c_gcc_w_unused_value)
|
||||
RB_MAYBE_CWARN([-Wno-unused-variable], charybdis_cv_c_gcc_w_unused_variable)
|
||||
RB_MAYBE_CWARN([-Wno-unused-parameter], charybdis_cv_c_gcc_w_unused_parameter)
|
||||
dnl Re-enable -Wunused-result so explicit annotations will still warn.
|
||||
RB_MAYBE_CWARN([-Wunused-result], charybdis_cv_c_gcc_w_unused_result)
|
||||
|
||||
dnl This warning is disabled to allow preprocessor statements like #endif to
|
||||
dnl contain text on the same line. This is used for example to write the
|
||||
|
@ -933,12 +1034,27 @@ AM_COND_IF([DEBUG],
|
|||
RB_MAYBE_CWARN([-Wsuggest-final-methods], charybdis_cv_c_gcc_w_suggest_final_methods)
|
||||
RB_MAYBE_CWARN([-Wsuggest-override], charybdis_cv_c_gcc_w_suggest_override)
|
||||
RB_MAYBE_CWARN([-Wmissing-noreturn], charybdis_cv_c_gcc_w_missing_noreturn)
|
||||
RB_MAYBE_CWARN([-Wuninitialized], charybdis_cv_c_gcc_w_uninitialized)
|
||||
|
||||
AM_COND_IF([GCC],
|
||||
[
|
||||
RB_MAYBE_CWARN([-Wnoexcept], charybdis_cv_c_gcc_w_noexcept)
|
||||
RB_MAYBE_CWARN([-Wsuggest-attribute=format], charybdis_cv_c_gcc_w_suggest_attribute_format)
|
||||
RB_MAYBE_CWARN([-Wsuggest-attribute=noreturn], charybdis_cv_c_gcc_w_suggest_attribute_noreturn)
|
||||
RB_MAYBE_CWARN([-Wsuggest-attribute=malloc], charybdis_cv_c_gcc_w_suggest_attribute_malloc)
|
||||
RB_MAYBE_CWARN([-Wsuggest-attribute=cold], charybdis_cv_c_gcc_w_suggest_attribute_cold)
|
||||
dnl RB_MAYBE_CWARN([-Wsuggest-attribute=pure], charybdis_cv_c_gcc_w_suggest_attribute_pure)
|
||||
dnl RB_MAYBE_CWARN([-Wsuggest-attribute=const], charybdis_cv_c_gcc_w_suggest_attribute_const)
|
||||
])
|
||||
], [
|
||||
RB_MAYBE_CWARN([-Wno-unknown-pragmas], charybdis_cv_c_gcc_w_no_unknown_pragmas)
|
||||
RB_MAYBE_CWARN([-Wno-deprecated-declarations], charybdis_cv_c_gcc_w_no_deprecated_declarations)
|
||||
RB_MAYBE_CWARN([-Wno-deprecated], charybdis_cv_c_gcc_w_no_deprecated)
|
||||
|
||||
AM_COND_IF([CLANG],
|
||||
[
|
||||
RB_MAYBE_CWARN([-Wno-unknown-attributes], charybdis_cv_c_gcc_w_no_unknown_attributes)
|
||||
RB_MAYBE_CWARN([-Wno-uninitialized], charybdis_cv_c_gcc_w_no_uninitialized)
|
||||
])
|
||||
|
||||
AM_COND_IF([GCC],
|
||||
|
@ -946,6 +1062,7 @@ AM_COND_IF([DEBUG],
|
|||
RB_MAYBE_CWARN([-Wno-ignored-attributes], charybdis_cv_c_gcc_w_no_ignored_attributes)
|
||||
RB_MAYBE_CWARN([-Wno-attributes], charybdis_cv_c_gcc_w_no_attributes)
|
||||
RB_MAYBE_CWARN([-Wno-pragmas], charybdis_cv_c_gcc_w_no_pragmas)
|
||||
RB_MAYBE_CWARN([-Wno-empty-body], charybdis_cv_c_gcc_w_no_empty_body)
|
||||
])
|
||||
])
|
||||
|
||||
|
@ -958,6 +1075,7 @@ AC_MSG_CHECKING(whether to enable warning discovery)
|
|||
AC_ARG_ENABLE(every-warning,
|
||||
RB_HELP_STRING([--enable-every-warning], [Enable warning discovery (-Weverything)]),
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
RB_MAYBE_CWARN([-Weverything], charybdis_cv_c_gcc_w_everything)
|
||||
|
||||
dnl Ignored a priori
|
||||
|
@ -995,9 +1113,11 @@ RB_HELP_STRING([--enable-every-warning], [Enable warning discovery (-Weverything
|
|||
dnl Ignored with issue high priority
|
||||
RB_MAYBE_CWARN([-Wno-reserved-identifier], charybdis_cv_c_gcc_w_no_reserved_identifier)
|
||||
RB_MAYBE_CWARN([-Wno-reserved-macro-identifier], charybdis_cv_c_gcc_w_no_reserved_macro_identifier)
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
AM_COND_IF_NOT([UNTUNED],
|
||||
AM_COND_IF_NOT([GENERIC],
|
||||
[
|
||||
dnl When tuning for a specific target ignore the ABI compat warnings
|
||||
RB_MAYBE_CWARN([-Wno-psabi], charybdis_cv_c_gcc_w_psabi)
|
||||
|
@ -1095,7 +1215,7 @@ AC_TYPE_INTPTR_T
|
|||
AC_TYPE_UINTPTR_T
|
||||
|
||||
dnl C standard type sizes on this platform
|
||||
AC_CHECK_SIZEOF([char])
|
||||
RB_CHECK_SIZEOF([char], 1)
|
||||
AC_CHECK_SIZEOF([short])
|
||||
AC_CHECK_SIZEOF([int])
|
||||
AC_CHECK_SIZEOF([float])
|
||||
|
@ -1321,19 +1441,20 @@ dnl
|
|||
dnl ip6
|
||||
dnl
|
||||
|
||||
AC_ARG_ENABLE(ipv6, RB_HELP_STRING([--disable-ipv6], [Disable IPv6 support]),
|
||||
AC_ARG_ENABLE(ipv6, RB_HELP_STRING([--enable-ipv6], [Enable IPv6 support]),
|
||||
[
|
||||
ipv6=$enableval
|
||||
], [
|
||||
ipv6="yes"
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([HAVE_IPV6], [[[[ "$ipv6" = "yes" ]]]])
|
||||
AM_CONDITIONAL([IPV6], [[[[ "$ipv6" = "yes" ]]]])
|
||||
|
||||
AM_COND_IF(HAVE_IPV6,
|
||||
AM_COND_IF(IPV6,
|
||||
[
|
||||
AC_DEFINE([HAVE_IPV6], [1], [IPv6 is supported])
|
||||
],[])
|
||||
AC_SUBST(IPV6, 1)
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl netdb / libnss_db
|
||||
|
@ -1392,12 +1513,14 @@ dnl
|
|||
|
||||
AM_COND_IF(LINUX,
|
||||
[
|
||||
AC_ARG_ENABLE(aio, RB_HELP_STRING([--disable-aio], [Disable kernel AIO support]),
|
||||
AC_ARG_ENABLE(aio, RB_HELP_STRING([--enable-aio], [Enable kernel AIO support]),
|
||||
[
|
||||
aio=$enableval
|
||||
], [
|
||||
aio=yes
|
||||
aio="yes"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$aio])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([AIO], [test "x$aio" = "xyes" ])
|
||||
|
@ -1415,12 +1538,14 @@ dnl
|
|||
|
||||
AM_COND_IF(LINUX,
|
||||
[
|
||||
AC_ARG_ENABLE(iou, RB_HELP_STRING([--disable-iou], [Disable kernel io_uring support]),
|
||||
AC_ARG_ENABLE(iou, RB_HELP_STRING([--enable-iou], [Enable kernel io_uring support]),
|
||||
[
|
||||
iou=$enableval
|
||||
], [
|
||||
iou=yes
|
||||
iou="yes"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$iou])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([IOU], [test "x$iou" = "xyes" ])
|
||||
|
@ -2289,20 +2414,15 @@ PKG_CHECK_MODULES(jemalloc, [jemalloc],
|
|||
])
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(whether to disable use of any found jemalloc)
|
||||
AC_ARG_ENABLE(jemalloc, RB_HELP_STRING([--disable-jemalloc], [Disable jemalloc as third-party dynamic memory manager]),
|
||||
AC_MSG_CHECKING(whether to enable use of any found jemalloc)
|
||||
AC_ARG_ENABLE(jemalloc, RB_HELP_STRING([--enable-jemalloc], [Enable jemalloc as dynamic memory manager]),
|
||||
[
|
||||
enable_jemalloc=$enableval
|
||||
if test "$enable_jemalloc" = "no"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
enable_jemalloc="yes"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$enable_jemalloc])
|
||||
AM_CONDITIONAL([JEMALLOC], [test "x$have_jemalloc" = "xyes" && test "x$enable_jemalloc" = "xyes" ])
|
||||
|
||||
dnl
|
||||
|
@ -2478,16 +2598,15 @@ dnl pop
|
|||
CPPFLAGS=$restore_cppflags
|
||||
LDFLAGS=$restore_ldflags
|
||||
|
||||
AC_MSG_CHECKING(whether to disable use of any found ROCm)
|
||||
AC_ARG_ENABLE(rocm, RB_HELP_STRING([--disable-rocm], [Disable ROCm support]),
|
||||
AC_MSG_CHECKING(whether to enable use of any found ROCm)
|
||||
AC_ARG_ENABLE(rocm, RB_HELP_STRING([--enable-rocm], [Enable ROCm support]),
|
||||
[
|
||||
AC_MSG_RESULT([$enableval])
|
||||
enable_rocm=$enableval
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
enable_rocm="yes"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$enable_rocm])
|
||||
AM_CONDITIONAL([ROCM], [test "x$have_rocm" = "xyes" && test "x$enable_rocm" = "xyes" ])
|
||||
|
||||
AM_COND_IF([ROCM],
|
||||
|
@ -2544,16 +2663,15 @@ dnl pop
|
|||
CPPFLAGS=$restore_cppflags
|
||||
LDFLAGS=$restore_ldflags
|
||||
|
||||
AC_MSG_CHECKING(whether to disable use of any found GPA)
|
||||
AC_ARG_ENABLE(gpa, RB_HELP_STRING([--disable-gpa], [Disable GPA support]),
|
||||
AC_MSG_CHECKING(whether to enable use of any found GPA)
|
||||
AC_ARG_ENABLE(gpa, RB_HELP_STRING([--enable-gpa], [Enable GPA support]),
|
||||
[
|
||||
AC_MSG_RESULT([$enableval])
|
||||
enable_gpa=$enableval
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
enable_gpa="yes"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$enable_gpa])
|
||||
AM_CONDITIONAL([GPA], [test "x$have_gpa" = "xyes" && test "x$enable_gpa" = "xyes" ])
|
||||
|
||||
AM_COND_IF([GPA],
|
||||
|
@ -2601,22 +2719,19 @@ PKG_CHECK_MODULES(OpenCL, [OpenCL],
|
|||
])
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(whether to disable use of any found OpenCL)
|
||||
AC_ARG_ENABLE(opencl, RB_HELP_STRING([--disable-opencl], [Disable OpenCL support]),
|
||||
AC_MSG_CHECKING(whether to enable use of any found OpenCL)
|
||||
AC_ARG_ENABLE(opencl, RB_HELP_STRING([--enable-opencl], [Enable OpenCL support]),
|
||||
[
|
||||
AC_MSG_RESULT([$enableval])
|
||||
enable_opencl=$enableval
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
enable_opencl="yes"
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(whether to enable use of any found OpenCL)
|
||||
AC_MSG_RESULT([$enable_opencl])
|
||||
AM_CONDITIONAL([OPENCL], [test "x$have_opencl" = "xyes" && test "x$enable_opencl" = "xyes" ])
|
||||
|
||||
AM_COND_IF([OPENCL],
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
IRCD_DEFINE(USE_OPENCL, [1], [OpenCL support is available and enabled])
|
||||
RB_VAR_APPEND([OPENCL_LIBS], ["-lOpenCL"])
|
||||
], [
|
||||
|
@ -2661,15 +2776,14 @@ PKG_CHECK_MODULES(armnn, [armnn],
|
|||
])
|
||||
|
||||
AC_MSG_CHECKING(whether to enable use of any found ArmNN)
|
||||
AC_ARG_ENABLE(armnn, RB_HELP_STRING([--disable-armnn], [Disable Arm NN support]),
|
||||
AC_ARG_ENABLE(armnn, RB_HELP_STRING([--enable-armnn], [Enable Arm NN support]),
|
||||
[
|
||||
AC_MSG_RESULT([$enableval])
|
||||
enable_armnn=$enableval
|
||||
], [
|
||||
AC_MSG_RESULT([yes])
|
||||
enable_armnn="yes"
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$enable_armnn])
|
||||
AM_CONDITIONAL([ARMNN], [test "x$have_armnn" = "xyes" && test "x$enable_armnn" = "xyes" ])
|
||||
|
||||
AM_COND_IF([ARMNN],
|
||||
|
@ -3151,6 +3265,7 @@ echo "Linker flags (LDFLAGS) ............ $LDFLAGS"
|
|||
echo
|
||||
echo "Developer platform (build) ........ $build_cpu $build_vendor $build_os"
|
||||
echo "Target platform (host) ............ $host_cpu $host_vendor $host_os"
|
||||
echo "Target clones ..................... $clones"
|
||||
echo "Target features ................... $machine_tuning $machine_features"
|
||||
echo
|
||||
echo "Precompile headers ................ $build_pch"
|
||||
|
|
|
@ -32,6 +32,7 @@ AM_LDFLAGS = \
|
|||
-Wl,--rosegment \
|
||||
-Wl,-z,noexecstack \
|
||||
-Wl,--wrap=epoll_wait \
|
||||
-Wl,--wrap=io_uring_queue_init \
|
||||
-L$(top_srcdir)/ircd \
|
||||
-L$(top_srcdir)/modules \
|
||||
$(PLATFORM_LDFLAGS) \
|
||||
|
|
|
@ -278,7 +278,15 @@ catch(const std::out_of_range &e)
|
|||
}
|
||||
catch(const bad_command &e)
|
||||
{
|
||||
std::cerr << "Bad command or file name: " << e.what() << std::endl;
|
||||
const ircd::string_view what(e.what());
|
||||
|
||||
std::cerr << "\nBad command";
|
||||
if(what)
|
||||
std::cerr << " :" << what;
|
||||
else
|
||||
std::cerr << '.';
|
||||
|
||||
std::cerr << std::endl;
|
||||
return true;
|
||||
}
|
||||
catch(const http::error &e)
|
||||
|
@ -348,6 +356,9 @@ construct::console::handle_line_bymodule()
|
|||
append(*record_fd, string_view(cmdline));
|
||||
}
|
||||
|
||||
if(empty(str))
|
||||
return;
|
||||
|
||||
append(*record_fd, str);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ bool yes6;
|
|||
bool norun;
|
||||
bool nomain;
|
||||
bool read_only;
|
||||
bool write_avoid;
|
||||
bool slave;
|
||||
std::array<bool, 6> smoketest;
|
||||
bool megatest;
|
||||
|
@ -50,6 +49,8 @@ const char *bootstrap;
|
|||
const char *diagnostic;
|
||||
bool nobanner;
|
||||
bool silentmode;
|
||||
bool noiouct;
|
||||
bool noioust;
|
||||
|
||||
lgetopt opts[]
|
||||
{
|
||||
|
@ -75,7 +76,6 @@ lgetopt opts[]
|
|||
{ "norun", &norun, lgetopt::BOOL, "[debug] Initialize but never run the event loop" },
|
||||
{ "nomain", &nomain, lgetopt::BOOL, "[debug] Initialize and run without entering ircd::main()" },
|
||||
{ "ro", &read_only, lgetopt::BOOL, "Read-only mode. No writes to database allowed" },
|
||||
{ "wa", &write_avoid, lgetopt::BOOL, "Like read-only mode, but writes permitted if triggered" },
|
||||
{ "slave", &slave, lgetopt::BOOL, "Like read-only mode; allows multiple instances of server" },
|
||||
{ "smoketest", &smoketest[0], lgetopt::BOOL, "Starts and stops the daemon to return success" },
|
||||
{ "megatest", &megatest, lgetopt::BOOL, "Trap execution every millionth tick for diagnostic and statistics." },
|
||||
|
@ -87,6 +87,8 @@ lgetopt opts[]
|
|||
{ "diagnostic", &diagnostic, lgetopt::STRING, "Specify a diagnostic type in conjunction with other commands" },
|
||||
{ "nobanner", &nobanner, lgetopt::BOOL, "Terminal log enabled only in runlevel RUN" },
|
||||
{ "silent", &silentmode, lgetopt::BOOL, "Like quiet mode without console output either" },
|
||||
{ "noiouct", &noiouct, lgetopt::BOOL, "Disable experimental IORING_SETUP_COOP_TASKRUN" },
|
||||
{ "noioust", &noioust, lgetopt::BOOL, "Disable experimental IORING_SETUP_SINGLE_ISSUER" },
|
||||
{ nullptr, nullptr, lgetopt::STRING, nullptr },
|
||||
};
|
||||
|
||||
|
@ -556,10 +558,11 @@ applyargs()
|
|||
ircd::db::auto_deletion.set("false");
|
||||
}
|
||||
|
||||
if(single && !bootstrap)
|
||||
if(single)
|
||||
{
|
||||
ircd::write_avoid.set("true");
|
||||
ircd::maintenance.set("true");
|
||||
cmdline = !debugmode;
|
||||
nobackfill = true;
|
||||
}
|
||||
|
||||
if(bootstrap)
|
||||
|
@ -570,21 +573,12 @@ applyargs()
|
|||
|
||||
if(slave)
|
||||
{
|
||||
ircd::db::open_slave.set("true");
|
||||
ircd::slave.set("true");
|
||||
read_only = true; // slave implies read_only
|
||||
}
|
||||
|
||||
if(read_only)
|
||||
{
|
||||
ircd::read_only.set("true");
|
||||
write_avoid = true; // read_only implies write_avoid.
|
||||
}
|
||||
|
||||
if(write_avoid)
|
||||
{
|
||||
ircd::write_avoid.set("true");
|
||||
nobackfill = true;
|
||||
}
|
||||
|
||||
if(debugmode)
|
||||
ircd::debugmode.set("true");
|
||||
|
@ -671,3 +665,70 @@ __wrap_epoll_wait(int __epfd,
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This is where we interpose additional features for io_uring not yet
|
||||
// leveraged by ASIO.
|
||||
//
|
||||
#if IRCD_USE_ASIO_IO_URING
|
||||
|
||||
extern "C" int
|
||||
__real_io_uring_queue_init(unsigned,
|
||||
struct io_uring *,
|
||||
unsigned flags);
|
||||
|
||||
extern "C" int
|
||||
__wrap_io_uring_queue_init(unsigned entries,
|
||||
struct io_uring *ring,
|
||||
unsigned flags)
|
||||
{
|
||||
namespace info = ircd::info;
|
||||
|
||||
#if defined(IORING_SETUP_COOP_TASKRUN)
|
||||
const bool have_coop_taskrun
|
||||
{
|
||||
info::kernel_version[0] > 5 ||
|
||||
(info::kernel_version[0] >= 5 && info::kernel_version[1] >= 19)
|
||||
};
|
||||
|
||||
if(have_coop_taskrun && !noiouct)
|
||||
flags |= IORING_SETUP_COOP_TASKRUN;
|
||||
#endif
|
||||
|
||||
#if defined(IORING_SETUP_SINGLE_ISSUER)
|
||||
const bool have_single_issuer
|
||||
{
|
||||
info::kernel_version[0] > 6 ||
|
||||
(info::kernel_version[0] >= 6 && info::kernel_version[1] >= 0)
|
||||
};
|
||||
|
||||
if(have_single_issuer && !noioust)
|
||||
flags |= IORING_SETUP_SINGLE_ISSUER;
|
||||
#endif
|
||||
|
||||
struct io_uring_params params
|
||||
{
|
||||
.flags = flags,
|
||||
};
|
||||
|
||||
int ret;
|
||||
if constexpr((true))
|
||||
ret = ::io_uring_queue_init_params
|
||||
(
|
||||
entries,
|
||||
ring,
|
||||
¶ms
|
||||
);
|
||||
else
|
||||
ret = __real_io_uring_queue_init
|
||||
(
|
||||
entries,
|
||||
ring,
|
||||
flags
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
namespace fs = ircd::fs;
|
||||
using ircd::string_view;
|
||||
|
||||
decltype(construct::homeserver::primary)
|
||||
construct::homeserver::primary;
|
||||
|
||||
construct::homeserver::homeserver(struct ircd::m::homeserver::opts opts)
|
||||
try
|
||||
:opts
|
||||
|
@ -45,6 +48,8 @@ try
|
|||
}
|
||||
}
|
||||
{
|
||||
assert(!primary);
|
||||
primary = this;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
|
@ -59,4 +64,6 @@ catch(const std::exception &e)
|
|||
construct::homeserver::~homeserver()
|
||||
noexcept
|
||||
{
|
||||
assert(primary);
|
||||
primary = nullptr;
|
||||
}
|
||||
|
|
|
@ -23,4 +23,6 @@ struct construct::homeserver
|
|||
public:
|
||||
homeserver(struct ircd::m::homeserver::opts);
|
||||
~homeserver() noexcept;
|
||||
|
||||
static homeserver *primary;
|
||||
};
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#include <ircd/ircd.h> // must include because asio.h.gch is fPIC
|
||||
#include <ircd/matrix.h>
|
||||
#include <ircd/asio.h>
|
||||
#include "construct.h"
|
||||
#include "homeserver.h"
|
||||
#include "signals.h"
|
||||
#include "console.h"
|
||||
|
||||
|
@ -19,6 +20,7 @@ namespace construct
|
|||
namespace ph = std::placeholders;
|
||||
|
||||
static void handle_cont();
|
||||
static void handle_usr2();
|
||||
static void handle_usr1();
|
||||
static void handle_quit();
|
||||
static void handle_interrupt();
|
||||
|
@ -41,6 +43,7 @@ construct::signals::signals(boost::asio::io_context &ios)
|
|||
signal_set->add(SIGQUIT);
|
||||
signal_set->add(SIGTERM);
|
||||
signal_set->add(SIGUSR1);
|
||||
signal_set->add(SIGUSR2);
|
||||
signal_set->add(SIGCONT);
|
||||
set_handle();
|
||||
}
|
||||
|
@ -132,6 +135,7 @@ construct::handle_signal(const int &signum)
|
|||
case SIGQUIT: return handle_quit();
|
||||
case SIGTERM: return handle_quit();
|
||||
case SIGUSR1: return handle_usr1();
|
||||
case SIGUSR2: return handle_usr2();
|
||||
case SIGCONT: return handle_cont();
|
||||
default: break;
|
||||
}
|
||||
|
@ -225,24 +229,73 @@ try
|
|||
return;
|
||||
}
|
||||
|
||||
if(!homeserver::primary || !homeserver::primary->module[0])
|
||||
return;
|
||||
|
||||
// This signal handler (though not a *real* signal handler) is still
|
||||
// running on the main async stack and not an ircd::ctx. The reload
|
||||
// function does a lot of IO so it requires an ircd::ctx.
|
||||
ircd::context{[]
|
||||
{
|
||||
ircd::mods::import<void ()> reload_conf
|
||||
static ircd::mods::import<void (ircd::m::homeserver *)> rehash
|
||||
{
|
||||
"s_conf", "reload_conf"
|
||||
homeserver::primary->module[0], "ircd::m::homeserver::rehash"
|
||||
};
|
||||
|
||||
reload_conf();
|
||||
assert(homeserver::primary->hs);
|
||||
rehash(homeserver::primary->hs.get());
|
||||
}};
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
ircd::log::error
|
||||
{
|
||||
"SIGUSR1 handler: %s", e.what()
|
||||
"SIGUSR1 handler :%s",
|
||||
e.what()
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
construct::handle_usr2()
|
||||
try
|
||||
{
|
||||
if(ircd::run::level != ircd::run::level::RUN)
|
||||
{
|
||||
ircd::log::warning
|
||||
{
|
||||
"Not synchronizing database from SIGUSR2 in runlevel %s",
|
||||
reflect(ircd::run::level)
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ircd::slave)
|
||||
return;
|
||||
|
||||
if(!homeserver::primary || !homeserver::primary->module[0])
|
||||
return;
|
||||
|
||||
ircd::context{[]
|
||||
{
|
||||
static ircd::mods::import<bool (ircd::m::homeserver *)> refresh
|
||||
{
|
||||
homeserver::primary->module[0], "ircd::m::homeserver::refresh"
|
||||
};
|
||||
|
||||
assert(homeserver::primary->hs);
|
||||
const bool refreshed
|
||||
{
|
||||
refresh(homeserver::primary->hs.get())
|
||||
};
|
||||
}};
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
ircd::log::error
|
||||
{
|
||||
"SIGUSR2 handler :%s",
|
||||
e.what()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
FROM --platform=$TARGETPLATFORM alpine:3.16.1
|
||||
ARG dist_name alpine
|
||||
ARG dist_version 3.16
|
||||
|
||||
FROM --platform=$TARGETPLATFORM ${dist_name}:${dist_version}
|
||||
|
||||
ENV packages="\
|
||||
boost-chrono \
|
||||
|
@ -12,7 +15,6 @@ libatomic \
|
|||
libmagic \
|
||||
libsodium \
|
||||
libstdc++ \
|
||||
liburing \
|
||||
lz4 \
|
||||
openssl \
|
||||
rocksdb \
|
||||
|
@ -24,7 +26,6 @@ boost-dev \
|
|||
file-dev \
|
||||
icu-dev \
|
||||
libsodium-dev \
|
||||
liburing-dev \
|
||||
lz4-dev \
|
||||
openssl-dev \
|
||||
rocksdb-dev \
|
|
@ -1,17 +1,20 @@
|
|||
ARG acct
|
||||
ARG repo
|
||||
ARG dist_name
|
||||
ARG dist_version
|
||||
ARG feature
|
||||
ARG machine
|
||||
|
||||
FROM ${acct}/${repo}:alpine-3.16-${feature}-${TARGETARCH}
|
||||
FROM ${acct}/${repo}:${dist_name}-${dist_version}-${feature}-${machine}
|
||||
|
||||
ARG cc
|
||||
ARG cxx
|
||||
ARG extra_packages_dev
|
||||
ARG extra_packages_dev1
|
||||
ARG extra_packages_dev2
|
||||
ARG rocksdb_version 7.4.3
|
||||
ARG rocksdb_url
|
||||
ARG ctor_url https://github.com/matrix-construct/construct
|
||||
ARG machine_spec
|
||||
ARG nprocs
|
||||
|
||||
ENV CC ${cc}
|
||||
ENV CXX ${cxx}
|
||||
|
@ -20,12 +23,13 @@ ENV CONFIG_SHELL bash
|
|||
ENV rocksdb_version ${rocksdb_version}
|
||||
ENV rocksdb_url https://codeload.github.com/facebook/rocksdb/tar.gz/refs/tags/v${rocksdb_version}
|
||||
ENV ctor_url ${ctor_url}
|
||||
ENV machine_spec ${machine_spec}
|
||||
ENV nprocs ${nprocs}
|
||||
|
||||
ENV packages_dev="\
|
||||
${packages_dev} \
|
||||
autoconf \
|
||||
autoconf-archive \
|
||||
autoconf2.13 \
|
||||
automake \
|
||||
bash \
|
||||
binutils-gold \
|
||||
|
@ -34,8 +38,6 @@ curl \
|
|||
git \
|
||||
libtool \
|
||||
${extra_packages_dev} \
|
||||
${extra_packages_dev1} \
|
||||
${extra_packages_dev2} \
|
||||
"
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
@ -50,8 +52,8 @@ RUN true \
|
|||
&& ln -sv /usr/src/rocksdb construct/deps/rocksdb \
|
||||
&& cd /usr/src/construct \
|
||||
&& ./autogen.sh \
|
||||
&& (./configure --with-profile=no || (cat config.log; exit 1)) \
|
||||
&& make -j `nproc` EXTRA_LDFLAGS="-Wl,--strip-all" install \
|
||||
&& (./configure --disable-iou --enable-generic --with-machine="${machine_spec}" || (cat config.log; exit 1)) \
|
||||
&& make -j ${nprocs} EXTRA_LDFLAGS="-Wl,--strip-all" install \
|
||||
&& rm -rf /usr/src/rocksdb \
|
||||
&& rm -rf /usr/src/construct \
|
||||
&& rm -rf /usr/include/ircd \
|
|
@ -1,7 +1,10 @@
|
|||
ARG acct
|
||||
ARG repo
|
||||
ARG dist_name
|
||||
ARG dist_version
|
||||
ARG machine
|
||||
|
||||
FROM ${acct}/${repo}:alpine-3.16-base-${TARGETARCH}
|
||||
FROM ${acct}/${repo}:${dist_name}-${dist_version}-base-${machine}
|
||||
|
||||
ENV packages="\
|
||||
freetype \
|
|
@ -1,9 +1,12 @@
|
|||
ARG acct
|
||||
ARG repo
|
||||
ARG dist_name
|
||||
ARG dist_version
|
||||
ARG feature
|
||||
ARG cc
|
||||
ARG machine
|
||||
|
||||
FROM ${acct}/${repo}:alpine-3.16-${feature}-built-${cc}-${TARGETARCH}
|
||||
FROM ${acct}/${repo}:${dist_name}-${dist_version}-${feature}-built-${cc}-${machine}
|
||||
|
||||
ENV ircd_mods_unload_check=false
|
||||
WORKDIR /root
|
|
@ -1,181 +1,283 @@
|
|||
#!/bin/sh
|
||||
|
||||
BASEDIR=$(dirname "$0")
|
||||
ACCT=jevolk
|
||||
REPO=construct
|
||||
ctor_url="https://github.com/matrix-construct/construct"
|
||||
rocksdb_version=7.4.3
|
||||
# Sundry configuration
|
||||
|
||||
ARGS_=""
|
||||
ARGS_="$ARGS_ --compress=true"
|
||||
ARGS_="$ARGS_ --build-arg acct=$ACCT"
|
||||
ARGS_="$ARGS_ --build-arg repo=$REPO"
|
||||
ARGS_="$ARGS_ --build-arg ctor_url=$ctor_url"
|
||||
ARGS_="$ARGS_ --build-arg rocksdb_version=$rocksdb_version"
|
||||
BASEDIR=$(dirname "$0")
|
||||
stage=$1
|
||||
mode=$2
|
||||
|
||||
export DOCKER_BUILDKIT=1
|
||||
#export BUILDKIT_PROGRESS=plain
|
||||
if test "$CI" = true; then
|
||||
export BUILDKIT_PROGRESS="plain"
|
||||
echo "plain"
|
||||
fi
|
||||
|
||||
# The stage argument can be "base" "full" "built" "test" or "push"
|
||||
default_stage="push"
|
||||
stage=${stage:=$default_stage}
|
||||
|
||||
# The mode argument can be "real" or "test"
|
||||
default_mode="real"
|
||||
mode=${mode:=$default_mode}
|
||||
|
||||
if test "$ctor_test" = true; then
|
||||
mode="test"
|
||||
fi
|
||||
|
||||
# Account configuration environment.
|
||||
#
|
||||
# Override these for yourself.
|
||||
|
||||
default_ctor_url="https://github.com/jevolk/charybdis"
|
||||
default_ctor_id="jevolk/construct"
|
||||
|
||||
ctor_url=${ctor_url:=$default_ctor_url}
|
||||
ctor_id=${ctor_id:=$default_ctor_id}
|
||||
ctor_acct=${ctor_acct:=$(echo $ctor_id | cut -d"/" -f1)}
|
||||
ctor_repo=${ctor_repo:=$(echo $ctor_id | cut -d"/" -f2)}
|
||||
|
||||
# Job matrix configuration environment
|
||||
#
|
||||
# All combinations of these arrays will be run by this script. Overriding
|
||||
# these with one element for each variable allows this script to do one thing
|
||||
# at a time.
|
||||
|
||||
default_ctor_features="base full"
|
||||
default_ctor_distros="ubuntu-22.04 ubuntu-22.10 alpine-3.17"
|
||||
default_ctor_machines="amd64 amd64-avx amd64-avx512"
|
||||
default_ctor_toolchains="gcc-10 gcc-11 gcc-12 clang-14"
|
||||
|
||||
ctor_features=${ctor_features:=$default_ctor_features}
|
||||
ctor_distros=${ctor_distros:=$default_ctor_distros}
|
||||
ctor_machines=${ctor_machines:=$default_ctor_machines}
|
||||
ctor_toolchains=${ctor_toolchains:=$default_ctor_toolchains}
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Alpine 3.16
|
||||
#
|
||||
|
||||
#
|
||||
# L0 - Base featured image
|
||||
#
|
||||
matrix()
|
||||
{
|
||||
for ctor_feature in $ctor_features; do
|
||||
for ctor_distro in $ctor_distros; do
|
||||
for ctor_machine in $ctor_machines; do
|
||||
for ctor_toolchain in $ctor_toolchains; do
|
||||
build $ctor_feature $ctor_distro $ctor_machine $ctor_toolchain
|
||||
if test $? -ne 0; then return 1; fi
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-base-amd64 $BASEDIR/alpine/3.16/base
|
||||
build()
|
||||
{
|
||||
feature=$1
|
||||
distro=$2
|
||||
machine=$3
|
||||
toolchain=$4
|
||||
dist_name=$(echo $distro | cut -d"-" -f1)
|
||||
dist_version=$(echo $distro | cut -d"-" -f2)
|
||||
runner_name=$(echo $RUNNER_NAME | cut -d"." -f1)
|
||||
runner_num=$(echo $RUNNER_NAME | cut -d"." -f2)
|
||||
|
||||
#
|
||||
# L1 - Fully featured image
|
||||
#
|
||||
args="$ctor_docker_build_args"
|
||||
args="$args --compress=true"
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-full-amd64 $BASEDIR/alpine/3.16/full
|
||||
if test ! -z "$runner_num"; then
|
||||
cpu_num=$(expr $runner_num % $(nproc))
|
||||
args="$args --cpuset-cpus=${cpu_num}"
|
||||
args="$args --build-arg nprocs=1"
|
||||
# https://github.com/moby/buildkit/issues/1276
|
||||
else
|
||||
nprocs=$(nproc)
|
||||
args="$args --build-arg nprocs=${nprocs}"
|
||||
fi
|
||||
|
||||
#
|
||||
# L2/L3 - Built/Test images
|
||||
#
|
||||
args="$args --build-arg acct=${ctor_acct}"
|
||||
args="$args --build-arg repo=${ctor_repo}"
|
||||
args="$args --build-arg ctor_url=${ctor_url}"
|
||||
args="$args --build-arg dist_name=${dist_name}"
|
||||
args="$args --build-arg dist_version=${dist_version}"
|
||||
args="$args --build-arg machine=${machine}"
|
||||
args="$args --build-arg feature=${feature}"
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
ARGS="$ARGS --build-arg feature=base"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev=gcc"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev1=g++"
|
||||
ARGS="$ARGS --build-arg cc=gcc --build-arg cxx=g++"
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-base-built-gcc-amd64 $BASEDIR/alpine/3.16/built
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-base-test-gcc-amd64 $BASEDIR/alpine/3.16/test
|
||||
args_dist $dist_name $dist_version
|
||||
if test $? -ne 0; then return 1; fi
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
ARGS="$ARGS --build-arg feature=base"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev=clang"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev1=llvm"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev2=llvm-dev"
|
||||
ARGS="$ARGS --build-arg cc=clang --build-arg cxx=clang++"
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-base-built-clang-amd64 $BASEDIR/alpine/3.16/built
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-base-test-clang-amd64 $BASEDIR/alpine/3.16/test
|
||||
args_machine $machine
|
||||
if test $? -ne 0; then return 1; fi
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
ARGS="$ARGS --build-arg feature=full"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev=gcc"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev1=g++"
|
||||
ARGS="$ARGS --build-arg cc=gcc --build-arg cxx=g++"
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-full-built-gcc-amd64 $BASEDIR/alpine/3.16/built
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-full-test-gcc-amd64 $BASEDIR/alpine/3.16/test
|
||||
args_platform $machine
|
||||
if test $? -ne 0; then return 1; fi
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
ARGS="$ARGS --build-arg feature=full"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev=clang"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev1=llvm"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev2=llvm-dev"
|
||||
ARGS="$ARGS --build-arg cc=clang --build-arg cxx=clang++"
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-full-built-clang-amd64 $BASEDIR/alpine/3.16/built
|
||||
docker build $ARGS -t $ACCT/$REPO:alpine-3.16-full-test-clang-amd64 $BASEDIR/alpine/3.16/test
|
||||
if test $toolchain != "false"; then
|
||||
args_toolchain $toolchain $dist_name $dist_version
|
||||
if test $? -ne 0; then return 1; fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Pushed images
|
||||
#
|
||||
if test $mode = "test"; then
|
||||
cmd=$(which echo)
|
||||
else
|
||||
cmd=$(which docker)
|
||||
fi
|
||||
|
||||
docker push $ACCT/$REPO:alpine-3.16-base-built-gcc-amd64
|
||||
docker push $ACCT/$REPO:alpine-3.16-base-built-clang-amd64
|
||||
# Intermediate stage build; usually cached from prior iteration.
|
||||
tag="$ctor_acct/$ctor_repo:${distro}-${feature}-${machine}"
|
||||
arg="$args -t $tag $BASEDIR/${dist_name}/${feature}"
|
||||
eval "$cmd build $arg"
|
||||
if test $? -ne 0; then return 1; fi
|
||||
if test $stage = $feature; then return 0; fi
|
||||
if test $toolchain = "false"; then return 0; fi
|
||||
|
||||
docker push $ACCT/$REPO:alpine-3.16-full-built-gcc-amd64
|
||||
docker push $ACCT/$REPO:alpine-3.16-full-built-clang-amd64
|
||||
# Leaf build; unique to each iteration.
|
||||
tag="$ctor_acct/$ctor_repo:${distro}-${feature}-built-${toolchain}-${machine}"
|
||||
arg="$args --no-cache -t $tag $BASEDIR/${dist_name}/built"
|
||||
eval "$cmd build $arg"
|
||||
if test $? -ne 0; then return 1; fi
|
||||
if test $stage = "built"; then return 0; fi
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Ubuntu 22.04
|
||||
#
|
||||
# Test built;
|
||||
arg="$args $BASEDIR/${dist_name}/test"
|
||||
eval "$cmd build $arg"
|
||||
if test $? -ne 0; then return 1; fi
|
||||
if test $stage = "test"; then return 0; fi
|
||||
|
||||
#
|
||||
# L0 - Base featured image
|
||||
#
|
||||
# Push built
|
||||
eval "$cmd push $tag"
|
||||
if test $? -ne 0; then return 1; fi
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-base-amd64 $BASEDIR/ubuntu/22.04/base
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# L1 - Fully featured image
|
||||
#
|
||||
args_dist()
|
||||
{
|
||||
case $1 in
|
||||
alpine)
|
||||
case $2 in
|
||||
3.16)
|
||||
args="$args --build-arg rocksdb_version=7.2.2"
|
||||
return 0
|
||||
;;
|
||||
3.17)
|
||||
args="$args --build-arg rocksdb_version=7.7.3"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
ubuntu)
|
||||
case $2 in
|
||||
22.04)
|
||||
args="$args --build-arg rocksdb_version=7.4.3"
|
||||
args="$args --build-arg boost_version=1.74"
|
||||
args="$args --build-arg icu_version=70"
|
||||
return 0
|
||||
;;
|
||||
22.10)
|
||||
args="$args --build-arg rocksdb_version=7.10.2"
|
||||
args="$args --build-arg boost_version=1.74"
|
||||
args="$args --build-arg icu_version=71"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-full-amd64 $BASEDIR/ubuntu/22.04/full
|
||||
args_toolchain()
|
||||
{
|
||||
_name=$(echo $1 | cut -d"-" -f1)
|
||||
_epoch=$(echo $1 | cut -d"-" -f2)
|
||||
|
||||
#
|
||||
# L2/L3 - Build/Built/Test
|
||||
#
|
||||
case $2 in
|
||||
alpine)
|
||||
toolchain=$_name
|
||||
case $1 in
|
||||
gcc*)
|
||||
extra_dev="gcc"
|
||||
extra_dev="${extra_dev} g++"
|
||||
args="$args --build-arg extra_packages_dev=\"${extra_dev}\""
|
||||
args="$args --build-arg cc=gcc --build-arg cxx=g++"
|
||||
return 0
|
||||
;;
|
||||
clang*)
|
||||
extra_dev="clang"
|
||||
extra_dev="${extra_dev} llvm"
|
||||
extra_dev="${extra_dev} llvm-dev"
|
||||
args="$args --build-arg extra_packages_dev=\"${extra_dev}\""
|
||||
args="$args --build-arg cc=clang --build-arg cxx=clang++"
|
||||
test $3 != "3.16"
|
||||
return $?
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
ubuntu)
|
||||
case $1 in
|
||||
gcc*)
|
||||
extra_dev="gcc-${_epoch}"
|
||||
extra_dev="${extra_dev} g++-${_epoch}"
|
||||
args="$args --build-arg extra_packages_dev=\"${extra_dev}\""
|
||||
args="$args --build-arg cc=gcc-${_epoch} --build-arg cxx=g++-${_epoch}"
|
||||
return 0
|
||||
;;
|
||||
clang*)
|
||||
if test "$_epoch" -ge 15; then
|
||||
extra="mesa-opencl-icd"
|
||||
extra="${extra} ocl-icd-opencl-dev"
|
||||
extra="${extra} libclc-${_epoch}-dev"
|
||||
args="$args --build-arg extra_packages=\"${extra}\""
|
||||
fi
|
||||
extra_dev="clang-${_epoch}"
|
||||
extra_dev="${extra_dev} llvm-${_epoch}"
|
||||
extra_dev="${extra_dev} llvm-spirv-${_epoch}"
|
||||
extra_dev="${extra_dev} libclc-${_epoch}-dev"
|
||||
args="$args --build-arg extra_packages_dev=\"${extra_dev}\""
|
||||
args="$args --build-arg cc=clang-${_epoch} --build-arg cxx=clang++-${_epoch}"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
ARGS="$ARGS --build-arg feature=base"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev=gcc-9"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev1=g++-9"
|
||||
ARGS="$ARGS --build-arg cc=gcc-9 --build-arg cxx=g++-9"
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-base-build-gcc-9-amd64 $BASEDIR/ubuntu/22.04/build
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-base-built-gcc-9-amd64 $BASEDIR/ubuntu/22.04/built
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-base-test-gcc-9-amd64 $BASEDIR/ubuntu/22.04/test
|
||||
args_machine()
|
||||
{
|
||||
case $1 in
|
||||
amd64)
|
||||
args="$args --build-arg machine_spec=arch=amdfam10"
|
||||
;;
|
||||
amd64-avx)
|
||||
args="$args --build-arg machine_spec=arch=sandybridge"
|
||||
args="$args --build-arg rocksdb_avx=1"
|
||||
;;
|
||||
amd64-avx2)
|
||||
args="$args --build-arg machine_spec=arch=haswell"
|
||||
args="$args --build-arg rocksdb_avx2=1"
|
||||
;;
|
||||
amd64-avx512)
|
||||
args="$args --build-arg machine_spec=arch=skylake-avx512"
|
||||
args="$args --build-arg rocksdb_avx2=1"
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
ARGS="$ARGS --build-arg feature=base"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev=gcc-12"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev1=g++-12"
|
||||
ARGS="$ARGS --build-arg cc=gcc-12 --build-arg cxx=g++-12"
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-base-build-gcc-12-amd64 $BASEDIR/ubuntu/22.04/build
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-base-built-gcc-12-amd64 $BASEDIR/ubuntu/22.04/built
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-base-test-gcc-12-amd64 $BASEDIR/ubuntu/22.04/test
|
||||
args_platform()
|
||||
{
|
||||
case $1 in
|
||||
amd64*)
|
||||
args="$args --platform linux/amd64"
|
||||
test $(uname -m) = "x86_64"
|
||||
return $?
|
||||
;;
|
||||
arm64*)
|
||||
args="$args --platform linux/arm64"
|
||||
test $(uname -m) = "aarch64"
|
||||
return $?
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
ARGS="$ARGS_"
|
||||
ARGS="$ARGS --platform linux/amd64"
|
||||
ARGS="$ARGS --build-arg feature=full"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev=clang-15"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev1=llvm-15-dev"
|
||||
ARGS="$ARGS --build-arg extra_packages_dev2=llvm-spirv-15"
|
||||
ARGS="$ARGS --build-arg cc=clang-15 --build-arg cxx=clang++-15"
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-full-build-clang-15-amd64 $BASEDIR/ubuntu/22.04/build
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-full-built-clang-15-amd64 $BASEDIR/ubuntu/22.04/built
|
||||
docker build $ARGS -t $ACCT/$REPO:ubuntu-22.04-full-test-clang-15-amd64 $BASEDIR/ubuntu/22.04/test
|
||||
|
||||
#
|
||||
# Pushed images
|
||||
#
|
||||
|
||||
docker push $ACCT/$REPO:ubuntu-22.04-base-build-gcc-9-amd64
|
||||
docker push $ACCT/$REPO:ubuntu-22.04-base-built-gcc-9-amd64
|
||||
|
||||
docker push $ACCT/$REPO:ubuntu-22.04-base-build-gcc-12-amd64
|
||||
docker push $ACCT/$REPO:ubuntu-22.04-base-built-gcc-12-amd64
|
||||
|
||||
docker push $ACCT/$REPO:ubuntu-22.04-full-build-clang-15-amd64
|
||||
docker push $ACCT/$REPO:ubuntu-22.04-full-built-clang-15-amd64
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Ubuntu 20.04
|
||||
#
|
||||
|
||||
#docker build -t $ACCT/$REPO:ubuntu-20.04 $BASEDIR/ubuntu/20.04/base
|
||||
#docker build -t $ACCT/$REPO:ubuntu-20.04-gcc-8 $BASEDIR/ubuntu/20.04/gcc-8
|
||||
#docker build -t $ACCT/$REPO:ubuntu-20.04-gcc-9 $BASEDIR/ubuntu/20.04/gcc-9
|
||||
#docker build -t $ACCT/$REPO:ubuntu-20.04-gcc-10 $BASEDIR/ubuntu/20.04/gcc-10
|
||||
#docker build -t $ACCT/$REPO:ubuntu-20.04-clang-9 $BASEDIR/ubuntu/20.04/clang-9
|
||||
#docker build -t $ACCT/$REPO:ubuntu-20.04-clang-10 $BASEDIR/ubuntu/20.04/clang-10
|
||||
#docker build -t $ACCT/$REPO:ubuntu-20.04-clang-11 $BASEDIR/ubuntu/20.04/clang-11
|
||||
#docker build -t $ACCT/$REPO:ubuntu-20.04-clang-12 $BASEDIR/ubuntu/20.04/clang-12
|
||||
|
||||
#docker push $ACCT/$REPO:ubuntu-20.04-gcc-8
|
||||
#docker push $ACCT/$REPO:ubuntu-20.04-gcc-9
|
||||
#docker push $ACCT/$REPO:ubuntu-20.04-gcc-10
|
||||
#docker push $ACCT/$REPO:ubuntu-20.04-clang-9
|
||||
#docker push $ACCT/$REPO:ubuntu-20.04-clang-10
|
||||
#docker push $ACCT/$REPO:ubuntu-20.04-clang-11
|
||||
#docker push $ACCT/$REPO:ubuntu-20.04-clang-12
|
||||
matrix
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
FROM ubuntu:20.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN \
|
||||
apt-get update && \
|
||||
apt-get install --no-install-recommends -y software-properties-common && \
|
||||
apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
autoconf \
|
||||
autoconf-archive \
|
||||
autoconf2.13 \
|
||||
automake \
|
||||
autotools-dev \
|
||||
boost1.71 \
|
||||
build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
libbz2-dev \
|
||||
liblz4-dev \
|
||||
libgraphicsmagick1-dev \
|
||||
libicu-dev \
|
||||
libjemalloc-dev \
|
||||
libmagic-dev \
|
||||
libnss-db \
|
||||
libsodium-dev \
|
||||
libssl-dev \
|
||||
libtool \
|
||||
libzstd-dev \
|
||||
shtool \
|
||||
xz-utils && \
|
||||
apt-get purge -y software-properties-common && \
|
||||
apt-get clean && \
|
||||
apt-get autoremove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV ROCKSDB_VERSION=6.6.4
|
||||
|
||||
RUN \
|
||||
cd /usr/src && \
|
||||
curl -sL https://github.com/facebook/rocksdb/archive/v${ROCKSDB_VERSION}.tar.gz -o rocksdb-${ROCKSDB_VERSION}.tar.gz && \
|
||||
tar xfvz rocksdb-${ROCKSDB_VERSION}.tar.gz && \
|
||||
rm rocksdb-${ROCKSDB_VERSION}.tar.gz && \
|
||||
ln -s /usr/src/rocksdb-${ROCKSDB_VERSION} /usr/src/rocksdb && \
|
||||
cd /usr/src/rocksdb-${ROCKSDB_VERSION} && \
|
||||
CFLAGS="-g0" \
|
||||
cmake -H. -Bbuild \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DWITH_TESTS=0 \
|
||||
-DWITH_TOOLS=0 \
|
||||
-DUSE_RTTI=1 \
|
||||
-DWITH_LZ4=1 \
|
||||
-DWITH_GFLAGS=0 \
|
||||
-DBUILD_SHARED_LIBS=1 && \
|
||||
cmake --build build --target install && \
|
||||
rm -rf build
|
||||
|
||||
RUN mkdir /build
|
||||
WORKDIR /build
|
|
@ -1,10 +0,0 @@
|
|||
FROM jevolk/construct:ubuntu-20.04
|
||||
|
||||
ENV CC clang-10
|
||||
ENV CXX clang++-10
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y clang-10 llvm-10-dev \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
FROM jevolk/construct:ubuntu-20.04
|
||||
|
||||
ENV CC clang-11
|
||||
ENV CXX clang++-11
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y clang-11 llvm-11-dev \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
FROM jevolk/construct:ubuntu-20.04
|
||||
|
||||
ENV CC clang-12
|
||||
ENV CXX clang++-12
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y clang-12 llvm-12-dev \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
FROM jevolk/construct:ubuntu-20.04
|
||||
|
||||
ENV CC clang-9
|
||||
ENV CXX clang++-9
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y clang-9 llvm-9-dev \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
FROM jevolk/construct:ubuntu-20.04
|
||||
|
||||
ENV CXX g++-10
|
||||
ENV CC gcc-10
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y software-properties-common \
|
||||
&& apt-get update \
|
||||
&& apt-get install --no-install-recommends -y g++-10 gcc-10 \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
|
@ -1,9 +0,0 @@
|
|||
FROM jevolk/construct:ubuntu-20.04
|
||||
|
||||
ENV CXX g++-8
|
||||
ENV CC gcc-8
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y g++-8 gcc-8 \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
|
@ -1,11 +0,0 @@
|
|||
FROM jevolk/construct:ubuntu-20.04
|
||||
|
||||
ENV CXX g++-9
|
||||
ENV CC gcc-9
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y software-properties-common \
|
||||
&& apt-get update \
|
||||
&& apt-get install --no-install-recommends -y g++-9 gcc-9 \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
|
@ -1,35 +0,0 @@
|
|||
ARG acct
|
||||
ARG repo
|
||||
ARG feature
|
||||
|
||||
FROM ${acct}/${repo}:ubuntu-22.04-${feature}-${TARGETARCH}
|
||||
|
||||
ARG cc
|
||||
ARG cxx
|
||||
ARG extra_packages_dev
|
||||
ARG extra_packages_dev1
|
||||
ARG extra_packages_dev2
|
||||
ARG ctor_url https://github.com/matrix-construct/construct
|
||||
|
||||
ENV CC ${cc}
|
||||
ENV CXX ${cxx}
|
||||
ENV ctor_url ${ctor_url}
|
||||
|
||||
ENV packages_dev="\
|
||||
${packages_dev} \
|
||||
autoconf \
|
||||
autoconf-archive \
|
||||
autoconf2.13 \
|
||||
automake \
|
||||
autotools-dev \
|
||||
libtool \
|
||||
shtool \
|
||||
${extra_packages_dev} \
|
||||
${extra_packages_dev1} \
|
||||
${extra_packages_dev2} \
|
||||
"
|
||||
|
||||
RUN true \
|
||||
&& eval ${do_install} ${packages_dev} \
|
||||
&& eval ${do_clean} \
|
||||
&& true
|
|
@ -1,11 +0,0 @@
|
|||
ARG acct
|
||||
ARG repo
|
||||
ARG feature
|
||||
ARG cc
|
||||
|
||||
FROM ${acct}/${repo}:ubuntu-22.04-${feature}-built-${cc}-${TARGETARCH}
|
||||
|
||||
WORKDIR /root
|
||||
RUN true \
|
||||
&& construct -debug -smoketest localhost \
|
||||
&& true
|
|
@ -1,22 +1,35 @@
|
|||
FROM ubuntu:22.04
|
||||
ARG dist_name ubuntu
|
||||
ARG dist_version 22.04
|
||||
|
||||
FROM --platform=$TARGETPLATFORM ${dist_name}:${dist_version}
|
||||
|
||||
ARG skiprocks
|
||||
ARG rocksdb_version 7.4.5
|
||||
ARG rocksdb_url
|
||||
ARG rocksdb_avx 0
|
||||
ARG rocksdb_avx2 0
|
||||
ARG boost_version 1.74
|
||||
ARG icu_version 70
|
||||
ARG nprocs 1
|
||||
|
||||
ENV rocksdb_version ${rocksdb_version}
|
||||
ENV rocksdb_url https://codeload.github.com/facebook/rocksdb/tar.gz/refs/tags/v${rocksdb_version}
|
||||
ENV rocksdb_avx ${rocksdb_avx}
|
||||
ENV rocksdb_avx2 ${rocksdb_avx2}
|
||||
ENV boost_version ${boost_version}
|
||||
ENV icu_version ${icu_version}
|
||||
ENV nprocs ${nprocs}
|
||||
|
||||
ENV packages="\
|
||||
ca-certificates \
|
||||
libatomic1 \
|
||||
libjemalloc2 \
|
||||
libboost-chrono1.74 \
|
||||
libboost-context1.74 \
|
||||
libboost-coroutine1.74 \
|
||||
libboost-system1.74 \
|
||||
libboost-thread1.74 \
|
||||
libicu70 \
|
||||
libboost-chrono${boost_version}.0 \
|
||||
libboost-context${boost_version}.0 \
|
||||
libboost-coroutine${boost_version}.0 \
|
||||
libboost-system${boost_version}.0 \
|
||||
libboost-thread${boost_version}.0 \
|
||||
libicu${icu_version} \
|
||||
libnss-db \
|
||||
libsodium23 \
|
||||
libssl3 \
|
||||
|
@ -28,8 +41,6 @@ libzstd1 \
|
|||
ENV packages_rocksdb_dev="\
|
||||
build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
libjemalloc-dev \
|
||||
liblz4-dev \
|
||||
libzstd-dev \
|
||||
|
@ -38,11 +49,11 @@ xz-utils \
|
|||
|
||||
ENV packages_dev="\
|
||||
${packages_rocksdb_dev} \
|
||||
libboost-chrono1.74-dev \
|
||||
libboost-context1.74-dev \
|
||||
libboost-coroutine1.74-dev \
|
||||
libboost-system1.74-dev \
|
||||
libboost-thread1.74-dev \
|
||||
libboost-chrono${boost_version}-dev \
|
||||
libboost-context${boost_version}-dev \
|
||||
libboost-coroutine${boost_version}-dev \
|
||||
libboost-system${boost_version}-dev \
|
||||
libboost-thread${boost_version}-dev \
|
||||
libicu-dev \
|
||||
libmagic-dev \
|
||||
libsodium-dev \
|
||||
|
@ -52,19 +63,24 @@ libssl-dev \
|
|||
ENV rocksdb_cmake="\
|
||||
-DCMAKE_RULE_MESSAGES:BOOL=OFF \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=1 \
|
||||
-DFAIL_ON_WARNINGS=0 \
|
||||
-DUSE_RTTI=1 \
|
||||
-DPORTABLE=1 \
|
||||
-DFORCE_AVX=${rocksdb_avx} \
|
||||
-DFORCE_AVX2=${rocksdb_avx2} \
|
||||
-DWITH_JNI=0 \
|
||||
-DWITH_TESTS=0 \
|
||||
-DWITH_BENCHMARK_TOOLS=0 \
|
||||
-DWITH_TRACE_TOOLS=0 \
|
||||
-DWITH_CORE_TOOLS=0 \
|
||||
-DFAIL_ON_WARNINGS=0 \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DWITH_TOOLS=0 \
|
||||
-DWITH_GFLAGS=0 \
|
||||
-DWITH_LIBURING=0 \
|
||||
-DWITH_JEMALLOC=1 \
|
||||
-DWITH_LZ4=1 \
|
||||
-DWITH_ZSTD=1 \
|
||||
-DUSE_RTTI=1 \
|
||||
-DBUILD_SHARED_LIBS=1 \
|
||||
"
|
||||
|
||||
ENV do_install true \
|
||||
|
@ -83,6 +99,17 @@ ENV do_clean true \
|
|||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& true
|
||||
|
||||
ENV do_fetch_rocksdb true \
|
||||
&& eval ${do_install} curl \
|
||||
&& cd /usr/src \
|
||||
&& curl -sL ${rocksdb_url} -o rocksdb-${rocksdb_version}.tar.gz \
|
||||
&& tar xfz rocksdb-${rocksdb_version}.tar.gz \
|
||||
&& rm rocksdb-${rocksdb_version}.tar.gz \
|
||||
&& mv /usr/src/rocksdb-${rocksdb_version} /usr/src/rocksdb \
|
||||
&& cd - \
|
||||
&& eval ${do_purge} curl \
|
||||
&& true
|
||||
|
||||
RUN true \
|
||||
&& eval ${do_install} ${packages} \
|
||||
&& update-ca-certificates \
|
||||
|
@ -96,18 +123,15 @@ RUN true \
|
|||
exit 0; \
|
||||
fi \
|
||||
&& eval ${do_install} ${packages_rocksdb_dev} \
|
||||
&& cd /usr/src \
|
||||
&& curl -sL ${rocksdb_url} -o rocksdb-${rocksdb_version}.tar.gz \
|
||||
&& tar xfvz rocksdb-${rocksdb_version}.tar.gz \
|
||||
&& rm rocksdb-${rocksdb_version}.tar.gz \
|
||||
&& ln -s /usr/src/rocksdb-${rocksdb_version} /usr/src/rocksdb \
|
||||
&& cd /usr/src/rocksdb-${rocksdb_version} \
|
||||
&& eval ${do_fetch_rocksdb} \
|
||||
&& cd /usr/src/rocksdb \
|
||||
&& \
|
||||
CFLAGS="-g0 -ftls-model=initial-exec" \
|
||||
LDFLAGS="-Wl,--strip-all" \
|
||||
cmake -H. -Bbuild ${rocksdb_cmake} \
|
||||
&& cmake --build build --target install --parallel `nproc` \
|
||||
&& rm -rf build \
|
||||
&& cmake --build build --target install --parallel ${nprocs} \
|
||||
&& rm -rf /usr/lib/$(uname -m)-linux-gnu/librocksdb.a \
|
||||
&& rm -rf /usr/src/rocksdb \
|
||||
&& eval ${do_purge} ${packages_rocksdb_dev} \
|
||||
&& eval ${do_clean} \
|
||||
&& true
|
|
@ -1,19 +1,24 @@
|
|||
ARG acct
|
||||
ARG repo
|
||||
ARG dist_name
|
||||
ARG dist_version
|
||||
ARG feature
|
||||
ARG machine
|
||||
|
||||
FROM ${acct}/${repo}:ubuntu-22.04-${feature}-${TARGETARCH}
|
||||
FROM ${acct}/${repo}:${dist_name}-${dist_version}-${feature}-${machine}
|
||||
|
||||
ARG cc
|
||||
ARG cxx
|
||||
ARG extra_packages_dev
|
||||
ARG extra_packages_dev1
|
||||
ARG extra_packages_dev2
|
||||
ARG ctor_url https://github.com/matrix-construct/construct
|
||||
ARG machine_spec
|
||||
ARG nprocs
|
||||
|
||||
ENV CC ${cc}
|
||||
ENV CXX ${cxx}
|
||||
ENV ctor_url ${ctor_url}
|
||||
ENV machine_spec ${machine_spec}
|
||||
ENV nprocs ${nprocs}
|
||||
|
||||
ENV packages_dev="\
|
||||
${packages_dev} \
|
||||
|
@ -22,26 +27,26 @@ autoconf-archive \
|
|||
autoconf2.13 \
|
||||
automake \
|
||||
autotools-dev \
|
||||
git \
|
||||
libtool \
|
||||
shtool \
|
||||
${extra_packages_dev} \
|
||||
${extra_packages_dev1} \
|
||||
${extra_packages_dev2} \
|
||||
"
|
||||
|
||||
RUN true \
|
||||
&& eval ${do_install} ${packages_dev} \
|
||||
&& eval ${do_fetch_rocksdb} \
|
||||
&& git clone ${ctor_url} construct \
|
||||
&& cd construct \
|
||||
&& rmdir -v deps/rocksdb \
|
||||
&& ln -sv /usr/src/rocksdb deps \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure \
|
||||
&& make -j `nproc` \
|
||||
&& (./configure --enable-generic --with-machine="${machine_spec}" || (cat config.log; exit 1)) \
|
||||
&& make -j ${nprocs} \
|
||||
&& make install \
|
||||
&& cd .. \
|
||||
&& rm -rf construct \
|
||||
&& rm -rf /usr/src/rocksdb* \
|
||||
&& rm -rf /usr/src/rocksdb \
|
||||
&& eval ${do_purge} ${packages_dev} \
|
||||
&& eval ${do_clean} \
|
||||
&& true
|
|
@ -1,13 +1,17 @@
|
|||
ARG acct
|
||||
ARG repo
|
||||
ARG dist_name
|
||||
ARG dist_version
|
||||
ARG machine
|
||||
|
||||
FROM ${acct}/${repo}:ubuntu-22.04-base-${TARGETARCH}
|
||||
FROM ${acct}/${repo}:${dist_name}-${dist_version}-base-${machine}
|
||||
|
||||
ARG extra_packages
|
||||
|
||||
ENV packages="\
|
||||
libgraphicsmagick-q16-3 \
|
||||
libpng16-16 \
|
||||
mesa-opencl-icd \
|
||||
ocl-icd-opencl-dev \
|
||||
${extra_packages} \
|
||||
"
|
||||
|
||||
ENV packages_dev="\
|
14
docker/ubuntu/test/Dockerfile
Normal file
14
docker/ubuntu/test/Dockerfile
Normal file
|
@ -0,0 +1,14 @@
|
|||
ARG acct
|
||||
ARG repo
|
||||
ARG dist_name
|
||||
ARG dist_version
|
||||
ARG feature
|
||||
ARG cc
|
||||
ARG machine
|
||||
|
||||
FROM ${acct}/${repo}:${dist_name}-${dist_version}-${feature}-built-${cc}-${machine}
|
||||
|
||||
WORKDIR /root
|
||||
RUN true \
|
||||
&& construct -debug -smoketest localhost \
|
||||
&& true
|
|
@ -43,6 +43,14 @@ namespace boost
|
|||
#include <RB_INC_SYS_EPOLL_H
|
||||
#include <RB_INC_SYS_TIMERFD_H
|
||||
#include <RB_INC_SYS_EVENTFD_H
|
||||
|
||||
// Workaround io_uring_service::get_sqe() bug; see below
|
||||
#if defined(HAVE_LIBURING_H) \
|
||||
&& IRCD_USE_URING == 1 \
|
||||
&& BOOST_VERSION <= 108100
|
||||
#define LIBURING_INTERNAL
|
||||
#endif
|
||||
|
||||
#include <RB_INC_LIBURING_H
|
||||
|
||||
#pragma GCC visibility push(internal)
|
||||
|
@ -66,7 +74,7 @@ namespace boost
|
|||
|
||||
// In boost 1.79+ asio implements some filesystem operations we can use. While
|
||||
// these are available in 1.78 they were buggy for our purposes until 1.79.
|
||||
#if BOOST_VERSION >= 107900
|
||||
#if IRCD_USE_ASIO_IO_URING && BOOST_VERSION >= 107900
|
||||
#define IRCD_USE_ASIO_READ 1
|
||||
#define IRCD_USE_ASIO_WRITE 1
|
||||
#else
|
||||
|
@ -154,4 +162,20 @@ noexcept
|
|||
}
|
||||
#endif
|
||||
|
||||
// Workaround for bug in io_uring_service::get_sqe(). We have to aim upstream
|
||||
// because we can't get to it directly; this won't affect other users in the
|
||||
// address space; if LIBURING_INTERNAL ever has another meaning sometime in
|
||||
// the future hopefully the boost version will be ancient history by then...
|
||||
#if defined(LIBURING_INTERNAL)
|
||||
inline struct io_uring_sqe *
|
||||
io_uring_get_sqe(struct io_uring *const ring)
|
||||
{
|
||||
struct io_uring_sqe *sqe;
|
||||
if(likely(sqe = _io_uring_get_sqe(ring)))
|
||||
::io_uring_sqe_set_data(sqe, nullptr);
|
||||
|
||||
return sqe;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif HAVE_IRCD_ASIO_H
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_B64_H
|
||||
|
||||
#define IRCD_B64_TARGETS \
|
||||
"avx", \
|
||||
"avx2", \
|
||||
"arch=skylake-avx512", \
|
||||
"default"
|
||||
|
||||
namespace ircd::b64
|
||||
{
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
|
@ -37,13 +43,9 @@ namespace ircd::b64
|
|||
size_t encode_size(const const_buffer &in) noexcept;
|
||||
size_t encode_unpadded_size(const const_buffer &in) noexcept;
|
||||
|
||||
const_buffer decode(const mutable_buffer &out, const string_view &in);
|
||||
|
||||
template<const dictionary & = dict_rfc1421>
|
||||
string_view encode(const mutable_buffer &out, const const_buffer &in) noexcept;
|
||||
|
||||
template<const dictionary & = dict_rfc1421>
|
||||
string_view encode_unpadded(const mutable_buffer &out, const const_buffer &in) noexcept;
|
||||
const_buffer decode(const mutable_buffer out, const string_view in);
|
||||
string_view encode_unpadded(const mutable_buffer out, const const_buffer in, const dictionary = dict_rfc1421) noexcept;
|
||||
string_view encode(const mutable_buffer out, const const_buffer in, const dictionary = dict_rfc1421) noexcept;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
|
|
|
@ -32,6 +32,7 @@ struct ircd::buffer::unique_buffer
|
|||
unique_buffer() = default;
|
||||
unique_buffer(const size_t &size, const size_t &align = 0);
|
||||
explicit unique_buffer(const const_buffer &);
|
||||
template<class T> unique_buffer(unique_buffer<T> &&) noexcept;
|
||||
unique_buffer(unique_buffer &&) noexcept;
|
||||
unique_buffer(const unique_buffer &) = delete;
|
||||
unique_buffer &operator=(unique_buffer &&) & noexcept;
|
||||
|
@ -71,6 +72,19 @@ ircd::buffer::unique_buffer<buffer_type>::unique_buffer(const size_t &size,
|
|||
}
|
||||
{}
|
||||
|
||||
template<class buffer_type>
|
||||
template<class other_type>
|
||||
inline
|
||||
ircd::buffer::unique_buffer<buffer_type>::unique_buffer(unique_buffer<other_type> &&other)
|
||||
noexcept
|
||||
:buffer_type
|
||||
{
|
||||
other.release()
|
||||
}
|
||||
{
|
||||
assert(std::get<0>(other) == nullptr);
|
||||
}
|
||||
|
||||
template<class buffer_type>
|
||||
inline
|
||||
ircd::buffer::unique_buffer<buffer_type>::unique_buffer(unique_buffer &&other)
|
||||
|
|
|
@ -56,7 +56,9 @@ struct ircd::client
|
|||
size_t write_all(const net::const_buffers &);
|
||||
size_t write_all(const const_buffer &);
|
||||
void close(const net::close_opts &, net::close_callback);
|
||||
ctx::future<void> close(const net::close_opts & = {});
|
||||
void close(const net::dc, net::close_callback);
|
||||
ctx::future<void> close(const net::close_opts &);
|
||||
ctx::future<void> close(const net::dc);
|
||||
|
||||
private:
|
||||
void discard_unconsumed(const http::request::head &);
|
||||
|
@ -78,7 +80,7 @@ struct ircd::client
|
|||
client &operator=(const client &) = delete;
|
||||
~client() noexcept;
|
||||
|
||||
static void create(net::listener &, const std::shared_ptr<socket> &);
|
||||
static void create(net::acceptor &, const std::shared_ptr<socket> &);
|
||||
static size_t count(const net::ipport &remote); // cmp is by IP only, not port
|
||||
static void terminate_all();
|
||||
static void interrupt_all();
|
||||
|
@ -124,6 +126,7 @@ struct ircd::client::settings
|
|||
|
||||
static item<size_t> stack_size;
|
||||
static item<size_t> pool_size;
|
||||
static item<size_t> pool_disp;
|
||||
static item<size_t> max_client;
|
||||
static item<size_t> max_client_per_peer;
|
||||
};
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace ircd::conf
|
|||
IRCD_EXCEPTION(error, not_found)
|
||||
IRCD_EXCEPTION(error, bad_value)
|
||||
|
||||
using set_cb = std::function<void ()>;
|
||||
using set_cb = std::function<void (item<void> &)>;
|
||||
|
||||
const size_t NAME_MAX_LEN {127};
|
||||
const size_t VALUE_MAX_LEN {48_KiB};
|
||||
|
|
|
@ -23,10 +23,13 @@ namespace ircd::ctx
|
|||
/// dock is a condition variable which has no requirement for locking because
|
||||
/// the context system does not require mutual exclusion for coherence.
|
||||
///
|
||||
class ircd::ctx::dock
|
||||
struct ircd::ctx::dock
|
||||
{
|
||||
enum opts :uint;
|
||||
struct continuation;
|
||||
using predicate = std::function<bool ()>;
|
||||
|
||||
private:
|
||||
list q;
|
||||
|
||||
public:
|
||||
|
@ -34,14 +37,14 @@ class ircd::ctx::dock
|
|||
size_t size() const noexcept;
|
||||
bool waiting(const ctx &) const noexcept;
|
||||
|
||||
bool wait_until(const system_point, const predicate &);
|
||||
bool wait_until(const system_point);
|
||||
bool wait_until(const system_point, const predicate &, const opts = (opts)0);
|
||||
bool wait_until(const system_point, const opts = (opts)0);
|
||||
|
||||
template<class duration> bool wait_for(const duration, const predicate &);
|
||||
template<class duration> bool wait_for(const duration);
|
||||
template<class duration> bool wait_for(const duration, const predicate &, const opts = (opts)0);
|
||||
template<class duration> bool wait_for(const duration, const opts = (opts)0);
|
||||
|
||||
void wait(const predicate &);
|
||||
void wait();
|
||||
void wait(const predicate &, const opts = (opts)0);
|
||||
void wait(const opts = (opts)0);
|
||||
|
||||
void terminate_all() noexcept;
|
||||
void interrupt_all() noexcept;
|
||||
|
@ -52,10 +55,40 @@ class ircd::ctx::dock
|
|||
|
||||
namespace ircd::ctx
|
||||
{
|
||||
template<> bool dock::wait_for(const microseconds, const predicate &);
|
||||
template<> bool dock::wait_for(const microseconds);
|
||||
template<> bool dock::wait_for(const microseconds, const predicate &, const opts);
|
||||
template<> bool dock::wait_for(const microseconds, const opts);
|
||||
}
|
||||
|
||||
struct [[gnu::visibility("internal")]]
|
||||
ircd::ctx::dock::continuation
|
||||
{
|
||||
dock *const d;
|
||||
const opts *const o;
|
||||
|
||||
continuation(dock *, const opts &opts);
|
||||
~continuation() noexcept;
|
||||
};
|
||||
|
||||
/// Options. These are bitflags for forward compatibility with unrelated opts
|
||||
/// even though some flags are exclusive to others.
|
||||
enum ircd::ctx::dock::opts
|
||||
:uint
|
||||
{
|
||||
/// No options.
|
||||
NONE = 0x00,
|
||||
|
||||
/// Waiting context will add itself to back of queue. This is the default.
|
||||
FIFO = 0x01,
|
||||
|
||||
/// Waiting context will add itself to front of queue. The default is FIFO
|
||||
/// for fair queuing preventing starvation.
|
||||
LIFO = 0x02,
|
||||
|
||||
/// Waiting context will add itself to front if its ID is lower than the
|
||||
/// front, otherwise back.
|
||||
SORT = 0x04,
|
||||
};
|
||||
|
||||
/// Wake up the next context waiting on the dock
|
||||
inline void
|
||||
ircd::ctx::dock::notify_one()
|
||||
|
@ -70,18 +103,20 @@ noexcept
|
|||
template<class duration>
|
||||
inline bool
|
||||
ircd::ctx::dock::wait_for(const duration dur,
|
||||
const predicate &pred)
|
||||
const predicate &pred,
|
||||
const opts opts)
|
||||
{
|
||||
static_assert(!std::is_same<duration, microseconds>());
|
||||
return wait_for(duration_cast<microseconds>(dur), pred);
|
||||
return wait_for(duration_cast<microseconds>(dur), pred, opts);
|
||||
}
|
||||
|
||||
template<class duration>
|
||||
inline bool
|
||||
ircd::ctx::dock::wait_for(const duration dur)
|
||||
ircd::ctx::dock::wait_for(const duration dur,
|
||||
const opts opts)
|
||||
{
|
||||
static_assert(!std::is_same<duration, microseconds>());
|
||||
return wait_for(duration_cast<microseconds>(dur));
|
||||
return wait_for(duration_cast<microseconds>(dur), opts);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ struct ircd::ctx::future
|
|||
|
||||
bool valid() const { return !is(state(), future_state::INVALID); }
|
||||
bool operator!() const { return !valid(); }
|
||||
std::exception_ptr eptr() const { return state().eptr; }
|
||||
string_view what() const { return util::what(eptr()); }
|
||||
explicit operator T() { return get(); }
|
||||
|
||||
template<class U, class time_point> friend bool wait_until(const future<U> &, const time_point &, std::nothrow_t);
|
||||
|
@ -75,6 +77,8 @@ struct ircd::ctx::future<void>
|
|||
|
||||
bool valid() const { return !is(state(), future_state::INVALID); }
|
||||
bool operator!() const { return !valid(); }
|
||||
std::exception_ptr eptr() const { return state().eptr; }
|
||||
string_view what() const { return util::what(eptr()); }
|
||||
|
||||
template<class U, class time_point> friend bool wait_until(const future<U> &, const time_point &, std::nothrow_t);
|
||||
template<class U, class time_point> friend void wait_until(const future<U> &, const time_point &);
|
||||
|
|
|
@ -31,10 +31,8 @@ namespace ircd::ctx
|
|||
struct ircd::ctx::list
|
||||
{
|
||||
struct node;
|
||||
using closure_bool_const = std::function<bool (const ctx &)>;
|
||||
using closure_const = std::function<void (const ctx &)>;
|
||||
using closure_bool = std::function<bool (ctx &)>;
|
||||
using closure = std::function<void (ctx &)>;
|
||||
using closure_const = util::closure_bool<std::function, const ctx &>;
|
||||
using closure = util::closure_bool<std::function, ctx &>;
|
||||
|
||||
private:
|
||||
ctx *head {nullptr};
|
||||
|
@ -56,29 +54,28 @@ struct ircd::ctx::list
|
|||
ctx *back() noexcept;
|
||||
|
||||
// iteration
|
||||
bool for_each(const closure_bool_const &) const;
|
||||
void for_each(const closure_const &) const;
|
||||
bool for_each(const closure_bool &);
|
||||
void for_each(const closure &);
|
||||
bool for_each(const closure_const &) const;
|
||||
bool for_each(const closure &);
|
||||
|
||||
// reverse iteration
|
||||
bool rfor_each(const closure_bool_const &) const;
|
||||
void rfor_each(const closure_const &) const;
|
||||
bool rfor_each(const closure_bool &);
|
||||
void rfor_each(const closure &);
|
||||
bool rfor_each(const closure_const &) const;
|
||||
bool rfor_each(const closure &);
|
||||
|
||||
bool empty() const noexcept;
|
||||
size_t size() const noexcept;
|
||||
|
||||
void push_front(ctx *const & = current) noexcept;
|
||||
void push_back(ctx *const & = current) noexcept;
|
||||
void push(ctx *const & = current) noexcept; // push_back
|
||||
void push_before(ctx *, ctx * = current) noexcept;
|
||||
void push_after(ctx *, ctx * = current) noexcept;
|
||||
void push_front(ctx * = current) noexcept;
|
||||
void push_back(ctx * = current) noexcept;
|
||||
void push_sort(ctx * = current) noexcept; // weak/partial
|
||||
void push(ctx * = current) noexcept; // push_back
|
||||
|
||||
ctx *pop_front() noexcept;
|
||||
ctx *pop_back() noexcept;
|
||||
ctx *pop() noexcept; // pop_front
|
||||
|
||||
void remove(ctx *const & = current) noexcept;
|
||||
void remove(ctx * = current) noexcept;
|
||||
|
||||
list() = default;
|
||||
list(list &&) noexcept;
|
||||
|
@ -132,7 +129,7 @@ noexcept
|
|||
}
|
||||
|
||||
inline void
|
||||
ircd::ctx::list::push(ctx *const &c)
|
||||
ircd::ctx::list::push(ctx *const c)
|
||||
noexcept
|
||||
{
|
||||
push_back(c);
|
||||
|
|
|
@ -115,6 +115,12 @@ struct ircd::ctx::pool::opts
|
|||
|
||||
/// Scheduler priority nice value for contexts in this pool.
|
||||
int8_t nice {0};
|
||||
|
||||
/// Worker dispatch strategy.
|
||||
/// - FIFO: Dispatch fairly (round-robin).
|
||||
/// - LIFO: Dispatch the last to finish.
|
||||
/// - SORT: Like LIFO but lower ID's are given partial precedence.
|
||||
dock::opts dispatch {dock::opts::LIFO};
|
||||
};
|
||||
|
||||
template<class F,
|
||||
|
@ -171,3 +177,9 @@ const
|
|||
assert(opt);
|
||||
return *opt;
|
||||
}
|
||||
|
||||
inline const ircd::string_view &
|
||||
ircd::ctx::name(const pool &pool)
|
||||
{
|
||||
return pool.name;
|
||||
}
|
||||
|
|
|
@ -15,13 +15,16 @@ namespace ircd::ctx
|
|||
{
|
||||
template<class T,
|
||||
class A = std::allocator<T>>
|
||||
class queue;
|
||||
struct queue;
|
||||
}
|
||||
|
||||
template<class T,
|
||||
class A>
|
||||
class ircd::ctx::queue
|
||||
struct ircd::ctx::queue
|
||||
{
|
||||
using opts = dock::opts;
|
||||
|
||||
private:
|
||||
dock d;
|
||||
std::deque<T, A> q;
|
||||
size_t w {0};
|
||||
|
@ -32,13 +35,18 @@ class ircd::ctx::queue
|
|||
size_t waiting() const;
|
||||
|
||||
// Consumer interface; waits for item and std::move() it off the queue
|
||||
template<class time_point> T pop_until(time_point&&);
|
||||
template<class duration> T pop_for(const duration &);
|
||||
T pop();
|
||||
template<class time_point> T pop_until(time_point&&, const opts & = (opts)0);
|
||||
template<class duration> T pop_for(const duration &, const opts & = (opts)0);
|
||||
T pop(const opts & = (opts)0);
|
||||
|
||||
// Producer interface; emplace item on the queue and notify consumer
|
||||
template<class... args> void emplace(const opts &, args&&...);
|
||||
template<class... args> void emplace(args&&...);
|
||||
|
||||
void push(const opts &, const T &);
|
||||
void push(const T &);
|
||||
|
||||
void push(const opts &, T &&) noexcept;
|
||||
void push(T &&) noexcept;
|
||||
|
||||
queue();
|
||||
|
@ -77,7 +85,22 @@ inline void
|
|||
ircd::ctx::queue<T, A>::push(T&& t)
|
||||
noexcept
|
||||
{
|
||||
q.push_back(std::forward<T>(t));
|
||||
static const opts opts {0};
|
||||
push(opts, std::forward<T>(t));
|
||||
}
|
||||
|
||||
template<class T,
|
||||
class A>
|
||||
inline void
|
||||
ircd::ctx::queue<T, A>::push(const opts &opts,
|
||||
T&& t)
|
||||
noexcept
|
||||
{
|
||||
if(opts & opts::LIFO)
|
||||
q.push_front(std::forward<T>(t));
|
||||
else
|
||||
q.push_back(std::forward<T>(t));
|
||||
|
||||
d.notify();
|
||||
}
|
||||
|
||||
|
@ -86,7 +109,21 @@ template<class T,
|
|||
inline void
|
||||
ircd::ctx::queue<T, A>::push(const T &t)
|
||||
{
|
||||
q.push_back(t);
|
||||
static const opts opts {0};
|
||||
push(opts, t);
|
||||
}
|
||||
|
||||
template<class T,
|
||||
class A>
|
||||
inline void
|
||||
ircd::ctx::queue<T, A>::push(const opts &opts,
|
||||
const T &t)
|
||||
{
|
||||
if(opts & opts::LIFO)
|
||||
q.push_front(t);
|
||||
else
|
||||
q.push_back(t);
|
||||
|
||||
d.notify();
|
||||
}
|
||||
|
||||
|
@ -96,24 +133,41 @@ template<class... args>
|
|||
inline void
|
||||
ircd::ctx::queue<T, A>::emplace(args&&... a)
|
||||
{
|
||||
q.emplace(std::forward<args>(a)...);
|
||||
static const opts opts {0};
|
||||
emplace(opts, std::forward<args>(a)...);
|
||||
}
|
||||
|
||||
template<class T,
|
||||
class A>
|
||||
template<class... args>
|
||||
inline void
|
||||
ircd::ctx::queue<T, A>::emplace(const opts &opts,
|
||||
args&&... a)
|
||||
{
|
||||
if(opts & opts::LIFO)
|
||||
q.emplace_front(std::forward<args>(a)...);
|
||||
else
|
||||
q.emplace_back(std::forward<args>(a)...);
|
||||
|
||||
d.notify();
|
||||
}
|
||||
|
||||
template<class T,
|
||||
class A>
|
||||
inline T
|
||||
ircd::ctx::queue<T, A>::pop()
|
||||
ircd::ctx::queue<T, A>::pop(const opts &opts)
|
||||
{
|
||||
const scope_count w
|
||||
{
|
||||
this->w
|
||||
};
|
||||
|
||||
d.wait([this]() noexcept
|
||||
const auto predicate{[this]() noexcept
|
||||
{
|
||||
return !q.empty();
|
||||
});
|
||||
}};
|
||||
|
||||
d.wait(predicate, opts);
|
||||
|
||||
assert(!q.empty());
|
||||
auto ret(std::move(q.front()));
|
||||
|
@ -125,22 +179,25 @@ template<class T,
|
|||
class A>
|
||||
template<class duration>
|
||||
inline T
|
||||
ircd::ctx::queue<T, A>::pop_for(const duration &dur)
|
||||
ircd::ctx::queue<T, A>::pop_for(const duration &dur,
|
||||
const opts &opts)
|
||||
{
|
||||
const scope_count w
|
||||
{
|
||||
this->w
|
||||
};
|
||||
|
||||
const auto predicate{[this]() noexcept
|
||||
{
|
||||
return !q.empty();
|
||||
}};
|
||||
|
||||
const bool ready
|
||||
{
|
||||
d.wait_for(dur, [this]() noexcept
|
||||
{
|
||||
return !q.empty();
|
||||
})
|
||||
d.wait_for(dur, predicate, opts)
|
||||
};
|
||||
|
||||
if(!ready)
|
||||
if(unlikely(!ready))
|
||||
throw timeout{};
|
||||
|
||||
assert(!q.empty());
|
||||
|
@ -153,22 +210,25 @@ template<class T,
|
|||
class A>
|
||||
template<class time_point>
|
||||
inline T
|
||||
ircd::ctx::queue<T, A>::pop_until(time_point&& tp)
|
||||
ircd::ctx::queue<T, A>::pop_until(time_point&& tp,
|
||||
const opts &opts)
|
||||
{
|
||||
const scope_count w
|
||||
{
|
||||
this->w
|
||||
};
|
||||
|
||||
const auto predicate{[this]() noexcept
|
||||
{
|
||||
return !q.empty();
|
||||
}};
|
||||
|
||||
const bool ready
|
||||
{
|
||||
d.wait_until(tp, [this]() noexcept
|
||||
{
|
||||
return !q.empty();
|
||||
})
|
||||
d.wait_until(tp, predicate, opts)
|
||||
};
|
||||
|
||||
if(!ready)
|
||||
if(unlikely(!ready))
|
||||
throw timeout{};
|
||||
|
||||
assert(!q.empty());
|
||||
|
|
|
@ -86,7 +86,7 @@ struct ircd::db::cell
|
|||
cell(column, const string_view &index = {}, const gopts & = {});
|
||||
cell(database &, const string_view &column, const string_view &index, const gopts & = {});
|
||||
cell(database &, const string_view &column, const gopts & = {});
|
||||
cell();
|
||||
cell() noexcept;
|
||||
cell(cell &&) noexcept;
|
||||
cell(const cell &) = delete;
|
||||
cell &operator=(cell &&) noexcept;
|
||||
|
@ -146,3 +146,10 @@ const
|
|||
{
|
||||
return val();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::db::cell::valid()
|
||||
const
|
||||
{
|
||||
return it && db::valid(*it);
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@ namespace ircd::db
|
|||
template<> prop_map property(const column &, const string_view &name);
|
||||
|
||||
// Access to the column's caches (see cache.h interface)
|
||||
const rocksdb::Cache *cache_compressed(const column &);
|
||||
[[gnu::deprecated]] const rocksdb::Cache *cache_compressed(const column &);
|
||||
const rocksdb::Cache *cache(const column &);
|
||||
rocksdb::Cache *cache_compressed(column &);
|
||||
[[gnu::deprecated]] rocksdb::Cache *cache_compressed(column &);
|
||||
rocksdb::Cache *cache(column &);
|
||||
|
||||
// [GET] Tests if key exists
|
||||
|
|
|
@ -51,8 +51,8 @@ struct ircd::db::column::const_iterator_base
|
|||
explicit operator database::snapshot &();
|
||||
explicit operator gopts &();
|
||||
|
||||
operator bool() const noexcept;
|
||||
bool operator!() const noexcept;
|
||||
operator bool() const;
|
||||
bool operator!() const;
|
||||
|
||||
const value_type *operator->() const;
|
||||
const value_type &operator*() const;
|
||||
|
@ -101,11 +101,18 @@ const
|
|||
|
||||
inline bool
|
||||
ircd::db::column::const_iterator_base::operator!()
|
||||
const noexcept
|
||||
const
|
||||
{
|
||||
return !static_cast<bool>(*this);
|
||||
}
|
||||
|
||||
inline ircd::db::column::const_iterator_base::operator
|
||||
bool()
|
||||
const
|
||||
{
|
||||
return it && valid(*it);
|
||||
}
|
||||
|
||||
inline ircd::db::column::const_iterator_base::operator
|
||||
gopts &()
|
||||
{
|
||||
|
|
|
@ -18,9 +18,16 @@ namespace ircd::db
|
|||
// Broad conf items
|
||||
extern conf::item<std::string> open_recover;
|
||||
extern conf::item<bool> open_repair;
|
||||
extern conf::item<bool> open_slave;
|
||||
extern conf::item<bool> auto_compact;
|
||||
extern conf::item<bool> auto_deletion;
|
||||
extern conf::item<bool> open_stats;
|
||||
extern conf::item<bool> paranoid;
|
||||
extern conf::item<bool> paranoid_checks;
|
||||
extern conf::item<bool> paranoid_size;
|
||||
extern conf::item<bool> paranoid_uuid;
|
||||
extern conf::item<bool> paranoid_wal;
|
||||
extern conf::item<bool> paranoid_sst;
|
||||
extern conf::item<bool> paranoid_lsm;
|
||||
|
||||
// General information
|
||||
const std::string &name(const database &);
|
||||
|
@ -108,7 +115,7 @@ struct ircd::db::database
|
|||
uint64_t checkpoint;
|
||||
std::string path;
|
||||
std::string optstr;
|
||||
bool fsck, slave, read_only;
|
||||
bool fsck, slave, read_only, opened;
|
||||
std::shared_ptr<struct env> env;
|
||||
std::shared_ptr<struct stats> stats;
|
||||
std::shared_ptr<struct logger> logger;
|
||||
|
@ -121,6 +128,7 @@ struct ircd::db::database
|
|||
std::shared_ptr<rocksdb::Cache> row_cache;
|
||||
std::vector<descriptor> descriptors;
|
||||
std::unique_ptr<rocksdb::DBOptions> opts;
|
||||
std::vector<std::unique_ptr<conf::item<std::string>>> confs;
|
||||
std::unordered_map<string_view, std::shared_ptr<column>> column_names;
|
||||
std::unique_ptr<rocksdb::DB> d;
|
||||
ctx::mutex write_mutex;
|
||||
|
|
|
@ -139,4 +139,8 @@ struct ircd::db::descriptor
|
|||
{
|
||||
2
|
||||
};
|
||||
|
||||
/// Circuit-breaker to disable automatic compaction specifically for this
|
||||
/// column from this descriptor.
|
||||
bool compaction {true};
|
||||
};
|
||||
|
|
|
@ -102,3 +102,11 @@ const
|
|||
{
|
||||
return &this->operator*();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::db::seek(domain::const_iterator_base &it,
|
||||
const string_view &p)
|
||||
{
|
||||
it.opts.prefix = true;
|
||||
return seek(static_cast<column::const_iterator_base &>(it), p);
|
||||
}
|
||||
|
|
|
@ -110,6 +110,12 @@ struct ircd::db::options
|
|||
struct ircd::db::options::map
|
||||
:std::unordered_map<std::string, std::string>
|
||||
{
|
||||
// Merge output of options structures from map (map takes precedence).
|
||||
rocksdb::DBOptions merge(const rocksdb::DBOptions &) const;
|
||||
rocksdb::ColumnFamilyOptions merge(const rocksdb::ColumnFamilyOptions &) const;
|
||||
rocksdb::PlainTableOptions merge(const rocksdb::PlainTableOptions &) const;
|
||||
rocksdb::BlockBasedTableOptions merge(const rocksdb::BlockBasedTableOptions &) const;
|
||||
|
||||
// Output of options structures from map
|
||||
operator rocksdb::DBOptions() const;
|
||||
operator rocksdb::ColumnFamilyOptions() const;
|
||||
|
@ -120,7 +126,7 @@ struct ircd::db::options::map
|
|||
map(const options &);
|
||||
|
||||
// Input of options map from user
|
||||
map(std::unordered_map<std::string, std::string> m)
|
||||
map(std::unordered_map<std::string, std::string> m = {})
|
||||
:std::unordered_map<std::string, std::string>{std::move(m)}
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -19,8 +19,8 @@ namespace rocksdb
|
|||
|
||||
namespace ircd::db
|
||||
{
|
||||
uint64_t sequence(const database::snapshot &); // Sequence of a snapshot
|
||||
uint64_t sequence(const rocksdb::Snapshot *const &);
|
||||
uint64_t sequence(const database::snapshot &) noexcept; // Sequence of a snapshot
|
||||
uint64_t sequence(const rocksdb::Snapshot *) noexcept;
|
||||
}
|
||||
|
||||
/// Database snapshot object. Maintaining this object will maintain a
|
||||
|
@ -31,12 +31,43 @@ struct ircd::db::database::snapshot
|
|||
std::shared_ptr<const rocksdb::Snapshot> s;
|
||||
|
||||
public:
|
||||
operator const rocksdb::Snapshot *() const { return s.get(); }
|
||||
operator const rocksdb::Snapshot *() const;
|
||||
|
||||
explicit operator bool() const { return bool(s); }
|
||||
bool operator !() const { return !s; }
|
||||
explicit operator bool() const;
|
||||
bool operator !() const;
|
||||
|
||||
explicit snapshot(database &);
|
||||
snapshot() = default;
|
||||
explicit snapshot(database &);
|
||||
snapshot(const snapshot &) = default;
|
||||
snapshot &operator=(const snapshot &) = default;
|
||||
~snapshot() noexcept;
|
||||
};
|
||||
|
||||
inline bool
|
||||
ircd::db::database::snapshot::operator!()
|
||||
const
|
||||
{
|
||||
return !s;
|
||||
}
|
||||
|
||||
inline ircd::db::database::snapshot::operator
|
||||
bool()
|
||||
const
|
||||
{
|
||||
return bool(s);
|
||||
}
|
||||
|
||||
inline ircd::db::database::snapshot::operator
|
||||
const rocksdb::Snapshot *()
|
||||
const
|
||||
{
|
||||
return s.get();
|
||||
}
|
||||
|
||||
inline uint64_t
|
||||
ircd::db::sequence(const database::snapshot &s)
|
||||
noexcept
|
||||
{
|
||||
const rocksdb::Snapshot *const rs(s);
|
||||
return sequence(rs);
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
namespace ircd::fs::dev
|
||||
{
|
||||
struct blk;
|
||||
struct stats;
|
||||
|
||||
using major_minor = std::pair<ulong, ulong>;
|
||||
using blk_closure = std::function<bool (const ulong &id, const blk &)>;
|
||||
|
||||
// Convert device ID's with the major(3) / minor(3) / makedev(3)
|
||||
ulong id(const major_minor &);
|
||||
|
@ -36,13 +36,12 @@ namespace ircd::fs::dev
|
|||
sysfs(const ulong &id,
|
||||
const string_view &path,
|
||||
const R &def = 0);
|
||||
|
||||
bool for_each(const string_view &devtype, const blk_closure &);
|
||||
bool for_each(const blk_closure &);
|
||||
}
|
||||
|
||||
struct ircd::fs::dev::blk
|
||||
{
|
||||
using closure = util::function_bool<const ulong &, const blk &>;
|
||||
|
||||
static const size_t SECTOR_SIZE;
|
||||
static const string_view BASE_PATH;
|
||||
|
||||
|
@ -66,6 +65,47 @@ struct ircd::fs::dev::blk
|
|||
|
||||
blk(const ulong &id);
|
||||
blk() = default;
|
||||
|
||||
static bool for_each(const string_view &devtype, const closure &);
|
||||
static bool for_each(const closure &);
|
||||
};
|
||||
|
||||
struct ircd::fs::dev::stats
|
||||
{
|
||||
using closure = util::function_bool<const stats &>;
|
||||
|
||||
char name[32] {0};
|
||||
major_minor id {0, 0};
|
||||
|
||||
uint64_t read {0};
|
||||
uint64_t read_merged {0};
|
||||
uint64_t read_sectors {0};
|
||||
milliseconds read_time {0ms};
|
||||
|
||||
uint64_t write {0};
|
||||
uint64_t write_merged {0};
|
||||
uint64_t write_sectors {0};
|
||||
milliseconds write_time {0ms};
|
||||
|
||||
uint64_t io_current {0};
|
||||
milliseconds io_time {0ms};
|
||||
milliseconds io_weighted_time {0ms};
|
||||
|
||||
// 4.18+
|
||||
uint64_t discard {0};
|
||||
uint64_t discard_merged {0};
|
||||
uint64_t discard_sectors {0};
|
||||
milliseconds discard_time {0ms};
|
||||
|
||||
// 5.5+
|
||||
uint64_t flush {0};
|
||||
milliseconds flush_time {0ms};
|
||||
|
||||
stats(const string_view &line);
|
||||
stats() = default;
|
||||
|
||||
static bool for_each(const closure &);
|
||||
static stats get(const major_minor &id);
|
||||
};
|
||||
|
||||
/// Return a lex_cast'able (an integer) from a sysfs target.
|
||||
|
|
|
@ -183,3 +183,23 @@ static_assert(sizeof(struct ircd_gpt_ctrl) % 4096 == 0);
|
|||
static_assert(offsetof(struct ircd_gpt_ctrl, token) == 2048);
|
||||
static_assert(std::is_standard_layout<struct ircd_gpt_ctrl>::value);
|
||||
#endif
|
||||
|
||||
#ifdef __OPENCL_VERSION__
|
||||
inline void
|
||||
ircd_gpt_prof_start(__global struct ircd_gpt_ctrl *const ctrl,
|
||||
const bool cond)
|
||||
{
|
||||
if(cond)
|
||||
ctrl->prof.custom[0] = ircd_simt_cycles();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __OPENCL_VERSION__
|
||||
inline void
|
||||
ircd_gpt_prof_stop(__global struct ircd_gpt_ctrl *const ctrl,
|
||||
const bool cond)
|
||||
{
|
||||
if(cond)
|
||||
ctrl->prof.custom[1] = ircd_simt_cycles();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -223,7 +223,7 @@ struct ircd::http::query
|
|||
struct ircd::http::query::string
|
||||
:string_view
|
||||
{
|
||||
using closure = std::function<bool (const query &)>;
|
||||
using closure = util::function_bool<const query &>;
|
||||
|
||||
bool for_each(const closure &) const;
|
||||
bool for_each(const string_view &key, const closure &) const;
|
||||
|
@ -271,19 +271,17 @@ struct ircd::http::header
|
|||
struct ircd::http::headers
|
||||
:string_view
|
||||
{
|
||||
using closure = std::function<void (const header &)>;
|
||||
using closure_bool = std::function<bool (const header &)>;
|
||||
using closure = util::function_bool<const header &>;
|
||||
|
||||
static const string_view terminator; // "\r\n\r\n"
|
||||
|
||||
bool for_each(const closure_bool &) const;
|
||||
bool for_each(const closure &) const;
|
||||
string_view operator[](const string_view &key) const;
|
||||
string_view at(const string_view &key) const;
|
||||
bool has(const string_view &key) const;
|
||||
|
||||
using string_view::string_view;
|
||||
headers(parse::capstan &, closure_bool);
|
||||
headers(parse::capstan &, const closure & = {});
|
||||
headers(parse::capstan &, closure = {});
|
||||
headers() = default;
|
||||
|
||||
friend bool has(const headers &, const string_view &key);
|
||||
|
@ -322,11 +320,13 @@ struct ircd::http::request::head
|
|||
string_view upgrade;
|
||||
string_view range;
|
||||
string_view if_range;
|
||||
string_view forwarded_for;
|
||||
string_view forwarded[1]; // last forwarded
|
||||
string_view forwarded_for[1]; // last x-forwarded-for
|
||||
string_view forwarded_host[1]; // last x-forwarded-host
|
||||
size_t content_length {0};
|
||||
|
||||
string_view uri; // full view of (path, query, fragmet)
|
||||
string_view headers; // full view of all headers
|
||||
string_view uri; // full view of (path, query, fragmet)
|
||||
http::headers headers; // full view of all headers
|
||||
|
||||
// full view of all head (request line and headers)
|
||||
operator string_view() const;
|
||||
|
@ -367,7 +367,7 @@ struct ircd::http::response::head
|
|||
string_view server;
|
||||
string_view location;
|
||||
|
||||
string_view headers;
|
||||
http::headers headers;
|
||||
|
||||
head(parse::capstan &pc, const headers::closure &c);
|
||||
head(parse::capstan &pc);
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace ircd::info::hardware::x86
|
|||
extern const string_view vendor;
|
||||
extern const bool sse, sse2, sse3, ssse3, sse4a, sse4_1, sse4_2;
|
||||
extern const bool avx, avx2, avx512f;
|
||||
extern const bool tsc, tsc_constant;
|
||||
extern const bool tsc, tsc_constant, tsc_nonstop;
|
||||
}
|
||||
|
||||
namespace ircd::info::hardware::arm
|
||||
|
|
|
@ -29,14 +29,14 @@ struct ircd::ios::descriptor
|
|||
|
||||
static uint64_t ids;
|
||||
|
||||
static void *default_allocator(handler &, const size_t &);
|
||||
static void default_deallocator(handler &, void *const &, const size_t &) noexcept;
|
||||
static void *default_allocator(handler &, const size_t);
|
||||
static void default_deallocator(handler &, void *, const size_t) noexcept;
|
||||
|
||||
string_view name;
|
||||
uint64_t id {++ids};
|
||||
std::unique_ptr<struct stats> stats;
|
||||
void *(*allocator)(handler &, const size_t &);
|
||||
void (*deallocator)(handler &, void *const &, const size_t &);
|
||||
void *(*allocator)(handler &, const size_t);
|
||||
void (*deallocator)(handler &, void *, const size_t);
|
||||
std::vector<std::array<uint64_t, 2>> history; // epoch, cycles
|
||||
uint8_t history_pos {0};
|
||||
bool continuation {false};
|
||||
|
@ -72,10 +72,10 @@ struct ircd::ios::descriptor::stats
|
|||
item alloc_bytes;
|
||||
item frees;
|
||||
item free_bytes;
|
||||
item slice_total;
|
||||
item slice_last;
|
||||
item latency_total;
|
||||
item slice_total;
|
||||
item latency_last;
|
||||
item latency_total;
|
||||
|
||||
stats(descriptor &);
|
||||
stats() = delete;
|
||||
|
@ -87,8 +87,8 @@ struct ircd::ios::descriptor::stats
|
|||
[[gnu::hot]]
|
||||
inline void
|
||||
ircd::ios::descriptor::default_deallocator(handler &handler,
|
||||
void *const &ptr,
|
||||
const size_t &size)
|
||||
void *const ptr,
|
||||
const size_t size)
|
||||
noexcept
|
||||
{
|
||||
#ifdef __clang__
|
||||
|
@ -101,7 +101,7 @@ noexcept
|
|||
[[gnu::hot]]
|
||||
inline void *
|
||||
ircd::ios::descriptor::default_allocator(handler &handler,
|
||||
const size_t &size)
|
||||
const size_t size)
|
||||
{
|
||||
return ::operator new(size);
|
||||
}
|
||||
|
|
|
@ -28,13 +28,13 @@ struct ircd::ios::handler
|
|||
static thread_local handler *current;
|
||||
static thread_local uint64_t epoch;
|
||||
|
||||
static void enqueue(handler *const &) noexcept;
|
||||
static void *allocate(handler *const &, const size_t &);
|
||||
static void deallocate(handler *const &, void *const &, const size_t &) noexcept;
|
||||
static bool continuation(handler *const &) noexcept;
|
||||
static void enter(handler *const &) noexcept;
|
||||
static void leave(handler *const &) noexcept;
|
||||
static bool fault(handler *const &) noexcept;
|
||||
static void enqueue(handler *) noexcept;
|
||||
static void *allocate(handler *, const size_t);
|
||||
static void deallocate(handler *, void *, const size_t) noexcept;
|
||||
static bool continuation(handler *) noexcept;
|
||||
static void enter(handler *) noexcept;
|
||||
static void leave(handler *) noexcept;
|
||||
static bool fault(handler *) noexcept;
|
||||
|
||||
ios::descriptor *descriptor {nullptr};
|
||||
uint64_t ts {0}; // last tsc sample; for profiling each phase
|
||||
|
@ -91,9 +91,9 @@ const
|
|||
|
||||
[[gnu::hot]]
|
||||
inline void
|
||||
ircd::ios::handler::deallocate(handler *const &handler,
|
||||
void *const &ptr,
|
||||
const size_t &size)
|
||||
ircd::ios::handler::deallocate(handler *const handler,
|
||||
void *const ptr,
|
||||
const size_t size)
|
||||
noexcept
|
||||
{
|
||||
assert(handler && handler->descriptor);
|
||||
|
@ -110,8 +110,8 @@ noexcept
|
|||
|
||||
[[gnu::hot]]
|
||||
inline void *
|
||||
ircd::ios::handler::allocate(handler *const &handler,
|
||||
const size_t &size)
|
||||
ircd::ios::handler::allocate(handler *const handler,
|
||||
const size_t size)
|
||||
{
|
||||
assert(handler && handler->descriptor);
|
||||
auto &descriptor(*handler->descriptor);
|
||||
|
@ -127,7 +127,7 @@ ircd::ios::handler::allocate(handler *const &handler,
|
|||
|
||||
[[gnu::hot]]
|
||||
inline void
|
||||
ircd::ios::handler::enqueue(handler *const &handler)
|
||||
ircd::ios::handler::enqueue(handler *const handler)
|
||||
noexcept
|
||||
{
|
||||
assert(handler && handler->descriptor);
|
||||
|
@ -152,7 +152,7 @@ noexcept
|
|||
|
||||
[[gnu::hot]]
|
||||
inline bool
|
||||
ircd::ios::handler::continuation(handler *const &handler)
|
||||
ircd::ios::handler::continuation(handler *const handler)
|
||||
noexcept
|
||||
{
|
||||
assert(handler && handler->descriptor);
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace ircd::ios
|
|||
extern asio::executor user, main;
|
||||
extern std::thread::id main_thread_id;
|
||||
extern thread_local bool is_main_thread;
|
||||
extern bool user_available, main_available;
|
||||
|
||||
bool available() noexcept;
|
||||
const uint64_t &epoch() noexcept;
|
||||
|
@ -64,3 +65,11 @@ noexcept
|
|||
{
|
||||
return handler::epoch;
|
||||
}
|
||||
|
||||
inline bool
|
||||
__attribute__((always_inline))
|
||||
ircd::ios::available()
|
||||
noexcept
|
||||
{
|
||||
return main_available;
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
#include "mods/mods.h"
|
||||
#include "net/net.h"
|
||||
#include "server/server.h"
|
||||
#include "rest.h"
|
||||
#include "png.h"
|
||||
#include "beep.h"
|
||||
#include "magick.h"
|
||||
|
@ -129,10 +130,10 @@ namespace ircd
|
|||
|
||||
// Operating Mode Selectors
|
||||
extern conf::item<bool> debugmode;
|
||||
extern conf::item<bool> maintenance;
|
||||
extern conf::item<bool> soft_assert;
|
||||
extern conf::item<bool> write_avoid; // implies maintenance
|
||||
extern conf::item<bool> read_only; // implies write_avoid
|
||||
extern conf::item<bool> maintenance;
|
||||
extern conf::item<bool> slave;
|
||||
extern conf::item<bool> read_only;
|
||||
extern conf::item<bool> defaults;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ namespace ircd::json
|
|||
bool operator!(const array &);
|
||||
size_t size(const array &);
|
||||
|
||||
size_t serialized(const string_view *const &begin, const string_view *const &end);
|
||||
size_t serialized(const std::string *const &begin, const std::string *const &end);
|
||||
size_t serialized(const string_view *begin, const string_view *end);
|
||||
size_t serialized(const std::string *begin, const std::string *end);
|
||||
size_t serialized(const array &);
|
||||
|
||||
string_view stringify(mutable_buffer &buf, const string_view *const &begin, const string_view *const &end);
|
||||
string_view stringify(mutable_buffer &buf, const std::string *const &begin, const std::string *const &end);
|
||||
string_view stringify(mutable_buffer &buf, const string_view *begin, const string_view *end);
|
||||
string_view stringify(mutable_buffer &buf, const std::string *begin, const std::string *end);
|
||||
string_view stringify(mutable_buffer &, const array &);
|
||||
std::ostream &operator<<(std::ostream &, const array &);
|
||||
}
|
||||
|
@ -62,8 +62,8 @@ struct ircd::json::array
|
|||
size_t size() const;
|
||||
|
||||
template<class T> T at(const size_t &i) const;
|
||||
string_view at(const size_t &i) const;
|
||||
string_view operator[](const size_t &i) const;
|
||||
string_view at(const size_t i) const;
|
||||
string_view operator[](const size_t i) const;
|
||||
|
||||
explicit operator std::string() const;
|
||||
|
||||
|
@ -109,3 +109,21 @@ const
|
|||
assert(sv.size() > 2 || sv.empty() || sv == empty_array || sv == empty_object);
|
||||
return sv.size() <= 2 || sv == literal_null;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::json::size(const array &array)
|
||||
{
|
||||
return array.size();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!(const array &array)
|
||||
{
|
||||
return empty(array);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::empty(const array &array)
|
||||
{
|
||||
return array.empty();
|
||||
}
|
||||
|
|
|
@ -38,21 +38,8 @@ namespace ircd::json
|
|||
#include "iov.h"
|
||||
#include "strung.h"
|
||||
#include "tuple/tuple.h"
|
||||
#include "stack.h"
|
||||
|
||||
// Convenience toolset for higher level operations.
|
||||
namespace ircd::json
|
||||
{
|
||||
strung append(const array &, const string_view &val);
|
||||
strung prepend(const array &, const string_view &val);
|
||||
|
||||
void merge(stack::object &out, const vector &);
|
||||
strung remove(const object &, const string_view &key);
|
||||
strung remove(const object &, const size_t &index);
|
||||
strung insert(const object &, const member &);
|
||||
strung replace(const object &, const member &);
|
||||
strung replace(const object &, const members &);
|
||||
}
|
||||
#include "stack/stack.h"
|
||||
#include "tool.h"
|
||||
|
||||
// Exports to ircd::
|
||||
namespace ircd
|
||||
|
|
|
@ -22,13 +22,13 @@ namespace ircd::json
|
|||
bool operator<(const member &a, const member &b);
|
||||
bool operator<(const member &a, const string_view &b);
|
||||
|
||||
bool sorted(const member *const &begin, const member *const &end);
|
||||
bool sorted(const member *begin, const member *end);
|
||||
|
||||
size_t serialized(const member *const &begin, const member *const &end);
|
||||
size_t serialized(const member *begin, const member *end);
|
||||
size_t serialized(const members &);
|
||||
size_t serialized(const member &);
|
||||
|
||||
string_view stringify(mutable_buffer &, const member *const &begin, const member *const &end);
|
||||
string_view stringify(mutable_buffer &, const member *begin, const member *end);
|
||||
string_view stringify(mutable_buffer &, const members &);
|
||||
string_view stringify(mutable_buffer &, const member &);
|
||||
|
||||
|
@ -86,3 +86,65 @@ ircd::json::member::member(const string_view &k)
|
|||
k, value{}
|
||||
}
|
||||
{}
|
||||
|
||||
inline ircd::string_view
|
||||
ircd::json::stringify(mutable_buffer &buf,
|
||||
const members &list)
|
||||
{
|
||||
return stringify(buf, std::begin(list), std::end(list));
|
||||
}
|
||||
|
||||
inline ircd::string_view
|
||||
ircd::json::stringify(mutable_buffer &buf,
|
||||
const member &m)
|
||||
{
|
||||
return stringify(buf, &m, &m + 1);
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::json::serialized(const members &m)
|
||||
{
|
||||
return serialized(std::begin(m), std::end(m));
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::json::serialized(const member &member)
|
||||
{
|
||||
return serialized(member.first) + 1 + serialized(member.second);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const member &a, const member &b)
|
||||
{
|
||||
return a.first < b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!=(const member &a, const member &b)
|
||||
{
|
||||
return a.first != b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator==(const member &a, const member &b)
|
||||
{
|
||||
return a.first == b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const member &a, const string_view &b)
|
||||
{
|
||||
return string_view{a.first.string, a.first.len} < b;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!=(const member &a, const string_view &b)
|
||||
{
|
||||
return string_view{a.first.string, a.first.len} != b;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator==(const member &a, const string_view &b)
|
||||
{
|
||||
return string_view{a.first.string, a.first.len} == b;
|
||||
}
|
||||
|
|
|
@ -257,6 +257,13 @@ catch(const bad_lex_cast &e)
|
|||
return def;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::json::object::size()
|
||||
const
|
||||
{
|
||||
return count();
|
||||
}
|
||||
|
||||
inline ircd::json::object::const_iterator
|
||||
ircd::json::object::end()
|
||||
const
|
||||
|
@ -272,3 +279,21 @@ const
|
|||
assert(sv.size() > 2 || (sv.empty() || sv == empty_object));
|
||||
return sv.size() <= 2 || sv == literal_null;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::json::size(const object &object)
|
||||
{
|
||||
return object.size();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!(const object &object)
|
||||
{
|
||||
return empty(object);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::empty(const object &object)
|
||||
{
|
||||
return object.empty();
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@ namespace ircd::json
|
|||
bool operator<(const object::member &, const object::member &);
|
||||
bool operator>(const object::member &, const object::member &);
|
||||
|
||||
bool sorted(const object::member *const &, const object::member *const &);
|
||||
size_t serialized(const object::member *const &, const object::member *const &);
|
||||
bool sorted(const object::member *, const object::member *);
|
||||
size_t serialized(const object::member *, const object::member *);
|
||||
size_t serialized(const object::member &);
|
||||
string_view stringify(mutable_buffer &, const object::member *const &, const object::member *const &);
|
||||
string_view stringify(mutable_buffer &, const object::member *, const object::member *);
|
||||
string_view stringify(mutable_buffer &, const object::member &);
|
||||
std::ostream &operator<<(std::ostream &, const object::member &);
|
||||
}
|
||||
|
|
|
@ -1,368 +0,0 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_STACK_H
|
||||
|
||||
namespace ircd::json
|
||||
{
|
||||
struct stack;
|
||||
}
|
||||
|
||||
/// Output stack machine for stringifying JSON as-you-go. This device allows
|
||||
/// the user to create JSON without knowing the contents when it is first
|
||||
/// constructed. An object or array is opened and the user can append to the
|
||||
/// stack creating the members or values or recursing further. The JSON is
|
||||
/// then closed automatically with exception safety. Partial JSON is written
|
||||
/// to the buffer as soon as possible.
|
||||
///
|
||||
/// The target buffer is not required to maintain earlier output from the same
|
||||
/// stack or even earlier members and values of the same object or array. The
|
||||
/// buffer may be smaller than the final JSON output and reused when the user
|
||||
/// chooses to flush it to some storage or socket. If the buffer becomes full
|
||||
/// a flush callback is attempted to make space and continue. This can occur
|
||||
/// while the output is still incomplete JSON.
|
||||
///
|
||||
/// The user first creates a master json::stack instance with some reasonable
|
||||
/// backing buffer. A suite of classes is provided to aid with building the
|
||||
/// JSON which attach to each other stackfully, and eventually lead to the
|
||||
/// root. There should only be one "active path" of instances at any given
|
||||
/// time, ideally following the scope of your code itself. You must force
|
||||
/// instances to go out of scope to continue at the same recursion depth.
|
||||
/// This way the json::stack can "follow" your code and "record" the final
|
||||
/// JSON output while allowing you to free the original resources required
|
||||
/// for each value.
|
||||
///
|
||||
struct ircd::json::stack
|
||||
{
|
||||
struct array;
|
||||
struct object;
|
||||
struct member;
|
||||
struct chase;
|
||||
struct const_chase;
|
||||
struct checkpoint;
|
||||
using flush_callback = std::function<const_buffer (const const_buffer &)>;
|
||||
|
||||
window_buffer buf;
|
||||
flush_callback flusher;
|
||||
std::exception_ptr eptr;
|
||||
checkpoint *cp {nullptr};
|
||||
size_t appended {0};
|
||||
size_t flushed {0};
|
||||
size_t level {0};
|
||||
size_t hiwat; ///< autoflush watermark
|
||||
size_t lowat; ///< flush(false) call min watermark
|
||||
|
||||
object *co {nullptr}; ///< The root object instance.
|
||||
array *ca {nullptr}; ///< Could be union with top_object but
|
||||
|
||||
void rethrow_exception();
|
||||
void append(const size_t &expect, const window_buffer::closure &) noexcept;
|
||||
void append(const string_view &) noexcept;
|
||||
void append(const char &) noexcept;
|
||||
|
||||
public:
|
||||
bool opened() const; ///< Current stacking in progress.
|
||||
bool closed() const; ///< No stacking in progress.
|
||||
bool failed() const; ///< Exception pending in eptr.
|
||||
bool clean() const; ///< Never opened.
|
||||
bool done() const; ///< Opened and closed.
|
||||
size_t remaining() const;
|
||||
string_view completed() const;
|
||||
|
||||
size_t invalidate_checkpoints();
|
||||
bool flush(const bool &force = false) noexcept;
|
||||
size_t rewind(const size_t &bytes);
|
||||
void clear();
|
||||
|
||||
stack(const mutable_buffer &,
|
||||
flush_callback = {},
|
||||
const size_t &hiwat = -1,
|
||||
const size_t &lowat = 0);
|
||||
|
||||
stack(stack &&) noexcept;
|
||||
stack(const stack &) = delete;
|
||||
~stack() noexcept;
|
||||
};
|
||||
|
||||
/// stack::member is an intermediary that is constructed under the scope of
|
||||
/// a parent stack::object. It takes a name argument. It then requires one
|
||||
/// object or array be constructed under its scope as its value, or a
|
||||
/// json::value / already strung JSON must be appended as its value.
|
||||
///
|
||||
/// If the value is supplied in the constructor argument an instance of
|
||||
/// this class does not have to be held (use constructor as function).
|
||||
///
|
||||
struct ircd::json::stack::member
|
||||
{
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
object *po {nullptr}; ///< parent object
|
||||
string_view name; ///< member name state
|
||||
object *co {nullptr}; ///< current child object
|
||||
array *ca {nullptr}; ///< current child array
|
||||
bool vc {false}; ///< value witnessed
|
||||
|
||||
void _pre_append();
|
||||
void _post_append();
|
||||
|
||||
public:
|
||||
template<class... T> void append(const json::tuple<T...> &);
|
||||
void append(const json::value &);
|
||||
|
||||
member(object &po, const string_view &name);
|
||||
member(stack &s, const string_view &name);
|
||||
member(object &po, const string_view &name, const json::value &v);
|
||||
member(stack &s, const string_view &name, const json::value &);
|
||||
template<class... T> member(object &po, const string_view &name, const json::tuple<T...> &t);
|
||||
template<class... T> member(stack &s, const string_view &name, const json::tuple<T...> &t);
|
||||
member() = default;
|
||||
member(const member &) = delete;
|
||||
member(member &&) noexcept;
|
||||
~member() noexcept;
|
||||
|
||||
static const member &top(const stack &);
|
||||
static member &top(stack &);
|
||||
};
|
||||
|
||||
/// stack::object is constructed under the scope of either a stack::member,
|
||||
/// or a stack::array, or a stack itself. Only stack::member can be
|
||||
/// constructed directly under its scope.
|
||||
///
|
||||
/// For a stack::member parent, the named member is waiting for this value
|
||||
/// after leaving the stack at ':' after the name, this object will then
|
||||
/// print '{' and dtor with '}' and then return to the stack::member which
|
||||
/// will then return to its parent object.
|
||||
///
|
||||
/// For a stack::array parent, the stack may have been left at '[' or ','
|
||||
/// but either way this object will then print '{' and dtor with '}' and
|
||||
/// then return to the stack::array.
|
||||
///
|
||||
/// For a stack itself, this object is considered the "top object" and will
|
||||
/// open the stack with '{' and accept member instances under its scope
|
||||
/// until closing the stack with '}' after which the stack is done()
|
||||
///
|
||||
struct ircd::json::stack::object
|
||||
{
|
||||
member m; ///< optional internal member
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
member *pm {nullptr}; ///< parent member (if value of one)
|
||||
array *pa {nullptr}; ///< parent array (if value in one)
|
||||
member *cm {nullptr}; ///< current child member
|
||||
size_t mc {0}; ///< members witnessed (monotonic)
|
||||
|
||||
public:
|
||||
template<class... T> void append(const json::tuple<T...> &);
|
||||
void append(const json::object &);
|
||||
|
||||
object(stack &s); ///< Object is top
|
||||
object(array &pa); ///< Object is value in the array
|
||||
object(member &pm); ///< Object is value of named member
|
||||
object(object &po, const string_view &name);
|
||||
object(stack &s, const string_view &name);
|
||||
object(object &&) noexcept;
|
||||
object(const object &) = delete;
|
||||
~object() noexcept;
|
||||
|
||||
static const object &top(const stack &);
|
||||
static object &top(stack &);
|
||||
};
|
||||
|
||||
/// stack::array is constructed under the scope of either a stack::member,
|
||||
/// or a stack::array, or a stack itself. stack::object and stack::array
|
||||
/// can be constructed directly under its scope, but not stack::member.
|
||||
///
|
||||
/// The same behavior as described by stack::object documentation applies
|
||||
/// here translated to arrays.
|
||||
///
|
||||
struct ircd::json::stack::array
|
||||
{
|
||||
member m; ///< optional internal member
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
member *pm {nullptr}; ///< parent member (if value of one)
|
||||
array *pa {nullptr}; ///< parent array (if value in one)
|
||||
object *co {nullptr}; ///< current child object
|
||||
array *ca {nullptr}; ///< current child array
|
||||
size_t vc {0}; ///< values witnessed (monotonic)
|
||||
|
||||
void _pre_append();
|
||||
void _post_append();
|
||||
|
||||
public:
|
||||
template<class... T> void append(const json::tuple<T...> &);
|
||||
void append(const json::value &);
|
||||
|
||||
array(member &pm); ///< Array is value of the named member
|
||||
array(array &pa); ///< Array is value in the array
|
||||
array(object &po, const string_view &name);
|
||||
array(stack &s, const string_view &name);
|
||||
array(stack &s);
|
||||
array(const array &) = delete;
|
||||
array(array &&) noexcept;
|
||||
~array() noexcept;
|
||||
|
||||
static const array &top(const stack &);
|
||||
static array &top(stack &);
|
||||
};
|
||||
|
||||
/// This device chases the current active path by updating its member pointers.
|
||||
struct ircd::json::stack::chase
|
||||
{
|
||||
array *a {nullptr};
|
||||
object *o {nullptr};
|
||||
member *m {nullptr};
|
||||
|
||||
bool next();
|
||||
bool prev();
|
||||
|
||||
chase(stack &s, const bool &prechase = false);
|
||||
chase() = default;
|
||||
};
|
||||
|
||||
/// This device chases the current active path by updating its member pointers.
|
||||
struct ircd::json::stack::const_chase
|
||||
{
|
||||
const array *a {nullptr};
|
||||
const object *o {nullptr};
|
||||
const member *m {nullptr};
|
||||
|
||||
bool next();
|
||||
bool prev();
|
||||
|
||||
const_chase(const stack &s, const bool &prechase = false);
|
||||
const_chase() = default;
|
||||
};
|
||||
|
||||
/// Checkpoint captures the current state of the json::stack on construction
|
||||
/// and allows a restoration to that state in one of three ways:
|
||||
///
|
||||
/// - Calling rollback() will immediately rewind the json::stack buffer and
|
||||
/// allow continuing from the check point. This should be used with care, as
|
||||
/// other json::stack objects may still be pending on the stack and destruct
|
||||
/// after calling rollback(), leaving an incoherent attempt to close the JSON.
|
||||
///
|
||||
/// - Calling decommit() will defer the rollback() until destruction time. Take
|
||||
/// care again that the checkpoint was still placed on the stack to avoid the
|
||||
/// rollback() pitfall.
|
||||
///
|
||||
/// - Destruction under an exception is equivalent to a decommit() and will
|
||||
/// perform a rollback() if exception_rollback is set.
|
||||
///
|
||||
/// Flushes are avoided under the scope of a checkpoint, but they are still
|
||||
/// forced if the json::stack buffer fills up. In this case all active
|
||||
/// checkpoints are invalidated and cannot be rolled back.
|
||||
///
|
||||
struct ircd::json::stack::checkpoint
|
||||
{
|
||||
stack *s {nullptr};
|
||||
checkpoint *pc {nullptr};
|
||||
size_t point {0};
|
||||
size_t vc {0};
|
||||
bool committed {true};
|
||||
bool exception_rollback {true};
|
||||
|
||||
public:
|
||||
bool committing() const noexcept; ///< When false, destructor will rollback()
|
||||
bool committing(const bool &) noexcept; ///< Sets committing() to value.
|
||||
bool rollback(); ///< Performs rollback of buffer.
|
||||
|
||||
checkpoint(stack &s,
|
||||
const bool &committed = true,
|
||||
const bool &exception_rollback = true);
|
||||
|
||||
checkpoint(checkpoint &&) = delete;
|
||||
checkpoint(const checkpoint &) = delete;
|
||||
~checkpoint() noexcept;
|
||||
};
|
||||
|
||||
template<class... T>
|
||||
ircd::json::stack::member::member(stack &s,
|
||||
const string_view &name,
|
||||
const json::tuple<T...> &t)
|
||||
:member
|
||||
{
|
||||
object::top(s), name, t
|
||||
}
|
||||
{}
|
||||
|
||||
template<class... T>
|
||||
ircd::json::stack::member::member(object &po,
|
||||
const string_view &name,
|
||||
const json::tuple<T...> &t)
|
||||
:member{po, name}
|
||||
{
|
||||
append(t);
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
void
|
||||
ircd::json::stack::member::append(const json::tuple<T...> &t)
|
||||
{
|
||||
_pre_append();
|
||||
const unwind post{[this]
|
||||
{
|
||||
_post_append();
|
||||
}};
|
||||
|
||||
s->append(serialized(t), [&t](mutable_buffer buf)
|
||||
{
|
||||
return ircd::size(stringify(buf, t));
|
||||
});
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
void
|
||||
ircd::json::stack::array::append(const json::tuple<T...> &t)
|
||||
{
|
||||
_pre_append();
|
||||
const unwind post{[this]
|
||||
{
|
||||
_post_append();
|
||||
}};
|
||||
|
||||
s->append(serialized(t), [&t](mutable_buffer buf)
|
||||
{
|
||||
return ircd::size(stringify(buf, t));
|
||||
});
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
void
|
||||
ircd::json::stack::object::append(const json::tuple<T...> &t)
|
||||
{
|
||||
for_each(t, [this](const auto &name, const auto &_value)
|
||||
{
|
||||
const json::value value
|
||||
{
|
||||
_value
|
||||
};
|
||||
|
||||
if(defined(value))
|
||||
json::stack::member
|
||||
{
|
||||
*this, name, value
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::checkpoint::committing(const bool &committed)
|
||||
noexcept
|
||||
{
|
||||
const bool ret(this->committed);
|
||||
this->committed = committed;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::checkpoint::committing()
|
||||
const noexcept
|
||||
{
|
||||
return committed;
|
||||
}
|
71
include/ircd/json/stack/array.h
Normal file
71
include/ircd/json/stack/array.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_STACK_ARRAY_H
|
||||
|
||||
/// stack::array is constructed under the scope of either a stack::member,
|
||||
/// or a stack::array, or a stack itself. stack::object and stack::array
|
||||
/// can be constructed directly under its scope, but not stack::member.
|
||||
///
|
||||
/// The same behavior as described by stack::object documentation applies
|
||||
/// here translated to arrays.
|
||||
///
|
||||
struct ircd::json::stack::array
|
||||
{
|
||||
member m; ///< optional internal member
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
member *pm {nullptr}; ///< parent member (if value of one)
|
||||
array *pa {nullptr}; ///< parent array (if value in one)
|
||||
object *co {nullptr}; ///< current child object
|
||||
array *ca {nullptr}; ///< current child array
|
||||
size_t vc {0}; ///< values witnessed (monotonic)
|
||||
|
||||
void _pre_append();
|
||||
void _post_append();
|
||||
|
||||
public:
|
||||
template<class... T> void append(const json::tuple<T...> &);
|
||||
void append(const json::value &);
|
||||
|
||||
array(member &pm); ///< Array is value of the named member
|
||||
array(array &pa); ///< Array is value in the array
|
||||
array(object &po, const string_view &name);
|
||||
array(stack &s, const string_view &name);
|
||||
array(stack &s);
|
||||
array(const array &) = delete;
|
||||
array(array &&) noexcept;
|
||||
~array() noexcept;
|
||||
|
||||
static const array &top(const stack &);
|
||||
static array &top(stack &);
|
||||
};
|
||||
|
||||
template<class... T>
|
||||
inline void
|
||||
ircd::json::stack::array::append(const json::tuple<T...> &t)
|
||||
{
|
||||
_pre_append();
|
||||
const unwind post{[this]
|
||||
{
|
||||
_post_append();
|
||||
}};
|
||||
|
||||
s->append(serialized(t), [&t](mutable_buffer buf)
|
||||
{
|
||||
return ircd::size(stringify(buf, t));
|
||||
});
|
||||
}
|
||||
|
||||
inline void
|
||||
ircd::json::stack::array::_post_append()
|
||||
{
|
||||
++vc;
|
||||
}
|
40
include/ircd/json/stack/chase.h
Normal file
40
include/ircd/json/stack/chase.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_STACK_CHASE_H
|
||||
|
||||
/// This device chases the current active path by updating its member pointers.
|
||||
struct ircd::json::stack::chase
|
||||
{
|
||||
array *a {nullptr};
|
||||
object *o {nullptr};
|
||||
member *m {nullptr};
|
||||
|
||||
bool next() noexcept;
|
||||
bool prev() noexcept;
|
||||
|
||||
chase(stack &s, const bool prechase = false) noexcept;
|
||||
chase() = default;
|
||||
};
|
||||
|
||||
/// This device chases the current active path by updating its member pointers.
|
||||
struct ircd::json::stack::const_chase
|
||||
{
|
||||
const array *a {nullptr};
|
||||
const object *o {nullptr};
|
||||
const member *m {nullptr};
|
||||
|
||||
bool next() noexcept;
|
||||
bool prev() noexcept;
|
||||
|
||||
const_chase(const stack &s, const bool prechase = false) noexcept;
|
||||
const_chase() = default;
|
||||
};
|
70
include/ircd/json/stack/checkpoint.h
Normal file
70
include/ircd/json/stack/checkpoint.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_STACK_CHECKPOINT_H
|
||||
|
||||
/// Checkpoint captures the current state of the json::stack on construction
|
||||
/// and allows a restoration to that state in one of three ways:
|
||||
///
|
||||
/// - Calling rollback() will immediately rewind the json::stack buffer and
|
||||
/// allow continuing from the check point. This should be used with care, as
|
||||
/// other json::stack objects may still be pending on the stack and destruct
|
||||
/// after calling rollback(), leaving an incoherent attempt to close the JSON.
|
||||
///
|
||||
/// - Calling decommit() will defer the rollback() until destruction time. Take
|
||||
/// care again that the checkpoint was still placed on the stack to avoid the
|
||||
/// rollback() pitfall.
|
||||
///
|
||||
/// - Destruction under an exception is equivalent to a decommit() and will
|
||||
/// perform a rollback() if exception_rollback is set.
|
||||
///
|
||||
/// Flushes are avoided under the scope of a checkpoint, but they are still
|
||||
/// forced if the json::stack buffer fills up. In this case all active
|
||||
/// checkpoints are invalidated and cannot be rolled back.
|
||||
///
|
||||
struct ircd::json::stack::checkpoint
|
||||
{
|
||||
stack *s {nullptr};
|
||||
checkpoint *pc {nullptr};
|
||||
size_t point {0};
|
||||
size_t vc {0};
|
||||
bool committed {true};
|
||||
bool exception_rollback {true};
|
||||
|
||||
public:
|
||||
bool committing() const noexcept; ///< When false, destructor will rollback()
|
||||
bool committing(const bool &) noexcept; ///< Sets committing() to value.
|
||||
bool rollback(); ///< Performs rollback of buffer.
|
||||
|
||||
checkpoint(stack &s,
|
||||
const bool committed = true,
|
||||
const bool exception_rollback = true);
|
||||
|
||||
checkpoint(checkpoint &&) = delete;
|
||||
checkpoint(const checkpoint &) = delete;
|
||||
~checkpoint() noexcept;
|
||||
};
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::checkpoint::committing(const bool &committed)
|
||||
noexcept
|
||||
{
|
||||
const bool ret(this->committed);
|
||||
this->committed = committed;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::checkpoint::committing()
|
||||
const noexcept
|
||||
{
|
||||
return committed;
|
||||
}
|
104
include/ircd/json/stack/member.h
Normal file
104
include/ircd/json/stack/member.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_STACK_MEMBER_H
|
||||
|
||||
/// stack::member is an intermediary that is constructed under the scope of
|
||||
/// a parent stack::object. It takes a name argument. It then requires one
|
||||
/// object or array be constructed under its scope as its value, or a
|
||||
/// json::value / already strung JSON must be appended as its value.
|
||||
///
|
||||
/// If the value is supplied in the constructor argument an instance of
|
||||
/// this class does not have to be held (use constructor as function).
|
||||
///
|
||||
struct ircd::json::stack::member
|
||||
{
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
object *po {nullptr}; ///< parent object
|
||||
string_view name; ///< member name state
|
||||
object *co {nullptr}; ///< current child object
|
||||
array *ca {nullptr}; ///< current child array
|
||||
bool vc {false}; ///< value witnessed
|
||||
|
||||
void _pre_append();
|
||||
void _post_append();
|
||||
|
||||
public:
|
||||
template<class... T> void append(const json::tuple<T...> &);
|
||||
void append(const json::value &);
|
||||
|
||||
member(object &po, const string_view &name);
|
||||
member(stack &s, const string_view &name);
|
||||
member(object &po, const string_view &name, const json::value &v);
|
||||
member(stack &s, const string_view &name, const json::value &);
|
||||
template<class... T> member(object &po, const string_view &name, const json::tuple<T...> &t);
|
||||
template<class... T> member(stack &s, const string_view &name, const json::tuple<T...> &t);
|
||||
explicit member(object &, const json::object::member &);
|
||||
explicit member(stack &, const json::object::member &);
|
||||
explicit member(object &, const json::member &);
|
||||
explicit member(stack &, const json::member &);
|
||||
member() = default;
|
||||
member(const member &) = delete;
|
||||
member(member &&) noexcept;
|
||||
~member() noexcept;
|
||||
|
||||
static const member &top(const stack &);
|
||||
static member &top(stack &);
|
||||
};
|
||||
|
||||
template<class... T>
|
||||
inline
|
||||
ircd::json::stack::member::member(stack &s,
|
||||
const string_view &name,
|
||||
const json::tuple<T...> &t)
|
||||
:member
|
||||
{
|
||||
stack::top<object>(s), name, t
|
||||
}
|
||||
{}
|
||||
|
||||
template<class... T>
|
||||
inline
|
||||
ircd::json::stack::member::member(object &po,
|
||||
const string_view &name,
|
||||
const json::tuple<T...> &t)
|
||||
:member{po, name}
|
||||
{
|
||||
append(t);
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
inline void
|
||||
ircd::json::stack::member::append(const json::tuple<T...> &t)
|
||||
{
|
||||
_pre_append();
|
||||
const unwind post{[this]
|
||||
{
|
||||
_post_append();
|
||||
}};
|
||||
|
||||
s->append(serialized(t), [&t](mutable_buffer buf)
|
||||
{
|
||||
return ircd::size(stringify(buf, t));
|
||||
});
|
||||
}
|
||||
|
||||
inline void
|
||||
ircd::json::stack::member::_pre_append()
|
||||
{
|
||||
assert(!vc);
|
||||
}
|
||||
|
||||
inline void
|
||||
ircd::json::stack::member::_post_append()
|
||||
{
|
||||
vc |= true;
|
||||
}
|
74
include/ircd/json/stack/object.h
Normal file
74
include/ircd/json/stack/object.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_STACK_OBJECT_H
|
||||
|
||||
/// stack::object is constructed under the scope of either a stack::member,
|
||||
/// or a stack::array, or a stack itself. Only stack::member can be
|
||||
/// constructed directly under its scope.
|
||||
///
|
||||
/// For a stack::member parent, the named member is waiting for this value
|
||||
/// after leaving the stack at ':' after the name, this object will then
|
||||
/// print '{' and dtor with '}' and then return to the stack::member which
|
||||
/// will then return to its parent object.
|
||||
///
|
||||
/// For a stack::array parent, the stack may have been left at '[' or ','
|
||||
/// but either way this object will then print '{' and dtor with '}' and
|
||||
/// then return to the stack::array.
|
||||
///
|
||||
/// For a stack itself, this object is considered the "top object" and will
|
||||
/// open the stack with '{' and accept member instances under its scope
|
||||
/// until closing the stack with '}' after which the stack is done()
|
||||
///
|
||||
struct ircd::json::stack::object
|
||||
{
|
||||
member m; ///< optional internal member
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
member *pm {nullptr}; ///< parent member (if value of one)
|
||||
array *pa {nullptr}; ///< parent array (if value in one)
|
||||
member *cm {nullptr}; ///< current child member
|
||||
size_t mc {0}; ///< members witnessed (monotonic)
|
||||
|
||||
public:
|
||||
template<class... T> void append(const json::tuple<T...> &);
|
||||
void append(const json::object &);
|
||||
|
||||
object(stack &s); ///< Object is top
|
||||
object(array &pa); ///< Object is value in the array
|
||||
object(member &pm); ///< Object is value of named member
|
||||
object(object &po, const string_view &name);
|
||||
object(stack &s, const string_view &name);
|
||||
object(object &&) noexcept;
|
||||
object(const object &) = delete;
|
||||
~object() noexcept;
|
||||
|
||||
static const object &top(const stack &);
|
||||
static object &top(stack &);
|
||||
};
|
||||
|
||||
template<class... T>
|
||||
inline void
|
||||
ircd::json::stack::object::append(const json::tuple<T...> &t)
|
||||
{
|
||||
for_each(t, [this](const auto &name, const auto &_value)
|
||||
{
|
||||
const json::value value
|
||||
{
|
||||
_value
|
||||
};
|
||||
|
||||
if(defined(value))
|
||||
json::stack::member
|
||||
{
|
||||
*this, name, value
|
||||
};
|
||||
});
|
||||
}
|
194
include/ircd/json/stack/stack.h
Normal file
194
include/ircd/json/stack/stack.h
Normal file
|
@ -0,0 +1,194 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_STACK_H
|
||||
|
||||
namespace ircd::json
|
||||
{
|
||||
struct stack;
|
||||
}
|
||||
|
||||
/// Output stack machine for stringifying JSON as-you-go. This device allows
|
||||
/// the user to create JSON without knowing the contents when it is first
|
||||
/// constructed. An object or array is opened and the user can append to the
|
||||
/// stack creating the members or values or recursing further. The JSON is
|
||||
/// then closed automatically with exception safety. Partial JSON is written
|
||||
/// to the buffer as soon as possible.
|
||||
///
|
||||
/// The target buffer is not required to maintain earlier output from the same
|
||||
/// stack or even earlier members and values of the same object or array. The
|
||||
/// buffer may be smaller than the final JSON output and reused when the user
|
||||
/// chooses to flush it to some storage or socket. If the buffer becomes full
|
||||
/// a flush callback is attempted to make space and continue. This can occur
|
||||
/// while the output is still incomplete JSON.
|
||||
///
|
||||
/// The user first creates a master json::stack instance with some reasonable
|
||||
/// backing buffer. A suite of classes is provided to aid with building the
|
||||
/// JSON which attach to each other stackfully, and eventually lead to the
|
||||
/// root. There should only be one "active path" of instances at any given
|
||||
/// time, ideally following the scope of your code itself. You must force
|
||||
/// instances to go out of scope to continue at the same recursion depth.
|
||||
/// This way the json::stack can "follow" your code and "record" the final
|
||||
/// JSON output while allowing you to free the original resources required
|
||||
/// for each value.
|
||||
///
|
||||
struct ircd::json::stack
|
||||
{
|
||||
struct array;
|
||||
struct object;
|
||||
struct member;
|
||||
struct chase;
|
||||
struct const_chase;
|
||||
struct checkpoint;
|
||||
using flush_callback = std::function<const_buffer (const const_buffer &)>;
|
||||
|
||||
window_buffer buf;
|
||||
flush_callback flusher;
|
||||
std::exception_ptr eptr;
|
||||
checkpoint *cp {nullptr};
|
||||
size_t appended {0};
|
||||
size_t flushed {0};
|
||||
size_t level {0};
|
||||
size_t hiwat; ///< autoflush watermark
|
||||
size_t lowat; ///< flush(false) call min watermark
|
||||
|
||||
object *co {nullptr}; ///< The root object instance.
|
||||
array *ca {nullptr}; ///< Could be union with top_object but
|
||||
|
||||
void rethrow_exception();
|
||||
void append(const size_t expect, const window_buffer::closure &) noexcept;
|
||||
void append(const string_view &) noexcept;
|
||||
void append(const char &) noexcept;
|
||||
|
||||
public:
|
||||
bool opened() const; ///< Current stacking in progress.
|
||||
bool closed() const; ///< No stacking in progress.
|
||||
bool failed() const; ///< Exception pending in eptr.
|
||||
bool clean() const; ///< Never opened.
|
||||
bool done() const; ///< Opened and closed.
|
||||
size_t remaining() const;
|
||||
string_view completed() const;
|
||||
|
||||
size_t invalidate_checkpoints() noexcept;
|
||||
bool flush(const bool force = false) noexcept;
|
||||
size_t rewind(const size_t bytes) noexcept;
|
||||
void clear() noexcept;
|
||||
|
||||
stack(const mutable_buffer &,
|
||||
flush_callback = {},
|
||||
const size_t &hiwat = -1,
|
||||
const size_t &lowat = 0);
|
||||
|
||||
stack(stack &&) noexcept;
|
||||
stack(const stack &) = delete;
|
||||
~stack() noexcept;
|
||||
|
||||
template<class T> static const T &top(const stack &);
|
||||
template<class T> static T &top(stack &);
|
||||
};
|
||||
|
||||
#include "member.h"
|
||||
#include "object.h"
|
||||
#include "array.h"
|
||||
#include "chase.h"
|
||||
#include "checkpoint.h"
|
||||
|
||||
template<>
|
||||
inline ircd::json::stack::array &
|
||||
ircd::json::stack::stack::top<ircd::json::stack::array>(stack &s)
|
||||
{
|
||||
return array::top(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline const ircd::json::stack::array &
|
||||
ircd::json::stack::stack::top<ircd::json::stack::array>(const stack &s)
|
||||
{
|
||||
return array::top(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::json::stack::object &
|
||||
ircd::json::stack::stack::top<ircd::json::stack::object>(stack &s)
|
||||
{
|
||||
return object::top(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline const ircd::json::stack::object &
|
||||
ircd::json::stack::stack::top<ircd::json::stack::object>(const stack &s)
|
||||
{
|
||||
return object::top(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::json::stack::member &
|
||||
ircd::json::stack::stack::top<ircd::json::stack::member>(stack &s)
|
||||
{
|
||||
return member::top(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline const ircd::json::stack::member &
|
||||
ircd::json::stack::stack::top<ircd::json::stack::member>(const stack &s)
|
||||
{
|
||||
return member::top(s);
|
||||
}
|
||||
|
||||
inline ircd::string_view
|
||||
ircd::json::stack::completed()
|
||||
const
|
||||
{
|
||||
return buf.completed();
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::json::stack::remaining()
|
||||
const
|
||||
{
|
||||
return buf.remaining();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::failed()
|
||||
const
|
||||
{
|
||||
return bool(eptr);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::done()
|
||||
const
|
||||
{
|
||||
assert((opened() && level) || !level);
|
||||
return closed() && buf.consumed();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::clean()
|
||||
const
|
||||
{
|
||||
return closed() && !buf.consumed();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::closed()
|
||||
const
|
||||
{
|
||||
return !opened();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::stack::opened()
|
||||
const
|
||||
{
|
||||
return co || ca;
|
||||
}
|
|
@ -65,3 +65,17 @@ ircd::json::strung::strung(T&&... t)
|
|||
})
|
||||
}
|
||||
{}
|
||||
|
||||
inline ircd::json::strung::operator
|
||||
json::array()
|
||||
const
|
||||
{
|
||||
return string_view{*this};
|
||||
}
|
||||
|
||||
inline ircd::json::strung::operator
|
||||
json::object()
|
||||
const
|
||||
{
|
||||
return string_view{*this};
|
||||
}
|
||||
|
|
44
include/ircd/json/tool.h
Normal file
44
include/ircd/json/tool.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_TOOL_H
|
||||
|
||||
// Convenience toolset for higher level operations.
|
||||
namespace ircd::json
|
||||
{
|
||||
strung append(const array &, const string_view &val);
|
||||
strung prepend(const array &, const string_view &val);
|
||||
|
||||
void merge(stack::object &out, const vector &);
|
||||
|
||||
strung remove(const object &, const string_view &key);
|
||||
strung remove(const object &, const size_t &index);
|
||||
|
||||
strung insert(const object &, const members &);
|
||||
strung insert(const object &, const member &);
|
||||
|
||||
strung replace(const object &, const members &);
|
||||
strung replace(const object &, const member &);
|
||||
}
|
||||
|
||||
inline ircd::json::strung
|
||||
ircd::json::replace(const object &s,
|
||||
const json::member &m)
|
||||
{
|
||||
return replace(s, json::members{m});
|
||||
}
|
||||
|
||||
inline ircd::json::strung
|
||||
ircd::json::insert(const object &s,
|
||||
const json::member &m)
|
||||
{
|
||||
return insert(s, json::members{m});
|
||||
}
|
|
@ -60,17 +60,18 @@ template<class T>
|
|||
struct ircd::json::keys<T>::include
|
||||
:selection
|
||||
{
|
||||
constexpr include(const vector_view<const string_view> list)
|
||||
include(const vector_view<const string_view> &keys)
|
||||
:selection{0}
|
||||
{
|
||||
for(const auto key : list)
|
||||
for(const auto &key : keys)
|
||||
selection::set(key, true);
|
||||
}
|
||||
|
||||
constexpr include(const std::initializer_list<const string_view> list)
|
||||
template<class... list>
|
||||
consteval include(list&&... keys)
|
||||
:selection{0}
|
||||
{
|
||||
for(const auto key : list)
|
||||
for(auto&& key : {keys...})
|
||||
selection::set(key, true);
|
||||
}
|
||||
|
||||
|
@ -86,17 +87,19 @@ template<class T>
|
|||
struct ircd::json::keys<T>::exclude
|
||||
:selection
|
||||
{
|
||||
constexpr exclude(const vector_view<const string_view> list)
|
||||
exclude(const vector_view<const string_view> &keys)
|
||||
:selection{}
|
||||
{
|
||||
for(const auto key : list)
|
||||
for(const auto &key : keys)
|
||||
selection::set(key, false);
|
||||
}
|
||||
|
||||
constexpr exclude(const std::initializer_list<const string_view> list)
|
||||
|
||||
template<class... list>
|
||||
consteval exclude(list&&... keys)
|
||||
:selection{}
|
||||
{
|
||||
for(const auto key : list)
|
||||
for(auto&& key : {keys...})
|
||||
selection::set(key, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,26 +29,18 @@ namespace ircd::json
|
|||
/// not use the strict overload.
|
||||
IRCD_OVERLOAD(strict)
|
||||
|
||||
// Determine the type
|
||||
enum type type(const string_view &);
|
||||
enum type type(const string_view &, std::nothrow_t);
|
||||
enum type type(const string_view &, strict_t);
|
||||
enum type type(const string_view &, strict_t, std::nothrow_t);
|
||||
|
||||
// Query if type
|
||||
bool type(const string_view &, const enum type &, strict_t);
|
||||
bool type(const string_view &, const enum type &);
|
||||
|
||||
// Utils
|
||||
string_view reflect(const enum type &);
|
||||
[[gnu::pure]] string_view reflect(const enum type) noexcept;
|
||||
|
||||
extern const string_view literal_null;
|
||||
extern const string_view literal_true;
|
||||
extern const string_view literal_false;
|
||||
extern const string_view empty_string;
|
||||
extern const string_view empty_object;
|
||||
extern const string_view empty_array;
|
||||
extern const int64_t undefined_number;
|
||||
// Determine the type w/ strict correctness (full scan)
|
||||
[[gnu::pure]] bool type(const string_view &, const enum type, strict_t) noexcept;
|
||||
[[gnu::pure]] enum type type(const string_view &, strict_t, std::nothrow_t) noexcept;
|
||||
enum type type(const string_view &, strict_t);
|
||||
|
||||
// Determine the type quickly
|
||||
[[gnu::pure]] bool type(const string_view &, const enum type) noexcept;
|
||||
[[gnu::pure]] enum type type(const string_view &, std::nothrow_t) noexcept;
|
||||
enum type type(const string_view &);
|
||||
}
|
||||
|
||||
enum ircd::json::type
|
||||
|
|
|
@ -36,7 +36,15 @@ namespace ircd::json
|
|||
void valid(const string_view &);
|
||||
std::string why(const string_view &);
|
||||
|
||||
struct stats extern stats;
|
||||
extern const string_view literal_null;
|
||||
extern const string_view literal_true;
|
||||
extern const string_view literal_false;
|
||||
extern const string_view empty_string;
|
||||
extern const string_view empty_object;
|
||||
extern const string_view empty_array;
|
||||
extern const int64_t undefined_number;
|
||||
|
||||
extern struct stats stats;
|
||||
}
|
||||
|
||||
/// Statistics counter access; unfortunately these cannot participate as
|
||||
|
|
|
@ -22,11 +22,11 @@ namespace ircd::json
|
|||
|
||||
size_t serialized(const bool &);
|
||||
size_t serialized(const value &);
|
||||
size_t serialized(const value *const &begin, const value *const &end);
|
||||
size_t serialized(const value *begin, const value *end);
|
||||
size_t serialized(const values &);
|
||||
|
||||
string_view stringify(mutable_buffer &, const value &);
|
||||
string_view stringify(mutable_buffer &, const value *const &begin, const value *const &end);
|
||||
string_view stringify(mutable_buffer &, const value *begin, const value *end);
|
||||
std::ostream &operator<<(std::ostream &, const value &);
|
||||
|
||||
bool operator==(const value &a, const value &b);
|
||||
|
@ -366,6 +366,18 @@ ircd::json::operator!=(const value &a, const value &b)
|
|||
return !operator==(a, b);
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::json::serialized(const bool &b)
|
||||
{
|
||||
constexpr const size_t tf[2]
|
||||
{
|
||||
_constexpr_strlen("false"),
|
||||
_constexpr_strlen("true"),
|
||||
};
|
||||
|
||||
return tf[b];
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::defined(const value &a)
|
||||
{
|
||||
|
|
|
@ -47,8 +47,8 @@ struct ircd::json::vector
|
|||
const_iterator begin() const;
|
||||
|
||||
const_iterator find(size_t i) const;
|
||||
value_type at(const size_t &i) const;
|
||||
value_type operator[](const size_t &i) const;
|
||||
value_type at(const size_t i) const;
|
||||
value_type operator[](const size_t i) const;
|
||||
|
||||
bool empty() const;
|
||||
operator bool() const;
|
||||
|
@ -60,9 +60,49 @@ struct ircd::json::vector
|
|||
|
||||
#include "vector_iterator.h"
|
||||
|
||||
inline size_t
|
||||
ircd::json::vector::size()
|
||||
const
|
||||
{
|
||||
return count();
|
||||
}
|
||||
|
||||
inline ircd::json::vector::operator
|
||||
bool()
|
||||
const
|
||||
{
|
||||
return !empty();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::vector::empty()
|
||||
const
|
||||
{
|
||||
const string_view &sv{*this};
|
||||
return sv.empty();
|
||||
}
|
||||
|
||||
inline ircd::json::vector::const_iterator
|
||||
ircd::json::vector::end()
|
||||
const
|
||||
{
|
||||
return { string_view::end(), string_view::end() };
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!(const vector &v)
|
||||
{
|
||||
return v.empty();
|
||||
}
|
||||
|
||||
inline size_t
|
||||
ircd::json::size(const vector &v)
|
||||
{
|
||||
return v.size();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::empty(const vector &v)
|
||||
{
|
||||
return v.empty();
|
||||
}
|
||||
|
|
79
include/ircd/m/creator.h
Normal file
79
include/ircd/m/creator.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_CREATOR_H
|
||||
|
||||
namespace ircd::m
|
||||
{
|
||||
id::user creator(const event &);
|
||||
id::user creation(const event &);
|
||||
|
||||
bool creator(const event &, const id::user &);
|
||||
bool creation(const event &, const id::user &);
|
||||
}
|
||||
|
||||
/// Events that are not type=m.room.create will return false; the sender field
|
||||
/// will be tried if available, otherwise content.creator will be tried.
|
||||
inline bool
|
||||
ircd::m::creation(const event &event,
|
||||
const id::user &user)
|
||||
{
|
||||
if(json::get<"type"_>(event) != "m.room.create")
|
||||
return false;
|
||||
|
||||
return creator(event, user);
|
||||
}
|
||||
|
||||
/// The sender field will be tried if available, otherwise content.creator will
|
||||
/// be tried.
|
||||
inline bool
|
||||
ircd::m::creator(const event &event,
|
||||
const id::user &user)
|
||||
{
|
||||
assert(defined(user));
|
||||
if(likely(defined(json::get<"sender"_>(event))))
|
||||
if(json::get<"sender"_>(event) == user)
|
||||
return true;
|
||||
|
||||
const json::string creator
|
||||
{
|
||||
json::get<"content"_>(event).get("creator")
|
||||
};
|
||||
|
||||
return creator == user;
|
||||
}
|
||||
|
||||
/// Events that are not type=m.room.create will return empty; the sender
|
||||
/// will be tried if available, otherwise content.creator will be tried.
|
||||
inline ircd::m::id::user
|
||||
ircd::m::creation(const event &event)
|
||||
{
|
||||
if(json::get<"type"_>(event) != "m.room.create")
|
||||
return id::user{};
|
||||
|
||||
return creator(event);
|
||||
}
|
||||
|
||||
/// The sender will be tried if available, otherwise content.creator will be
|
||||
/// tried.
|
||||
inline ircd::m::id::user
|
||||
ircd::m::creator(const event &event)
|
||||
{
|
||||
if(likely(defined(json::get<"sender"_>(event))))
|
||||
return json::get<"sender"_>(event);
|
||||
|
||||
const json::string creator
|
||||
{
|
||||
json::get<"content"_>(event).get("creator")
|
||||
};
|
||||
|
||||
return creator;
|
||||
}
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using event_horizon_tuple = std::tuple<event::idx>;
|
||||
|
||||
constexpr size_t EVENT_HORIZON_KEY_MAX_SIZE
|
||||
{
|
||||
id::MAX_SIZE + 1 + 8
|
||||
|
@ -20,7 +22,7 @@ namespace ircd::m::dbs
|
|||
|
||||
string_view event_horizon_key(const mutable_buffer &out, const id::event &, const event::idx &);
|
||||
string_view event_horizon_key(const mutable_buffer &out, const id::event &);
|
||||
std::tuple<event::idx> event_horizon_key(const string_view &amalgam);
|
||||
event_horizon_tuple event_horizon_key(const string_view &amalgam);
|
||||
|
||||
size_t _prefetch_event_horizon_resolve(const event &, const opts &);
|
||||
void _index_event_horizon_resolve(db::txn &, const event &, const opts &); //query
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using event_refs_tuple = std::tuple<ref, event::idx>;
|
||||
|
||||
constexpr size_t EVENT_REFS_KEY_MAX_SIZE
|
||||
{
|
||||
sizeof(event::idx) + sizeof(event::idx)
|
||||
|
@ -34,7 +36,7 @@ namespace ircd::m::dbs
|
|||
const ref &type,
|
||||
const event::idx &referer);
|
||||
|
||||
std::tuple<ref, event::idx>
|
||||
event_refs_tuple
|
||||
event_refs_key(const string_view &amalgam);
|
||||
|
||||
string_view
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using event_sender_tuple = std::tuple<event::idx>;
|
||||
using event_sender_origin_tuple = std::tuple<string_view, event::idx>;
|
||||
|
||||
constexpr size_t EVENT_SENDER_KEY_MAX_SIZE
|
||||
{
|
||||
id::MAX_SIZE + 1 + 8
|
||||
|
@ -21,13 +24,13 @@ namespace ircd::m::dbs
|
|||
// sender keyspace
|
||||
bool is_event_sender_key(const string_view &amalgam);
|
||||
string_view event_sender_key(const mutable_buffer &out, const id::user &, const event::idx & = 0UL);
|
||||
std::tuple<event::idx> event_sender_key(const string_view &amalgam);
|
||||
event_sender_tuple event_sender_key(const string_view &amalgam);
|
||||
|
||||
// sender_origin keyspace
|
||||
bool is_event_sender_origin_key(const string_view &amalgam);
|
||||
string_view event_sender_origin_key(const mutable_buffer &out, const string_view &origin, const string_view &localpart = {}, const event::idx & = 0UL);
|
||||
string_view event_sender_origin_key(const mutable_buffer &out, const id::user &, const event::idx &);
|
||||
std::tuple<string_view, event::idx> event_sender_origin_key(const string_view &amalgam);
|
||||
event_sender_origin_tuple event_sender_origin_key(const string_view &amalgam);
|
||||
|
||||
void _index_event_sender(db::txn &, const event &, const opts &);
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
// state_key, type, room_id, depth, event_idx
|
||||
using event_state_tuple = std::tuple<string_view, string_view, string_view, int64_t, event::idx>;
|
||||
|
||||
constexpr size_t EVENT_STATE_KEY_MAX_SIZE
|
||||
{
|
||||
0
|
||||
|
@ -24,9 +27,6 @@ namespace ircd::m::dbs
|
|||
+ 8
|
||||
};
|
||||
|
||||
// state_key, type, room_id, depth, event_idx
|
||||
using event_state_tuple = std::tuple<string_view, string_view, string_view, int64_t, event::idx>;
|
||||
|
||||
string_view event_state_key(const mutable_buffer &out, const event_state_tuple &);
|
||||
event_state_tuple event_state_key(const string_view &);
|
||||
|
||||
|
|
|
@ -13,13 +13,15 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using event_type_tuple = std::tuple<event::idx>;
|
||||
|
||||
constexpr size_t EVENT_TYPE_KEY_MAX_SIZE
|
||||
{
|
||||
event::TYPE_MAX_SIZE + 1 + 8
|
||||
};
|
||||
|
||||
string_view event_type_key(const mutable_buffer &out, const string_view &, const event::idx & = 0);
|
||||
std::tuple<event::idx> event_type_key(const string_view &amalgam);
|
||||
event_type_tuple event_type_key(const string_view &amalgam);
|
||||
|
||||
void _index_event_type(db::txn &, const event &, const opts &);
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using room_events_tuple = std::tuple<uint64_t, event::idx>;
|
||||
|
||||
constexpr size_t ROOM_EVENTS_KEY_MAX_SIZE
|
||||
{
|
||||
id::MAX_SIZE + 1 + 8 + 8
|
||||
|
@ -20,7 +22,7 @@ namespace ircd::m::dbs
|
|||
|
||||
string_view room_events_key(const mutable_buffer &out, const id::room &, const uint64_t &depth, const event::idx &);
|
||||
string_view room_events_key(const mutable_buffer &out, const id::room &, const uint64_t &depth);
|
||||
std::tuple<uint64_t, event::idx> room_events_key(const string_view &amalgam);
|
||||
room_events_tuple room_events_key(const string_view &amalgam);
|
||||
|
||||
void _index_room_events(db::txn &, const event &, const opts &);
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using room_joined_tuple = std::tuple<string_view, string_view>;
|
||||
|
||||
constexpr size_t ROOM_JOINED_KEY_MAX_SIZE
|
||||
{
|
||||
id::MAX_SIZE + event::ORIGIN_MAX_SIZE + id::MAX_SIZE
|
||||
|
@ -20,7 +22,7 @@ namespace ircd::m::dbs
|
|||
|
||||
string_view room_joined_key(const mutable_buffer &out, const id::room &, const string_view &origin, const id::user &member);
|
||||
string_view room_joined_key(const mutable_buffer &out, const id::room &, const string_view &origin);
|
||||
std::tuple<string_view, string_view> room_joined_key(const string_view &amalgam);
|
||||
room_joined_tuple room_joined_key(const string_view &amalgam);
|
||||
|
||||
void _index_room_joined(db::txn &, const event &, const opts &);
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using room_state_tuple = std::tuple<string_view, string_view>;
|
||||
|
||||
constexpr size_t ROOM_STATE_KEY_MAX_SIZE
|
||||
{
|
||||
id::MAX_SIZE + event::TYPE_MAX_SIZE + event::STATE_KEY_MAX_SIZE
|
||||
|
@ -20,7 +22,7 @@ namespace ircd::m::dbs
|
|||
|
||||
string_view room_state_key(const mutable_buffer &out, const id::room &, const string_view &type, const string_view &state_key);
|
||||
string_view room_state_key(const mutable_buffer &out, const id::room &, const string_view &type);
|
||||
std::tuple<string_view, string_view> room_state_key(const string_view &amalgam);
|
||||
room_state_tuple room_state_key(const string_view &amalgam);
|
||||
|
||||
void _index_room_state(db::txn &, const event &, const opts &);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using room_state_space_key_parts = std::tuple<string_view, string_view, int64_t, event::idx>;
|
||||
using room_state_space_tuple = std::tuple<string_view, string_view, int64_t, event::idx>;
|
||||
|
||||
constexpr size_t ROOM_STATE_SPACE_KEY_MAX_SIZE
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ namespace ircd::m::dbs
|
|||
string_view room_state_space_key(const mutable_buffer &out, const id::room &, const string_view &type, const string_view &state_key);
|
||||
string_view room_state_space_key(const mutable_buffer &out, const id::room &, const string_view &type);
|
||||
string_view room_state_space_key(const mutable_buffer &out, const id::room &);
|
||||
room_state_space_key_parts room_state_space_key(const string_view &amalgam);
|
||||
room_state_space_tuple room_state_space_key(const string_view &amalgam);
|
||||
|
||||
void _index_room_state_space(db::txn &, const event &, const opts &);
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
using room_type_tuple = std::tuple<string_view, uint64_t, event::idx>;
|
||||
|
||||
constexpr size_t ROOM_TYPE_KEY_MAX_SIZE
|
||||
{
|
||||
id::MAX_SIZE // room_id
|
||||
|
@ -23,8 +25,6 @@ namespace ircd::m::dbs
|
|||
+ 8 // u64
|
||||
};
|
||||
|
||||
using room_type_tuple = std::tuple<string_view, uint64_t, event::idx>;
|
||||
|
||||
room_type_tuple
|
||||
room_type_key(const string_view &amalgam);
|
||||
|
||||
|
|
|
@ -53,11 +53,14 @@ struct ircd::m::signing_key_update
|
|||
/// Required. The user ID whose cross-signing keys have changed.
|
||||
json::property<name::user_id, json::string>,
|
||||
|
||||
/// Cross signing key
|
||||
/// Master signing key
|
||||
json::property<name::master_key, json::object>,
|
||||
|
||||
/// Cross signing key
|
||||
json::property<name::self_signing_key, json::object>
|
||||
/// Self signing key
|
||||
json::property<name::self_signing_key, json::object>,
|
||||
|
||||
/// User signing key (local only)
|
||||
json::property<name::user_signing_key, json::object>
|
||||
>
|
||||
{
|
||||
using super_type::tuple;
|
||||
|
|
|
@ -29,6 +29,29 @@ struct ircd::m::event::append
|
|||
{
|
||||
struct opts;
|
||||
|
||||
private:
|
||||
static const event::keys::exclude exclude_keys;
|
||||
static const event::keys default_keys;
|
||||
static conf::item<std::string> exclude_types;
|
||||
static conf::item<bool> info;
|
||||
static log::log log;
|
||||
|
||||
bool is_ignored(const event &, const opts &) const;
|
||||
bool is_redacted(const event &, const opts &) const;
|
||||
bool is_invisible(const event &, const opts &) const;
|
||||
bool is_excluded(const event &, const opts &) const;
|
||||
|
||||
bool bundle_replace(json::stack::object &, const event &, const opts &);
|
||||
void _relations(json::stack::object &, const event &, const opts &);
|
||||
void _age(json::stack::object &, const event &, const opts &);
|
||||
void _txnid(json::stack::object &, const event &, const opts &);
|
||||
void _prev_state(json::stack::object &, const event &, const opts &);
|
||||
void _unsigned(json::stack::object &, const event &, const opts &);
|
||||
|
||||
bool members(json::stack::object &, const event &, const opts &);
|
||||
bool object(json::stack::array &, const event &, const opts &);
|
||||
|
||||
public:
|
||||
append(json::stack::object &, const event &, const opts &);
|
||||
append(json::stack::object &, const event &);
|
||||
append(json::stack::array &, const event &, const opts &);
|
||||
|
@ -39,11 +62,11 @@ struct ircd::m::event::append
|
|||
/// can provide the best result.
|
||||
struct ircd::m::event::append::opts
|
||||
{
|
||||
const event::idx *event_idx {nullptr};
|
||||
const string_view *client_txnid {nullptr};
|
||||
const id::user *user_id {nullptr};
|
||||
const room *user_room {nullptr};
|
||||
const int64_t *room_depth {nullptr};
|
||||
event::idx event_idx {0};
|
||||
string_view client_txnid;
|
||||
id::user user_id;
|
||||
id::room user_room_id;
|
||||
int64_t room_depth {-1L};
|
||||
const event::keys *keys {nullptr};
|
||||
const m::event_filter *event_filter {nullptr};
|
||||
long age {std::numeric_limits<long>::min()};
|
||||
|
@ -51,6 +74,8 @@ struct ircd::m::event::append::opts
|
|||
bool query_prev_state {true};
|
||||
bool query_redacted {true};
|
||||
bool query_visible {false};
|
||||
bool bundle_all {false};
|
||||
bool bundle_replace {false};
|
||||
};
|
||||
|
||||
inline
|
||||
|
@ -64,3 +89,23 @@ ircd::m::event::append::append(json::stack::object &o,
|
|||
const event &e)
|
||||
:append{o, e, {}}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::m::event::append::append(json::stack::array &array,
|
||||
const event &event,
|
||||
const opts &opts)
|
||||
:returns<bool>{[this, &array, &event, &opts]
|
||||
{
|
||||
return object(array, event, opts);
|
||||
}}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::m::event::append::append(json::stack::object &object,
|
||||
const event &event,
|
||||
const opts &opts)
|
||||
:returns<bool>{[this, &object, &event, &opts]
|
||||
{
|
||||
return members(object, event, opts);
|
||||
}}
|
||||
{}
|
||||
|
|
|
@ -41,11 +41,12 @@ namespace ircd::m
|
|||
size_t degree(const event &);
|
||||
bool before(const event &a, const event &b);
|
||||
|
||||
json::object hashes(const mutable_buffer &, const event &);
|
||||
event signatures(const mutable_buffer &, const m::event &, const string_view &origin);
|
||||
event signatures(const mutable_buffer &, const m::event &);
|
||||
event essential(event, const mutable_buffer &content, const bool &sigs = false);
|
||||
event signatures(const mutable_buffer &, const event &, const string_view &origin, const ed25519::sk &, const string_view &pkid);
|
||||
event signatures(const mutable_buffer &, const event &, const string_view &origin);
|
||||
event signatures(const mutable_buffer &, const event &);
|
||||
|
||||
json::object hashes(const mutable_buffer &, const event &);
|
||||
bool verify_hash(const event &, const sha256::buf &);
|
||||
bool verify_hash(const event &);
|
||||
|
||||
|
|
|
@ -26,9 +26,8 @@ namespace ircd::m::dbs
|
|||
/// scan when using this interface, etc).
|
||||
struct ircd::m::event::refs
|
||||
{
|
||||
using closure = util::closure_bool
|
||||
using closure = util::function_bool
|
||||
<
|
||||
std::function,
|
||||
const event::idx &, const dbs::ref &
|
||||
>;
|
||||
|
||||
|
|
|
@ -97,9 +97,8 @@ namespace ircd::m::events::refs
|
|||
namespace ircd::m::events::relates
|
||||
{
|
||||
// (source, rel_type, target)
|
||||
using closure = util::closure_bool
|
||||
using closure = util::function_bool
|
||||
<
|
||||
std::function,
|
||||
const event::idx &, const m::relates_to &, const event::idx &
|
||||
>;
|
||||
|
||||
|
@ -112,9 +111,9 @@ namespace ircd::m::events::relates
|
|||
namespace ircd::m::events::annotates
|
||||
{
|
||||
// (source, key, target)
|
||||
using closure = util::closure_bool
|
||||
using closure = util::function_bool
|
||||
<
|
||||
std::function, const event::idx &, const string_view &, const event::idx &
|
||||
const event::idx &, const string_view &, const event::idx &
|
||||
>;
|
||||
|
||||
// Iterate events in range
|
||||
|
|
|
@ -21,9 +21,9 @@ struct ircd::m::fed::send_join
|
|||
{
|
||||
struct opts;
|
||||
|
||||
explicit operator json::array() const
|
||||
explicit operator json::object() const
|
||||
{
|
||||
return json::array
|
||||
return json::object
|
||||
{
|
||||
in.content
|
||||
};
|
||||
|
@ -42,4 +42,5 @@ struct ircd::m::fed::send_join::opts
|
|||
:request::opts
|
||||
{
|
||||
bool knock {false};
|
||||
bool omit_members {false};
|
||||
};
|
||||
|
|
|
@ -83,6 +83,8 @@ struct ircd::m::homeserver
|
|||
/// Factory to create homeserver with single procedure for shlib purposes.
|
||||
static homeserver *init(const struct opts *);
|
||||
static void fini(homeserver *) noexcept;
|
||||
static bool rehash(homeserver *);
|
||||
static bool refresh(homeserver *);
|
||||
};
|
||||
|
||||
struct ircd::m::homeserver::key
|
||||
|
|
|
@ -63,7 +63,8 @@ struct ircd::m::keys
|
|||
static bool get(const queries &, const closure_bool &);
|
||||
static bool get(const string_view &server_name, const closure &);
|
||||
static bool get(const string_view &server_name, const string_view &key_id, const closure &);
|
||||
static bool query(const string_view &query_server, const queries &, const closure_bool &);
|
||||
static bool query(const string_view &remote, const queries &, const closure_bool &, const mutable_buffer &, const bool dynamic = false);
|
||||
static bool query(const string_view &remote, const queries &, const closure_bool &);
|
||||
static size_t fetch(const queries &);
|
||||
static size_t fetch(const pdus &);
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace ircd::m
|
|||
#include "device.h"
|
||||
#include "push.h"
|
||||
#include "createroom.h"
|
||||
#include "creator.h"
|
||||
#include "txn.h"
|
||||
#include "relates.h"
|
||||
#include "room/room.h"
|
||||
|
@ -73,6 +74,7 @@ namespace ircd::m
|
|||
#include "rooms_summary.h"
|
||||
#include "groups.h"
|
||||
#include "membership.h"
|
||||
#include "member.h"
|
||||
#include "filter.h"
|
||||
#include "events.h"
|
||||
#include "node.h"
|
||||
|
@ -87,6 +89,7 @@ namespace ircd::m
|
|||
#include "direct_to_device.h"
|
||||
#include "visible.h"
|
||||
#include "redacted.h"
|
||||
#include "replaced.h"
|
||||
#include "feds.h"
|
||||
#include "app.h"
|
||||
#include "bridge.h"
|
||||
|
|
|
@ -27,11 +27,13 @@ namespace ircd::m::media::file
|
|||
{
|
||||
using closure = std::function<void (const const_buffer &)>;
|
||||
|
||||
constexpr bool debug_read {false};
|
||||
|
||||
room::id room_id(room::id::buf &out, const mxc &);
|
||||
room::id::buf room_id(const mxc &);
|
||||
|
||||
size_t read(const room &, const closure &);
|
||||
size_t write(const room &, const user::id &, const const_buffer &content, const string_view &content_type);
|
||||
size_t write(const room &, const user::id &, const const_buffer &content, const string_view &content_type, const string_view &name = {});
|
||||
|
||||
room::id::buf
|
||||
download(const mxc &,
|
||||
|
|
42
include/ircd/m/member.h
Normal file
42
include/ircd/m/member.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2023 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_MEMBER_H
|
||||
|
||||
namespace ircd::m
|
||||
{
|
||||
bool member(const event &, const string_view &membership);
|
||||
bool member(const event &, const vector_view<const string_view> &);
|
||||
}
|
||||
|
||||
/// Events that are not type=m.room.member will return false; the rest will be
|
||||
/// passed to the analogous m::membership function which does not check type.
|
||||
inline bool
|
||||
ircd::m::member(const event &event,
|
||||
const vector_view<const string_view> &membership)
|
||||
{
|
||||
if(json::get<"type"_>(event) != "m.room.member")
|
||||
return false;
|
||||
|
||||
return m::membership(event, membership);
|
||||
}
|
||||
|
||||
/// Events that are not type=m.room.member will return false; the rest will be
|
||||
/// passed to the analogous m::membership function which does not check type.
|
||||
inline bool
|
||||
ircd::m::member(const event &event,
|
||||
const string_view &membership)
|
||||
{
|
||||
if(json::get<"type"_>(event) != "m.room.member")
|
||||
return false;
|
||||
|
||||
return m::membership(event) == membership;
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
namespace ircd::m
|
||||
{
|
||||
// Extract membership string from event data.
|
||||
string_view membership(const event &);
|
||||
[[gnu::pure]] string_view membership(const event &);
|
||||
|
||||
// Query and copy membership string to buffer. Note that the event type
|
||||
// is not checked here, only content.membership is sought.
|
||||
|
|
|
@ -191,6 +191,7 @@ struct ircd::m::name
|
|||
static constexpr const char *const pattern {"pattern"};
|
||||
static constexpr const char *const is {"is"};
|
||||
static constexpr const char *const cond {"cond"};
|
||||
static constexpr const char *const value {"value"};
|
||||
|
||||
static constexpr const char *const actions {"actions"};
|
||||
static constexpr const char *const default_ {"default"};
|
||||
|
@ -220,4 +221,5 @@ struct ircd::m::name
|
|||
static constexpr const char *const usage {"usage"};
|
||||
static constexpr const char *const master_key {"master_key"};
|
||||
static constexpr const char *const self_signing_key {"self_signing_key"};
|
||||
static constexpr const char *const user_signing_key {"user_signing_key"};
|
||||
};
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue