rearrange indicators of db open state, invalidate db handles after remove operation (per doc),

add more warnings about open handles,
This commit is contained in:
danj 2007-03-07 18:22:11 +00:00
parent 9bdf7392b9
commit 0d6da8af0a

53
bdb.c
View file

@ -10,6 +10,7 @@
#define LMEMFLAG 0 #define LMEMFLAG 0
#define NOFLAGS 0 #define NOFLAGS 0
#undef DEBUG_DB
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h> #include <stdarg.h>
@ -90,12 +91,13 @@ static void db_free(t_dbh *dbh)
{ {
#ifdef DEBUG_DB #ifdef DEBUG_DB
if ( RTEST(ruby_debug) ) if ( RTEST(ruby_debug) )
fprintf(stderr,"%s/%d %s 0x%x\n",__FILE__,__LINE__,"db_free cleanup!",p); fprintf(stderr,"%s/%d %s 0x%x\n",__FILE__,__LINE__,"db_free cleanup!",dbh);
#endif #endif
if ( dbh ) { if ( dbh ) {
if ( dbh->db && dbh->filename[0]!=0 ) { if ( dbh->db && dbh->filename[0]!=0 ) {
dbh->db->close(dbh->db,NOFLAGS); dbh->db->close(dbh->db,NOFLAGS);
dbh->db=NULL;
} }
free(dbh); free(dbh);
} }
@ -157,7 +159,7 @@ VALUE db_init_aux(VALUE obj,t_envh * eh)
} }
#ifdef DEBUG_DB #ifdef DEBUG_DB
dbh->db->set_errfile(dbh->db,stderr); db->set_errfile(db,stderr);
#endif #endif
dbh=ALLOC(t_dbh); dbh=ALLOC(t_dbh);
@ -169,11 +171,14 @@ VALUE db_init_aux(VALUE obj,t_envh * eh)
dbh->aproc=Qnil; dbh->aproc=Qnil;
memset(&(dbh->filename),0,FNLEN+1); memset(&(dbh->filename),0,FNLEN+1);
if (eh) {
rb_ary_push(eh->adb,obj);
}
dbh->adbc=Qnil; dbh->adbc=Qnil;
if (dbh->env) {
#ifdef DEBUG_DB
fprintf(stderr,"Adding 0x%x 0x%x\n",obj,dbh);
#endif
rb_ary_push(dbh->env->adb,obj);
}
return obj; return obj;
} }
@ -436,7 +441,7 @@ VALUE db_close(VALUE obj, VALUE vflags)
flags=NUM2INT(vflags); flags=NUM2INT(vflags);
Data_Get_Struct(obj,t_dbh,dbh); Data_Get_Struct(obj,t_dbh,dbh);
if ( dbh->db==NULL || strlen(dbh->filename)==0 ) if ( dbh->db==NULL )
return Qnil; return Qnil;
if (! NIL_P(dbh->adbc) && RARRAY(dbh->adbc)->len > 0 ) { if (! NIL_P(dbh->adbc) && RARRAY(dbh->adbc)->len > 0 ) {
@ -449,15 +454,19 @@ VALUE db_close(VALUE obj, VALUE vflags)
if ( RTEST(ruby_debug) ) if ( RTEST(ruby_debug) )
rb_warning("%s/%d %s 0x%x %s",__FILE__,__LINE__,"db_close!",dbh, rb_warning("%s/%d %s 0x%x %s",__FILE__,__LINE__,"db_close!",dbh,
dbh->filename); (dbh->filename==NULL||*(dbh->filename)=='0') ? "unknown" : dbh->filename);
rv = dbh->db->close(dbh->db,flags); rv = dbh->db->close(dbh->db,flags);
if ( rv != 0 ) { if ( rv != 0 ) {
if ( dbh->env ) {
rb_ary_delete(dbh->env->adb,obj);
}
raise_error(rv, "db_close failure: %s",db_strerror(rv)); raise_error(rv, "db_close failure: %s",db_strerror(rv));
} }
dbh->db=NULL; dbh->db=NULL;
dbh->aproc=Qnil; dbh->aproc=Qnil;
if ( dbh->env ) { if ( dbh->env ) {
rb_warning("%s/%d %s 0x%x",__FILE__,__LINE__,"db_close! removing",obj);
rb_ary_delete(dbh->env->adb,obj); rb_ary_delete(dbh->env->adb,obj);
} }
@ -810,7 +819,8 @@ VALUE db_remove(VALUE obj, VALUE vdisk_file,
NIL_P(vdisk_file)?NULL:StringValueCStr(vdisk_file), NIL_P(vdisk_file)?NULL:StringValueCStr(vdisk_file),
NIL_P(vlogical_db)?NULL:StringValueCStr(vlogical_db), NIL_P(vlogical_db)?NULL:StringValueCStr(vlogical_db),
flags); flags);
/* handle cannot be accessed again per docs */
dbh->db=NULL;
if (rv) if (rv)
raise_error(rv,"db_remove failed: %s",db_strerror(rv)); raise_error(rv,"db_remove failed: %s",db_strerror(rv));
return Qtrue; return Qtrue;
@ -1013,6 +1023,11 @@ int assoc_callback(DB *secdb,const DBT* key, const DBT* data, DBT* result)
rb_warning("return from assoc callback not a string!"); rb_warning("return from assoc callback not a string!");
StringValue(retv); StringValue(retv);
#ifdef DEBUG_DB
fprintf(stderr,"assoc_key %*s for %*s\n",
RSTRING(retv)->len,RSTRING(retv)->ptr,
data->size,data->data);
#endif
result->data=RSTRING(retv)->ptr; result->data=RSTRING(retv)->ptr;
result->size=RSTRING(retv)->len; result->size=RSTRING(retv)->len;
result->flags=LMEMFLAG; result->flags=LMEMFLAG;
@ -1337,6 +1352,7 @@ static void env_free(void *p)
if ( eh ) { if ( eh ) {
if ( eh->env ) { if ( eh->env ) {
eh->env->close(eh->env,NOFLAGS); eh->env->close(eh->env,NOFLAGS);
eh->env=NULL;
} }
free(p); free(p);
} }
@ -1439,11 +1455,14 @@ VALUE env_close(VALUE obj)
return Qnil; return Qnil;
if (RARRAY(eh->adb)->len > 0) { if (RARRAY(eh->adb)->len > 0) {
rb_warning("%s/%d %s",__FILE__,__LINE__, rb_warning("%s/%d %s %d",__FILE__,__LINE__,
"database handles still open"); "database handles still open",RARRAY(eh->adb)->len);
while ( (db=rb_ary_pop(eh->adb)) != Qnil ) { while (RARRAY(eh->adb)->len > 0)
db_close(db,INT2FIX(0)); if ((db=rb_ary_pop(eh->adb)) != Qnil ) {
} rb_warning("%s/%d %s 0x%x",__FILE__,__LINE__,
"closing",db);
db_close(db,INT2FIX(0));
}
} }
if (RARRAY(eh->atxn)->len > 0) { if (RARRAY(eh->atxn)->len > 0) {
rb_warning("%s/%d %s",__FILE__,__LINE__, rb_warning("%s/%d %s",__FILE__,__LINE__,
@ -1457,13 +1476,13 @@ VALUE env_close(VALUE obj)
rb_warning("%s/%d %s 0x%x",__FILE__,__LINE__,"env_close!",eh); rb_warning("%s/%d %s 0x%x",__FILE__,__LINE__,"env_close!",eh);
rv = eh->env->close(eh->env,NOFLAGS); rv = eh->env->close(eh->env,NOFLAGS);
eh->env=NULL;
eh->adb=Qnil;
eh->atxn=Qnil;
if ( rv != 0 ) { if ( rv != 0 ) {
raise_error(rv, "env_close failure: %s",db_strerror(rv)); raise_error(rv, "env_close failure: %s",db_strerror(rv));
return Qnil; return Qnil;
} }
eh->env=NULL;
eh->adb=Qnil;
eh->atxn=Qnil;
return obj; return obj;
} }