Check-in [cf4ca88d48]
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");