about summary refs log tree commit diff
path: root/src/cache/tcpconnection.c
blob: 71a42991915c0ff60a304382be369e46f3d5e48b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* ISC license. */

#include <stdint.h>
#include <errno.h>

#include <skalibs/allreadwrite.h>
#include <skalibs/error.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#include <skalibs/bufalloc.h>
#include <skalibs/genalloc.h>

#include "shibari-cache-internal.h"

void tcpconnection_removequery (tcpconnection *p, uint16_t id)
{
  uint16_t *tab = genalloc_s(uint16_t, &p->queries) ;
  uint16_t n = genalloc_len(uint16_t, &p->queries) ;
  uint16_t i = 0 ;
  for (; i < n ; i++) if (id == tab[i]) break ;
  if (i >= n) return ;
  tab[i] = tab[--n] ;
  genalloc_setlen(uint16_t, &p->queries, n) ;
}

uint16_t tcpconnection_delete (tcpconnection *p)
{
  uint16_t newi = p->prev ;
  p->out.x.len = 0 ;
  p->in.len = 0 ;
  p->instate = 0 ;
  fd_close(p->out.fd) ;
  for (uint16_t i = 0 ; i < genalloc_len(uint16_t, &p->queries) ; i++)
    query_abort(genalloc_s(uint16_t, &p->queries)[i]) ;
  genalloc_setlen(uint16_t, &p->queries, 0) ;
  TCPCONNECTION(newi)->next = p->next ;
  TCPCONNECTION(p->next)->prev = p->prev ;
  p->xindex = UINT16_MAX ;
  return newi ;
}

int tcpconnection_flush (tcpconnection *p)
{
  return bufalloc_flush(&p->out) ? 1 :
    error_isagain(errno) ? 0 : -1 ;
}

static void tcpconnection_init (tcpconnection *p, int fd)
{
  if (!p->out.op) bufalloc_init(&p->out, &fd_write, fd) ;
  else { p->out.fd = fd ; p->out.x.len = 0 ; }
  tain_add_g(&p->rdeadline, &tain_infinite_relative) ;
  tain_add_g(&p->wdeadline, &tain_infinite_relative) ;
}

void tcpconnection_new (int fd)
{
  uint16_t n = genset_new(&g->tcpconnections) ;
  tcpconnection *sentinel = TCPCONNECTION(g->tcpsentinel) ;
  tcpconnection *p = TCPCONNECTION(n) ;
  tcpconnection_init(p, fd) ;
  p->prev = g->tcpsentinel ;
  p->next = sentinel->next ;
  TCPCONNECTION(sentinel->next)->prev = n ;
  sentinel->next = n ;
}