return (pos - 1);
}
-/* Returns the HTX block before <blk> in the HTX message <htx>. If <blk> is the
- * head, NULL returned.
+/* Returns the HTX block before <blk> in the HTX message <htx>, skipping all
+ * UNUSED blocks. If <blk> is the head, NULL returned.
*/
static inline struct htx_blk *htx_get_prev_blk(const struct htx *htx,
const struct htx_blk *blk)
{
- int32_t pos;
+ struct htx_blk *pblk = NULL;
+ int32_t pos = htx_get_blk_pos(htx, blk);
- pos = htx_get_prev(htx, htx_get_blk_pos(htx, blk));
- return ((pos == -1) ? NULL : htx_get_blk(htx, pos));
+ for (pos = htx_get_prev(htx, pos); pos != -1; pos = htx_get_prev(htx, pos)) {
+ pblk = htx_get_blk(htx, pos);
+ if (htx_get_blk_type(pblk) != HTX_BLK_UNUSED)
+ break;
+ pblk = NULL;
+ }
+ return pblk;
}
/* Returns the position of block immediately after the one pointed by <pos>. If
}
-/* Returns the HTX block after <blk> in the HTX message <htx>. If <blk> is the
- * tail, NULL returned.
+/* Returns the HTX block after <blk> in the HTX message <htx>, skipping UNUSED
+ * blocks. If <blk> is the tail, NULL returned.
*/
static inline struct htx_blk *htx_get_next_blk(const struct htx *htx,
const struct htx_blk *blk)
{
- int32_t pos;
+ struct htx_blk *nblk = NULL;
+ int32_t pos = htx_get_blk_pos(htx, blk);
- pos = htx_get_next(htx, htx_get_blk_pos(htx, blk));
- return ((pos == -1) ? NULL : htx_get_blk(htx, pos));
+ for (pos = htx_get_next(htx, pos); pos != -1; pos = htx_get_next(htx, pos)) {
+ nblk = htx_get_blk(htx, pos);
+ if (htx_get_blk_type(nblk) != HTX_BLK_UNUSED)
+ break;
+ nblk = NULL;
+ }
+ return nblk;
}
+
/* Returns the position of the first block in the HTX message <htx>. -1 means
* the first block is unset or the HTS is empty.
*/
return htx->first;
}
-/* Returns the first HTX block in the HTX message <htx>. If unset or if <htx> is
- * empty, NULL returned.
+/* Returns the first HTX block in the HTX message <htx>, skipping UNUSED
+ * blocks. If unset or if <htx> is empty, NULL returned.
*/
static inline struct htx_blk *htx_get_first_blk(const struct htx *htx)
{
+ struct htx_blk *fblk = NULL;
int32_t pos;
- pos = htx_get_first(htx);
- return ((pos == -1) ? NULL : htx_get_blk(htx, pos));
+ for (pos = htx_get_first(htx); pos != -1; pos = htx_get_next(htx, pos)) {
+ fblk = htx_get_blk(htx, pos);
+ if (htx_get_blk_type(fblk) != HTX_BLK_UNUSED)
+ break;
+ fblk = NULL;
+ }
+ return fblk;
}
/* Returns the type of the first block in the HTX message <htx>. If unset or if
*/
struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk)
{
+ struct htx_blk *prevblk, *nextblk;
enum htx_blk_type type;
uint32_t pos, addr, sz;
return NULL;
}
+ /* Get prev and next blocks, skipping all UNUSED blocks.
+ * <prevblk> may NULL if the head is removed otherwise it must exists
+ * <nextblk> may NULL if the tail is removed otherwise it must exists
+ */
+ prevblk = htx_get_prev_blk(htx, blk);
+ nextblk = htx_get_next_blk(htx, blk);
+
+ /* There is at least 2 used blocks, so (head != tail and tail > 0) */
+
type = htx_get_blk_type(blk);
pos = htx_get_blk_pos(htx, blk);
sz = htx_get_blksz(blk);
blk->info = ((uint32_t)HTX_BLK_UNUSED << 28);
}
- /* There is at least 2 blocks, so tail is always > 0 */
+
if (pos == htx->head) {
/* move the head forward */
- htx->head++;
+ BUG_ON_HOT(prevblk != NULL || nextblk == NULL);
+ htx->head = htx_get_blk_pos(htx, nextblk);
}
else if (pos == htx->tail) {
- /* remove the tail. this was the last inserted block so
- * return NULL. */
- htx->tail--;
- blk = NULL;
+ /* remove the tail */
+ BUG_ON_HOT(prevblk == NULL || nextblk != NULL);
+ htx->tail = htx_get_blk_pos(htx, prevblk);
goto end;
}
else
htx->flags |= HTX_FL_FRAGMENTED;
- blk = htx_get_blk(htx, pos+1);
-
end:
if (pos == htx->first)
- htx->first = (blk ? htx_get_blk_pos(htx, blk) : -1);
+ htx->first = (nextblk ? htx_get_blk_pos(htx, nextblk) : -1);
if (htx->head == htx->tail) {
/* If there is just one block in the HTX message, free space can
BUG_ON((int32_t)htx->head_addr < 0);
BUG_ON(htx->end_addr > htx->tail_addr);
BUG_ON(htx->head_addr > htx->end_addr);
- return blk;
+ return nextblk;
}
/* Looks for the HTX block containing the offset <offset>, starting at the HTX