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