q66 pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=6b20fcdc8fdd498956e61aa9534bccccb3480763
commit 6b20fcdc8fdd498956e61aa9534bccccb3480763 Author: Daniel Kolesa <d.kol...@samsung.com> Date: Thu Nov 6 10:57:19 2014 +0000 elua: two-stage bytecode caching This unbreaks parallel builds where an elua process tries to read a bytecode file that is currently being written. Now, we write into a temporary file first instead and when it's written, rename. @fix --- src/bin/elua/cache.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/bin/elua/cache.c b/src/bin/elua/cache.c index ae90d30..c71fd04 100644 --- a/src/bin/elua/cache.c +++ b/src/bin/elua/cache.c @@ -60,14 +60,41 @@ writef(lua_State *L EINA_UNUSED, const void *p, size_t size, void *ud) return ferror(f) || (fwrite(p, 1, size, f) != size); } +static FILE * +bc_tmp_open(const char *fname, char *buf, size_t buflen) +{ + int fd; +#ifndef _WIN32 + mode_t old_umask; +#endif + char *fs = strrchr(fname, '/'), *bs = strrchr(fname, '\\'); + if (!fs && !bs) + snprintf(buf, buflen, "./XXXXXX"); + else + { + char *ss = (fs > bs) ? fs : bs; + snprintf(buf, buflen, "%.*sXXXXXX", (int)(ss - fname + 1), fname); + } +#ifndef _WIN32 + old_umask = umask(S_IRWXG|S_IRWXO); +#endif + fd = mkstemp(buf); +#ifndef _WIN32 + umask(old_umask); +#endif + if (fd < 0) + return NULL; + return fdopen(fd, "w"); +} + static void write_bc(lua_State *L, const char *fname) { FILE *f; - char buf[PATH_MAX]; - snprintf(buf, sizeof(buf), "%sc", fname); - if ((f = fopen(buf, "wb"))) + char buf[PATH_MAX]; + if ((f = bc_tmp_open(fname, buf, sizeof(buf)))) { + char buf2[PATH_MAX]; if (lua_dump(L, writef, f)) { fclose(f); @@ -75,6 +102,13 @@ write_bc(lua_State *L, const char *fname) (void)!!remove(buf); } else fclose(f); + snprintf(buf2, sizeof(buf2), "%sc", fname); + if (rename(buf, buf2)) + { + /* a futile attempt at cleanup */ + (void)!!remove(buf); + (void)!!remove(buf2); + } } } --