|
|
@ -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) |
|
|
|