Browse Source

Remove old instances from regularly used hashtables

master
Con Kolivas 11 years ago
parent
commit
9290d1566a
  1. 21
      src/connector.c

21
src/connector.c

@ -34,12 +34,17 @@ struct connector_instance {
typedef struct connector_instance conn_instance_t; typedef struct connector_instance conn_instance_t;
struct client_instance { struct client_instance {
/* For clients hashtable */
UT_hash_handle hh; UT_hash_handle hh;
int id; int id;
/* For fdclients hashtable */
UT_hash_handle fdhh; UT_hash_handle fdhh;
int fd; int fd;
/* For dead_clients list */
struct client_instance *next;
struct sockaddr address; struct sockaddr address;
socklen_t address_len; socklen_t address_len;
char buf[PAGESIZE]; char buf[PAGESIZE];
@ -52,6 +57,8 @@ typedef struct client_instance client_instance_t;
static client_instance_t *clients; static client_instance_t *clients;
/* A hashtable of the clients sorted by fd */ /* A hashtable of the clients sorted by fd */
static client_instance_t *fdclients; static client_instance_t *fdclients;
/* Linked list of dead clients no longer in use but may still have references */
static client_instance_t *dead_clients;
static int client_id; static int client_id;
@ -113,7 +120,9 @@ out:
return NULL; return NULL;
} }
/* Invalidate this instance */ /* Invalidate this instance. Remove them from the hashtables we look up
* regularly but keep the instances in a linked list indefinitely in case we
* still reference any of its members. */
static void invalidate_client(ckpool_t *ckp, conn_instance_t *ci, client_instance_t *client) static void invalidate_client(ckpool_t *ckp, conn_instance_t *ci, client_instance_t *client)
{ {
char buf[256]; char buf[256];
@ -123,7 +132,9 @@ static void invalidate_client(ckpool_t *ckp, conn_instance_t *ci, client_instanc
fd = client->fd; fd = client->fd;
if (fd != -1) { if (fd != -1) {
close(fd); close(fd);
HASH_DEL(clients, client);
HASH_DELETE(fdhh, fdclients, client); HASH_DELETE(fdhh, fdclients, client);
LL_PREPEND(dead_clients, client);
client->fd = -1; client->fd = -1;
} }
ck_wunlock(&ci->lock); ck_wunlock(&ci->lock);
@ -139,14 +150,16 @@ static void send_client(conn_instance_t *ci, int id, char *buf);
static void parse_client_msg(conn_instance_t *ci, client_instance_t *client) static void parse_client_msg(conn_instance_t *ci, client_instance_t *client)
{ {
ckpool_t *ckp = ci->pi->ckp; ckpool_t *ckp = ci->pi->ckp;
int buflen, ret, flags = 0;
char msg[PAGESIZE], *eol; char msg[PAGESIZE], *eol;
int buflen, ret; bool moredata = false;
bool moredata;
json_t *val; json_t *val;
retry: retry:
buflen = PAGESIZE - client->bufofs; buflen = PAGESIZE - client->bufofs;
ret = recv(client->fd, client->buf + client->bufofs, buflen, MSG_DONTWAIT); if (moredata)
flags = MSG_DONTWAIT;
ret = recv(client->fd, client->buf + client->bufofs, buflen, flags);
if (ret < 1) { if (ret < 1) {
/* Nothing else ready to be read */ /* Nothing else ready to be read */
if (!ret) if (!ret)

Loading…
Cancel
Save