Commit: 414c70435dcd52eb67df59f56132837de0a63b64 Author: Bastien Montagne Date: Mon Jun 23 13:42:19 2014 +0200 https://developer.blender.org/rB414c70435dcd52eb67df59f56132837de0a63b64
T39690: Modifications to Blender's 'temp dir' system. Current temporary data of Blender suffers one major issue - default 'temp' dir on Windows is never automatically cleaned up, and can end being quite big when used by Blender, especially when we have to store per-process data (using getpid() in file names). To address this, this patch: * Divides tempdir paths in two, one for 'base' temp dir (the same as previous unique tempdir path), the other is a mkdtemp-generated sub-dir, specific to each Blender instance. * Only uses base tempdir when we need some shallow persistance accross Blender sessions - and we always reuse the same filename (quit.blend...) or generate small file (crash reports...). * Uses temp sub-dir for heavy files like pointcache or renderEXRs (Save Buffer option). * Erases temp sub-dir on quit or crash. To get this working it also adds a working 'recursive delete' to BLI_delete() under Windows. Note that, as in current code, the 'recover render result' hack-feature that was possible with SaveBuffer option is still removed. A real renderresult cache feature will be added soon, though. Reviewers: campbellbarton, brecht, sergey Reviewed By: campbellbarton, sergey CC: sergey Differential Revision: https://developer.blender.org/D531 =================================================================== M source/blender/blenkernel/intern/blender.c M source/blender/blenkernel/intern/modifier.c M source/blender/blenkernel/intern/pointcache.c M source/blender/blenkernel/intern/smoke.c M source/blender/blenlib/BLI_path_util.h M source/blender/blenlib/intern/fileops.c M source/blender/blenlib/intern/path_util.c M source/blender/compositor/intern/COM_Debug.cpp M source/blender/editors/space_view3d/view3d_ops.c M source/blender/makesrna/intern/rna_userdef.c M source/blender/python/intern/bpy_app.c M source/blender/render/intern/source/render_result.c M source/blender/windowmanager/intern/wm_files.c M source/blender/windowmanager/intern/wm_init_exit.c M source/blender/windowmanager/intern/wm_operators.c M source/creator/creator.c M source/gameengine/GamePlayer/ghost/GPG_ghost.cpp =================================================================== diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 38a180f..a71d398 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -668,7 +668,7 @@ void BKE_write_undo(bContext *C, const char *name) counter = counter % U.undosteps; BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); - BLI_make_file_string("/", filepath, BLI_temporary_dir(), numstr); + BLI_make_file_string("/", filepath, BLI_temp_dir_session(), numstr); /* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index b5cbec2..1c42603 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -709,7 +709,7 @@ const char *modifier_path_relbase(Object *ob) else { /* last resort, better then using "" which resolves to the current * working directory */ - return BLI_temporary_dir(); + return BLI_temp_dir_session(); } } @@ -719,7 +719,7 @@ void modifier_path_init(char *path, int path_maxlen, const char *name) /* elubie: changed this to default to the same dir as the render output * to prevent saving to C:\ on Windows */ BLI_join_dirfile(path, path_maxlen, - G.relbase_valid ? "//" : BLI_temporary_dir(), + G.relbase_valid ? "//" : BLI_temp_dir_session(), name); } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index c804217..063a81e 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -51,7 +51,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_system.h" -#include BLI_SYSTEM_PID_H #include "BLF_translation.h" @@ -96,7 +95,6 @@ #endif /* needed for directory lookup */ -/* untitled blend's need getpid for a unique name */ #ifndef WIN32 # include <dirent.h> #else @@ -1466,7 +1464,7 @@ static int ptcache_path(PTCacheID *pid, char *filename) /* use the temp path. this is weak but better then not using point cache at all */ /* temporary directory is assumed to exist and ALWAYS has a trailing slash */ - BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH"%d", BLI_temporary_dir(), abs(getpid())); + BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH, BLI_temp_dir_session()); return BLI_add_slash(filename); /* new strlen() */ } diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index bfbd8c6..89245d2 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -205,7 +205,7 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[ /* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */ BLI_lock_thread(LOCK_FFTW); - sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BLI_temporary_dir(), use_fire, use_colors); + sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BLI_temp_dir_session(), use_fire, use_colors); BLI_unlock_thread(LOCK_FFTW); diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index b33b26a..244c308 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -191,12 +191,14 @@ void BLI_char_switch(char *string, char from, char to) ATTR_NONNULL(); void BLI_init_program_path(const char *argv0); /* Initialize path to temporary directory. * NOTE: On Window userdir will be set to the temporary directory! */ -void BLI_init_temporary_dir(char *userdir); +void BLI_temp_dir_init(char *userdir); const char *BLI_program_path(void); const char *BLI_program_dir(void); -const char *BLI_temporary_dir(void); +const char *BLI_temp_dir_session(void); +const char *BLI_temp_dir_base(void); void BLI_system_temporary_dir(char *dir); +void BLI_temp_dir_session_purge(void); #ifdef WITH_ICONV void BLI_string_to_utf8(char *original, char *utf_8, const char *code); diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 5df4675..c1a103b 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -48,6 +48,7 @@ # include <io.h> # include "BLI_winstuff.h" # include "BLI_callbacks.h" +# include "BLI_fileops_types.h" # include "utf_winfunc.h" # include "utfconv.h" #else @@ -284,26 +285,72 @@ int BLI_access(const char *filename, int mode) return uaccess(filename, mode); } -int BLI_delete(const char *file, bool dir, bool recursive) +static bool delete_unique(const char *path, const bool dir) { - int err; - - UTF16_ENCODE(file); + bool err; - if (recursive) { - callLocalErrorCallBack("Recursive delete is unsupported on Windows"); - err = 1; - } - else if (dir) { - err = !RemoveDirectoryW(file_16); + UTF16_ENCODE(path); + + if (dir) { + err = !RemoveDirectoryW(path_16); if (err) printf("Unable to remove directory"); } else { - err = !DeleteFileW(file_16); + err = !DeleteFileW(path_16); if (err) callLocalErrorCallBack("Unable to delete file"); } - UTF16_UN_ENCODE(file); + UTF16_UN_ENCODE(path); + + return err; +} + +static bool delete_recursive(const char *dir) +{ + struct direntry *filelist, *fl; + bool err = false; + unsigned int nbr, i; + + i = nbr = BLI_dir_contents(dir, &filelist); + fl = filelist; + while(i--) { + char file[8]; + BLI_split_file_part(fl->path, file, sizeof(file)); + if (STREQ(file, ".") || STREQ(file, "..")) { + /* Skip! */ + } + else if (S_ISDIR(fl->type)) { + if (delete_recursive(fl->path) { + err = true; + } + } + else { + if (delete_unique(fl->path, false)) { + err = true; + } + } + ++fl; + } + + if (!err && delete_unique(dir, true)) { + err = true; + } + + BLI_free_filelist(filelist, nbr); + + return err; +} + +int BLI_delete(const char *file, bool dir, bool recursive) +{ + int err; + + if (recursive) { + err = delete_recursive(file); + } + else { + err = delete_unique(file, dir); + } return err; } diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index e00631f..d95cb5e 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -49,9 +49,9 @@ #include "GHOST_Path-api.h" -#ifdef WIN32 -# include "MEM_guardedalloc.h" +#include "MEM_guardedalloc.h" +#ifdef WIN32 # include "utf_winfunc.h" # include "utfconv.h" # include <io.h> @@ -73,7 +73,8 @@ static char bprogname[FILE_MAX]; /* full path to program executable */ static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */ -static char btempdir[FILE_MAX]; /* temporary directory */ +static char btempdir_base[FILE_MAX]; /* persistent temporary directory */ +static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */ /* implementation */ @@ -2319,14 +2320,21 @@ const char *BLI_program_dir(void) * * Also make sure the temp dir has a trailing slash * - * \param fullname The full path to the temp directory + * \param fullname The full path to the temporary temp directory + * \param basename The full path to the persistent temp directory (may be NULL) * \param maxlen The size of the fullname buffer * \param userdir Directory specified in user preferences */ -static void BLI_where_is_temp(char *fullname, const size_t maxlen, char *userdir) +static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir) { + /* Clear existing temp dir, if needed. */ + BLI_temp_dir_session_purge(); + fullname[0] = '\0'; - + if (basename) { + basename[0] = '\0'; + } + if (userdir && BLI_is_dir(userdir)) { BLI_strncpy(fullname, userdir, maxlen); } @@ -2368,23 +2376,59 @@ static void BLI_where_is_temp(char *fullname, const size_t maxlen, char *userdir } #endif } + + /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ + if (basename) { + /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */ + char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX"); + const size_t ln = strlen(tmp_name) + 1; + if (ln <= maxlen) { +#ifdef WIN32 + if (_mktemp_s(tmp_name, ln) == 0) { + BLI_dir_create_recursive(tmp_name); + } +#else + mkdtemp(tmp_name); +#endif + } + if (BLI_is_dir(tmp_name)) { + BLI_strncpy(basename, fullname, maxlen); + BLI_strncpy(fullname, tmp_name, maxlen); + BLI_add_slash(fullname); + } + else { + printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname); + } + + MEM_freeN(tmp_name); + } } /** - * Sets btempdir to userdir if specified and is a valid directory, otherwise + * Sets btempdir_base to userdir if specified and is a valid directory, otherwise * chooses a suitable OS-specific temporary directory. + * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base. */ -void BLI_init_temporary_dir(char *userdir) +void BLI_temp_dir_init(char *userdir) { - BLI_where_is_temp(btempdir, FILE_MAX, userdir); + BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir); +; } /** * Path to temporary directory (with trailing slash) */ -const char *BLI_temporary_dir(void) +const char *BLI_temp_dir_session(void) +{ + return btempdir_session[0] ? btempdir_session : BLI_temp_dir_base(); +} + +/** + * Path to persistent temporary directory (with trailing slash) + */ +const char *BLI_temp_dir_base(void) { - return btempdir; + return btempdir_base; } /** @@ -2392,7 +2436,17 @@ const char *BLI_temporary_dir(void) */ void BLI_system_temporary_dir(char *dir) { - BLI_where_is_temp(dir, FILE_MAX, NULL); + BLI_where_is_temp(dir, NULL, FILE_MAX, NULL); +} + +/** + * Delete content of this instance's temp dir. + */ +void BLI_temp_dir_session_purge(void) +{ + if (btempdir_session[0] && BLI_is_dir(btempdir_session)) { + BLI_delete(btempdir_session, true, true); + @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-blender-cvs
