annotate common.cpp @ 601:82d23418d867

Fix some fd leaks in the command-line binary Strictly speaking, they're not really leaks, because the only codepath that suffers from these leaks exits immediately afterwards. On the other hand, this fix makes valgrind on e.g. tests/0025 happier, going from 5 errors to none.
author mas01cr
date Fri, 14 Aug 2009 16:39:32 +0000
parents 4eedc18634f5
children 4c4389325ae4
rev   line source
mas01cr@239 1 #include "audioDB.h"
mas01cr@239 2
mas01cr@239 3 #if defined(O2_DEBUG)
mas01cr@239 4 void sigterm_action(int signal, siginfo_t *info, void *context) {
mas01cr@239 5 exit(128+signal);
mas01cr@239 6 }
mas01cr@239 7
mas01cr@239 8 void sighup_action(int signal, siginfo_t *info, void *context) {
mas01cr@239 9 // FIXME: reread any configuration files
mas01cr@239 10 }
mas01cr@239 11 #endif
mas01cr@239 12
mas01cr@239 13 void audioDB::error(const char* a, const char* b, const char *sysFunc) {
mas01ik@355 14
mas01ik@355 15
mas01ik@355 16 if(isServer) {
mas01cr@370 17 /* FIXME: I think this is leaky -- we never delete err.
mas01cr@370 18 actually deleting it is tricky, though; it gets placed into
mas01cr@370 19 some soap-internal struct with uncertain extent... -- CSR,
mas01cr@370 20 2007-10-01 */
mas01cr@370 21 char *err = new char[256]; /* FIXME: overflows */
mas01cr@370 22 snprintf(err, 255, "%s: %s\n%s", a, b, sysFunc ? strerror(errno) : "");
mas01cr@370 23 /* FIXME: actually we could usefully do with a properly
mas01cr@370 24 structured type, so that we can throw separate faultstring
mas01cr@370 25 and details. -- CSR, 2007-10-01 */
mas01ik@355 26 throw(err);
mas01ik@355 27 } else {
mas01ik@355 28 std::cerr << a << ": " << b << std::endl;
mas01ik@355 29 if (sysFunc) {
mas01ik@355 30 perror(sysFunc);
mas01ik@355 31 }
mas01ik@355 32 exit(1);
mas01cr@239 33 }
mas01cr@239 34 }
mas01cr@239 35
mas01cr@284 36 void audioDB::initRNG() {
mas01cr@284 37 rng = gsl_rng_alloc(gsl_rng_mt19937);
mas01cr@284 38 if(!rng) {
mas01cr@284 39 error("could not allocate Random Number Generator");
mas01cr@284 40 }
mas01cr@284 41 /* FIXME: maybe we should use a real source of entropy? */
mas01cr@284 42 gsl_rng_set(rng, time(NULL));
mas01cr@284 43 }
mas01cr@284 44
mas01cr@239 45 void audioDB::initDBHeader(const char* dbName) {
mas01cr@498 46 if(!adb) {
mas01cr@498 47 adb = audiodb_open(dbName, forWrite ? O_RDWR : O_RDONLY);
mas01cr@498 48 if(!adb) {
mas01cr@498 49 error("Failed to open database", dbName);
mas01cr@498 50 }
mas01cr@239 51 }
mas01cr@498 52 dbfid = adb->fd;
mas01cr@498 53 dbH = adb->header;
mas01cr@239 54
mas01cr@239 55 // Make some handy tables with correct types
mas01cr@239 56 if(forWrite || (dbH->length > 0)) {
mas01cr@239 57 if(forWrite) {
mas01cr@239 58 fileTableLength = dbH->trackTableOffset - dbH->fileTableOffset;
mas01cr@239 59 trackTableLength = dbH->dataOffset - dbH->trackTableOffset;
mas01cr@239 60 timesTableLength = dbH->powerTableOffset - dbH->timesTableOffset;
mas01cr@239 61 powerTableLength = dbH->l2normTableOffset - dbH->powerTableOffset;
mas01cr@239 62 l2normTableLength = dbH->dbSize - dbH->l2normTableOffset;
mas01cr@239 63 } else {
mas01cr@256 64 fileTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01cr@256 65 trackTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_TRACKTABLE_ENTRY_SIZE);
mas01mc@324 66 if( dbH->flags & O2_FLAG_LARGE_ADB ){
mas01mc@324 67 timesTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 68 powerTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 69 l2normTableLength = 0;
mas01mc@324 70 }
mas01mc@324 71 else{
mas01mc@324 72 timesTableLength = ALIGN_PAGE_UP(2*(dbH->length / dbH->dim));
mas01mc@324 73 powerTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim);
mas01mc@324 74 l2normTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim);
mas01mc@324 75 }
mas01cr@239 76 }
mas01cr@239 77 CHECKED_MMAP(char *, fileTable, dbH->fileTableOffset, fileTableLength);
mas01cr@239 78 CHECKED_MMAP(unsigned *, trackTable, dbH->trackTableOffset, trackTableLength);
mas01mc@324 79 if( dbH->flags & O2_FLAG_LARGE_ADB ){
mas01mc@324 80 CHECKED_MMAP(char *, featureFileNameTable, dbH->dataOffset, fileTableLength);
mas01mc@324 81 if( dbH->flags & O2_FLAG_TIMES )
mas01mc@324 82 CHECKED_MMAP(char *, timesFileNameTable, dbH->timesTableOffset, fileTableLength);
mas01mc@324 83 if( dbH->flags & O2_FLAG_POWER )
mas01mc@324 84 CHECKED_MMAP(char *, powerFileNameTable, dbH->powerTableOffset, fileTableLength);
mas01mc@324 85 }
mas01mc@324 86 else{
mas01mc@324 87 CHECKED_MMAP(double *, timesTable, dbH->timesTableOffset, timesTableLength);
mas01mc@324 88 CHECKED_MMAP(double *, powerTable, dbH->powerTableOffset, powerTableLength);
mas01mc@324 89 CHECKED_MMAP(double *, l2normTable, dbH->l2normTableOffset, l2normTableLength);
mas01mc@324 90 }
mas01cr@239 91 }
mas01cr@239 92 }
mas01cr@239 93
mas01cr@498 94 void audioDB::initInputFile (const char *inFile) {
mas01cr@239 95 if (inFile) {
mas01cr@239 96 if ((infid = open(inFile, O_RDONLY)) < 0) {
mas01cr@239 97 error("can't open input file for reading", inFile, "open");
mas01cr@239 98 }
mas01cr@239 99
mas01cr@239 100 if (fstat(infid, &statbuf) < 0) {
mas01cr@239 101 error("fstat error finding size of input", inFile, "fstat");
mas01cr@239 102 }
mas01cr@239 103
mas01cr@239 104 if(dbH->dim == 0 && dbH->length == 0) { // empty database
mas01cr@239 105 // initialize with input dimensionality
mas01cr@239 106 if(read(infid, &dbH->dim, sizeof(unsigned)) != sizeof(unsigned)) {
mas01cr@239 107 error("short read of input file", inFile);
mas01cr@239 108 }
mas01cr@239 109 if(dbH->dim == 0) {
mas01cr@239 110 error("dimensionality of zero in input file", inFile);
mas01cr@239 111 }
mas01cr@239 112 } else {
mas01cr@239 113 unsigned test;
mas01cr@239 114 if(read(infid, &test, sizeof(unsigned)) != sizeof(unsigned)) {
mas01cr@239 115 error("short read of input file", inFile);
mas01cr@239 116 }
mas01cr@239 117 if(dbH->dim == 0) {
mas01cr@239 118 error("dimensionality of zero in input file", inFile);
mas01cr@239 119 }
mas01cr@239 120 if(dbH->dim != test) {
mas01cr@239 121 std::cerr << "error: expected dimension: " << dbH->dim << ", got : " << test <<std::endl;
mas01cr@239 122 error("feature dimensions do not match database table dimensions", inFile);
mas01cr@239 123 }
mas01cr@239 124 }
mas01cr@239 125 }
mas01cr@239 126 }
mas01cr@239 127
mas01mc@292 128 void audioDB::initTables(const char* dbName, const char* inFile) {
mas01cr@284 129 /* FIXME: initRNG() really logically belongs in the audioDB
mas01cr@284 130 contructor. However, there are of the order of four constructors
mas01cr@284 131 at the moment, and more to come from API implementation. Given
mas01cr@284 132 that duplication, I think this is the least worst place to put
mas01cr@284 133 it; the assumption is that nothing which doesn't look at a
mas01cr@284 134 database will need an RNG. -- CSR, 2008-07-02 */
mas01cr@284 135 initRNG();
mas01cr@239 136 initDBHeader(dbName);
mas01mc@292 137 if(inFile)
mas01mc@292 138 initInputFile(inFile);
mas01cr@239 139 }
mas01mc@292 140
mas01mc@324 141 // If name is relative path, side effect name with prefix/name
mas01mc@324 142 // Do not free original pointer
mas01mc@324 143 void audioDB::prefix_name(char** const name, const char* prefix){
mas01mc@324 144 // No prefix if prefix is empty
mas01mc@324 145 if(!prefix)
mas01mc@324 146 return;
mas01mc@324 147 // Allocate new memory, keep old memory
mas01mc@324 148 assert(name && *name);
mas01mc@324 149 if (strlen(*name) + strlen(prefix) + 1 > O2_MAXFILESTR)
mas01mc@324 150 error("error: path prefix + filename too long",prefix);
mas01mc@324 151 // Do not prefix absolute path+filename
mas01mc@324 152 if(**name=='/')
mas01mc@324 153 return;
mas01mc@324 154 // OK to prefix relative path+filename
mas01mc@324 155 char* prefixedName = (char*) malloc(O2_MAXFILESTR);
mas01mc@324 156 sprintf(prefixedName, "%s/%s", prefix, *name);
mas01mc@324 157 *name = prefixedName; // side effect new name to old name
mas01mc@324 158 }
mas01cr@498 159
mas01cr@498 160 void audioDB::insertTimeStamps(unsigned numVectors, std::ifstream *timesFile, double *timesdata) {
mas01cr@498 161 assert(usingTimes);
mas01cr@498 162
mas01cr@498 163 unsigned numtimes = 0;
mas01cr@498 164
mas01cr@498 165 if(!timesFile->is_open()) {
mas01cr@498 166 error("problem opening times file on timestamped database", timesFileName);
mas01cr@498 167 }
mas01cr@498 168
mas01cr@498 169 double timepoint, next;
mas01cr@498 170 *timesFile >> timepoint;
mas01cr@498 171 if (timesFile->eof()) {
mas01cr@498 172 error("no entries in times file", timesFileName);
mas01cr@498 173 }
mas01cr@498 174 numtimes++;
mas01cr@498 175 do {
mas01cr@498 176 *timesFile >> next;
mas01cr@498 177 if (timesFile->eof()) {
mas01cr@498 178 break;
mas01cr@498 179 }
mas01cr@498 180 numtimes++;
mas01cr@498 181 timesdata[0] = timepoint;
mas01cr@498 182 timepoint = (timesdata[1] = next);
mas01cr@498 183 timesdata += 2;
mas01cr@498 184 } while (numtimes < numVectors + 1);
mas01cr@498 185
mas01cr@498 186 if (numtimes < numVectors + 1) {
mas01cr@498 187 error("too few timepoints in times file", timesFileName);
mas01cr@498 188 }
mas01cr@498 189
mas01cr@498 190 *timesFile >> next;
mas01cr@498 191 if (!timesFile->eof()) {
mas01cr@498 192 error("too many timepoints in times file", timesFileName);
mas01cr@498 193 }
mas01cr@498 194 }