-------
Removed DCB states DCB_STATE_IDLE, and DCB_STATE_PROCESSING.
Added DCB_STATE_UNDEFINED for initial content for state variable which doesn't have any specific value set, and DCB_STATE_NOPOLLING to indicate that dcb has been removed from poll set.

Added following dcb roles: DCB_ROLE_SERVICE_LISTENER for listeners of services, and DCB_ROLE_REQUEST_HANDLER for client/backend dcbs. Listeners may have state DCB_STATE_LISTENING, but not DCB_STATE_POLLING. Request handlers may have DCB_STATE_POLLING but not DCB_STATE_LISTENING. Role is passed as an argument to dcb.c:dcb_alloc.

From now on, struct check numbers of DCB are included and checked in DEBUG build only.

Added dcb_role_t dcb_role-member to DCB as well as SPINLOCK dcb_initlock, which protects state changes.

Removed extern keyword from function declarations because functions are by default externally visible if they are declared in header.

dcb.b
------
Function dcb_set_state, and dcb_set_state_nomutex provide functions for changing dcb states. Latter implements a state machine for dcb.
Function dcb_add_to_zombieslist replaces dcb_free. It adds in atomic step dcb to zombieslist and changes state to DCB_STATE_ZOMBIE.
Function dcb_final_free removes dcb from allDCBs list, terminates router and client sessions, and frees dcb and related memory.
Function dcb_process_zombies removes executing thread from dcb's bitmask, and it there are no further thread bits, moves dcb to a victim list, and finally, for each dcb on victim list, closes fd and sets state to DCB_STATE_DISCONNECTED.
Function dcb_close sets dcb state to DCB_STATE_NOPOLLIN, removes dcb from poll set and sets bit to bitmask for each server thread in an atomic step.  

poll.c
------
Function poll_add_dcb sets either DCB_STATE_LISTENING or DCB_STATE_POLLING state for newly created dcb, depending whether the role of dcb is DCB_ROLE_SERVICE_LISTENER, or DCB_ROLE_REQUEST_HANDLER, respectively. Then dcb is set to poll set.

poll_waitevents : commented out code which skipped event if dcb was added to zombieslist or if fd was closed. Added state checks.

service.c : Minor changes.
httpd.c : Removed dcb state changes. They are done in core.
mysql_backend.c : Added checks, removed dcb state changes.
mysql_client.c : Removed dcb state changes. Added checks.
mysql_common.c : Minor changes
telnetd.c : Removed state changes. Replaced some typecasts and pointer references with local variable reads.
skygw_debug.h : Removed two states, and added two to state printing macro.
This commit is contained in:
vraatikka
2013-09-05 22:00:02 +03:00
parent 17ec98fa3d
commit 66e9be814b
10 changed files with 576 additions and 384 deletions

View File

@ -144,7 +144,6 @@ char *password, *t;
if ((n = dcb_read(dcb, &head)) != -1)
{
dcb->state = DCB_STATE_PROCESSING;
if (head)
{
unsigned char *ptr = GWBUF_DATA(head);
@ -198,8 +197,6 @@ char *password, *t;
}
}
}
dcb->state = DCB_STATE_POLLING;
return n;
}
@ -269,40 +266,48 @@ int n_connect = 0;
int so;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr);
DCB *client;
DCB *client_dcb;
TELNETD* telnetd_pr = NULL;
dcb_state_t old_state = DCB_STATE_UNDEFINED;
bool succp = FALSE;
if ((so = accept(dcb->fd, (struct sockaddr *)&addr, &addrlen)) == -1)
so = accept(dcb->fd, (struct sockaddr *)&addr, &addrlen);
if (so == -1)
return n_connect;
else
{
atomic_add(&dcb->stats.n_accepts, 1);
if ((client = dcb_alloc()) == NULL)
client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
if (client_dcb == NULL)
{
return n_connect;
}
client->fd = so;
client->remote = strdup(inet_ntoa(addr.sin_addr));
memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL));
client->session = session_alloc(dcb->session->service, client);
client_dcb->fd = so;
client_dcb->remote = strdup(inet_ntoa(addr.sin_addr));
memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL));
client_dcb->session =
session_alloc(dcb->session->service, client_dcb);
telnetd_pr = (TELNETD *)malloc(sizeof(TELNETD));
client_dcb->protocol = (void *)telnetd_pr;
client->state = DCB_STATE_IDLE;
if ((client->protocol = malloc(sizeof(TELNETD))) == NULL)
{
dcb_free(client);
if (telnetd_pr == NULL)
{
dcb_add_to_zombieslist(client_dcb);
return n_connect;
}
if (poll_add_dcb(client) == -1)
if (poll_add_dcb(client_dcb) == -1)
{
dcb_free(client);
dcb_add_to_zombieslist(dcb);
return n_connect;
}
n_connect++;
((TELNETD *)(client->protocol))->state = TELNETD_STATE_LOGIN;
((TELNETD *)(client->protocol))->username = NULL;
dcb_printf(client, "MaxScale login: ");
client->state = DCB_STATE_POLLING;
telnetd_pr->state = TELNETD_STATE_LOGIN;
telnetd_pr->username = NULL;
dcb_printf(client_dcb, "MaxScale login: ");
}
}
return n_connect;
@ -368,8 +373,6 @@ short pnum;
{
return 0;
}
listener->state = DCB_STATE_LISTENING;
listen(listener->fd, SOMAXCONN);
if (poll_add_dcb(listener) == -1)