Commit acb7984b authored by Yoni Fogel's avatar Yoni Fogel

Closes #1339

Logger now unlocks all mutexes and destroys the two mutexes it contains.

Protected by a logger-close mutex to prevent anything from happening between the unlock and destroy.

git-svn-id: file:///svn/toku/tokudb.1032b@8397 c7de825b-a66e-492c-adef-691d508d4ae1
parent 4596a99c
...@@ -4285,10 +4285,12 @@ int toku_brt_truncate (BRT brt) { ...@@ -4285,10 +4285,12 @@ int toku_brt_truncate (BRT brt) {
static void toku_brt_lock_init(void) { static void toku_brt_lock_init(void) {
toku_pwrite_lock_init(); toku_pwrite_lock_init();
toku_logger_lock_init();
} }
static void toku_brt_lock_destroy(void) { static void toku_brt_lock_destroy(void) {
toku_pwrite_lock_destroy(); toku_pwrite_lock_destroy();
toku_logger_lock_destroy();
} }
void toku_brt_init(void) { void toku_brt_init(void) {
......
...@@ -3,6 +3,17 @@ ...@@ -3,6 +3,17 @@
#include "includes.h" #include "includes.h"
static toku_pthread_mutex_t logger_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER;
void toku_logger_lock_init(void) {
int r = toku_pthread_mutex_init(&logger_mutex, NULL);
assert(r == 0);
}
void toku_logger_lock_destroy(void) {
int r = toku_pthread_mutex_destroy(&logger_mutex);
assert(r == 0);
}
void* toku_malloc_in_rollback(TOKUTXN txn, size_t size) { void* toku_malloc_in_rollback(TOKUTXN txn, size_t size) {
return malloc_in_memarena(txn->rollentry_arena, size); return malloc_in_memarena(txn->rollentry_arena, size);
} }
...@@ -309,25 +320,35 @@ int toku_logger_log_bytes (TOKULOGGER logger, struct logbytes *bytes, int do_fsy ...@@ -309,25 +320,35 @@ int toku_logger_log_bytes (TOKULOGGER logger, struct logbytes *bytes, int do_fsy
// No locks held on entry // No locks held on entry
// No locks held on exit. // No locks held on exit.
// No locks are needed, since you cannot legally close the log concurrently with doing anything else. // No locks are needed, since you cannot legally close the log concurrently with doing anything else.
// But grab the locks just to be careful. // But grab the locks just to be careful, including one to prevent access
// between unlocking and destroying.
int toku_logger_close(TOKULOGGER *loggerp) { int toku_logger_close(TOKULOGGER *loggerp) {
TOKULOGGER logger = *loggerp; TOKULOGGER logger = *loggerp;
if (logger->is_panicked) return EINVAL; if (logger->is_panicked) return EINVAL;
int r = 0; int r = 0;
int locked_logger = 0;
if (!logger->is_open) goto is_closed; if (!logger->is_open) goto is_closed;
r = ml_lock(&logger->output_lock); if (r!=0) goto panic; r = ml_lock(&logger->output_lock); if (r!=0) goto panic;
r = ml_lock(&logger->input_lock); if (r!=0) goto panic; r = ml_lock(&logger->input_lock); if (r!=0) goto panic;
r = do_write(logger, 1); if (r!=0) goto panic; r = toku_pthread_mutex_lock(&logger_mutex); if (r!=0) goto panic;
locked_logger = 1;
r = do_write(logger, 1); if (r!=0) goto panic; //Releases the input lock
if (logger->fd!=-1) { if (logger->fd!=-1) {
r = close(logger->fd); if (r!=0) { r=errno; goto panic; } r = close(logger->fd); if (r!=0) { r=errno; goto panic; }
} }
logger->fd=-1; logger->fd=-1;
r = ml_unlock(&logger->output_lock);
r = ml_unlock(&logger->output_lock); if (r!=0) goto panic;
r = ml_destroy(&logger->output_lock); if (r!=0) goto panic;
r = ml_destroy(&logger->input_lock); if (r!=0) goto panic;
is_closed: is_closed:
logger->is_panicked=1; // Just in case this might help. logger->is_panicked=1; // Just in case this might help.
if (logger->directory) toku_free(logger->directory); if (logger->directory) toku_free(logger->directory);
toku_free(logger); toku_free(logger);
*loggerp=0; *loggerp=0;
if (locked_logger) {
r = toku_pthread_mutex_unlock(&logger_mutex); if (r!=0) goto panic;
}
return r; return r;
panic: panic:
toku_logger_panic(logger, r); toku_logger_panic(logger, r);
...@@ -1093,3 +1114,4 @@ int toku_txn_find_by_xid (BRT brt, TXNID xid, TOKUTXN *txnptr) { ...@@ -1093,3 +1114,4 @@ int toku_txn_find_by_xid (BRT brt, TXNID xid, TOKUTXN *txnptr) {
if (r == 0) *txnptr = txnv; if (r == 0) *txnptr = txnv;
return r; return r;
} }
...@@ -22,6 +22,8 @@ struct logbytes { ...@@ -22,6 +22,8 @@ struct logbytes {
#define MALLOC_LOGBYTES(n) toku_malloc(sizeof(struct logbytes)+n -1) #define MALLOC_LOGBYTES(n) toku_malloc(sizeof(struct logbytes)+n -1)
void toku_logger_lock_init(void);
void toku_logger_lock_destroy(void);
int toku_logger_create(TOKULOGGER */*resultp*/); int toku_logger_create(TOKULOGGER */*resultp*/);
void toku_logger_set_cachetable (TOKULOGGER, CACHETABLE); void toku_logger_set_cachetable (TOKULOGGER, CACHETABLE);
void toku_logger_write_log_files (TOKULOGGER, int do_write_log_files); void toku_logger_write_log_files (TOKULOGGER, int do_write_log_files);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment