1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-23 00:00:06 +01:00
libwebsockets/include/libwebsockets/lws-diskcache.h
Andy Green c9731c5f17 type comparisons: fixes
This is a huge patch that should be a global NOP.

For unix type platforms it enables -Wconversion to issue warnings (-> error)
for all automatic casts that seem less than ideal but are normally concealed
by the toolchain.

This is things like passing an int to a size_t argument.  Once enabled, I
went through all args on my default build (which build most things) and
tried to make the removed default cast explicit.

With that approach it neither change nor bloat the code, since it compiles
to whatever it was doing before, just with the casts made explicit... in a
few cases I changed some length args from int to size_t but largely left
the causes alone.

From now on, new code that is relying on less than ideal casting
will complain and nudge me to improve it by warnings.
2021-01-05 10:56:38 +00:00

187 lines
8.4 KiB
C

/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup diskcache LWS disk cache
* ## Disk cache API
*
* Lws provides helper apis useful if you need a disk cache containing hashed
* files and need to delete files from it on an LRU basis to keep it below some
* size limit.
*
* The API `lws_diskcache_prepare()` deals with creating the cache dir and
* 256 subdirs, which are used according to the first two chars of the hex
* hash of the cache file.
*
* `lws_diskcache_create()` and `lws_diskcache_destroy()` allocate and free
* an opaque struct that represents the disk cache.
*
* `lws_diskcache_trim()` should be called at eg, 1s intervals to perform the
* cache dir monitoring and LRU autodelete in the background lazily. It can
* be done in its own thread or on a timer... it monitors the directories in a
* stateful way that stats one or more file in the cache per call, and keeps
* a list of the oldest files as it goes. When it completes a scan, if the
* aggregate size is over the limit, it will delete oldest files first to try
* to keep it under the limit.
*
* The cache size monitoring is extremely efficient in time and memory even when
* the cache directory becomes huge.
*
* `lws_diskcache_query()` is used to determine if the file already exists in
* the cache, or if it must be created. If it must be created, then the file
* is opened using a temp name that must be converted to a findable name with
* `lws_diskcache_finalize_name()` when the generation of the file contents are
* complete. Aborted cached files that did not complete generation will be
* flushed by the LRU eventually. If the file already exists, it is 'touched'
* to make it new again and the fd returned.
*
*/
///@{
struct lws_diskcache_scan;
/**
* lws_diskcache_create() - creates an opaque struct representing the disk cache
*
* \param cache_dir_base: The cache dir path, eg `/var/cache/mycache`
* \param cache_size_limit: maximum size on disk the cache is allowed to use
*
* This returns an opaque `struct lws_diskcache_scan *` which represents the
* disk cache, the trim scanning state and so on. You should use
* `lws_diskcache_destroy()` to free it to destroy it.
*/
LWS_VISIBLE LWS_EXTERN struct lws_diskcache_scan *
lws_diskcache_create(const char *cache_dir_base, uint64_t cache_size_limit);
/**
* lws_diskcache_destroy() - destroys the pointer returned by ...create()
*
* \param lds: pointer to the pointer returned by lws_diskcache_create()
*
* Frees *lds and any allocations it did, and then sets *lds to NULL and
* returns.
*/
LWS_VISIBLE LWS_EXTERN void
lws_diskcache_destroy(struct lws_diskcache_scan **lds);
/**
* lws_diskcache_prepare() - ensures the cache dir structure exists on disk
*
* \param cache_base_dir: The cache dir path, eg `/var/cache/mycache`
* \param mode: octal dir mode to enforce, like 0700
* \param uid: uid the cache dir should belong to
*
* This should be called while your app is still privileged. It will create
* the cache directory structure on disk as necessary, enforce the given access
* mode on it and set the given uid as the owner. It won't make any trouble
* if the cache already exists.
*
* Typically the mode is 0700 and the owner is the user that your application
* will transition to use when it drops root privileges.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_prepare(const char *cache_base_dir, int mode, uid_t uid);
#define LWS_DISKCACHE_QUERY_NO_CACHE 0
#define LWS_DISKCACHE_QUERY_EXISTS 1
#define LWS_DISKCACHE_QUERY_CREATING 2
#define LWS_DISKCACHE_QUERY_ONGOING 3 /* something else is creating it */
/**
* lws_diskcache_query() - ensures the cache dir structure exists on disk
*
* \param lds: The opaque struct representing the disk cache
* \param is_bot: nonzero means the request is from a bot. Don't create new cache contents if so.
* \param hash_hex: hex string representation of the cache object hash
* \param _fd: pointer to the fd to be set
* \param cache: destination string to take the cache filepath
* \param cache_len: length of the buffer at `cache`
* \param extant_cache_len: pointer to a size_t to take any extant cached file size
*
* This function is called when you want to find if the hashed name already
* exists in the cache. The possibilities for the return value are
*
* - LWS_DISKCACHE_QUERY_NO_CACHE: It's not in the cache and you can't create
* it in the cache for whatever reason.
* - LWS_DISKCACHE_QUERY_EXISTS: It exists in the cache. It's open RDONLY and
* *_fd has been set to the file descriptor. *extant_cache_len has been set
* to the size of the cached file in bytes. cache has been set to the
* full filepath of the cached file. Closing _fd is your responsibility.
* - LWS_DISKCACHE_QUERY_CREATING: It didn't exist, but a temp file has been
* created in the cache and *_fd set to a file descriptor opened on it RDWR.
* You should create the contents, and call `lws_diskcache_finalize_name()`
* when it is done. Closing _fd is your responsibility.
* - LWS_DISKCACHE_QUERY_ONGOING: not returned by this api, but you may find it
* desirable to make a wrapper function which can handle another asynchronous
* process that is already creating the cached file. This can be used to
* indicate that situation externally... how to determine the same thing is
* already being generated is out of scope of this api.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_query(struct lws_diskcache_scan *lds, int is_bot,
const char *hash_hex, int *_fd, char *cache, int cache_len,
size_t *extant_cache_len);
/**
* lws_diskcache_query() - ensures the cache dir structure exists on disk
*
* \param cache: The cache file temp name returned with LWS_DISKCACHE_QUERY_CREATING
*
* This renames the cache file you are creating to its final name. It should
* be called on the temp name returned by `lws_diskcache_query()` if it gave a
* LWS_DISKCACHE_QUERY_CREATING return, after you have filled the cache file and
* closed it.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_finalize_name(char *cache);
/**
* lws_diskcache_trim() - performs one or more file checks in the cache for size management
*
* \param lds: The opaque object representing the cache
*
* This should be called periodically to statefully walk the cache on disk
* collecting the oldest files. When it has visited every file, if the cache
* is oversize it will delete the oldest files until it's back under size again.
*
* Each time it's called, it will look at one or more dir in the cache. If
* called when the cache is oversize, it increases the amount of work done each
* call until it is reduced again. Typically it will take 256 calls before it
* deletes anything, so if called once per second, it will delete files once
* every 4 minutes. Each call is very inexpensive both in memory and time.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_trim(struct lws_diskcache_scan *lds);
/**
* lws_diskcache_secs_to_idle() - see how long to idle before calling trim
*
* \param lds: The opaque object representing the cache
*
* If the cache is undersize, there's no need to monitor it immediately. This
* suggests how long to "sleep" before calling `lws_diskcache_trim()` again.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_secs_to_idle(struct lws_diskcache_scan *lds);
///@}