Added back read and write mutex to dcb. Locks are acquired in poll.c before calling call-back functions. Additional locks efficiently hide memory corruption issue, which appears when readconn router is used without using those mutexes, with multiple parallel maxscale threads and intensive load.

This commit is contained in:
vraatikka 2013-11-20 17:23:04 +02:00
parent 35d34862b9
commit a30e2ab29b
3 changed files with 39 additions and 1 deletions

View File

@ -106,6 +106,12 @@ if ((rval = calloc(1, sizeof(DCB))) == NULL)
rval->dcb_chk_tail = CHK_NUM_DCB;
#endif
rval->dcb_role = role;
#if 1
simple_mutex_init(&rval->dcb_write_lock, "DCB write mutex");
simple_mutex_init(&rval->dcb_read_lock, "DCB read mutex");
rval->dcb_write_active = false;
rval->dcb_read_active = false;
#endif
spinlock_init(&rval->dcb_initlock);
spinlock_init(&rval->writeqlock);
spinlock_init(&rval->delayqlock);

View File

@ -406,10 +406,24 @@ poll_waitevents(void *arg)
eno = gw_getsockerrno(dcb->fd);
if (eno == 0) {
#if 1
simple_mutex_lock(
&dcb->dcb_write_lock,
true);
ss_info_dassert(
!dcb->dcb_write_active,
"Write already active");
dcb->dcb_write_active = TRUE;
#endif
atomic_add(
&pollStats.n_write,
&pollStats.n_write,
1);
dcb->func.write_ready(dcb);
#if 1
dcb->dcb_write_active = FALSE;
simple_mutex_unlock(
&dcb->dcb_write_lock);
#endif
} else {
skygw_log_write(
LOGFILE_DEBUG,
@ -425,6 +439,13 @@ poll_waitevents(void *arg)
}
if (ev & EPOLLIN)
{
#if 1
simple_mutex_lock(&dcb->dcb_read_lock,
true);
ss_info_dassert(!dcb->dcb_read_active,
"Read already active");
dcb->dcb_read_active = TRUE;
#endif
if (dcb->state == DCB_STATE_LISTENING)
{
skygw_log_write(
@ -449,6 +470,11 @@ poll_waitevents(void *arg)
atomic_add(&pollStats.n_read, 1);
dcb->func.read(dcb);
}
#if 1
dcb->dcb_read_active = FALSE;
simple_mutex_unlock(
&dcb->dcb_read_lock);
#endif
}
} /**< for */
no_op = FALSE;

View File

@ -156,6 +156,12 @@ typedef struct dcb {
#endif
dcb_role_t dcb_role;
SPINLOCK dcb_initlock;
#if 1
simple_mutex_t dcb_read_lock;
simple_mutex_t dcb_write_lock;
bool dcb_read_active;
bool dcb_write_active;
#endif
int fd; /**< The descriptor */
dcb_state_t state; /**< Current descriptor state */
char *remote; /**< Address of remote end */