Commit a70b5f83 authored by Bradley C. Kuszmaul's avatar Bradley C. Kuszmaul

Get rid of various memory leaks in the cxx (and test cxx exceptions) Addresses #215.

git-svn-id: file:///svn/tokudb@1327 c7de825b-a66e-492c-adef-691d508d4ae1
parent 1bb050e6
......@@ -6,9 +6,16 @@ DbTxn::DbTxn(DB_TXN *txn)
txn->api_internal = this;
}
DbTxn::~DbTxn()
{
if (the_txn) {
the_txn->abort(0);
}
}
int DbTxn::commit (u_int32_t flags) {
DB_TXN *txn = get_DB_TXN();
int ret = txn->commit(txn, flags);
DbEnv *env = (DbEnv*)txn->mgrp->api1_internal;
DbEnv *env = (DbEnv*)the_txn->mgrp->api1_internal; // Must grab the env before committing the txn (because that releases the txn memory.)
int ret = the_txn->commit(the_txn, flags);
the_txn=0; // So we don't touch it my mistake.
return env->maybe_throw_error(ret);
}
......@@ -141,8 +141,9 @@ class DbEnv {
void err(int error, const char *fmt, ...);
void set_errfile(FILE *errfile);
int do_no_exceptions; // This should be private!!!
private:
int do_no_exceptions;
DB_ENV *the_env;
DbEnv(DB_ENV *, u_int32_t /*flags*/);
......@@ -155,6 +156,8 @@ class DbTxn {
public:
int commit (u_int32_t /*flags*/);
virtual ~DbTxn();
DB_TXN *get_DB_TXN()
{
if (this==0) return 0;
......
......@@ -60,17 +60,21 @@ log_code.c log_header.h: logformat
libs: log.o
bins: $(BINS)
check: bins
$(DTOOL) ./test_oexcl
$(DTOOL) ./ybt-test
$(DTOOL) ./pma-test
$(DTOOL) ./cachetable-test
$(DTOOL) ./cachetable-test2
$(DTOOL) ./brt-serialize-test
$(DTOOL) ./brt-test
$(DTOOL) ./hashtest
$(DTOOL) ./test_toku_malloc_plain_free
./benchmark-test --valsize 256 --verify 1
CHECKS = \
test_oexcl \
ybt-test \
pma-test \
cachetable-test \
cachetable-test2 \
brt-serialize-test \
brt-test hashtest \
test_toku_malloc_plain_free
check: bins $(patsubst %,check_%,$(CHECKS)) check_benchmarktest_256
check_benchmarktest_256: benchmark-test
$(DTOOL) ./benchmark-test --valsize 256 --verify 1
check_%: %
$(DTOOL) ./$<
check-fanout:
let BRT_FANOUT=4; \
......
......@@ -238,8 +238,8 @@ int toku_logger_log_phys_add_or_delete_in_leaf (DB *db, TOKUTXN txn, DISKOFF dis
return toku_logger_finish(txn->logger, &wbuf);
}
int toku_logger_commit (TOKUTXN txn) {
int r = toku_log_commit(txn, txn->txnid64);
int toku_logger_commit (TOKUTXN txn, int nosync) {
int r = toku_log_commit(txn, txn->txnid64, nosync);
toku_free(txn);
return r;
}
......
......@@ -13,7 +13,7 @@ int toku_logger_log_checkpoint (TOKULOGGER, LSN*);
int toku_logger_log_phys_add_or_delete_in_leaf (DB *db, TOKUTXN txn, DISKOFF diskoff, int is_add, const struct kv_pair *pair);
int toku_logger_commit (TOKUTXN txn);
int toku_logger_commit (TOKUTXN txn, int no_sync);
int toku_logger_log_block_rename (TOKULOGGER /*logger*/, FILENUM /*fileid*/, DISKOFF /*olddiskoff*/, DISKOFF /*newdiskoff*/, DISKOFF /*parentdiskoff*/, int /*childnum*/);
......
......@@ -153,6 +153,9 @@ void generate_log_writer (void) {
fprintf2(cf, hf, "int toku_log_%s (TOKUTXN txn", lt->name);
DO_FIELDS(ft, lt,
fprintf2(cf, hf, ", %s %s", ft->type, ft->name));
if (lt->command=='C') {
fprintf2(cf,hf, ", int nosync");
}
fprintf(hf, ");\n");
fprintf(cf, ") {\n");
fprintf(cf, " if (txn==0) return 0;\n");
......@@ -180,7 +183,7 @@ void generate_log_writer (void) {
if (lt->command=='C') {
fprintf(cf, " if (r!=0) return r;\n");
fprintf(cf, " // commit has some extra work to do.\n");
fprintf(cf, " if (txn->parent) return 0; // don't fsync if there is a parent.\n");
fprintf(cf, " if (txn->parent || nosync) return 0; // don't fsync if there is a parent.\n");
fprintf(cf, " else return toku_logger_fsync(txn->logger);\n");
} else {
fprintf(cf, " return r;\n");
......
......@@ -114,7 +114,9 @@ FOO_NO_VGRIND = \
reverse_compare_fun \
# Comment to terminate list so the previous line can end with a slash
NO_VGRIND = db_env_open_nocreate \
NO_VGRIND = \
db_curs2 \
db_env_open_nocreate \
db_env_open_open_close \
db_open_notexist_reopen \
db_remove_subdb \
......
......@@ -543,16 +543,22 @@ int db_env_create(DB_ENV ** envp, u_int32_t flags) {
static int toku_db_txn_commit(DB_TXN * txn, u_int32_t flags) {
//notef("flags=%d\n", flags);
flags=flags;
if (!txn)
return -1;
int r = toku_logger_commit(txn->i->tokutxn);
if (r != 0)
return r;
int r;
int nosync = (flags & DB_TXN_NOSYNC)!=0;
flags &= ~DB_TXN_NOSYNC;
if (!txn) return EINVAL;
if (flags!=0) goto return_invalid;
r = toku_logger_commit(txn->i->tokutxn, nosync);
if (0) {
return_invalid:
r = EINVAL;
toku_free(txn->i->tokutxn);
}
// Cleanup */
if (txn->i)
toku_free(txn->i);
toku_free(txn);
return 0;
return r; // The txn is no good after the commit.
}
static u_int32_t toku_db_txn_id(DB_TXN * txn) {
......@@ -569,12 +575,14 @@ static int toku_txn_abort(DB_TXN * txn) {
}
static int toku_txn_begin(DB_ENV * env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t flags) {
if (!env->i->logger) return EINVAL;
flags=flags;
DB_TXN *MALLOC(result);
if (result == 0)
return ENOMEM;
memset(result, 0, sizeof *result);
//notef("parent=%p flags=0x%x\n", stxn, flags);
result->mgrp = env;
result->abort = toku_txn_abort;
result->commit = toku_db_txn_commit;
result->id = toku_db_txn_id;
......
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