annotate common.cpp @ 213:78a144448bda refactoring

Use "override CFLAGS+=" in Makefile. Allows e.g. "make CFLAGS=-pg" and still getting "-g -O3"
author mas01cr
date Tue, 04 Dec 2007 09:16:48 +0000
parents 2ea1908707c7
children acafe033b962
rev   line source
mas01cr@204 1 #include "audioDB.h"
mas01cr@204 2
mas01cr@204 3 #if defined(O2_DEBUG)
mas01cr@204 4 void sigterm_action(int signal, siginfo_t *info, void *context) {
mas01cr@204 5 exit(128+signal);
mas01cr@204 6 }
mas01cr@204 7
mas01cr@204 8 void sighup_action(int signal, siginfo_t *info, void *context) {
mas01cr@204 9 // FIXME: reread any configuration files
mas01cr@204 10 }
mas01cr@204 11 #endif
mas01cr@204 12
mas01cr@204 13 void audioDB::get_lock(int fd, bool exclusive) {
mas01cr@204 14 struct flock lock;
mas01cr@204 15 int status;
mas01cr@204 16
mas01cr@204 17 lock.l_type = exclusive ? F_WRLCK : F_RDLCK;
mas01cr@204 18 lock.l_whence = SEEK_SET;
mas01cr@204 19 lock.l_start = 0;
mas01cr@204 20 lock.l_len = 0; /* "the whole file" */
mas01cr@204 21
mas01cr@204 22 retry:
mas01cr@204 23 do {
mas01cr@204 24 status = fcntl(fd, F_SETLKW, &lock);
mas01cr@204 25 } while (status != 0 && errno == EINTR);
mas01cr@204 26
mas01cr@204 27 if (status) {
mas01cr@204 28 if (errno == EAGAIN) {
mas01cr@204 29 sleep(1);
mas01cr@204 30 goto retry;
mas01cr@204 31 } else {
mas01cr@204 32 error("fcntl lock error", "", "fcntl");
mas01cr@204 33 }
mas01cr@204 34 }
mas01cr@204 35 }
mas01cr@204 36
mas01cr@204 37 void audioDB::release_lock(int fd) {
mas01cr@204 38 struct flock lock;
mas01cr@204 39 int status;
mas01cr@204 40
mas01cr@204 41 lock.l_type = F_UNLCK;
mas01cr@204 42 lock.l_whence = SEEK_SET;
mas01cr@204 43 lock.l_start = 0;
mas01cr@204 44 lock.l_len = 0;
mas01cr@204 45
mas01cr@204 46 status = fcntl(fd, F_SETLKW, &lock);
mas01cr@204 47
mas01cr@204 48 if (status)
mas01cr@204 49 error("fcntl unlock error", "", "fcntl");
mas01cr@204 50 }
mas01cr@204 51
mas01cr@204 52 void audioDB::error(const char* a, const char* b, const char *sysFunc) {
mas01cr@204 53 if(isServer) {
mas01cr@204 54 /* FIXME: I think this is leaky -- we never delete err. actually
mas01cr@204 55 deleting it is tricky, though; it gets placed into some
mas01cr@204 56 soap-internal struct with uncertain extent... -- CSR,
mas01cr@204 57 2007-10-01 */
mas01cr@204 58 char *err = new char[256]; /* FIXME: overflows */
mas01cr@204 59 snprintf(err, 255, "%s: %s\n%s", a, b, sysFunc ? strerror(errno) : "");
mas01cr@204 60 /* FIXME: actually we could usefully do with a properly structured
mas01cr@204 61 type, so that we can throw separate faultstring and details.
mas01cr@204 62 -- CSR, 2007-10-01 */
mas01cr@204 63 throw(err);
mas01cr@204 64 } else {
mas01cr@204 65 std::cerr << a << ": " << b << std::endl;
mas01cr@204 66 if (sysFunc) {
mas01cr@204 67 perror(sysFunc);
mas01cr@204 68 }
mas01cr@204 69 exit(1);
mas01cr@204 70 }
mas01cr@204 71 }
mas01cr@204 72
mas01cr@204 73 void audioDB::initDBHeader(const char* dbName) {
mas01cr@204 74 if ((dbfid = open(dbName, forWrite ? O_RDWR : O_RDONLY)) < 0) {
mas01cr@204 75 error("Can't open database file", dbName, "open");
mas01cr@204 76 }
mas01cr@204 77
mas01cr@204 78 get_lock(dbfid, forWrite);
mas01cr@204 79 // Get the database header info
mas01cr@204 80 dbH = new dbTableHeaderT();
mas01cr@204 81 assert(dbH);
mas01cr@204 82
mas01cr@204 83 if(read(dbfid, (char *) dbH, O2_HEADERSIZE) != O2_HEADERSIZE) {
mas01cr@204 84 error("error reading db header", dbName, "read");
mas01cr@204 85 }
mas01cr@204 86
mas01cr@204 87 if(dbH->magic == O2_OLD_MAGIC) {
mas01cr@204 88 // FIXME: if anyone ever complains, write the program to convert
mas01cr@204 89 // from the old audioDB format to the new...
mas01cr@204 90 error("database file has old O2 header", dbName);
mas01cr@204 91 }
mas01cr@204 92
mas01cr@204 93 if(dbH->magic != O2_MAGIC) {
mas01cr@204 94 std::cerr << "expected: " << O2_MAGIC << ", got: " << dbH->magic << std::endl;
mas01cr@204 95 error("database file has incorrect header", dbName);
mas01cr@204 96 }
mas01cr@204 97
mas01cr@204 98 if(dbH->version != O2_FORMAT_VERSION) {
mas01cr@204 99 error("database file has incorect version", dbName);
mas01cr@204 100 }
mas01cr@204 101
mas01cr@204 102 CHECKED_MMAP(char *, db, 0, getpagesize());
mas01cr@204 103
mas01cr@204 104 // Make some handy tables with correct types
mas01cr@204 105 if(forWrite || (dbH->length > 0)) {
mas01cr@204 106 if(forWrite) {
mas01cr@204 107 fileTableLength = dbH->trackTableOffset - dbH->fileTableOffset;
mas01cr@204 108 trackTableLength = dbH->dataOffset - dbH->trackTableOffset;
mas01cr@204 109 dataBufLength = dbH->timesTableOffset - dbH->dataOffset;
mas01cr@204 110 timesTableLength = dbH->powerTableOffset - dbH->timesTableOffset;
mas01cr@204 111 powerTableLength = dbH->l2normTableOffset - dbH->powerTableOffset;
mas01cr@204 112 l2normTableLength = dbH->dbSize - dbH->l2normTableOffset;
mas01cr@204 113 } else {
mas01cr@204 114 fileTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLESIZE);
mas01cr@204 115 trackTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_TRACKTABLESIZE);
mas01cr@204 116 dataBufLength = ALIGN_PAGE_UP(dbH->length);
mas01cr@204 117 timesTableLength = ALIGN_PAGE_UP(2*(dbH->length / dbH->dim));
mas01cr@204 118 powerTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim);
mas01cr@204 119 l2normTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim);
mas01cr@204 120 }
mas01cr@204 121 CHECKED_MMAP(char *, fileTable, dbH->fileTableOffset, fileTableLength);
mas01cr@204 122 CHECKED_MMAP(unsigned *, trackTable, dbH->trackTableOffset, trackTableLength);
mas01cr@204 123 /*
mas01cr@204 124 * No more mmap() for dataBuf
mas01cr@204 125 *
mas01cr@204 126 * FIXME: Actually we do do the mmap() in the two cases where it's
mas01cr@204 127 * still "needed": in pointQuery and in l2norm if dbH->length is
mas01cr@204 128 * non-zero. Removing those cases too (and deleting the dataBuf
mas01cr@204 129 * variable completely) would be cool. -- CSR, 2007-11-19
mas01cr@204 130 *
mas01cr@204 131 * CHECKED_MMAP(double *, dataBuf, dbH->dataOffset, dataBufLength);
mas01cr@204 132 */
mas01cr@204 133 CHECKED_MMAP(double *, timesTable, dbH->timesTableOffset, timesTableLength);
mas01cr@204 134 CHECKED_MMAP(double *, powerTable, dbH->powerTableOffset, powerTableLength);
mas01cr@204 135 CHECKED_MMAP(double *, l2normTable, dbH->l2normTableOffset, l2normTableLength);
mas01cr@204 136 }
mas01cr@204 137 }
mas01cr@204 138
mas01cr@204 139 void audioDB::initInputFile (const char *inFile) {
mas01cr@204 140 if (inFile) {
mas01cr@204 141 if ((infid = open(inFile, O_RDONLY)) < 0) {
mas01cr@204 142 error("can't open input file for reading", inFile, "open");
mas01cr@204 143 }
mas01cr@204 144
mas01cr@204 145 if (fstat(infid, &statbuf) < 0) {
mas01cr@204 146 error("fstat error finding size of input", inFile, "fstat");
mas01cr@204 147 }
mas01cr@204 148
mas01cr@204 149 if(dbH->dim == 0 && dbH->length == 0) { // empty database
mas01cr@204 150 // initialize with input dimensionality
mas01cr@204 151 if(read(infid, &dbH->dim, sizeof(unsigned)) != sizeof(unsigned)) {
mas01cr@204 152 error("short read of input file", inFile);
mas01cr@204 153 }
mas01cr@204 154 if(dbH->dim == 0) {
mas01cr@204 155 error("dimensionality of zero in input file", inFile);
mas01cr@204 156 }
mas01cr@204 157 } else {
mas01cr@204 158 unsigned test;
mas01cr@204 159 if(read(infid, &test, sizeof(unsigned)) != sizeof(unsigned)) {
mas01cr@204 160 error("short read of input file", inFile);
mas01cr@204 161 }
mas01cr@204 162 if(dbH->dim == 0) {
mas01cr@204 163 error("dimensionality of zero in input file", inFile);
mas01cr@204 164 }
mas01cr@204 165 if(dbH->dim != test) {
mas01cr@204 166 std::cerr << "error: expected dimension: " << dbH->dim << ", got : " << test <<std::endl;
mas01cr@204 167 error("feature dimensions do not match database table dimensions", inFile);
mas01cr@204 168 }
mas01cr@204 169 }
mas01cr@204 170
mas01cr@204 171 if ((indata = (char *) mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, infid, 0)) == (caddr_t) -1) {
mas01cr@204 172 error("mmap error for input", inFile, "mmap");
mas01cr@204 173 }
mas01cr@204 174 }
mas01cr@204 175 }
mas01cr@204 176
mas01cr@204 177 void audioDB::initTables(const char* dbName, const char* inFile = 0) {
mas01cr@204 178 initDBHeader(dbName);
mas01cr@204 179 initInputFile(inFile);
mas01cr@204 180 }