mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
lwsac
Introduce an api for efficiently dealing with allocations for large, unknown amounts of objects.
This commit is contained in:
parent
ed00704566
commit
a5b2248e72
14 changed files with 1036 additions and 0 deletions
|
@ -110,6 +110,7 @@ option(LWS_WITH_GCOV "Build with gcc gcov coverage instrumentation" OFF)
|
|||
option(LWS_WITH_EXPORT_LWSTARGETS "Export libwebsockets CMake targets. Disable if they conflict with an outer cmake project." ON)
|
||||
option(LWS_REPRODUCIBLE "Build libwebsockets reproducible. It removes the build user and hostname from the build" ON)
|
||||
option(LWS_WITH_MINIMAL_EXAMPLES "Also build the normally standalone minimal examples, for QA" OFF)
|
||||
option(LWS_WITH_LWSAC "lwsac Chunk Allocation api" ON)
|
||||
#
|
||||
# End of user settings
|
||||
#
|
||||
|
@ -149,6 +150,10 @@ if (WIN32 OR LWS_WITH_ESP32)
|
|||
set(LWS_UNIX_SOCK 0)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_ESP32)
|
||||
set(LWS_WITH_LWSAC 0)
|
||||
endif()
|
||||
|
||||
project(libwebsockets C)
|
||||
|
||||
set(PACKAGE "libwebsockets")
|
||||
|
@ -875,6 +880,12 @@ if (LWS_WITH_PEER_LIMITS)
|
|||
lib/misc/peer-limits.c)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_LWSAC)
|
||||
list(APPEND SOURCES
|
||||
lib/misc/lwsac/lwsac.c
|
||||
lib/misc/lwsac/cached-file.c)
|
||||
endif()
|
||||
|
||||
if (NOT LWS_WITHOUT_CLIENT)
|
||||
list(APPEND SOURCES
|
||||
lib/core/connect.c
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#cmakedefine LWS_ROLE_CGI
|
||||
#cmakedefine LWS_ROLE_DBUS
|
||||
|
||||
#cmakedefine LWS_WITH_LWSAC
|
||||
|
||||
/* Define to 1 to use wolfSSL/CyaSSL as a replacement for OpenSSL.
|
||||
* LWS_OPENSSL_SUPPORT needs to be set also for this to work. */
|
||||
#cmakedefine USE_WOLFSSL
|
||||
|
|
131
doc-assets/lwsac.svg
Normal file
131
doc-assets/lwsac.svg
Normal file
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="187.8mm" height="80.752mm" version="1.1" viewBox="0 0 187.79663 80.752144" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<filter id="a" x="-.014418" y="-.034864" width="1.0288" height="1.0697" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="1.5466839"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g transform="translate(-161.61 156.88)">
|
||||
<g>
|
||||
<g stroke="#666" stroke-linejoin="round">
|
||||
<rect transform="matrix(.709 0 0 .709 167.83 -486.38)" x="-5.0609" y="468.46" width="257.45" height="106.47" ry="0" filter="url(#a)" stroke-width=".24551"/>
|
||||
<rect x="163.71" y="-154.85" width="182.53" height="75.489" ry="0" fill="#f2f2f2" stroke-width=".17406"/>
|
||||
<rect x="171.7" y="-140.36" width="30.952" height="50.082" fill="#808080" stroke-width=".40058"/>
|
||||
<rect x="172.68" y="-139.06" width="28.784" height="6.4996" fill="#a00" stroke-width=".11698"/>
|
||||
<rect x="172.74" y="-131.83" width="28.784" height="40.39" fill="#c4c8b7" stroke-width=".11698"/>
|
||||
</g>
|
||||
<text x="181.33067" y="-136.13423" fill="#ffffff" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="181.33067" y="-136.13423" fill="#ffffff" font-family="'Open Sans'" font-size="2.8222px" stroke-width=".39677">struct lwsac</tspan></text>
|
||||
<text x="184.53554" y="-92.850395" fill="#000000" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="184.53554" y="-92.850395" font-family="'Open Sans'" stroke-width=".39677">allocated area</tspan></text>
|
||||
<path d="m206.96-138.6 1.5352 0.74171-1.4119 0.76078-0.0812-0.34638-6.239-0.0174c0.0635-0.40246-0.0214-0.51522 0.0725-0.82588l6.136 5e-3z" fill="#2a7fff"/>
|
||||
<rect x="172" y="-150.67" width="26.156" height="4.4025" fill="#500" stroke="#666" stroke-linejoin="round" stroke-width=".091779"/>
|
||||
<text x="185.17738" y="-147.67433" fill="#ffffff" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="185.17738" y="-147.67433" fill="#ffffff" font-family="'Open Sans'" font-size="2.8222px" stroke-width=".39677">struct lwsac *head</tspan></text>
|
||||
<text x="198.1916" y="-137.38612" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="198.1916" y="-137.38612">next</tspan><tspan x="198.1916" y="-135.51024">head</tspan><tspan x="198.1916" y="-133.63435">curr</tspan></text>
|
||||
<path d="m174.55-138.71-0.74171 2.0619-0.76078-1.8964 0.34638-0.10906 0.0174-8.3796c0.40246 0.0853 0.51522-0.0288 0.82587 0.0974l-5e-3 8.2413z" fill="#2a7fff"/>
|
||||
<text x="188.84824" y="-135.46999" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="188.84824" y="-135.46999" text-align="start">ofs</tspan><tspan x="188.84824" y="-133.5941" text-align="start">alloc_size</tspan></text>
|
||||
<path d="m195.91-144.71-0.7417-2.0619-0.76078 1.8964 0.34637 0.10906-0.0412 9.1651c0.24984 0.0323 0.88518-0.0192 1.5658-0.0156 0.0711-0.0968 0.0691-0.46205 0.015-0.82619-0.45397 2e-3 -0.78488-5e-3 -0.69634-0.0411l-5e-3 -8.2413z" fill="#2a7fff"/>
|
||||
</g>
|
||||
<path d="m201.26-131.89-2.3876 2.1223-0.13265 35.947 2.7855 2.255" fill="none" stroke="#000" stroke-dasharray="0.5627649, 0.1875883" stroke-width=".18759"/>
|
||||
<path d="m191.97-133.09 6.8975 7.6934" fill="none" stroke="#000" stroke-dasharray="0.37517659, 0.1875883" stroke-width=".18759"/>
|
||||
<path d="m174.12-132.51-1.5352 0.7417 1.4119 0.76078 0.0812-0.34638 2.127 0.0157c-0.0635-0.40245 0.0214-0.54838-0.0725-0.85903l-2.024 5e-3z"/>
|
||||
<path d="m176.09-131.63 5.7037 0.0664 6.2343-3.913 0.66323-0.0995" fill="none" stroke="#000" stroke-dasharray="0.37517659, 0.1875883" stroke-width=".18759"/>
|
||||
<g>
|
||||
<rect x="220.5" y="-140.05" width="30.952" height="50.082" fill="#808080" stroke="#666" stroke-linejoin="round" stroke-width=".40058"/>
|
||||
<rect x="221.48" y="-138.74" width="28.784" height="6.4996" fill="#a00" stroke="#666" stroke-linejoin="round" stroke-width=".11698"/>
|
||||
<text x="226.27528" y="-118.77273" fill="#000000" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="226.27528" y="-118.77273" font-family="'Open Sans'" stroke-width=".18759">ptr aligned</tspan></text>
|
||||
<rect x="221.54" y="-131.51" width="28.784" height="40.39" fill="#c4c8b7" stroke="#666" stroke-linejoin="round" stroke-width=".11698"/>
|
||||
<text x="230.13133" y="-135.82219" fill="#ffffff" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="230.13133" y="-135.82219" fill="#ffffff" font-family="'Open Sans'" font-size="2.8222px" stroke-width=".39677">struct lwsac</tspan></text>
|
||||
<text x="233.3362" y="-92.538383" fill="#000000" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="233.3362" y="-92.538383" font-family="'Open Sans'" stroke-width=".39677">allocated area</tspan></text>
|
||||
<path d="m255.76-138.29 1.5352 0.74171-1.4119 0.76078-0.0812-0.34638-6.239-0.0174c0.0635-0.40246-0.0214-0.51522 0.0725-0.82588l6.136 5e-3z" fill="#2a7fff"/>
|
||||
<rect x="220.8" y="-150.36" width="26.156" height="4.4025" fill="#500" stroke="#666" stroke-linejoin="round" stroke-width=".091779"/>
|
||||
<text x="233.97806" y="-147.36229" fill="#ffffff" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="233.97806" y="-147.36229" fill="#ffffff" font-family="'Open Sans'" font-size="2.8222px" stroke-width=".39677">struct lwsac *head</tspan></text>
|
||||
<text x="246.99228" y="-137.07408" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="246.99228" y="-137.07408">next</tspan><tspan x="246.99228" y="-135.1982">head</tspan><tspan x="246.99228" y="-133.32231">curr</tspan></text>
|
||||
<path d="m223.35-138.4-0.74171 2.0619-0.76078-1.8964 0.34638-0.10905 0.0174-8.3796c0.40246 0.0853 0.51522-0.0288 0.82588 0.0974l-5e-3 8.2413z" fill="#2a7fff"/>
|
||||
<text x="237.64891" y="-135.15791" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="237.64891" y="-135.15791" text-align="start">ofs</tspan><tspan x="237.64891" y="-133.28203" text-align="start">alloc_size</tspan></text>
|
||||
<path d="m244.71-144.39-0.74171-2.0619-0.76078 1.8964 0.34638 0.10906-0.0412 9.1651c0.24984 0.0323 0.88518-0.0192 1.5658-0.0156 0.0711-0.0968 0.0691-0.46205 0.015-0.82618-0.45397 2e-3 -0.78488-5e-3 -0.69634-0.0411l-5e-3 -8.2413z" fill="#2a7fff"/>
|
||||
<rect x="221.98" y="-130.85" width="27.712" height="7.4313" fill="#ff8080" stroke="#666" stroke-linejoin="round" stroke-width=".14463"/>
|
||||
<rect x="221.97" y="-121.59" width="27.712" height="7.4313" fill="#ff8080" stroke="#666" stroke-linejoin="round" stroke-width=".14463"/>
|
||||
</g>
|
||||
<path d="m250.06-131.58-2.3876 2.1223-0.13265 35.947 2.7855 2.255" fill="none" stroke="#000" stroke-dasharray="0.56276491, 0.1875883" stroke-width=".18759"/>
|
||||
<path d="m240.78-132.77 6.8975 7.6934" fill="none" stroke="#000" stroke-dasharray="0.37517659, 0.1875883" stroke-width=".18759"/>
|
||||
<text x="235.9016" y="-126.22051" fill="#ffffff" font-family="'Open Sans'" font-size="2.5582px" letter-spacing="0px" stroke-width=".31977" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="235.9016" y="-126.22051" fill="#ffffff" font-family="'Open Sans'" stroke-width=".31977">lwsac_use area</tspan></text>
|
||||
<path d="m223.49-112.72-1.5352 0.7417 1.4119 0.76079 0.0812-0.34638 2.127 0.0157c-0.0635-0.40245 0.0214-0.54838-0.0725-0.85903l-2.024 5e-3z"/>
|
||||
<path d="m225.29-112.13 8.31 0.0664 3.0298-2.9076 0.20032-20.194 0.66323-0.0995" fill="none" stroke="#000" stroke-dasharray="0.37517659, 0.1875883" stroke-width=".18759"/>
|
||||
<g>
|
||||
<text x="177.42035" y="-129.76131" fill="#000000" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="177.42035" y="-129.76131" font-family="'Open Sans'" stroke-width=".18759">ptr aligned</tspan></text>
|
||||
<text x="235.79298" y="-122.17254" fill="#000000" font-family="'Open Sans'" font-size="1.0364px" letter-spacing="0px" stroke-width=".12956" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="235.79298" y="-122.17254" font-family="'Open Sans'" stroke-width=".12956">alignment padding</tspan></text>
|
||||
<path d="m220.64-131.26 1.5352 0.7417-1.4119 0.76079-0.0812-0.34638-2.127 0.0157c0.0635-0.40246-0.0214-0.54838 0.0725-0.85903l2.024 5e-3z"/>
|
||||
<g font-family="'Open Sans'" letter-spacing="0px" text-anchor="middle" word-spacing="0px">
|
||||
<text x="235.89856" y="-116.96035" fill="#ffffff" font-size="2.5582px" stroke-width=".31977" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="235.89856" y="-116.96035" fill="#ffffff" font-family="'Open Sans'" stroke-width=".31977">lwsac_use area</tspan></text>
|
||||
<text x="226.27226" y="-109.51257" fill="#000000" font-size="1.5007px" stroke-width=".18759" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="226.27226" y="-109.51257" font-family="'Open Sans'" stroke-width=".18759">ptr aligned</tspan></text>
|
||||
<text x="235.78995" y="-112.91241" fill="#000000" font-size="1.0364px" stroke-width=".12956" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="235.78995" y="-112.91241" font-family="'Open Sans'" stroke-width=".12956">alignment padding</tspan></text>
|
||||
</g>
|
||||
<path d="m220.64-122 1.5352 0.7417-1.4119 0.76079-0.0812-0.34638-2.127 0.0157c0.0635-0.40245-0.0214-0.54838 0.0725-0.85903l2.024 5e-3z"/>
|
||||
<rect x="268.33" y="-140.45" width="30.952" height="50.082" fill="#808080" stroke="#666" stroke-linejoin="round" stroke-width=".40058"/>
|
||||
<rect x="269.31" y="-139.14" width="28.784" height="6.4996" fill="#a00" stroke="#666" stroke-linejoin="round" stroke-width=".11698"/>
|
||||
<text x="274.10483" y="-119.17068" fill="#000000" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="274.10483" y="-119.17068" font-family="'Open Sans'" stroke-width=".18759">ptr aligned</tspan></text>
|
||||
<rect x="269.37" y="-131.91" width="28.784" height="40.39" fill="#c4c8b7" stroke="#666" stroke-linejoin="round" stroke-width=".11698"/>
|
||||
<text x="277.96088" y="-136.22011" fill="#ffffff" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="277.96088" y="-136.22011" fill="#ffffff" font-family="'Open Sans'" font-size="2.8222px" stroke-width=".39677">struct lwsac</tspan></text>
|
||||
<text x="281.16574" y="-92.936333" fill="#000000" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="281.16574" y="-92.936333" font-family="'Open Sans'" stroke-width=".39677">allocated area</tspan></text>
|
||||
<rect x="302.47" y="-140.62" width="30.952" height="50.082" fill="#808080" stroke="#666" stroke-linejoin="round" stroke-width=".40058"/>
|
||||
<rect x="303.45" y="-139.31" width="28.784" height="6.4996" fill="#a00" stroke="#666" stroke-linejoin="round" stroke-width=".11698"/>
|
||||
<path d="m303.59-138.69 1.5352 0.7417-1.4119 0.76078-0.0812-0.34638-6.239-0.0174c0.0635-0.40245-0.0214-0.51522 0.0725-0.82587l6.136 5e-3z" fill="#2a7fff"/>
|
||||
<rect x="268.63" y="-150.76" width="26.156" height="4.4025" fill="#500" stroke="#666" stroke-linejoin="round" stroke-width=".091779"/>
|
||||
<text x="281.80762" y="-147.76024" fill="#ffffff" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="281.80762" y="-147.76024" fill="#ffffff" font-family="'Open Sans'" font-size="2.8222px" stroke-width=".39677">struct lwsac *head</tspan></text>
|
||||
<text x="294.82181" y="-137.47203" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="294.82181" y="-137.47203">next</tspan><tspan x="294.82181" y="-135.59615">head</tspan><tspan x="294.82181" y="-133.72026">curr</tspan></text>
|
||||
<path d="m271.18-138.8-0.74171 2.0619-0.76078-1.8964 0.34638-0.10906 0.0174-8.3796c0.40246 0.0853 0.51522-0.0288 0.82587 0.0974l-5e-3 8.2413z" fill="#2a7fff"/>
|
||||
<text x="285.47845" y="-135.55586" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="285.47845" y="-135.55586" text-align="start">ofs</tspan><tspan x="285.47845" y="-133.67998" text-align="start">alloc_size</tspan></text>
|
||||
<path d="m292.54-144.79-0.74171-2.0619-0.76078 1.8964 0.34638 0.10906-0.0412 9.1651c0.24984 0.0323 0.88517-0.0192 1.5658-0.0156 0.0711-0.0968 0.0691-0.46206 0.015-0.82619-0.45397 2e-3 -0.78487-5e-3 -0.69633-0.0411l-5e-3 -8.2413z" fill="#2a7fff"/>
|
||||
<rect x="269.81" y="-131.25" width="27.712" height="7.4313" fill="#ff8080" stroke="#666" stroke-linejoin="round" stroke-width=".14463"/>
|
||||
<rect x="269.8" y="-121.99" width="27.712" height="7.4313" fill="#ff8080" stroke="#666" stroke-linejoin="round" stroke-width=".14463"/>
|
||||
</g>
|
||||
<path d="m297.89-131.98-2.3876 2.1223-0.13264 35.947 2.7855 2.255" fill="none" stroke="#000" stroke-dasharray="0.56276492, 0.1875883" stroke-width=".18759"/>
|
||||
<path d="m288.61-133.17 6.8975 7.6934" fill="none" stroke="#000" stroke-dasharray="0.37517659, 0.1875883" stroke-width=".18759"/>
|
||||
<text x="283.73114" y="-126.61846" fill="#ffffff" font-family="'Open Sans'" font-size="2.5582px" letter-spacing="0px" stroke-width=".31977" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="283.73114" y="-126.61846" fill="#ffffff" font-family="'Open Sans'" stroke-width=".31977">lwsac_use area</tspan></text>
|
||||
<path d="m271.31-113.11-1.5352 0.7417 1.4119 0.76079 0.0812-0.34638 2.127 0.0157c-0.0635-0.40246 0.0214-0.54838-0.0725-0.85904l-2.024 5e-3z"/>
|
||||
<path d="m273.12-112.52 8.31 0.0664 3.0298-2.9076 0.20032-20.194 0.66323-0.0995" fill="none" stroke="#000" stroke-dasharray="0.37517659, 0.1875883" stroke-width=".18759"/>
|
||||
<g>
|
||||
<text x="283.62253" y="-122.57049" fill="#000000" font-family="'Open Sans'" font-size="1.0364px" letter-spacing="0px" stroke-width=".12956" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="283.62253" y="-122.57049" font-family="'Open Sans'" stroke-width=".12956">alignment padding</tspan></text>
|
||||
<path d="m268.47-131.66 1.5352 0.74171-1.4119 0.76078-0.0812-0.34638-2.127 0.0157c0.0635-0.40245-0.0214-0.54838 0.0725-0.85903l2.024 5e-3z"/>
|
||||
<g font-family="'Open Sans'" letter-spacing="0px" text-anchor="middle" word-spacing="0px">
|
||||
<text x="283.72812" y="-117.3583" fill="#ffffff" font-size="2.5582px" stroke-width=".31977" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="283.72812" y="-117.3583" fill="#ffffff" font-family="'Open Sans'" stroke-width=".31977">lwsac_use area</tspan></text>
|
||||
<text x="274.10181" y="-109.91051" fill="#000000" font-size="1.5007px" stroke-width=".18759" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="274.10181" y="-109.91051" font-family="'Open Sans'" stroke-width=".18759">ptr aligned</tspan></text>
|
||||
<text x="283.61948" y="-113.31036" fill="#000000" font-size="1.0364px" stroke-width=".12956" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="283.61948" y="-113.31036" font-family="'Open Sans'" stroke-width=".12956">alignment padding</tspan></text>
|
||||
</g>
|
||||
<path d="m268.47-122.4 1.5352 0.7417-1.4119 0.76079-0.0812-0.34638-2.127 0.0157c0.0635-0.40246-0.0214-0.54838 0.0725-0.85904l2.024 5e-3z"/>
|
||||
<rect x="303.52" y="-132.08" width="28.784" height="40.39" fill="#c4c8b7" stroke="#666" stroke-linejoin="round" stroke-width=".11698"/>
|
||||
<text x="312.10593" y="-136.39232" fill="#ffffff" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="312.10593" y="-136.39232" fill="#ffffff" font-family="'Open Sans'" font-size="2.8222px" stroke-width=".39677">struct lwsac</tspan></text>
|
||||
<text x="315.31079" y="-93.108513" fill="#000000" font-family="'Open Sans'" font-size="3.1742px" letter-spacing="0px" stroke-width=".39677" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="315.31079" y="-93.108513" font-family="'Open Sans'" stroke-width=".39677">allocated area</tspan></text>
|
||||
<path d="m337.74-138.86 1.5352 0.74171-1.4119 0.76078-0.0812-0.34638-6.239-0.0174c0.0635-0.40245-0.0214-0.51522 0.0725-0.82587l6.136 5e-3z" fill="#2a7fff"/>
|
||||
<text x="328.96686" y="-137.64424" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="328.96686" y="-137.64424">next</tspan><tspan x="328.96686" y="-135.76836">head</tspan><tspan x="328.96686" y="-133.89247">curr</tspan></text>
|
||||
<text x="319.6235" y="-135.72807" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" stroke-width=".18759" text-align="center" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="319.6235" y="-135.72807" text-align="start">ofs</tspan><tspan x="319.6235" y="-133.85219" text-align="start">alloc_size</tspan></text>
|
||||
<rect x="304.15" y="-131.34" width="27.572" height="28.913" fill="#ff8080" stroke="#666" stroke-linejoin="round" stroke-width=".28455"/>
|
||||
</g>
|
||||
<path d="m332.04-132.15-2.3876 2.1223-0.13264 35.947 2.7855 2.255" fill="none" stroke="#000" stroke-dasharray="0.56276491, 0.1875883" stroke-width=".18759"/>
|
||||
<path d="m322.75-133.34 6.8975 7.6934" fill="none" stroke="#000" stroke-dasharray="0.37517659, 0.1875883" stroke-width=".18759"/>
|
||||
<path d="m292.68-145.32 0.74171-1.5352 0.76078 1.4119-0.34638 0.0812 0.0259 2.071 28.542 0.041 2.225 2.8639 0.0875 2.9524 0.64641 0.65493 1.5316 2e-3 0.0488 0.76904-2.1195-0.0297-1.142-1.1761-0.0569-2.9726-2.1165-2.253c-0.40246-0.0635-28.205 0.0547-28.516-0.0391l5e-3 -2.8532z" fill="#2a7fff"/>
|
||||
<path d="m303.21-134.9 1.5352 0.74171-1.4119 0.76078-0.0812-0.34638-6.239-0.0174c0.0635-0.40245-0.0214-0.51522 0.0725-0.82587l6.136 5e-3z" fill="#2a7fff"/>
|
||||
<path d="m307.26-100.45 1.4591 0.0664 3.06-3.7843-9e-3 -23.607 7.6934-8.0582" fill="none" stroke="#000" stroke-dasharray="0.37517659, 0.1875883" stroke-width=".18759"/>
|
||||
<g>
|
||||
<path d="m305.59-100.91-1.5352 0.74171 1.4119 0.76078 0.0812-0.34638 2.127 0.01569c-0.0635-0.40245 0.0214-0.54838-0.0725-0.85903l-2.024 5e-3z"/>
|
||||
<g font-family="'Open Sans'" letter-spacing="0px" text-anchor="middle" word-spacing="0px">
|
||||
<text x="318.0058" y="-105.15496" fill="#ffffff" font-size="2.5582px" stroke-width=".31977" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="318.0058" y="-105.15496" fill="#ffffff" font-family="'Open Sans'" stroke-width=".31977">lwsac_use area</tspan></text>
|
||||
<text x="308.37949" y="-97.707207" fill="#000000" font-size="1.5007px" stroke-width=".18759" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="308.37949" y="-97.707207" font-family="'Open Sans'" stroke-width=".18759">ptr aligned</tspan></text>
|
||||
<text x="317.89719" y="-101.10705" fill="#000000" font-size="1.0364px" stroke-width=".12956" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="317.89719" y="-101.10705" font-family="'Open Sans'" stroke-width=".12956">alignment padding</tspan></text>
|
||||
</g>
|
||||
<path d="m302.48-132.08 1.5352 0.74171-1.4119 0.76078-0.0812-0.34638-2.127 0.0157c0.0635-0.40245-0.0214-0.54838 0.0725-0.85903l2.024 5e-3z"/>
|
||||
<g stroke-width=".18759">
|
||||
<rect x="204.83" y="-139.17" width="5.018" height="2.6731" ry="1.3366" fill="#808080" stroke="#666" stroke-linejoin="round"/>
|
||||
<text x="207.36176" y="-137.33116" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="207.36176" y="-137.33116" fill="#ffffff" font-family="'Open Sans'" stroke-width=".18759">NULL</tspan></text>
|
||||
<rect x="253.14" y="-139.13" width="5.018" height="2.6731" ry="1.3366" fill="#808080" stroke="#666" stroke-linejoin="round"/>
|
||||
<text x="255.6705" y="-137.29219" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="255.6705" y="-137.29219" fill="#ffffff" font-family="'Open Sans'" stroke-width=".18759">NULL</tspan></text>
|
||||
<rect x="336.04" y="-139.46" width="5.018" height="2.6731" ry="1.3366" fill="#808080" stroke="#666" stroke-linejoin="round"/>
|
||||
<text x="338.57361" y="-137.62383" fill="#ffffff" font-family="'Open Sans'" font-size="1.5007px" letter-spacing="0px" text-align="center" text-anchor="middle" word-spacing="0px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="338.57361" y="-137.62383" fill="#ffffff" font-family="'Open Sans'" stroke-width=".18759">NULL</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g fill="#0000ff" font-family="'Open Sans'" font-size="3.2649px" letter-spacing="0px" stroke-width=".40811" text-anchor="middle" word-spacing="0px">
|
||||
<text x="187.11359" y="-84.657211" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="187.11359" y="-84.657211" fill="#0000ff" font-family="'Open Sans'" stroke-width=".40811">empty, generic lwsac</tspan></text>
|
||||
<text x="235.71112" y="-84.353561" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="235.71112" y="-84.353561" fill="#0000ff" font-family="'Open Sans'" stroke-width=".40811">lwsac with 2 "uses"</tspan></text>
|
||||
<text x="300.70877" y="-83.844711" text-align="center" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;line-height:1.25" xml:space="preserve"><tspan x="300.70877" y="-83.844711" fill="#0000ff" font-family="'Open Sans'" stroke-width=".40811">lwsac with 2 "uses", 3rd requires a new one</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 28 KiB |
|
@ -409,6 +409,7 @@ struct lws;
|
|||
#include <libwebsockets/lws-stats.h>
|
||||
#include <libwebsockets/lws-threadpool.h>
|
||||
#include <libwebsockets/lws-tokenize.h>
|
||||
#include <libwebsockets/lws-lwsac.h>
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
|
||||
|
|
191
include/libwebsockets/lws-lwsac.h
Normal file
191
include/libwebsockets/lws-lwsac.h
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* libwebsockets - lws alloc chunk
|
||||
*
|
||||
* Copyright (C) 2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* included from libwebsockets.h
|
||||
*/
|
||||
|
||||
/** \defgroup log lwsac
|
||||
*
|
||||
* ##Allocated Chunks
|
||||
*
|
||||
* If you know you will be allocating a large, unknown number of same or
|
||||
* differently sized objects, it's certainly possible to do it with libc
|
||||
* malloc. However the allocation cost in time and memory overhead can
|
||||
* add up, and deallocation means walking the structure of every object and
|
||||
* freeing them in turn.
|
||||
*
|
||||
* lwsac (LWS Allocated Chunks) allocates chunks intended to be larger
|
||||
* than your objects (4000 bytes by default) which you linearly allocate from
|
||||
* using lwsac_use().
|
||||
*
|
||||
* If your next request won't fit in the current chunk, a new chunk is added
|
||||
* to the chain of chunks and the allocaton done from there. If the request
|
||||
* is larger than the chunk size, an oversize chunk is created to satisfy it.
|
||||
*
|
||||
* When you are finished with the allocations, you call lwsac_free() and
|
||||
* free all the *chunks*. So you may have thousands of objects in the chunks,
|
||||
* but they are all destroyed with the chunks without having to deallocate them
|
||||
* one by one pointlessly.
|
||||
*/
|
||||
///@{
|
||||
|
||||
struct lwsac;
|
||||
typedef unsigned char * lwsac_cached_file_t;
|
||||
|
||||
|
||||
#define lws_list_ptr_container(P,T,M) ((T *)((char *)(P) - offsetof(T, M)))
|
||||
|
||||
/*
|
||||
* linked-list helper that's commonly useful to manage lists of things
|
||||
* allocated using lwsac.
|
||||
*
|
||||
* These lists point to their corresponding "next" member in the target, NOT
|
||||
* the original containing struct. To get the containing struct, you must use
|
||||
* lws_list_ptr_container() to convert.
|
||||
*
|
||||
* It's like that because it means we no longer have to have the next pointer
|
||||
* at the start of the struct, and we can have the same struct on multiple
|
||||
* linked-lists with everything held in the struct itself.
|
||||
*/
|
||||
typedef void * lws_list_ptr;
|
||||
|
||||
/*
|
||||
* optional sorting callback called by lws_list_ptr_insert() to sort the right
|
||||
* things inside the opqaue struct being sorted / inserted on the list.
|
||||
*/
|
||||
typedef int (*lws_list_ptr_sort_func_t)(lws_list_ptr a, lws_list_ptr b);
|
||||
|
||||
#define lws_list_ptr_advance(_lp) _lp = *((void **)_lp)
|
||||
|
||||
/* sort may be NULL if you don't care about order */
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lws_list_ptr_insert(lws_list_ptr *phead, lws_list_ptr *add,
|
||||
lws_list_ptr_sort_func_t sort);
|
||||
|
||||
|
||||
/**
|
||||
* lwsac_use - allocate / use some memory from a lwsac
|
||||
*
|
||||
* \param head: pointer to the lwsac list object
|
||||
* \param ensure: the number of bytes we want to use
|
||||
* \param chunk_size: 0, or the size of the chunk to (over)allocate if
|
||||
* what we want won't fit in the current tail chunk. If
|
||||
* 0, the default value of 4000 is used. If ensure is
|
||||
* larger, it is used instead.
|
||||
*
|
||||
* This also serves to init the lwsac if *head is NULL. Basically it does
|
||||
* whatever is necessary to return you a pointer to ensure bytes of memory
|
||||
* reserved for the caller.
|
||||
*
|
||||
* Returns NULL if OOM.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN void *
|
||||
lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size);
|
||||
|
||||
/**
|
||||
* lwsac_free - deallocate all chunks in the lwsac and set head NULL
|
||||
*
|
||||
* \param head: pointer to the lwsac list object
|
||||
*
|
||||
* This deallocates all chunks in the lwsac, then sets *head to NULL. All
|
||||
* lwsac_use() pointers are invalidated in one hit without individual frees.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lwsac_free(struct lwsac **head);
|
||||
|
||||
/*
|
||||
* Optional helpers useful for where consumers may need to defer destruction
|
||||
* until all consumers are finished with the lwsac
|
||||
*/
|
||||
|
||||
/**
|
||||
* lwsac_detach() - destroy an lwsac unless somebody else is referencing it
|
||||
*
|
||||
* \param head: pointer to the lwsac list object
|
||||
*
|
||||
* The creator of the lwsac can all this instead of lwsac_free() when it itself
|
||||
* has finished with the lwsac, but other code may be consuming it.
|
||||
*
|
||||
* If there are no other references, the lwsac is destroyed, *head is set to
|
||||
* NULL and that's the end; however if something else has called
|
||||
* lwsac_reference() on the lwsac, it simply returns. When lws_unreference()
|
||||
* is called and no references are left, it will be destroyed then.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lwsac_detach(struct lwsac **head);
|
||||
|
||||
/**
|
||||
* lwsac_reference() - increase the lwsac reference count
|
||||
*
|
||||
* \param head: pointer to the lwsac list object
|
||||
*
|
||||
* Increment the reference count on the lwsac to defer destruction.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lwsac_reference(struct lwsac *head);
|
||||
|
||||
/**
|
||||
* lwsac_reference() - increase the lwsac reference count
|
||||
*
|
||||
* \param head: pointer to the lwsac list object
|
||||
*
|
||||
* Decrement the reference count on the lwsac... if it reached 0 on a detached
|
||||
* lwsac then the lwsac is immediately destroyed and *head set to NULL.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lwsac_unreference(struct lwsac **head);
|
||||
|
||||
|
||||
/* helpers to keep a file cached in memory */
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lwsac_use_cached_file_start(lwsac_cached_file_t cache);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lwsac_use_cached_file_end(lwsac_cached_file_t *cache);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lwsac_use_cached_file_detach(lwsac_cached_file_t *cache);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lwsac_cached_file(const char *filepath, lwsac_cached_file_t *cache,
|
||||
size_t *len);
|
||||
|
||||
/* more advanced helpers */
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN size_t
|
||||
lwsac_sizeof(void);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN size_t
|
||||
lwsac_get_tail_pos(struct lwsac *lac);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN struct lwsac *
|
||||
lwsac_get_next(struct lwsac *lac);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN size_t
|
||||
lwsac_align(size_t length);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lwsac_info(struct lwsac *head);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN uint64_t
|
||||
lwsac_total_alloc(struct lwsac *head);
|
||||
|
||||
///@}
|
63
lib/misc/lwsac/README.md
Normal file
63
lib/misc/lwsac/README.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
## LWS Allocated Chunks
|
||||
|
||||

|
||||
|
||||
These apis provide a way to manage a linked-list of allocated chunks...
|
||||
|
||||
[ HEAD alloc ] -> [ next alloc ] -> [ next alloc ] -> [ curr alloc ]
|
||||
|
||||
... and sub-allocate trivially inside the chunks. These sub-allocations are
|
||||
not tracked by lwsac at all, there is a "used" high-water mark for each chunk
|
||||
that's simply advanced by the amount sub-allocated. If the allocation size
|
||||
matches the platform pointer alignment, there is zero overhead to sub-allocate
|
||||
(otherwise the allocation is padded to the next platform pointer alignment
|
||||
automatically).
|
||||
|
||||
If you have an unknown amount of relatively little things to allocate, including
|
||||
strings or other unstructured data, lwsac is significantly more efficient than
|
||||
individual allocations using malloc or so.
|
||||
|
||||
## lwsac_use() api
|
||||
|
||||
When you make an sub-allocation using `lwsac_use()`, you can either
|
||||
set the `chunk_size` arg to zero, defaulting to 4000, or a specific chunk size.
|
||||
In the event the requested sub-allocation exceeds the chunk size, the chunk
|
||||
size is increated to match it automatically for this allocation only.
|
||||
|
||||
Subsequent `lwsac_use()` calls will advance internal pointers to use up the
|
||||
remaining space inside the current chunk if possible; if not enough remaining
|
||||
space it is skipped, a new allocation is chained on and the request pointed to
|
||||
there.
|
||||
|
||||
Lwsac does not store information about sub-allocations. There is really zero
|
||||
overhead for individual sub-allocations (unless their size is not
|
||||
pointer-aligned, in which case the actual amount sub-allocated is rounded up to
|
||||
the next pointer alignment automatically). For structs, which are pointer-
|
||||
aligned naturally, and a chunk size relatively large for the sub-allocation
|
||||
size, lwsac is extremely efficient even for huge numbers of small allocations.
|
||||
|
||||
This makes lwsac very effective when the total amount of allocation needed is
|
||||
not known at the start and may be large... it will simply add on chunks to cope
|
||||
with whatever happens.
|
||||
|
||||
## lwsac_free() api
|
||||
|
||||
When you are finished with the lwsac, you simply free the chain of allocated
|
||||
chunks using lwsac_free() on the lwsac head. There's no tracking or individual
|
||||
destruction of suballocations - the whole chain of chunks the suballocations
|
||||
live in are freed and invalidated all together.
|
||||
|
||||
If the structs stored in the lwsac allocated things **outside** the lwsac, then the
|
||||
user must unwind through them and perform the frees. But the idea of lwsac is
|
||||
things stored in the lwsac also suballocate into the lwsac, and point into the
|
||||
lwsac if they need to, avoiding any need to visit them during destroy. It's
|
||||
like clearing up after a kids' party by gathering up a disposable tablecloth:
|
||||
no matter what was left on the table, it's all gone in one step.
|
||||
|
||||
## lws_list_ptr helpers
|
||||
|
||||
A common pattern needed with sub-allocated structs is they are on one or more
|
||||
linked-list. To make that simple to do cleanly, lws_list... apis are provided
|
||||
along with a generic insertion function that can take a sort callback. These
|
||||
allow a struct to participate on multiple linked-lists simultaneously.
|
||||
|
202
lib/misc/lwsac/cached-file.c
Normal file
202
lib/misc/lwsac/cached-file.c
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* libwebsockets - lws alloc chunk live file caching
|
||||
*
|
||||
* Copyright (C) 2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "core/private.h"
|
||||
#include "misc/lwsac/private.h"
|
||||
|
||||
/*
|
||||
* Helper for caching a file in memory in a lac, but also to check at intervals
|
||||
* no less than 5s if the file is still fresh.
|
||||
*
|
||||
* Set *cache to NULL the first time before calling.
|
||||
*
|
||||
* You should call this each time before using the cache... if it's
|
||||
*
|
||||
* - less than 5s since the last freshness check, and
|
||||
* - the file is already in memory
|
||||
*
|
||||
* it just returns with *cache left alone; this costs very little. You should
|
||||
* call `lwsac_use_cached_file_start()` and `lwsac_use_cached_file_end()` to lock
|
||||
* the cache against deletion while you are using it.
|
||||
*
|
||||
* If it's
|
||||
*
|
||||
* - at least 5s since the last freshness check, and
|
||||
* - the file timestamp has changed
|
||||
*
|
||||
* then
|
||||
*
|
||||
* - the file is reloaded into a new lac and *cache set to that
|
||||
*
|
||||
* - the old cache lac, if any, is detached (so it will be freed when its
|
||||
* reference count reaches zero, or immediately if nobody has it)
|
||||
*
|
||||
* Note the call can fail due to OOM or filesystem issue at any time.
|
||||
*
|
||||
*
|
||||
* After the LAC header there is stored a `struct cached_file_info` and then
|
||||
* the raw file contents. *
|
||||
*
|
||||
* [LAC header]
|
||||
* [struct cached_file_info]
|
||||
* [file contents] <--- *cache is set to here
|
||||
*
|
||||
* The api returns a lwsac_cached_file_t type offset to point to the file
|
||||
* contents. Helpers for reference counting and freeing are also provided
|
||||
* that take that type and know how to correct it back to operate on the LAC.
|
||||
*/
|
||||
|
||||
#define cache_file_to_lac(c) ((struct lwsac *)((char *)c - \
|
||||
sizeof(struct cached_file_info) - \
|
||||
sizeof(struct lwsac)))
|
||||
|
||||
void
|
||||
lwsac_use_cached_file_start(lwsac_cached_file_t cache)
|
||||
{
|
||||
struct lwsac *lac = cache_file_to_lac(cache);
|
||||
|
||||
lac->refcount++;
|
||||
// lwsl_debug("%s: html refcount: %d\n", __func__, lac->refcount);
|
||||
}
|
||||
|
||||
void
|
||||
lwsac_use_cached_file_end(lwsac_cached_file_t *cache)
|
||||
{
|
||||
struct lwsac *lac;
|
||||
|
||||
if (!cache || !*cache)
|
||||
return;
|
||||
|
||||
lac = cache_file_to_lac(*cache);
|
||||
|
||||
if (!lac->refcount)
|
||||
lwsl_err("%s: html refcount zero on entry\n", __func__);
|
||||
|
||||
if (lac->refcount && !--lac->refcount && lac->detached) {
|
||||
*cache = NULL; /* not usable any more */
|
||||
lwsac_free(&lac);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lwsac_use_cached_file_detach(lwsac_cached_file_t *cache)
|
||||
{
|
||||
struct lwsac *lac = cache_file_to_lac(*cache);
|
||||
|
||||
lac->detached = 1;
|
||||
if (lac->refcount)
|
||||
return;
|
||||
|
||||
*cache = NULL;
|
||||
lwsac_free(&lac);
|
||||
}
|
||||
|
||||
int
|
||||
lwsac_cached_file(const char *filepath, lwsac_cached_file_t *cache, size_t *len)
|
||||
{
|
||||
struct cached_file_info *info = NULL;
|
||||
lwsac_cached_file_t old = *cache;
|
||||
struct lwsac *lac = NULL;
|
||||
time_t t = time(NULL);
|
||||
unsigned char *a;
|
||||
struct stat s;
|
||||
size_t all;
|
||||
ssize_t rd;
|
||||
int fd;
|
||||
|
||||
if (old) { /* we already have a cached copy of it */
|
||||
|
||||
info = (struct cached_file_info *)((*cache) - sizeof(*info));
|
||||
|
||||
if (t - info->last_confirm < 5)
|
||||
/* we checked it as fresh less than 5s ago, use old */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ...it's been 5s, we should check again on the filesystem
|
||||
* that the file hasn't changed
|
||||
*/
|
||||
|
||||
fd = open(filepath, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
lwsl_err("%s: cannot open %s\n", __func__, filepath);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fstat(fd, &s)) {
|
||||
lwsl_err("%s: cannot stat %s\n", __func__, filepath);
|
||||
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (old && s.st_mtime == info->s.st_mtime) {
|
||||
/* it still seems to be the same as our cached one */
|
||||
info->last_confirm = t;
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* we either didn't cache it yet, or it has changed since we cached
|
||||
* it... reload in a new lac and then detach the old lac.
|
||||
*/
|
||||
|
||||
all = sizeof(*info) + s.st_size + 1;
|
||||
|
||||
info = lwsac_use(&lac, all, all);
|
||||
if (!info)
|
||||
goto bail;
|
||||
|
||||
info->s = s;
|
||||
info->last_confirm = t;
|
||||
|
||||
a = (unsigned char *)(info + 1);
|
||||
|
||||
*len = s.st_size;
|
||||
a[s.st_size] = '\0';
|
||||
|
||||
rd = read(fd, a, s.st_size);
|
||||
if (rd != s.st_size) {
|
||||
lwsl_err("%s: cannot read %s (%d)\n", __func__, filepath,
|
||||
(int)rd);
|
||||
goto bail1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
*cache = (lwsac_cached_file_t)a;
|
||||
if (old)
|
||||
lwsac_use_cached_file_detach(&old);
|
||||
|
||||
return 0;
|
||||
|
||||
bail1:
|
||||
lwsac_free(&lac);
|
||||
|
||||
bail:
|
||||
close(fd);
|
||||
|
||||
return 1;
|
||||
}
|
182
lib/misc/lwsac/lwsac.c
Normal file
182
lib/misc/lwsac/lwsac.c
Normal file
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* libwebsockets - lws alloc chunk
|
||||
*
|
||||
* Copyright (C) 2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "core/private.h"
|
||||
#include "misc/lwsac/private.h"
|
||||
|
||||
void
|
||||
lws_list_ptr_insert(lws_list_ptr *head, lws_list_ptr *add,
|
||||
lws_list_ptr_sort_func_t sort_func)
|
||||
{
|
||||
while (sort_func && *head) {
|
||||
if (sort_func(add, *head) <= 0)
|
||||
break;
|
||||
|
||||
head = *head;
|
||||
}
|
||||
|
||||
*add = *head;
|
||||
*head = add;
|
||||
}
|
||||
|
||||
size_t
|
||||
lwsac_align(size_t length)
|
||||
{
|
||||
size_t align = sizeof(int *);
|
||||
|
||||
if (length & (align - 1))
|
||||
length += align - (length & (align - 1));
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
size_t
|
||||
lwsac_sizeof(void)
|
||||
{
|
||||
return sizeof(struct lwsac);
|
||||
}
|
||||
|
||||
size_t
|
||||
lwsac_get_tail_pos(struct lwsac *lac)
|
||||
{
|
||||
return lac->ofs;
|
||||
}
|
||||
|
||||
struct lwsac *
|
||||
lwsac_get_next(struct lwsac *lac)
|
||||
{
|
||||
return lac->next;
|
||||
}
|
||||
|
||||
void *
|
||||
lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size)
|
||||
{
|
||||
struct lwsac *chunk;
|
||||
size_t ofs, alloc;
|
||||
|
||||
/* ensure there's a chunk and enough space in it for this name */
|
||||
|
||||
if (!*head || (*head)->curr->alloc_size - (*head)->curr->ofs < ensure) {
|
||||
|
||||
if (!chunk_size)
|
||||
alloc = LWSAC_CHUNK_SIZE + sizeof(*chunk);
|
||||
else
|
||||
alloc = chunk_size + sizeof(*chunk);
|
||||
|
||||
/*
|
||||
* If we get asked for something outside our expectation,
|
||||
* allocate to meet it
|
||||
*/
|
||||
|
||||
if (ensure >= alloc - sizeof(*chunk))
|
||||
alloc = ensure + sizeof(*chunk);
|
||||
|
||||
chunk = malloc(alloc);
|
||||
if (!chunk) {
|
||||
lwsl_err("%s: OOM trying to alloc %llud\n", __func__,
|
||||
(unsigned long long)alloc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!*head) {
|
||||
*head = chunk;
|
||||
chunk->total_alloc_size = 0;
|
||||
chunk->total_blocks = 0;
|
||||
}
|
||||
else
|
||||
(*head)->curr->next = chunk;
|
||||
|
||||
(*head)->curr = chunk;
|
||||
(*head)->curr->head = *head;
|
||||
|
||||
chunk->next = NULL;
|
||||
chunk->alloc_size = alloc;
|
||||
chunk->detached = 0;
|
||||
chunk->refcount = 0;
|
||||
|
||||
(*head)->total_alloc_size += alloc;
|
||||
(*head)->total_blocks++;
|
||||
|
||||
/*
|
||||
* belabouring the point... ofs is aligned to the platform's
|
||||
* generic struct alignment at the start then
|
||||
*/
|
||||
(*head)->curr->ofs = sizeof(*chunk);
|
||||
}
|
||||
|
||||
ofs = (*head)->curr->ofs;
|
||||
|
||||
(*head)->curr->ofs += lwsac_align(ensure);
|
||||
if ((*head)->curr->ofs >= (*head)->curr->alloc_size)
|
||||
(*head)->curr->ofs = (*head)->curr->alloc_size;
|
||||
|
||||
return (char *)(*head)->curr + ofs;
|
||||
}
|
||||
|
||||
void
|
||||
lwsac_free(struct lwsac **head)
|
||||
{
|
||||
struct lwsac *it = *head;
|
||||
|
||||
while (it) {
|
||||
struct lwsac *tmp = it->next;
|
||||
|
||||
free(it);
|
||||
it = tmp;
|
||||
}
|
||||
|
||||
*head = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
lwsac_info(struct lwsac *head)
|
||||
{
|
||||
lwsl_notice("%s: lac %p: %dKiB in %d blocks\n", __func__, head,
|
||||
(int)(head->total_alloc_size >> 10), head->total_blocks);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
lwsac_total_alloc(struct lwsac *head)
|
||||
{
|
||||
return head->total_alloc_size;
|
||||
}
|
||||
|
||||
void
|
||||
lwsac_reference(struct lwsac *head)
|
||||
{
|
||||
head->refcount++;
|
||||
}
|
||||
|
||||
void
|
||||
lwsac_unreference(struct lwsac **head)
|
||||
{
|
||||
(*head)->refcount--;
|
||||
if ((*head)->detached && !(*head)->refcount)
|
||||
lwsac_free(head);
|
||||
}
|
||||
|
||||
void
|
||||
lwsac_detach(struct lwsac **head)
|
||||
{
|
||||
(*head)->detached = 1;
|
||||
if (!(*head)->refcount)
|
||||
lwsac_free(head);
|
||||
}
|
48
lib/misc/lwsac/private.h
Normal file
48
lib/misc/lwsac/private.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* libwebsockets - lws alloc chunk
|
||||
*
|
||||
* Copyright (C) 2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* under page size of 4096 to allow overhead */
|
||||
#define LWSAC_CHUNK_SIZE 4000
|
||||
|
||||
/*
|
||||
* the chunk list members all point back to the head themselves so the list
|
||||
* can be detached from the formal head and free itself when its reference
|
||||
* count reaches zero.
|
||||
*/
|
||||
|
||||
struct lwsac {
|
||||
struct lwsac *next;
|
||||
struct lwsac *head; /* pointer back to the first chunk */
|
||||
struct lwsac *curr; /* applies to head chunk only */
|
||||
size_t total_alloc_size; /* applies to head chunk only */
|
||||
size_t alloc_size;
|
||||
size_t ofs; /* next writeable position inside chunk */
|
||||
int refcount; /* applies to head chunk only */
|
||||
int total_blocks; /* applies to head chunk only */
|
||||
char detached; /* if our refcount gets to zero, free the chunk list */
|
||||
};
|
||||
|
||||
struct cached_file_info {
|
||||
struct stat s;
|
||||
time_t last_confirm;
|
||||
};
|
5
minimal-examples/api-tests/README.md
Normal file
5
minimal-examples/api-tests/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
|name|tests|
|
||||
---|---
|
||||
api-test-lwsac|LWS Allocated Chunks
|
||||
api-test-lws_tokenize|Generic secure string tokenizer
|
||||
|
73
minimal-examples/api-tests/api-test-lwsac/CMakeLists.txt
Normal file
73
minimal-examples/api-tests/api-test-lwsac/CMakeLists.txt
Normal file
|
@ -0,0 +1,73 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
set(SAMP lws-api-test-lwsac)
|
||||
set(SRCS main.c)
|
||||
|
||||
# If we are being built as part of lws, confirm current build config supports
|
||||
# reqconfig, else skip building ourselves.
|
||||
#
|
||||
# If we are being built externally, confirm installed lws was configured to
|
||||
# support reqconfig, else error out with a helpful message about the problem.
|
||||
#
|
||||
MACRO(require_lws_config reqconfig _val result)
|
||||
|
||||
if (DEFINED ${reqconfig})
|
||||
if (${reqconfig})
|
||||
set (rq 1)
|
||||
else()
|
||||
set (rq 0)
|
||||
endif()
|
||||
else()
|
||||
set(rq 0)
|
||||
endif()
|
||||
|
||||
if (${_val} EQUAL ${rq})
|
||||
set(SAME 1)
|
||||
else()
|
||||
set(SAME 0)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_MINIMAL_EXAMPLES AND NOT ${SAME})
|
||||
if (${_val})
|
||||
message("${SAMP}: skipping as lws being built without ${reqconfig}")
|
||||
else()
|
||||
message("${SAMP}: skipping as lws built with ${reqconfig}")
|
||||
endif()
|
||||
set(${result} 0)
|
||||
else()
|
||||
if (LWS_WITH_MINIMAL_EXAMPLES)
|
||||
set(MET ${SAME})
|
||||
else()
|
||||
CHECK_C_SOURCE_COMPILES("#include <libwebsockets.h>\nint main(void) {\n#if defined(${reqconfig})\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_${reqconfig})
|
||||
if (NOT DEFINED HAS_${reqconfig} OR NOT HAS_${reqconfig})
|
||||
set(HAS_${reqconfig} 0)
|
||||
else()
|
||||
set(HAS_${reqconfig} 1)
|
||||
endif()
|
||||
if ((HAS_${reqconfig} AND ${_val}) OR (NOT HAS_${reqconfig} AND NOT ${_val}))
|
||||
set(MET 1)
|
||||
else()
|
||||
set(MET 0)
|
||||
endif()
|
||||
endif()
|
||||
if (NOT MET)
|
||||
if (${_val})
|
||||
message(FATAL_ERROR "This project requires lws must have been configured with ${reqconfig}")
|
||||
else()
|
||||
message(FATAL_ERROR "Lws configuration of ${reqconfig} is incompatible with this project")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
|
||||
if (websockets_shared)
|
||||
target_link_libraries(${SAMP} websockets_shared)
|
||||
add_dependencies(${SAMP} websockets_shared)
|
||||
else()
|
||||
target_link_libraries(${SAMP} websockets)
|
||||
endif()
|
22
minimal-examples/api-tests/api-test-lwsac/README.md
Normal file
22
minimal-examples/api-tests/api-test-lwsac/README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# lws api test lwsac
|
||||
|
||||
Demonstrates how to use and performs selftests for lwsac
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
Commandline option|Meaning
|
||||
---|---
|
||||
-d <loglevel>|Debug verbosity in decimal, eg, -d15
|
||||
|
||||
```
|
||||
$ ./lws-api-test-lwsac
|
||||
[2018/10/09 09:14:17:4834] USER: LWS API selftest: lwsac
|
||||
[2018/10/09 09:14:17:4835] USER: Completed: PASS
|
||||
```
|
||||
|
81
minimal-examples/api-tests/api-test-lwsac/main.c
Normal file
81
minimal-examples/api-tests/api-test-lwsac/main.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* lws-api-test-lwsac
|
||||
*
|
||||
* Copyright (C) 2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
struct mytest {
|
||||
int payload;
|
||||
/* notice doesn't have to be at start of struct */
|
||||
lws_list_ptr list_next;
|
||||
/* a struct can appear on multiple lists too... */
|
||||
};
|
||||
|
||||
/* converts a ptr to struct mytest .list_next to a ptr to struct mytest */
|
||||
#define list_to_mytest(p) lws_list_ptr_container(p, struct mytest, list_next)
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
int n, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE, acc;
|
||||
lws_list_ptr list_head = NULL, iter;
|
||||
struct lwsac *lwsac = NULL;
|
||||
struct mytest *m;
|
||||
const char *p;
|
||||
|
||||
if ((p = lws_cmdline_option(argc, argv, "-d")))
|
||||
logs = atoi(p);
|
||||
|
||||
lws_set_log_level(logs, NULL);
|
||||
lwsl_user("LWS API selftest: lwsac\n");
|
||||
|
||||
/*
|
||||
* 1) allocate and create 1000 struct mytest in a linked-list
|
||||
*/
|
||||
|
||||
for (n = 0; n < 1000; n++) {
|
||||
m = lwsac_use(&lwsac, sizeof(*m), 0);
|
||||
m->payload = n;
|
||||
|
||||
lws_list_ptr_insert(&list_head, &m->list_next, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* 2) report some debug info about the lwsac state... those 1000
|
||||
* allocations actually only required 4 mallocs
|
||||
*/
|
||||
|
||||
lwsac_info(lwsac);
|
||||
|
||||
/* 3) iterate the list, accumulating the payloads */
|
||||
|
||||
acc = 0;
|
||||
iter = list_head;
|
||||
while (iter) {
|
||||
m = list_to_mytest(iter);
|
||||
acc += m->payload;
|
||||
|
||||
lws_list_ptr_advance(iter);
|
||||
}
|
||||
|
||||
if (acc != 499500) {
|
||||
lwsl_err("%s: FAIL acc %d\n", __func__, acc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 4) deallocate everything (lwsac is also set to NULL). It just
|
||||
* deallocates the 4 mallocs, everything in there is gone accordingly
|
||||
*/
|
||||
|
||||
lwsac_free(&lwsac);
|
||||
|
||||
lwsl_user("Completed: PASS\n");
|
||||
|
||||
return 0;
|
||||
}
|
24
minimal-examples/api-tests/api-test-lwsac/selftest.sh
Executable file
24
minimal-examples/api-tests/api-test-lwsac/selftest.sh
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# $1: path to minimal example binaries...
|
||||
# if lws is built with -DLWS_WITH_MINIMAL_EXAMPLES=1
|
||||
# that will be ./bin from your build dir
|
||||
#
|
||||
# $2: path for logs and results. The results will go
|
||||
# in a subdir named after the directory this script
|
||||
# is in
|
||||
#
|
||||
# $3: offset for test index count
|
||||
#
|
||||
# $4: total test count
|
||||
#
|
||||
# $5: path to ./minimal-examples dir in lws
|
||||
#
|
||||
# Test return code 0: OK, 254: timed out, other: error indication
|
||||
|
||||
. $5/selftests-library.sh
|
||||
|
||||
COUNT_TESTS=1
|
||||
|
||||
dotest $1 $2 apiselftest
|
||||
exit $FAILS
|
Loading…
Add table
Reference in a new issue