1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

lwsac: add lwsac_extend api

This commit is contained in:
Andy Green 2020-01-24 19:23:52 +00:00
parent 4b3801ab6f
commit 6a737b7ca6
3 changed files with 71 additions and 8 deletions

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
* Copyright (C) 2010 - 2020 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
@ -198,6 +198,38 @@ lwsac_reference(struct lwsac *head);
LWS_VISIBLE LWS_EXTERN void
lwsac_unreference(struct lwsac **head);
/**
* lwsac_extend() - try to increase the size of the last block
*
* \param head: pointer to the lwsac list object
* \param amount: amount to try to increase usage for
*
* This will either increase the usage reservation of the last allocated block
* by amount and return 0, or fail and return 1.
*
* This is very cheap to call and is designed to optimize usage after a static
* struct for vari-sized additional content which may flow into an additional
* block in a new chunk if necessary, but wants to make the most of the space
* in front of it first to try to avoid gaps and the new chunk if it can.
*
* The additional area if the call succeeds will have been memset to 0.
*
* To use it, the following must be true:
*
* - only the last lwsac use can be extended
*
* - if another use happens inbetween the use and extend, it will break
*
* - the use cannot have been using backfill
*
* - a user object must be tracking the current allocated size of the last use
* (lwsac doesn't know it) and increment by amount if the extend call succeeds
*
* Despite these restrictions this can be an important optimization for some
* cases
*/
LWS_VISIBLE LWS_EXTERN int
lwsac_extend(struct lwsac *head, int amount);
/* helpers to keep a file cached in memory */

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
* Copyright (C) 2010 - 2020 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
@ -69,6 +69,29 @@ lwsac_get_next(struct lwsac *lac)
return lac->next;
}
int
lwsac_extend(struct lwsac *head, int amount)
{
struct lwsac_head *lachead;
struct lwsac *bf;
assert(head);
lachead = (struct lwsac_head *)&head[1];
bf = lachead->curr;
assert(bf);
if (bf->alloc_size - bf->ofs < lwsac_align(amount))
return 1;
/* memset so constant folding never sees uninitialized data */
memset(((uint8_t *)bf) + bf->ofs, 0, lwsac_align(amount));
bf->ofs += lwsac_align(amount);
return 0;
}
static void *
_lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size, char backfill)
{

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
* Copyright (C) 2010 - 2020 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
@ -38,18 +38,26 @@
* count reaches zero.
*/
/*
* One of these per chunk
*/
struct lwsac {
struct lwsac *next;
struct lwsac *head; /* pointer back to the first chunk */
size_t alloc_size;
size_t alloc_size; /* alloc size of the whole chunk */
size_t ofs; /* next writeable position inside chunk */
};
/*
* One of these per lwsac, at start of first chunk
*/
struct lwsac_head {
struct lwsac *curr; /* applies to head chunk only */
size_t total_alloc_size; /* applies to head chunk only */
int refcount; /* applies to head chunk only */
int total_blocks; /* applies to head chunk only */
struct lwsac *curr;
size_t total_alloc_size;
int refcount;
int total_blocks;
char detached; /* if our refcount gets to zero, free the chunk list */
};