Overview
Comment: | Updated to create separate interpreters per thread |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | cf4ca88d48cdde7696d9b534228ac2b4efeb55da |
User & Date: | rkeene on 2014-09-09 07:33:57 |
Other Links: | manifest | tags |
Context
2014-09-09
| ||
07:51 | Fixed bug where blank extraData was added check-in: 95ec92e5d0 user: rkeene tags: trunk | |
07:33 | Updated to create separate interpreters per thread check-in: cf4ca88d48 user: rkeene tags: trunk | |
06:46 | Implemented basic open() and read() check-in: a7c7a7a363 user: rkeene tags: trunk | |
Changes
Modified appfs.c from [4ed6fa78a6] to [9a50e0345b].
1 1 #define FUSE_USE_VERSION 26 2 2 3 3 #include <sys/types.h> 4 4 #include <sqlite3.h> 5 +#include <pthread.h> 5 6 #include <string.h> 6 7 #include <stdarg.h> 7 8 #include <stdlib.h> 8 9 #include <unistd.h> 9 10 #include <errno.h> 10 11 #include <fcntl.h> 11 12 #include <stdio.h> ................................................................................ 12 13 #include <fuse.h> 13 14 #include <tcl.h> 14 15 15 16 #define APPFS_CACHEDIR "/tmp/appfs-cache" 16 17 17 18 #define APPFS_DEBUG(x...) { fprintf(stderr, "[debug] %s:%i:%s: ", __FILE__, __LINE__, __func__); fprintf(stderr, x); fprintf(stderr, "\n"); } 18 19 20 +static pthread_key_t interpKey; 21 + 19 22 struct appfs_thread_data { 20 - Tcl_Interp *interp; 21 23 sqlite3 *db; 24 + const char *cachedir; 22 25 }; 23 26 24 27 struct appfs_thread_data globalThread; 25 28 26 29 typedef enum { 27 30 APPFS_OS_UNKNOWN, 28 31 APPFS_OS_ALL, ................................................................................ 163 166 return("arm"); 164 167 case APPFS_CPU_UNKNOWN: 165 168 return("unknown"); 166 169 } 167 170 168 171 return("unknown"); 169 172 } 173 + 174 +static Tcl_Interp *appfs_create_TclInterp(const char *cachedir) { 175 + Tcl_Interp *interp; 176 + int tcl_ret; 177 + 178 + interp = Tcl_CreateInterp(); 179 + if (interp == NULL) { 180 + fprintf(stderr, "Unable to create Tcl Interpreter. Aborting.\n"); 181 + 182 + return(NULL); 183 + } 184 + 185 + tcl_ret = Tcl_Init(interp); 186 + if (tcl_ret != TCL_OK) { 187 + fprintf(stderr, "Unable to initialize Tcl. Aborting.\n"); 188 + 189 + return(NULL); 190 + } 191 + 192 + tcl_ret = Tcl_Eval(interp, "" 193 +#include "appfs.tcl.h" 194 + ""); 195 + if (tcl_ret != TCL_OK) { 196 + fprintf(stderr, "Unable to initialize Tcl AppFS script. Aborting.\n"); 197 + fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp)); 198 + 199 + return(NULL); 200 + } 201 + 202 + if (Tcl_SetVar(interp, "::appfs::cachedir", cachedir, TCL_GLOBAL_ONLY) == NULL) { 203 + fprintf(stderr, "Unable to set cache directory. This should never fail.\n"); 204 + 205 + return(NULL); 206 + } 207 + 208 + tcl_ret = Tcl_Eval(interp, "::appfs::init"); 209 + if (tcl_ret != TCL_OK) { 210 + fprintf(stderr, "Unable to initialize Tcl AppFS script (::appfs::init). Aborting.\n"); 211 + fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp)); 212 + 213 + return(NULL); 214 + } 215 + 216 + return(interp); 217 +} 170 218 171 219 static int appfs_Tcl_Eval(Tcl_Interp *interp, int objc, const char *cmd, ...) { 172 220 Tcl_Obj **objv; 173 221 const char *arg; 174 222 va_list argp; 175 223 int retval; 176 224 int i; ................................................................................ 190 238 retval = Tcl_EvalObjv(interp, objc, objv, 0); 191 239 192 240 for (i = 0; i < objc; i++) { 193 241 Tcl_DecrRefCount(objv[i]); 194 242 } 195 243 196 244 ckfree((void *) objv); 245 + 246 + if (retval != TCL_OK) { 247 + APPFS_DEBUG("Tcl command failed, ::errorInfo contains: %s\n", Tcl_GetVar(interp, "::errorInfo", 0)); 248 + } 197 249 198 250 return(retval); 199 251 } 200 252 201 -static int appfs_update_index(const char *hostname) { 253 +static void appfs_update_index(const char *hostname) { 254 + Tcl_Interp *interp; 202 255 int tcl_ret; 203 256 204 - tcl_ret = appfs_Tcl_Eval(globalThread.interp, 2, "::appfs::getindex", hostname); 257 + APPFS_DEBUG("Enter: hostname = %s", hostname); 258 + 259 + interp = pthread_getspecific(interpKey); 260 + if (interp == NULL) { 261 + interp = appfs_create_TclInterp(globalThread.cachedir); 262 + 263 + pthread_setspecific(interpKey, interp); 264 + } 265 + 266 + tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getindex", hostname); 205 267 if (tcl_ret != TCL_OK) { 206 - APPFS_DEBUG("Call to ::appfs::getindex failed: %s", Tcl_GetStringResult(globalThread.interp)); 268 + APPFS_DEBUG("Call to ::appfs::getindex failed: %s", Tcl_GetStringResult(interp)); 207 269 208 - return(-1); 270 + return; 209 271 } 210 272 211 - return(0); 273 + return; 212 274 } 213 275 214 276 static const char *appfs_getfile(const char *hostname, const char *sha1) { 277 + Tcl_Interp *interp; 215 278 char *retval; 216 279 int tcl_ret; 217 280 218 - tcl_ret = appfs_Tcl_Eval(globalThread.interp, 3, "::appfs::download", hostname, sha1); 281 + interp = pthread_getspecific(interpKey); 282 + if (interp == NULL) { 283 + interp = appfs_create_TclInterp(globalThread.cachedir); 284 + 285 + pthread_setspecific(interpKey, interp); 286 + } 287 + 288 + tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::download", hostname, sha1); 219 289 if (tcl_ret != TCL_OK) { 220 - APPFS_DEBUG("Call to ::appfs::download failed: %s", Tcl_GetStringResult(globalThread.interp)); 290 + APPFS_DEBUG("Call to ::appfs::download failed: %s", Tcl_GetStringResult(interp)); 221 291 222 292 return(NULL); 223 293 } 224 294 225 - retval = strdup(Tcl_GetStringResult(globalThread.interp)); 295 + retval = strdup(Tcl_GetStringResult(interp)); 226 296 227 297 return(retval); 228 298 } 229 299 230 -static int appfs_update_manifest(const char *hostname, const char *sha1) { 300 +static void appfs_update_manifest(const char *hostname, const char *sha1) { 301 + Tcl_Interp *interp; 231 302 int tcl_ret; 232 303 233 - tcl_ret = appfs_Tcl_Eval(globalThread.interp, 3, "::appfs::getpkgmanifest", hostname, sha1); 304 + interp = pthread_getspecific(interpKey); 305 + if (interp == NULL) { 306 + interp = appfs_create_TclInterp(globalThread.cachedir); 307 + 308 + pthread_setspecific(interpKey, interp); 309 + } 310 + 311 + tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::getpkgmanifest", hostname, sha1); 234 312 if (tcl_ret != TCL_OK) { 235 - APPFS_DEBUG("Call to ::appfs::getpkgmanifest failed: %s", Tcl_GetStringResult(globalThread.interp)); 313 + APPFS_DEBUG("Call to ::appfs::getpkgmanifest failed: %s", Tcl_GetStringResult(interp)); 236 314 237 - return(-1); 315 + return; 238 316 } 239 317 240 - return(0); 318 + return; 241 319 } 242 320 243 321 244 322 #define appfs_free_list_type(id, type) static void appfs_free_list_ ## id(type *head) { \ 245 323 type *obj, *next; \ 246 324 for (obj = head; obj; obj = next) { \ 247 325 next = obj->_next; \ ................................................................................ 324 402 325 403 return(0); 326 404 } 327 405 328 406 static struct appfs_package *appfs_getindex(const char *hostname, int *package_count_p) { 329 407 struct appfs_package *head = NULL; 330 408 char *sql; 331 - int index_ret, sqlite_ret; 409 + int sqlite_ret; 332 410 333 411 if (package_count_p == NULL) { 334 412 return(NULL); 335 413 } 336 414 337 - index_ret = appfs_update_index(hostname); 338 - if (index_ret != 0) { 339 - return(NULL); 340 - } 415 + appfs_update_index(hostname); 341 416 342 417 sql = sqlite3_mprintf("SELECT package, version, sha1, os, cpuArch, isLatest FROM packages WHERE hostname = %Q;", hostname); 343 418 if (sql == NULL) { 344 419 APPFS_DEBUG("Call to sqlite3_mprintf failed."); 345 420 346 421 return(NULL); 347 422 } ................................................................................ 383 458 return(0); 384 459 385 460 } 386 461 387 462 static struct appfs_children *appfs_getchildren(const char *hostname, const char *package_hash, const char *path, int *children_count_p) { 388 463 struct appfs_children *head = NULL; 389 464 char *sql; 390 - int index_ret, sqlite_ret, manifest_ret; 465 + int sqlite_ret; 391 466 392 467 if (children_count_p == NULL) { 393 468 return(NULL); 394 469 } 395 470 396 - index_ret = appfs_update_index(hostname); 397 - if (index_ret != 0) { 398 - return(NULL); 399 - } 400 - 401 - manifest_ret = appfs_update_manifest(hostname, package_hash); 402 - if (manifest_ret != 0) { 403 - return(NULL); 404 - } 471 + appfs_update_index(hostname); 472 + appfs_update_manifest(hostname, package_hash); 405 473 406 474 sql = sqlite3_mprintf("SELECT file_name FROM files WHERE package_sha1 = %Q AND file_directory = %Q;", package_hash, path); 407 475 if (sql == NULL) { 408 476 APPFS_DEBUG("Call to sqlite3_mprintf failed."); 409 477 410 478 return(NULL); 411 479 } ................................................................................ 434 502 435 503 return(0); 436 504 } 437 505 438 506 static char *appfs_lookup_package_hash(const char *hostname, const char *package, appfs_os_t os, appfs_cpuArch_t cpuArch, const char *version) { 439 507 char *sql; 440 508 char *retval = NULL; 441 - int index_ret, sqlite_ret; 509 + int sqlite_ret; 442 510 443 - index_ret = appfs_update_index(hostname); 444 - if (index_ret != 0) { 445 - return(NULL); 446 - } 511 + appfs_update_index(hostname); 447 512 448 513 sql = sqlite3_mprintf("SELECT sha1 FROM packages WHERE hostname = %Q AND package = %Q AND os = %Q AND cpuArch = %Q AND version = %Q;", 449 514 hostname, 450 515 package, 451 516 appfs_convert_os_toString(os), 452 517 appfs_convert_cpuArch_toString(cpuArch), 453 518 version ................................................................................ 523 588 /* Until this is used, prevent the compiler from complaining */ 524 589 source = source; 525 590 } 526 591 527 592 static int appfs_getfileinfo(const char *hostname, const char *package_hash, const char *_path, struct appfs_pathinfo *pathinfo) { 528 593 char *directory, *file, *path; 529 594 char *sql; 530 - int index_ret, sqlite_ret, manifest_ret; 595 + int sqlite_ret; 531 596 532 597 if (pathinfo == NULL) { 533 598 return(-EIO); 534 599 } 535 600 536 - index_ret = appfs_update_index(hostname); 537 - if (index_ret != 0) { 538 - return(-EIO); 539 - } 540 - 541 - manifest_ret = appfs_update_manifest(hostname, package_hash); 542 - if (manifest_ret != 0) { 543 - return(-EIO); 544 - } 601 + appfs_update_index(hostname); 602 + appfs_update_manifest(hostname, package_hash); 545 603 546 604 path = strdup(_path); 547 605 directory = path; 548 606 file = strrchr(path, '/'); 549 607 if (file == NULL) { 550 608 file = path; 551 609 directory = ""; ................................................................................ 1006 1064 .read = appfs_fuse_read 1007 1065 }; 1008 1066 #endif 1009 1067 1010 1068 int main(int argc, char **argv) { 1011 1069 const char *cachedir = APPFS_CACHEDIR; 1012 1070 char dbfilename[1024]; 1013 - int tcl_ret, snprintf_ret, sqlite_ret; 1071 + int pthread_ret, snprintf_ret, sqlite_ret; 1014 1072 1015 - globalThread.interp = Tcl_CreateInterp(); 1016 - if (globalThread.interp == NULL) { 1017 - fprintf(stderr, "Unable to create Tcl Interpreter. Aborting.\n"); 1073 + globalThread.cachedir = cachedir; 1018 1074 1019 - return(1); 1020 - } 1021 - 1022 - tcl_ret = Tcl_Init(globalThread.interp); 1023 - if (tcl_ret != TCL_OK) { 1024 - fprintf(stderr, "Unable to initialize Tcl. Aborting.\n"); 1025 - 1026 - return(1); 1027 - } 1028 - 1029 - tcl_ret = Tcl_Eval(globalThread.interp, "" 1030 -#include "appfs.tcl.h" 1031 - ""); 1032 - if (tcl_ret != TCL_OK) { 1033 - fprintf(stderr, "Unable to initialize Tcl AppFS script. Aborting.\n"); 1034 - fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(globalThread.interp)); 1035 - 1036 - return(1); 1037 - } 1038 - 1039 - if (Tcl_SetVar(globalThread.interp, "::appfs::cachedir", cachedir, TCL_GLOBAL_ONLY) == NULL) { 1040 - fprintf(stderr, "Unable to set cache directory. This should never fail.\n"); 1041 - 1042 - return(1); 1043 - } 1044 - 1045 - tcl_ret = appfs_Tcl_Eval(globalThread.interp, 1, "::appfs::init"); 1046 - if (tcl_ret != TCL_OK) { 1047 - fprintf(stderr, "Unable to initialize Tcl AppFS script (::appfs::init). Aborting.\n"); 1048 - fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(globalThread.interp)); 1075 + pthread_ret = pthread_key_create(&interpKey, NULL); 1076 + if (pthread_ret != 0) { 1077 + fprintf(stderr, "Unable to create TSD key for Tcl. Aborting.\n"); 1049 1078 1050 1079 return(1); 1051 1080 } 1052 1081 1053 1082 snprintf_ret = snprintf(dbfilename, sizeof(dbfilename), "%s/%s", cachedir, "cache.db"); 1054 1083 if (snprintf_ret >= sizeof(dbfilename)) { 1055 1084 fprintf(stderr, "Unable to set database filename. Aborting.\n");