comparison common.cpp @ 392:78fed0d4c108 api-inversion

Include some necessary information in struct adb. Now the struct adb contains a database fd, the flags used to open that fd (so that we can later tell if it was for write or not) and a database header pointer. audiodb_open() is now responsible for filling in all of that information. To do that, it needs to take an open(2) flag; that's good, because it means that the call to open(2) is no longer invoking undefined behaviour. (Also, the previous version of audiodb_open() leaked an fd). Unfortunately, that means we have broken ABI and API compatibility. (Fortunately, we have fewer than 12 users). Use audiodb_open() in audioDB::initDBHeader(). We've temporarily(?) put acquire_lock(int, bool) in the API header; that means we need to include <stdbool.h> and compile C files with -std=c99. Do so. Make audiodb_close() free resources allocated by audiodb_open(). Include a struct adb * field in the audioDB C++ object... ... which lets us actually implement memory-correctness, by audiodb_close()ing the database in audioDB::cleanup(). [ The lock is, I think, correctly disposed of; man fcntl(2) on Linux says that the locks are released once any file descriptor relating to the file is closed, and we close the fd in audiodb_close(). ]
author mas01cr
date Mon, 24 Nov 2008 15:42:15 +0000
parents 4e68f7d4d524
children bc7a821004bb
comparison
equal deleted inserted replaced
391:69f8bf88c0ff 392:78fed0d4c108
1 #include "audioDB.h" 1 #include "audioDB.h"
2 extern "C" {
3 #include "audioDB_API.h"
4 }
2 5
3 #if defined(O2_DEBUG) 6 #if defined(O2_DEBUG)
4 void sigterm_action(int signal, siginfo_t *info, void *context) { 7 void sigterm_action(int signal, siginfo_t *info, void *context) {
5 exit(128+signal); 8 exit(128+signal);
6 } 9 }
93 /* FIXME: maybe we should use a real source of entropy? */ 96 /* FIXME: maybe we should use a real source of entropy? */
94 gsl_rng_set(rng, time(NULL)); 97 gsl_rng_set(rng, time(NULL));
95 } 98 }
96 99
97 void audioDB::initDBHeader(const char* dbName) { 100 void audioDB::initDBHeader(const char* dbName) {
98 if ((dbfid = open(dbName, forWrite ? O_RDWR : O_RDONLY)) < 0) { 101 adb = audiodb_open(dbName, forWrite ? O_RDWR : O_RDONLY);
99 error("Can't open database file", dbName, "open"); 102 if(!adb) {
100 } 103 error("Failed to open database", dbName);
101 104 }
102 get_lock(dbfid, forWrite); 105 dbfid = adb->fd;
103 // Get the database header info 106 dbH = adb->header;
104 dbH = new dbTableHeaderT();
105 assert(dbH);
106
107 if(read(dbfid, (char *) dbH, O2_HEADERSIZE) != O2_HEADERSIZE) {
108 error("error reading db header", dbName, "read");
109 }
110
111 if(dbH->magic == O2_OLD_MAGIC) {
112 // FIXME: if anyone ever complains, write the program to convert
113 // from the old audioDB format to the new...
114 error("database file has old O2 header", dbName);
115 }
116
117 if(dbH->magic != O2_MAGIC) {
118 std::cerr << "expected: " << O2_MAGIC << ", got: " << dbH->magic << std::endl;
119 error("database file has incorrect header", dbName);
120 }
121
122 if(dbH->version != O2_FORMAT_VERSION) {
123 error("database file has incorrect version", dbName);
124 }
125
126 if(dbH->headerSize != O2_HEADERSIZE) {
127 error("sizeof(dbTableHeader) unexpected: platform ABI mismatch?", dbName);
128 }
129 107
130 CHECKED_MMAP(char *, db, 0, getpagesize()); 108 CHECKED_MMAP(char *, db, 0, getpagesize());
131 109
132 // Make some handy tables with correct types 110 // Make some handy tables with correct types
133 if(forWrite || (dbH->length > 0)) { 111 if(forWrite || (dbH->length > 0)) {