From 1e346d26a03735f09bba33ddbaba4cc9b268d381 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 9 Dec 2006 20:00:46 +0100 Subject: [PATCH] Creation of temporary files is now thread-safe (ugh). --- lib/fastbuf.h | 3 +++ lib/fb-temp.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/lib/fastbuf.h b/lib/fastbuf.h index c5e1deb8..27f0f584 100644 --- a/lib/fastbuf.h +++ b/lib/fastbuf.h @@ -88,6 +88,9 @@ struct fastbuf *bfdopen(int fd, uns buflen); struct fastbuf *bfdopen_shared(int fd, uns buflen); void bfilesync(struct fastbuf *b); +#define TEMP_FILE_NAME_LEN 256 +void temp_file_name(byte *name); + /* FastIO on in-memory streams */ struct fastbuf *fbmem_create(unsigned blocksize); /* Create stream and return its writing fastbuf */ diff --git a/lib/fb-temp.c b/lib/fb-temp.c index b8189ab9..ed7623ff 100644 --- a/lib/fb-temp.c +++ b/lib/fb-temp.c @@ -1,7 +1,7 @@ /* * UCW Library -- Temporary Fastbufs * - * (c) 2002--2004 Martin Mares + * (c) 2002--2006 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -14,29 +14,89 @@ #include #include -static byte *temp_template = "/tmp/temp%d.%d"; +static byte *temp_prefix = "/tmp/temp"; static struct cf_section temp_config = { CF_ITEMS { - CF_STRING("Template", &temp_template), + CF_STRING("Prefix", &temp_prefix), CF_END } }; -static void CONSTRUCTOR temp_init_config(void) +static void CONSTRUCTOR temp_global_init(void) { cf_declare_section("Tempfiles", &temp_config, 0); } +#ifdef CONFIG_UCW_THREADS +#include + +static pthread_key_t temp_counter_key; + +static void CONSTRUCTOR +temp_key_init(void) +{ + if (pthread_key_create(&temp_counter_key, NULL) < 0) + die("Cannot create fbdir_queue_key: %m"); +} + +void +temp_file_name(byte *buf) +{ + int cnt = (int) pthread_getspecific(temp_counter_key); + cnt++; + pthread_setspecific(temp_counter_key, (void *) cnt); + + int pid = getpid(); +#if 0 + /* FIXME: This is Linux-specific and not declared anywhere :( */ + int tid = gettid(); +#else + int tid = pid; +#endif + if (pid == tid) + sprintf(buf, "%s%d-%d", temp_prefix, pid, cnt); + else + sprintf(buf, "%s%d-%d-%d", temp_prefix, pid, tid, cnt); +} + +#else + +void +temp_file_name(byte *buf) +{ + static int cnt; + sprintf(buf, "%s%d-%d", temp_prefix, (int)getpid(), cnt++); +} + +#endif + struct fastbuf * bopen_tmp(uns buflen) { - byte buf[256]; + byte buf[TEMP_FILE_NAME_LEN]; struct fastbuf *f; - static uns temp_counter; - sprintf(buf, temp_template, (int) getpid(), temp_counter++); + temp_file_name(buf); f = bopen(buf, O_RDWR | O_CREAT | O_TRUNC, buflen); bconfig(f, BCONFIG_IS_TEMP_FILE, 1); return f; } + +#ifdef TEST + +#include "lib/getopt.h" + +int main(int argc, char **argv) +{ + log_init(NULL); + if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0) + die("Hey, whaddya want?"); + + struct fastbuf *f = bopen_tmp(65536); + bputsn(f, "Hello, world!"); + bclose(f); + return 0; +} + +#endif -- 2.39.2