annotate soap.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 d5ada9532a40
children 5b2c0d9bc63d
rev   line source
mas01cr@239 1 #include "audioDB.h"
mas01cr@239 2 #include "adb.nsmap"
mas01cr@239 3
mas01cr@239 4 /* Command-line client definitions */
mas01cr@239 5
mas01cr@239 6 // FIXME: this can't propagate the sequence length argument (used for
mas01cr@239 7 // dudCount). See adb__status() definition for the other half of
mas01cr@239 8 // this. -- CSR, 2007-10-01
mas01cr@239 9 void audioDB::ws_status(const char*dbName, char* hostport){
mas01cr@239 10 struct soap soap;
mas01cr@239 11 adb__statusResponse adbStatusResponse;
mas01cr@239 12
mas01cr@239 13 // Query an existing adb database
mas01cr@239 14 soap_init(&soap);
mas01cr@239 15 if(soap_call_adb__status(&soap,hostport,NULL,(char*)dbName,adbStatusResponse)==SOAP_OK) {
mas01cr@239 16 std::cout << "numFiles = " << adbStatusResponse.result.numFiles << std::endl;
mas01cr@239 17 std::cout << "dim = " << adbStatusResponse.result.dim << std::endl;
mas01cr@239 18 std::cout << "length = " << adbStatusResponse.result.length << std::endl;
mas01cr@239 19 std::cout << "dudCount = " << adbStatusResponse.result.dudCount << std::endl;
mas01cr@239 20 std::cout << "nullCount = " << adbStatusResponse.result.nullCount << std::endl;
mas01mc@324 21 std::cout << "flags = " << (adbStatusResponse.result.flags & 0x00FFFFFF) << std::endl;
mas01cr@239 22 } else {
mas01cr@550 23 char fault[MAXSTR];
mas01cr@550 24 soap_sprint_fault(&soap, fault, MAXSTR);
mas01cr@550 25 error(fault);
mas01cr@239 26 }
mas01cr@239 27
mas01cr@239 28 soap_destroy(&soap);
mas01cr@239 29 soap_end(&soap);
mas01cr@239 30 soap_done(&soap);
mas01cr@239 31 }
mas01cr@239 32
mas01mc@334 33 void audioDB::ws_liszt(const char* dbName, char* Hostport){
mas01mc@334 34 struct soap soap;
mas01mc@334 35 adb__lisztResponse adbLisztResponse;
mas01mc@334 36
mas01mc@334 37 soap_init(&soap);
mas01mc@334 38 if(soap_call_adb__liszt(&soap, hostport, NULL, (char*)dbName, lisztOffset, lisztLength, adbLisztResponse)==SOAP_OK){
mas01mc@334 39 for(int i = 0; i < adbLisztResponse.result.__sizeRkey; i++) {
mas01mc@334 40 std::cout << "[" << i+lisztOffset << "] " << adbLisztResponse.result.Rkey[i] << " ("
mas01mc@334 41 << adbLisztResponse.result.Rlen[i] << ")" << std::endl;
mas01mc@334 42 }
mas01mc@334 43 } else {
mas01cr@550 44 char fault[MAXSTR];
mas01cr@550 45 soap_sprint_fault(&soap, fault, MAXSTR);
mas01cr@550 46 error(fault);
mas01mc@334 47 }
mas01cr@550 48 soap_destroy(&soap);
mas01cr@550 49 soap_end(&soap);
mas01cr@550 50 soap_done(&soap);
mas01mc@334 51 }
mas01mc@334 52
mas01mc@308 53 // WS_QUERY (CLIENT SIDE)
mas01mc@307 54 void audioDB::ws_query(const char*dbName, const char *featureFileName, const char* hostport){
mas01cr@239 55 struct soap soap;
mas01cr@239 56 adb__queryResponse adbQueryResponse;
mas01mc@329 57 VERB_LOG(1, "Calling fileName query on database %s with featureFile=%s\n", dbName, featureFileName);
mas01cr@333 58 soap_init(&soap);
mas01cr@333 59 if(soap_call_adb__query(&soap, hostport, NULL, (char *) dbName,
mas01cr@333 60 (char *)featureFileName, (char *)trackFileName,
mas01cr@333 61 (char *)timesFileName, (char *) powerFileName,
mas01cr@333 62 queryType, queryPoint,
mas01cr@333 63 pointNN, trackNN, sequenceLength,
mas01cr@333 64 radius, absolute_threshold, relative_threshold,
mas01mc@471 65 !usingQueryPoint, lsh_exact, no_unit_norming,
mas01cr@333 66 adbQueryResponse)
mas01cr@333 67 == SOAP_OK) {
mas01cr@333 68 if(radius == 0) {
mas01cr@333 69 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++) {
mas01cr@333 70 std::cout << adbQueryResponse.result.Rlist[i] << " "
mas01cr@333 71 << adbQueryResponse.result.Dist[i] << " "
mas01cr@333 72 << adbQueryResponse.result.Qpos[i] << " "
mas01cr@333 73 << adbQueryResponse.result.Spos[i] << std::endl;
mas01cr@333 74 }
mas01cr@333 75 } else {
mas01cr@333 76 for(int i = 0; i < adbQueryResponse.result.__sizeRlist; i++) {
mas01cr@333 77 std::cout << adbQueryResponse.result.Rlist[i] << " "
mas01cr@333 78 << adbQueryResponse.result.Spos[i] << std::endl;
mas01cr@333 79 }
mas01cr@333 80 }
mas01cr@333 81 } else {
mas01cr@550 82 char fault[MAXSTR];
mas01cr@550 83 soap_sprint_fault(&soap, fault, MAXSTR);
mas01cr@550 84 error(fault);
mas01cr@239 85 }
mas01cr@333 86
mas01cr@239 87 soap_destroy(&soap);
mas01cr@239 88 soap_end(&soap);
mas01cr@239 89 soap_done(&soap);
mas01cr@239 90 }
mas01mc@307 91
mas01mc@308 92 // WS_QUERY_BY_KEY (CLIENT SIDE)
mas01mc@328 93 void audioDB::ws_query_by_key(const char*dbName, const char *trackKey, const char* featureFileName, const char* hostport){
mas01mc@307 94 struct soap soap;
mas01mc@307 95 adb__queryResponse adbQueryResponse;
mas01mc@314 96 /* JUST TRY TO USE A DATA STRUCTURE WITH PHP
mas01mc@314 97 adb__sequenceQueryParms asqp;
mas01mc@314 98 asqp.keyList = (char*)trackFileName;
mas01mc@314 99 asqp.timesFileName = (char*)timesFileName;
mas01mc@314 100 asqp.queryPoint = queryPoint;
mas01mc@314 101 asqp.pointNN = pointNN;
mas01mc@314 102 asqp.trackNN = trackNN;
mas01mc@314 103 asqp.sequenceLength = sequenceLength;
mas01mc@314 104 asqp.radius = radius;
mas01mc@314 105 asqp.relative_threshold = relative_threshold;
mas01mc@314 106 asqp.absolute_threshold = absolute_threshold;
mas01mc@314 107 asqp.usingQueryPoint = usingQueryPoint;
mas01mc@314 108 asqp.lsh_exact = lsh_exact;
mas01mc@314 109 */
mas01mc@331 110 VERB_LOG(1, "Calling %s query on database %s with %s=%s\n", (trackKey&&strlen(trackKey))?"KEY":"FILENAME", dbName, (trackKey&&strlen(trackKey))?"KEY":"FILENAME",(trackKey&&strlen(trackKey))?trackKey:featureFileName);
mas01mc@307 111 soap_init(&soap);
mas01mc@307 112 if(queryType==O2_SEQUENCE_QUERY || queryType==O2_N_SEQUENCE_QUERY){
mas01mc@314 113 if(soap_call_adb__sequenceQueryByKey(&soap,hostport,NULL,
mas01mc@328 114 (char*)dbName,
mas01mc@328 115 (char*)trackKey,
mas01mc@328 116 (char*)featureFileName,
mas01mc@328 117 queryType,
mas01mc@328 118 (char*)trackFileName, // this means keyFileName
mas01mc@328 119 (char*)timesFileName,
mas01mc@314 120 queryPoint,
mas01mc@328 121 pointNN,
mas01mc@328 122 trackNN,
mas01mc@328 123 sequenceLength,
mas01mc@328 124 radius,
mas01mc@328 125 absolute_threshold,
mas01mc@328 126 usingQueryPoint,
mas01mc@471 127 lsh_exact,
mas01mc@471 128 no_unit_norming,
mas01mc@314 129 adbQueryResponse)==SOAP_OK){
mas01mc@307 130 //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
mas01mc@307 131 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
mas01mc@307 132 std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i]
mas01mc@307 133 << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
mas01cr@550 134 } else {
mas01cr@550 135 char fault[MAXSTR];
mas01cr@550 136 soap_sprint_fault(&soap, fault, MAXSTR);
mas01cr@550 137 error(fault);
mas01mc@307 138 }
mas01cr@550 139 } else
mas01mc@307 140 ;// FIX ME: WRITE NON-SEQUENCE QUERY BY KEY ?
mas01mc@307 141
mas01mc@307 142 soap_destroy(&soap);
mas01mc@307 143 soap_end(&soap);
mas01mc@307 144 soap_done(&soap);
mas01mc@307 145 }
mas01mc@307 146
mas01cr@239 147
mas01cr@333 148 /* handy macros */
mas01cr@333 149 #define INTSTRINGIFY(val, str) \
mas01cr@333 150 char str[256]; \
mas01cr@333 151 snprintf(str, 256, "%d", val);
mas01cr@333 152 #define DOUBLESTRINGIFY(val, str) \
mas01cr@333 153 char str[256]; \
mas01cr@333 154 snprintf(str, 256, "%f", val);
mas01cr@333 155
mas01cr@239 156 /* Server definitions */
mas01cr@239 157 int adb__status(struct soap* soap, xsd__string dbName, adb__statusResponse &adbStatusResponse){
mas01cr@370 158 const char *argv[]={"./audioDB",COM_STATUS,"-d",dbName};
mas01cr@239 159 const unsigned argc = 4;
mas01cr@239 160 try {
mas01cr@239 161 audioDB(argc, argv, &adbStatusResponse);
mas01cr@239 162 return SOAP_OK;
mas01cr@239 163 } catch(char *err) {
mas01cr@239 164 soap_receiver_fault(soap, err, "");
mas01cr@239 165 return SOAP_FAULT;
mas01cr@239 166 }
mas01cr@239 167 }
mas01mc@334 168
mas01mc@334 169 int adb__liszt(struct soap* soap, xsd__string dbName, xsd__int lisztOffset, xsd__int lisztLength,
mas01mc@334 170 adb__lisztResponse& adbLisztResponse){
mas01mc@334 171
mas01mc@334 172 INTSTRINGIFY(lisztOffset, lisztOffsetStr);
mas01mc@334 173 INTSTRINGIFY(lisztLength, lisztLengthStr);
mas01mc@334 174
mas01cr@370 175 const char *argv[] = {"./audioDB", COM_LISZT, "-d",dbName, "--lisztOffset", lisztOffsetStr, "--lisztLength", lisztLengthStr};
mas01mc@334 176 const unsigned argc = 8;
mas01mc@334 177 try{
mas01cr@548 178 audioDB(argc, argv, soap, &adbLisztResponse);
mas01mc@334 179 return SOAP_OK;
mas01mc@334 180 } catch(char *err) {
mas01mc@334 181 soap_receiver_fault(soap, err, "");
mas01mc@334 182 return SOAP_FAULT;
mas01mc@334 183 }
mas01mc@334 184 }
mas01mc@334 185
mas01cr@239 186 // Literal translation of command line to web service
mas01cr@333 187 int adb__query(struct soap* soap, xsd__string dbName,
mas01cr@333 188 xsd__string qKey, xsd__string keyList,
mas01cr@333 189 xsd__string timesFileName, xsd__string powerFileName,
mas01cr@333 190 xsd__int qType,
mas01cr@333 191 xsd__int qPos, xsd__int pointNN, xsd__int trackNN,
mas01cr@333 192 xsd__int seqLen,
mas01cr@333 193 xsd__double radius,
mas01cr@333 194 xsd__double absolute_threshold, xsd__double relative_threshold,
mas01mc@471 195 xsd__int exhaustive, xsd__int lsh_exact, xsd__int no_unit_norming,
mas01cr@333 196 adb__queryResponse &adbQueryResponse){
mas01cr@239 197 char queryType[256];
mas01mc@329 198
mas01mc@329 199 fprintf(stderr,"Calling fileName query on database %s with featureFile=%s\n", dbName, qKey);
mas01mc@329 200
mas01cr@239 201 for(int k=0; k<256; k++)
mas01cr@239 202 queryType[k]='\0';
mas01cr@239 203 if(qType == O2_POINT_QUERY)
mas01cr@239 204 strncpy(queryType, "point", strlen("point"));
mas01cr@239 205 else if (qType == O2_SEQUENCE_QUERY)
mas01cr@239 206 strncpy(queryType, "sequence", strlen("sequence"));
mas01cr@239 207 else if(qType == O2_TRACK_QUERY)
mas01cr@239 208 strncpy(queryType,"track", strlen("track"));
mas01mc@324 209 else if(qType == O2_N_SEQUENCE_QUERY)
mas01mc@324 210 strncpy(queryType,"nsequence", strlen("nsequence"));
mas01cr@239 211
mas01cr@239 212 if(pointNN==0)
mas01cr@239 213 pointNN=10;
mas01cr@239 214 if(trackNN==0)
mas01cr@239 215 trackNN=10;
mas01cr@239 216 if(seqLen==0)
mas01cr@239 217 seqLen=16;
mas01cr@239 218
mas01cr@333 219 INTSTRINGIFY(qPos, qPosStr);
mas01cr@333 220 INTSTRINGIFY(pointNN, pointNNStr);
mas01cr@333 221 INTSTRINGIFY(trackNN, trackNNStr);
mas01cr@333 222 INTSTRINGIFY(seqLen, seqLenStr);
mas01cr@239 223
mas01cr@333 224 /* We don't necessarily use these, but because of scope we do this
mas01cr@333 225 anyway. We waste 756 bytes of stack this way. */
mas01cr@333 226 DOUBLESTRINGIFY(radius, radiusStr);
mas01cr@333 227 DOUBLESTRINGIFY(absolute_threshold, absolute_thresholdStr);
mas01cr@333 228 DOUBLESTRINGIFY(relative_threshold, relative_thresholdStr);
mas01cr@333 229
mas01cr@333 230 unsigned int argc = 19;
mas01cr@333 231 if (powerFileName) {
mas01cr@333 232 argc += 2;
mas01cr@333 233 }
mas01cr@333 234 if (radius != 0) {
mas01cr@333 235 argc += 2;
mas01cr@333 236 }
mas01cr@333 237 /* we can't use use_absolute_threshold and friends because we're not
mas01cr@333 238 in the audioDB class here. */
mas01cr@333 239 if (absolute_threshold != 0) {
mas01cr@333 240 argc += 2;
mas01cr@333 241 }
mas01cr@333 242 if (relative_threshold != 0) {
mas01cr@333 243 argc += 2;
mas01cr@333 244 }
mas01cr@333 245 if (exhaustive) {
mas01cr@333 246 argc++;
mas01cr@333 247 }
mas01cr@333 248 if (lsh_exact) {
mas01cr@333 249 argc++;
mas01cr@333 250 }
mas01cr@333 251
mas01mc@471 252 if(no_unit_norming){
mas01mc@471 253 argc++;
mas01mc@471 254 }
mas01mc@471 255
mas01cr@345 256 const char **argv = new const char*[argc+1];
mas01cr@333 257 argv[0] = "./audioDB";
mas01cr@333 258 argv[1] = COM_QUERY;
mas01cr@333 259 argv[2] = queryType;
mas01cr@333 260 argv[3] = COM_DATABASE;
mas01cr@333 261 argv[4] = (char *) (ENSURE_STRING(dbName));
mas01cr@333 262 argv[5] = COM_FEATURES;
mas01cr@333 263 argv[6] = (char *) (ENSURE_STRING(qKey));
mas01cr@333 264 argv[7] = COM_KEYLIST;
mas01cr@333 265 argv[8] = (char *) (ENSURE_STRING(keyList));
mas01cr@333 266 argv[9] = COM_TIMES;
mas01cr@333 267 argv[10] = (char *) (ENSURE_STRING(timesFileName));
mas01cr@333 268 argv[11] = COM_QPOINT;
mas01cr@333 269 argv[12] = qPosStr;
mas01cr@333 270 argv[13] = COM_POINTNN;
mas01cr@333 271 argv[14] = pointNNStr;
mas01cr@333 272 argv[15] = COM_TRACKNN;
mas01cr@333 273 argv[16] = trackNNStr;
mas01cr@333 274 argv[17] = COM_SEQLEN;
mas01cr@333 275 argv[18] = seqLenStr;
mas01cr@333 276 int argv_counter = 19;
mas01cr@333 277 if (powerFileName) {
mas01cr@333 278 argv[argv_counter++] = COM_QUERYPOWER;
mas01cr@333 279 argv[argv_counter++] = powerFileName;
mas01cr@333 280 }
mas01cr@333 281 if (radius != 0) {
mas01cr@333 282 argv[argv_counter++] = COM_RADIUS;
mas01cr@333 283 argv[argv_counter++] = radiusStr;
mas01cr@333 284 }
mas01cr@333 285 if (absolute_threshold != 0) {
mas01cr@333 286 argv[argv_counter++] = COM_ABSOLUTE_THRESH;
mas01cr@333 287 argv[argv_counter++] = absolute_thresholdStr;
mas01cr@333 288 }
mas01cr@333 289 if (relative_threshold != 0) {
mas01cr@333 290 argv[argv_counter++] = COM_RELATIVE_THRESH;
mas01cr@333 291 argv[argv_counter++] = relative_thresholdStr;
mas01cr@333 292 }
mas01cr@333 293 if (exhaustive) {
mas01cr@333 294 argv[argv_counter++] = COM_EXHAUSTIVE;
mas01cr@333 295 }
mas01cr@333 296 if (lsh_exact) {
mas01cr@333 297 argv[argv_counter++] = COM_LSH_EXACT;
mas01cr@333 298 }
mas01mc@471 299
mas01mc@471 300 if (no_unit_norming) {
mas01mc@471 301 argv[argv_counter++] = COM_NO_UNIT_NORMING;
mas01mc@471 302 }
mas01mc@471 303
mas01cr@333 304 argv[argv_counter] = NULL;
mas01cr@333 305
mas01cr@239 306 try {
mas01cr@508 307 audioDB(argc, argv, soap, &adbQueryResponse);
mas01cr@333 308 delete [] argv;
mas01cr@239 309 return SOAP_OK;
mas01cr@239 310 } catch (char *err) {
mas01cr@239 311 soap_receiver_fault(soap, err, "");
mas01cr@333 312 delete [] argv;
mas01cr@239 313 return SOAP_FAULT;
mas01cr@239 314 }
mas01cr@239 315 }
mas01cr@239 316
mas01mc@314 317 int adb__sequenceQueryByKey(struct soap* soap,xsd__string dbName,
mas01mc@314 318 xsd__string trackKey,
mas01mc@328 319 xsd__string featureFileName,
mas01mc@314 320 xsd__int queryType,
mas01mc@328 321 xsd__string keyFileName,
mas01mc@314 322 xsd__string timesFileName,
mas01mc@314 323 xsd__int queryPoint,
mas01mc@314 324 xsd__int pointNN,
mas01mc@314 325 xsd__int trackNN,
mas01mc@314 326 xsd__int sequenceLength,
mas01mc@314 327 xsd__double radius,
mas01mc@314 328 xsd__double absolute_threshold,
mas01mc@314 329 xsd__int usingQueryPoint,
mas01mc@471 330 xsd__int lsh_exact, xsd__int no_unit_norming,
mas01mc@314 331 struct adb__queryResponse& adbQueryResponse){
mas01mc@307 332 char qtypeStr[256];
mas01cr@239 333
mas01mc@471 334 fprintf(stderr, "Calling %s query on database %s with %s=%s, distFun:%s\n", (trackKey&&strlen(trackKey))?"KEY":"FILENAME", dbName, (trackKey&&strlen(trackKey))?"KEY":"FILENAME",(trackKey&&strlen(trackKey))?trackKey:featureFileName, no_unit_norming?"Euclidean":"Normed Euclidean");
mas01mc@329 335
mas01mc@314 336 INTSTRINGIFY(queryPoint, qPosStr);
mas01mc@314 337 INTSTRINGIFY(pointNN, pointNNStr);
mas01mc@314 338 INTSTRINGIFY(trackNN, trackNNStr);
mas01mc@314 339 INTSTRINGIFY(sequenceLength, seqLenStr);
mas01mc@314 340 DOUBLESTRINGIFY(absolute_threshold, absolute_thresholdStr);
mas01mc@314 341 DOUBLESTRINGIFY(radius, radiusStr);
mas01mc@307 342
mas01mc@307 343 snprintf(qtypeStr, 256, "nsequence");
mas01mc@310 344 const char *argv[]={
mas01cr@239 345 "./audioDB",
mas01cr@239 346 COM_QUERY,
mas01mc@307 347 qtypeStr,
mas01cr@239 348 COM_DATABASE,
mas01cr@239 349 dbName,
mas01mc@330 350 (trackKey&&strlen(trackKey))?COM_QUERYKEY:COM_FEATURES,
mas01mc@330 351 (trackKey&&strlen(trackKey))?ENSURE_STRING(trackKey):ENSURE_STRING(featureFileName),
mas01cr@239 352 COM_KEYLIST,
mas01mc@328 353 ENSURE_STRING(keyFileName),
mas01mc@314 354 usingQueryPoint?COM_QPOINT:COM_EXHAUSTIVE,
mas01mc@314 355 usingQueryPoint?qPosStr:"",
mas01cr@239 356 COM_POINTNN,
mas01cr@239 357 pointNNStr,
mas01cr@239 358 COM_TRACKNN,
mas01cr@239 359 trackNNStr,
mas01mc@307 360 COM_RADIUS,
mas01mc@307 361 radiusStr,
mas01cr@239 362 COM_SEQLEN,
mas01cr@239 363 seqLenStr,
mas01cr@239 364 COM_ABSOLUTE_THRESH,
mas01mc@310 365 absolute_thresholdStr,
mas01mc@471 366 lsh_exact?COM_LSH_EXACT:"",
mas01mc@471 367 no_unit_norming?COM_NO_UNIT_NORMING:"",
mas01cr@239 368 };
mas01cr@239 369
mas01mc@471 370 const unsigned argc = 23;
mas01mc@310 371
mas01mc@310 372
mas01cr@239 373 try {
mas01cr@508 374 audioDB(argc, argv, soap, &adbQueryResponse);
mas01cr@239 375 return SOAP_OK;
mas01cr@239 376 } catch (char *err) {
mas01cr@239 377 soap_receiver_fault(soap, err, "");
mas01cr@239 378 return SOAP_FAULT;
mas01cr@239 379 }
mas01cr@239 380 }
mas01mc@354 381
mas01mc@354 382 // Query an audioDB database by vector (serialized)
mas01mc@471 383 int adb__shingleQuery(struct soap* soap, xsd__string dbName, struct adb__queryVector qVector, xsd__string keyList, xsd__string timesFileName, xsd__int queryType, xsd__int queryPos, xsd__int pointNN, xsd__int trackNN, xsd__int sequenceLength, xsd__double radius, xsd__double absolute_threshold, xsd__double relative_threshold, xsd__int exhaustive, xsd__int lsh_exact, xsd__int no_unit_norming, struct adb__queryResponse &adbQueryResponse){
mas01mc@354 384
mas01mc@354 385 // open a tmp file on the server, write shingle, query as a file with query point 0
mas01mc@354 386 // and shingle length l/dim
mas01mc@354 387 char tmpFileName[] = "/tmp/adb_XXXXXX";
mas01mc@354 388 int tmpFid = mkstemp(tmpFileName);
mas01mc@354 389 if(tmpFid==-1){
mas01mc@354 390 cerr << "Cannot make tmpfile <" << tmpFileName << "> on server" << endl;
mas01mc@354 391 return SOAP_FAULT;
mas01mc@354 392 }
mas01mc@354 393
mas01mc@354 394 FILE* tmpFile = fdopen(tmpFid, "r+b");
mas01mc@354 395 if(!tmpFile){
mas01mc@354 396 cerr << "error opening <" << tmpFileName << "> for write" << endl;
mas01mc@354 397 return SOAP_FAULT;
mas01mc@354 398 }
mas01mc@354 399
mas01mc@354 400 if(fwrite(&qVector.dim, sizeof(int), 1, tmpFile)!=1){
mas01mc@354 401 cerr << "error writing tmp file dim <"<< tmpFileName << ">" << endl;
mas01mc@354 402 return SOAP_FAULT;
mas01mc@354 403 }
mas01mc@354 404
mas01mc@354 405 if(fwrite(qVector.v, sizeof(double), qVector.__sizev, tmpFile)!=(size_t)qVector.__sizev){
mas01mc@354 406 cerr << "error writing tmp file doubles <" << tmpFileName << ">" << endl;
mas01mc@354 407 return SOAP_FAULT;
mas01mc@354 408 }
mas01mc@354 409
mas01mc@354 410 // Close the file so that a new FD can be opened
mas01mc@354 411 fclose(tmpFile);
mas01mc@354 412
mas01mc@354 413 char tmpFileName2[] = "/tmp/adbP_XXXXXX";
mas01mc@354 414 int tmpFid2 = 0;
mas01mc@354 415 FILE* tmpFile2 = NULL;
mas01mc@354 416
mas01mc@354 417 // Check if powers have been passed and write accordingly
mas01mc@354 418 if(qVector.__sizep){
mas01mc@354 419 tmpFid2 = mkstemp(tmpFileName2);
mas01mc@354 420 tmpFile2 = fdopen(tmpFid2, "r+b");
mas01mc@354 421 if(!tmpFile2){
mas01mc@354 422 cerr << "error opening power file <" << tmpFileName2 << "> for write" << endl;
mas01mc@354 423 return SOAP_FAULT;
mas01mc@354 424 }
mas01mc@354 425 int pSize=1;
mas01mc@354 426 if(fwrite(&pSize, sizeof(int), 1, tmpFile2)!=1){
mas01mc@354 427 cerr << "error writing tmp power file dim <"<< tmpFileName2 << ">" << endl;
mas01mc@354 428 return SOAP_FAULT;
mas01mc@354 429 }
mas01mc@354 430
mas01mc@354 431 if(fwrite(qVector.p, sizeof(double), qVector.__sizep, tmpFile2)!=(size_t)qVector.__sizep){
mas01mc@354 432 cerr << "error writing tmp power file doubles <" << tmpFileName2 << ">" << endl;
mas01mc@354 433 return SOAP_FAULT;
mas01mc@354 434 }
mas01mc@354 435 fclose(tmpFile2);
mas01mc@354 436 }
mas01mc@354 437
mas01mc@354 438 // fix up sequenceLength if it isn't provided, we know what the caller wants by the size of the shingle
mas01mc@354 439 // and the feature dimensionality
mas01mc@354 440 if(!sequenceLength)
mas01mc@354 441 sequenceLength = qVector.__sizev/qVector.dim;
mas01mc@354 442
mas01mc@354 443 int retVal = adb__query(soap, dbName, tmpFileName, keyList, timesFileName, qVector.__sizep?tmpFileName2:0,
mas01mc@354 444 queryType, queryPos, pointNN, trackNN, sequenceLength, radius,
mas01mc@471 445 absolute_threshold, relative_threshold, exhaustive, lsh_exact, no_unit_norming, adbQueryResponse);
mas01mc@354 446
mas01mc@354 447 return retVal;
mas01mc@354 448 }
mas01mc@354 449
mas01cr@239 450 /* Server loop */
mas01cr@239 451 void audioDB::startServer(){
mas01cr@239 452 struct soap soap;
mas01cr@239 453 int m, s; // master and slave sockets
mas01cr@239 454 soap_init(&soap);
mas01cr@239 455 // FIXME: largely this use of SO_REUSEADDR is to make writing (and
mas01cr@239 456 // running) test cases more convenient, so that multiple test runs
mas01cr@239 457 // in close succession don't fail because of a bin() error.
mas01cr@239 458 // Investigate whether there are any potential drawbacks in this,
mas01cr@239 459 // and also whether there's a better way to write the tests. --
mas01cr@239 460 // CSR, 2007-10-03
mas01cr@239 461 soap.bind_flags |= SO_REUSEADDR;
mas01cr@239 462 m = soap_bind(&soap, NULL, port, 100);
mas01cr@239 463 if (m < 0)
mas01cr@239 464 soap_print_fault(&soap, stderr);
mas01cr@239 465 else
mas01cr@239 466 {
mas01cr@239 467 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
mas01cr@498 468 /* FIXME: we used to have a global cache of a single LSH index
mas01cr@498 469 * here. CSR removed it because it interacted badly with
mas01cr@498 470 * APIification of querying, replacing it with a per-open-adb
mas01cr@498 471 * cache; we should try to take advantage of that instead.
mas01cr@498 472 */
mas01cr@498 473
mas01mc@324 474 // Server-side path prefix to databases and features
mas01mc@324 475 if(adb_root)
mas01mc@324 476 SERVER_ADB_ROOT = (char*)adb_root; // Server-side database root
mas01mc@324 477 if(adb_feature_root)
mas01mc@324 478 SERVER_ADB_FEATURE_ROOT = (char*)adb_feature_root; // Server-side features root
mas01mc@338 479
mas01mc@338 480 isServer = 1; // From this point, errors are reported via SOAP to the client
mas01cr@239 481 for (int i = 1; ; i++)
mas01cr@239 482 {
mas01cr@239 483 s = soap_accept(&soap);
mas01cr@239 484 if (s < 0)
mas01cr@239 485 {
mas01cr@239 486 soap_print_fault(&soap, stderr);
mas01cr@239 487 break;
mas01cr@239 488 }
mas01cr@239 489 /* FIXME: find a way to play nice with logging when run from
mas01cr@239 490 /etc/init.d scripts: at present this just goes nowhere */
mas01cr@239 491 fprintf(stderr, "%d: accepted connection from IP=%lu.%lu.%lu.%lu socket=%d\n", i,
mas01cr@239 492 (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s);
mas01cr@239 493 if (soap_serve(&soap) != SOAP_OK) // process RPC request
mas01cr@239 494 soap_print_fault(&soap, stderr); // print error
mas01cr@239 495 fprintf(stderr, "request served\n");
mas01cr@239 496 soap_destroy(&soap); // clean up class instances
mas01cr@239 497 soap_end(&soap); // clean up everything and close socket
mas01cr@239 498 }
mas01cr@239 499 }
mas01cr@239 500 soap_done(&soap); // close master socket and detach environment
mas01cr@239 501 }