log_manager.cc

blockbuf_get_writepos, when all existing buffers in blockbuf list are full, a new block buffer is created and added to the list. Adding to the list is done with mutex on hold. Mutex shouldn't be freed before the next iteration in while loop, which expects that bblist mutex is on hold. At the end of the function, removed an unnecessary debug assertion.

testlog.c
	Enabled more intensive write test. Replaced TRUE and FALSE with true, false, respectively.

skygw_utils.cc
	simple_mutex_unlock, added debug assertion to ensure that pthread mutex's user counter is always at least 0 (it goes negative in double free).
This commit is contained in:
vraatikka
2013-10-10 16:46:51 +03:00
parent e1c7887726
commit cd507f1461
3 changed files with 31 additions and 14 deletions

View File

@ -771,9 +771,6 @@ static char* blockbuf_get_writepos(
*/
bb_list->mlist_versno += 1;
ss_dassert(bb_list->mlist_versno%2 == 0);
/** Unlock list */
simple_mutex_unlock(&bb_list->mlist_mutex);
} else {
/**
* List and buffers are full.
@ -865,7 +862,6 @@ static char* blockbuf_get_writepos(
/** Unlock buffer */
simple_mutex_unlock(&bb->bb_mutex);
ss_dassert(bb_list->mlist_mutex.sm_lock_thr != pthread_self());
return pos;
}

View File

@ -40,9 +40,12 @@ static void* thr_run_morelog(void* data);
#define NTHR 256
#define NITER 100
#if 1
# define TEST1
#endif
#if 0
#define TEST1
#define TEST2
# define TEST2
#endif
#define TEST3
@ -172,13 +175,13 @@ int main(int argc, char* argv[])
do {
skygw_message_wait(mes);
simple_mutex_lock(mtx, TRUE);
simple_mutex_lock(mtx, true);
if (nactive > 0) {
simple_mutex_unlock(mtx);
continue;
}
break;
} while(TRUE);
} while(true);
for (i=0; i<NTHR; i++) {
pthread_join(thr[i]->tid, NULL);
@ -223,13 +226,13 @@ int main(int argc, char* argv[])
do {
skygw_message_wait(mes);
simple_mutex_lock(mtx, TRUE);
simple_mutex_lock(mtx, true);
if (nactive > 0) {
simple_mutex_unlock(mtx);
continue;
}
break;
} while(TRUE);
} while(true);
for (i=0; i<NTHR; i++) {
pthread_join(thr[i]->tid, NULL);
@ -504,7 +507,7 @@ static void* thr_run(
skygw_logmanager_init( 0, NULL);
skygw_logmanager_init( 0, NULL);
skygw_logmanager_done();
simple_mutex_lock(td->mtx, TRUE);
simple_mutex_lock(td->mtx, true);
*td->nactive -= 1;
simple_mutex_unlock(td->mtx);
skygw_message_send(td->mes);
@ -557,7 +560,7 @@ static void* thr_run_morelog(
str,
i);
}
simple_mutex_lock(td->mtx, TRUE);
simple_mutex_lock(td->mtx, true);
*td->nactive -= 1;
simple_mutex_unlock(td->mtx);
skygw_message_send(td->mes);

View File

@ -1321,6 +1321,12 @@ int simple_mutex_lock(
{
int err;
/**
* Leaving the following serves as a reminder. It may assert
* any given time because sm_lock_thr is not protected.
*
* ss_dassert(sm->sm_lock_thr != pthread_self());
*/
if (block) {
err = pthread_mutex_lock(&sm->sm_mutex);
} else {
@ -1336,6 +1342,9 @@ int simple_mutex_lock(
strerror(errno));
perror("simple_mutex : ");
} else {
/**
* Note that these updates are not protected.
*/
sm->sm_locked = true;
sm->sm_lock_thr = pthread_self();
}
@ -1346,18 +1355,27 @@ int simple_mutex_unlock(
simple_mutex_t* sm)
{
int err;
/**
* Leaving the following serves as a reminder. It may assert
* any given time because sm_lock_thr is not protected.
*
* ss_dassert(sm->sm_lock_thr == pthread_self());
*/
err = pthread_mutex_unlock(&sm->sm_mutex);
if (err != 0) {
fprintf(stderr,
"* Locking simple mutex %s failed due error "
"* Unlocking simple mutex %s failed due error "
"%d, %s\n",
sm->sm_name,
err,
strerror(errno));
perror("simple_mutex : ");
ss_dassert(sm->sm_mutex.__data.__nusers >= 0);
} else {
/**
* Note that these updates are not protected.
*/
sm->sm_locked = false;
sm->sm_lock_thr = 0;
}